2 Unix SMB/CIFS implementation.
3 client file read/write routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) James Myers 2003
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/raw/raw_proto.h"
24 #include "libcli/libcli.h"
26 /****************************************************************************
27 Read size bytes at offset offset using SMBreadX.
28 ****************************************************************************/
29 ssize_t
smbcli_read(struct smbcli_tree
*tree
, int fnum
, void *_buf
, off_t offset
,
32 uint8_t *buf
= (uint8_t *)_buf
;
41 parms
.readx
.level
= RAW_READ_READX
;
42 parms
.readx
.in
.file
.fnum
= fnum
;
45 * Set readsize to the maximum size we can handle in one readX,
46 * rounded down to a multiple of 1024.
48 readsize
= (tree
->session
->transport
->negotiate
.max_xmit
- (MIN_SMB_SIZE
+32));
49 if (readsize
> 0xFFFF) readsize
= 0xFFFF;
51 while (total
< size
) {
54 readsize
= MIN(readsize
, size
-total
);
56 parms
.readx
.in
.offset
= offset
;
57 parms
.readx
.in
.mincnt
= readsize
;
58 parms
.readx
.in
.maxcnt
= readsize
;
59 parms
.readx
.in
.remaining
= size
- total
;
60 parms
.readx
.in
.read_for_execute
= false;
61 parms
.readx
.out
.data
= buf
+ total
;
63 status
= smb_raw_read(tree
, &parms
);
65 if (!NT_STATUS_IS_OK(status
)) {
69 total
+= parms
.readx
.out
.nread
;
70 offset
+= parms
.readx
.out
.nread
;
72 /* If the server returned less than we asked for we're at EOF */
73 if (parms
.readx
.out
.nread
< readsize
)
81 /****************************************************************************
83 write_mode: 0x0001 disallow write caching
84 0x0002 return bytes remaining
85 0x0004 use raw named pipe protocol
86 0x0008 start of message mode named pipe protocol
87 ****************************************************************************/
88 ssize_t
smbcli_write(struct smbcli_tree
*tree
,
89 int fnum
, uint16_t write_mode
,
90 const void *_buf
, off_t offset
, size_t size
)
92 const uint8_t *buf
= (const uint8_t *)_buf
;
93 union smb_write parms
;
94 int block
= (tree
->session
->transport
->negotiate
.max_xmit
- (MIN_SMB_SIZE
+32));
101 if (block
> 0xFFFF) block
= 0xFFFF;
104 parms
.writex
.level
= RAW_WRITE_WRITEX
;
105 parms
.writex
.in
.file
.fnum
= fnum
;
106 parms
.writex
.in
.wmode
= write_mode
;
107 parms
.writex
.in
.remaining
= 0;
112 block
= MIN(block
, size
- total
);
114 parms
.writex
.in
.offset
= offset
;
115 parms
.writex
.in
.count
= block
;
116 parms
.writex
.in
.data
= buf
;
118 status
= smb_raw_write(tree
, &parms
);
120 if (!NT_STATUS_IS_OK(status
)) {
124 offset
+= parms
.writex
.out
.nwritten
;
125 total
+= parms
.writex
.out
.nwritten
;
126 buf
+= parms
.writex
.out
.nwritten
;
127 } while (total
< size
);
132 /****************************************************************************
133 write to a file using a SMBwrite and not bypassing 0 byte writes
134 ****************************************************************************/
135 ssize_t
smbcli_smbwrite(struct smbcli_tree
*tree
,
136 int fnum
, const void *_buf
, off_t offset
, size_t size1
)
138 const uint8_t *buf
= (const uint8_t *)_buf
;
139 union smb_write parms
;
142 parms
.write
.level
= RAW_WRITE_WRITE
;
143 parms
.write
.in
.remaining
= 0;
146 size_t size
= MIN(size1
, tree
->session
->transport
->negotiate
.max_xmit
- 48);
147 if (size
> 0xFFFF) size
= 0xFFFF;
149 parms
.write
.in
.file
.fnum
= fnum
;
150 parms
.write
.in
.offset
= offset
;
151 parms
.write
.in
.count
= size
;
152 parms
.write
.in
.data
= buf
+ total
;
154 if (NT_STATUS_IS_ERR(smb_raw_write(tree
, &parms
)))
157 size
= parms
.write
.out
.nwritten
;