2 Unix SMB/CIFS implementation.
3 test suite for various write operations
5 Copyright (C) Andrew Tridgell 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 "system/time.h"
24 #include "system/filesys.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
28 #define CHECK_STATUS(status, correct) do { \
29 if (!NT_STATUS_EQUAL(status, correct)) { \
30 printf("(%s) Incorrect status %s - should be %s\n", \
31 __location__, nt_errstr(status), nt_errstr(correct)); \
36 #define CHECK_VALUE(v, correct) do { \
37 if ((v) != (correct)) { \
38 printf("(%s) Incorrect value %s=%d - should be %d\n", \
39 __location__, #v, v, correct); \
44 #define CHECK_BUFFER(buf, seed, len) do { \
45 if (!check_buffer(buf, seed, len, __location__)) { \
50 #define CHECK_ALL_INFO(v, field) do { \
51 finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
52 finfo.all_info.in.file.path = fname; \
53 status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
54 CHECK_STATUS(status, NT_STATUS_OK); \
55 if ((v) != finfo.all_info.out.field) { \
56 printf("(%s) wrong value for field %s %.0f - %.0f\n", \
57 __location__, #field, (double)v, (double)finfo.all_info.out.field); \
58 dump_all_info(tctx, &finfo); \
63 #define BASEDIR "\\testwrite"
67 setup a random buffer based on a seed
69 static void setup_buffer(uint8_t *buf
, unsigned int seed
, int len
)
73 for (i
=0;i
<len
;i
++) buf
[i
] = random();
77 check a random buffer based on a seed
79 static bool check_buffer(uint8_t *buf
, unsigned int seed
, int len
, const char *location
)
86 printf("Buffer incorrect at %s! ofs=%d buf=0x%x correct=0x%x\n",
87 location
, i
, buf
[i
], v
);
97 static bool test_write(struct torture_context
*tctx
,
98 struct smbcli_state
*cli
)
105 const int maxsize
= 90000;
106 const char *fname
= BASEDIR
"\\test.txt";
107 unsigned int seed
= time(NULL
);
108 union smb_fileinfo finfo
;
110 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
112 if (!torture_setup_dir(cli
, BASEDIR
)) {
116 printf("Testing RAW_WRITE_WRITE\n");
117 io
.generic
.level
= RAW_WRITE_WRITE
;
119 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
121 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
126 printf("Trying zero write\n");
127 io
.write
.in
.file
.fnum
= fnum
;
128 io
.write
.in
.count
= 0;
129 io
.write
.in
.offset
= 0;
130 io
.write
.in
.remaining
= 0;
131 io
.write
.in
.data
= buf
;
132 status
= smb_raw_write(cli
->tree
, &io
);
133 CHECK_STATUS(status
, NT_STATUS_OK
);
134 CHECK_VALUE(io
.write
.out
.nwritten
, 0);
136 setup_buffer(buf
, seed
, maxsize
);
138 printf("Trying small write\n");
139 io
.write
.in
.count
= 9;
140 io
.write
.in
.offset
= 4;
141 io
.write
.in
.data
= buf
;
142 status
= smb_raw_write(cli
->tree
, &io
);
143 CHECK_STATUS(status
, NT_STATUS_OK
);
144 CHECK_VALUE(io
.write
.out
.nwritten
, io
.write
.in
.count
);
146 memset(buf
, 0, maxsize
);
147 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
148 printf("read failed at %s\n", __location__
);
152 CHECK_BUFFER(buf
+4, seed
, 9);
153 CHECK_VALUE(IVAL(buf
,0), 0);
155 setup_buffer(buf
, seed
, maxsize
);
157 printf("Trying large write\n");
158 io
.write
.in
.count
= 4000;
159 io
.write
.in
.offset
= 0;
160 io
.write
.in
.data
= buf
;
161 status
= smb_raw_write(cli
->tree
, &io
);
162 CHECK_STATUS(status
, NT_STATUS_OK
);
163 CHECK_VALUE(io
.write
.out
.nwritten
, 4000);
165 memset(buf
, 0, maxsize
);
166 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
167 printf("read failed at %s\n", __location__
);
171 CHECK_BUFFER(buf
, seed
, 4000);
173 printf("Trying bad fnum\n");
174 io
.write
.in
.file
.fnum
= fnum
+1;
175 io
.write
.in
.count
= 4000;
176 io
.write
.in
.offset
= 0;
177 io
.write
.in
.data
= buf
;
178 status
= smb_raw_write(cli
->tree
, &io
);
179 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
181 printf("Setting file as sparse\n");
182 status
= torture_set_sparse(cli
->tree
, fnum
);
183 CHECK_STATUS(status
, NT_STATUS_OK
);
185 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
186 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
190 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
191 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
195 printf("Trying 2^32 offset\n");
196 setup_buffer(buf
, seed
, maxsize
);
197 io
.write
.in
.file
.fnum
= fnum
;
198 io
.write
.in
.count
= 4000;
199 io
.write
.in
.offset
= 0xFFFFFFFF - 2000;
200 io
.write
.in
.data
= buf
;
201 status
= smb_raw_write(cli
->tree
, &io
);
202 CHECK_STATUS(status
, NT_STATUS_OK
);
203 CHECK_VALUE(io
.write
.out
.nwritten
, 4000);
204 CHECK_ALL_INFO(io
.write
.in
.count
+ (uint64_t)io
.write
.in
.offset
, size
);
206 memset(buf
, 0, maxsize
);
207 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.write
.in
.offset
, 4000) != 4000) {
208 printf("read failed at %s\n", __location__
);
212 CHECK_BUFFER(buf
, seed
, 4000);
215 smbcli_close(cli
->tree
, fnum
);
216 smb_raw_exit(cli
->session
);
217 smbcli_deltree(cli
->tree
, BASEDIR
);
225 static bool test_writex(struct torture_context
*tctx
,
226 struct smbcli_state
*cli
)
233 const int maxsize
= 90000;
234 const char *fname
= BASEDIR
"\\test.txt";
235 unsigned int seed
= time(NULL
);
236 union smb_fileinfo finfo
;
239 if (!torture_setting_bool(tctx
, "dangerous", false)) {
241 torture_comment(tctx
, "dangerous not set - limiting range of test to 2^%d\n", max_bits
);
244 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
246 if (!torture_setup_dir(cli
, BASEDIR
)) {
250 printf("Testing RAW_WRITE_WRITEX\n");
251 io
.generic
.level
= RAW_WRITE_WRITEX
;
253 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
255 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
260 printf("Trying zero write\n");
261 io
.writex
.in
.file
.fnum
= fnum
;
262 io
.writex
.in
.offset
= 0;
263 io
.writex
.in
.wmode
= 0;
264 io
.writex
.in
.remaining
= 0;
265 io
.writex
.in
.count
= 0;
266 io
.writex
.in
.data
= buf
;
267 status
= smb_raw_write(cli
->tree
, &io
);
268 CHECK_STATUS(status
, NT_STATUS_OK
);
269 CHECK_VALUE(io
.writex
.out
.nwritten
, 0);
271 setup_buffer(buf
, seed
, maxsize
);
273 printf("Trying small write\n");
274 io
.writex
.in
.count
= 9;
275 io
.writex
.in
.offset
= 4;
276 io
.writex
.in
.data
= buf
;
277 status
= smb_raw_write(cli
->tree
, &io
);
278 CHECK_STATUS(status
, NT_STATUS_OK
);
279 CHECK_VALUE(io
.writex
.out
.nwritten
, io
.writex
.in
.count
);
281 memset(buf
, 0, maxsize
);
282 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
283 printf("read failed at %s\n", __location__
);
287 CHECK_BUFFER(buf
+4, seed
, 9);
288 CHECK_VALUE(IVAL(buf
,0), 0);
290 setup_buffer(buf
, seed
, maxsize
);
292 printf("Trying large write\n");
293 io
.writex
.in
.count
= 4000;
294 io
.writex
.in
.offset
= 0;
295 io
.writex
.in
.data
= buf
;
296 status
= smb_raw_write(cli
->tree
, &io
);
297 CHECK_STATUS(status
, NT_STATUS_OK
);
298 CHECK_VALUE(io
.writex
.out
.nwritten
, 4000);
300 memset(buf
, 0, maxsize
);
301 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
302 printf("read failed at %s\n", __location__
);
306 CHECK_BUFFER(buf
, seed
, 4000);
308 printf("Trying bad fnum\n");
309 io
.writex
.in
.file
.fnum
= fnum
+1;
310 io
.writex
.in
.count
= 4000;
311 io
.writex
.in
.offset
= 0;
312 io
.writex
.in
.data
= buf
;
313 status
= smb_raw_write(cli
->tree
, &io
);
314 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
316 printf("Testing wmode\n");
317 io
.writex
.in
.file
.fnum
= fnum
;
318 io
.writex
.in
.count
= 1;
319 io
.writex
.in
.offset
= 0;
320 io
.writex
.in
.wmode
= 1;
321 io
.writex
.in
.data
= buf
;
322 status
= smb_raw_write(cli
->tree
, &io
);
323 CHECK_STATUS(status
, NT_STATUS_OK
);
324 CHECK_VALUE(io
.writex
.out
.nwritten
, io
.writex
.in
.count
);
326 io
.writex
.in
.wmode
= 2;
327 status
= smb_raw_write(cli
->tree
, &io
);
328 CHECK_STATUS(status
, NT_STATUS_OK
);
329 CHECK_VALUE(io
.writex
.out
.nwritten
, io
.writex
.in
.count
);
332 printf("Trying locked region\n");
334 if (NT_STATUS_IS_ERR(smbcli_lock(cli
->tree
, fnum
, 3, 1, 0, WRITE_LOCK
))) {
335 printf("Failed to lock file at %s\n", __location__
);
340 io
.writex
.in
.wmode
= 0;
341 io
.writex
.in
.count
= 4;
342 io
.writex
.in
.offset
= 0;
343 status
= smb_raw_write(cli
->tree
, &io
);
344 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
346 printf("Setting file as sparse\n");
347 status
= torture_set_sparse(cli
->tree
, fnum
);
348 CHECK_STATUS(status
, NT_STATUS_OK
);
350 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
351 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
355 printf("Trying 2^32 offset\n");
356 setup_buffer(buf
, seed
, maxsize
);
357 io
.writex
.in
.file
.fnum
= fnum
;
358 io
.writex
.in
.count
= 4000;
359 io
.writex
.in
.offset
= 0xFFFFFFFF - 2000;
360 io
.writex
.in
.data
= buf
;
361 status
= smb_raw_write(cli
->tree
, &io
);
362 CHECK_STATUS(status
, NT_STATUS_OK
);
363 CHECK_VALUE(io
.writex
.out
.nwritten
, 4000);
364 CHECK_ALL_INFO(io
.writex
.in
.count
+ (uint64_t)io
.writex
.in
.offset
, size
);
366 memset(buf
, 0, maxsize
);
367 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writex
.in
.offset
, 4000) != 4000) {
368 printf("read failed at %s\n", __location__
);
372 CHECK_BUFFER(buf
, seed
, 4000);
374 for (i
=33;i
<max_bits
;i
++) {
375 printf("Trying 2^%d offset\n", i
);
376 setup_buffer(buf
, seed
+1, maxsize
);
377 io
.writex
.in
.file
.fnum
= fnum
;
378 io
.writex
.in
.count
= 4000;
379 io
.writex
.in
.offset
= ((uint64_t)1) << i
;
380 io
.writex
.in
.data
= buf
;
381 status
= smb_raw_write(cli
->tree
, &io
);
383 NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
386 CHECK_STATUS(status
, NT_STATUS_OK
);
387 CHECK_VALUE(io
.writex
.out
.nwritten
, 4000);
388 CHECK_ALL_INFO(io
.writex
.in
.count
+ (uint64_t)io
.writex
.in
.offset
, size
);
390 memset(buf
, 0, maxsize
);
391 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writex
.in
.offset
, 4000) != 4000) {
392 printf("read failed at %s\n", __location__
);
396 CHECK_BUFFER(buf
, seed
+1, 4000);
398 printf("limit is 2^%d\n", i
);
400 setup_buffer(buf
, seed
, maxsize
);
403 smbcli_close(cli
->tree
, fnum
);
404 smb_raw_exit(cli
->session
);
405 smbcli_deltree(cli
->tree
, BASEDIR
);
411 test write unlock ops
413 static bool test_writeunlock(struct torture_context
*tctx
,
414 struct smbcli_state
*cli
)
421 const int maxsize
= 90000;
422 const char *fname
= BASEDIR
"\\test.txt";
423 unsigned int seed
= time(NULL
);
424 union smb_fileinfo finfo
;
426 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
428 if (!cli
->transport
->negotiate
.lockread_supported
) {
429 printf("Server does not support writeunlock - skipping\n");
433 if (!torture_setup_dir(cli
, BASEDIR
)) {
437 printf("Testing RAW_WRITE_WRITEUNLOCK\n");
438 io
.generic
.level
= RAW_WRITE_WRITEUNLOCK
;
440 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
442 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
447 printf("Trying zero write\n");
448 io
.writeunlock
.in
.file
.fnum
= fnum
;
449 io
.writeunlock
.in
.count
= 0;
450 io
.writeunlock
.in
.offset
= 0;
451 io
.writeunlock
.in
.remaining
= 0;
452 io
.writeunlock
.in
.data
= buf
;
453 status
= smb_raw_write(cli
->tree
, &io
);
454 CHECK_STATUS(status
, NT_STATUS_OK
);
455 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, io
.writeunlock
.in
.count
);
457 setup_buffer(buf
, seed
, maxsize
);
459 printf("Trying small write\n");
460 io
.writeunlock
.in
.count
= 9;
461 io
.writeunlock
.in
.offset
= 4;
462 io
.writeunlock
.in
.data
= buf
;
463 status
= smb_raw_write(cli
->tree
, &io
);
464 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
465 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
466 printf("read failed at %s\n", __location__
);
470 CHECK_BUFFER(buf
+4, seed
, 9);
471 CHECK_VALUE(IVAL(buf
,0), 0);
473 setup_buffer(buf
, seed
, maxsize
);
474 smbcli_lock(cli
->tree
, fnum
, io
.writeunlock
.in
.offset
, io
.writeunlock
.in
.count
,
476 status
= smb_raw_write(cli
->tree
, &io
);
477 CHECK_STATUS(status
, NT_STATUS_OK
);
478 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, io
.writeunlock
.in
.count
);
480 memset(buf
, 0, maxsize
);
481 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
482 printf("read failed at %s\n", __location__
);
486 CHECK_BUFFER(buf
+4, seed
, 9);
487 CHECK_VALUE(IVAL(buf
,0), 0);
489 setup_buffer(buf
, seed
, maxsize
);
491 printf("Trying large write\n");
492 io
.writeunlock
.in
.count
= 4000;
493 io
.writeunlock
.in
.offset
= 0;
494 io
.writeunlock
.in
.data
= buf
;
495 smbcli_lock(cli
->tree
, fnum
, io
.writeunlock
.in
.offset
, io
.writeunlock
.in
.count
,
497 status
= smb_raw_write(cli
->tree
, &io
);
498 CHECK_STATUS(status
, NT_STATUS_OK
);
499 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, 4000);
501 status
= smb_raw_write(cli
->tree
, &io
);
502 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
504 memset(buf
, 0, maxsize
);
505 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
506 printf("read failed at %s\n", __location__
);
510 CHECK_BUFFER(buf
, seed
, 4000);
512 printf("Trying bad fnum\n");
513 io
.writeunlock
.in
.file
.fnum
= fnum
+1;
514 io
.writeunlock
.in
.count
= 4000;
515 io
.writeunlock
.in
.offset
= 0;
516 io
.writeunlock
.in
.data
= buf
;
517 status
= smb_raw_write(cli
->tree
, &io
);
518 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
520 printf("Setting file as sparse\n");
521 status
= torture_set_sparse(cli
->tree
, fnum
);
522 CHECK_STATUS(status
, NT_STATUS_OK
);
524 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
525 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
529 printf("Trying 2^32 offset\n");
530 setup_buffer(buf
, seed
, maxsize
);
531 io
.writeunlock
.in
.file
.fnum
= fnum
;
532 io
.writeunlock
.in
.count
= 4000;
533 io
.writeunlock
.in
.offset
= 0xFFFFFFFF - 2000;
534 io
.writeunlock
.in
.data
= buf
;
535 smbcli_lock(cli
->tree
, fnum
, io
.writeunlock
.in
.offset
, io
.writeunlock
.in
.count
,
537 status
= smb_raw_write(cli
->tree
, &io
);
538 CHECK_STATUS(status
, NT_STATUS_OK
);
539 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, 4000);
540 CHECK_ALL_INFO(io
.writeunlock
.in
.count
+ (uint64_t)io
.writeunlock
.in
.offset
, size
);
542 memset(buf
, 0, maxsize
);
543 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writeunlock
.in
.offset
, 4000) != 4000) {
544 printf("read failed at %s\n", __location__
);
548 CHECK_BUFFER(buf
, seed
, 4000);
551 smbcli_close(cli
->tree
, fnum
);
552 smb_raw_exit(cli
->session
);
553 smbcli_deltree(cli
->tree
, BASEDIR
);
561 static bool test_writeclose(struct torture_context
*tctx
,
562 struct smbcli_state
*cli
)
569 const int maxsize
= 90000;
570 const char *fname
= BASEDIR
"\\test.txt";
571 unsigned int seed
= time(NULL
);
572 union smb_fileinfo finfo
;
574 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
576 if (!torture_setting_bool(tctx
, "writeclose_support", true)) {
577 printf("Server does not support writeclose - skipping\n");
581 if (!torture_setup_dir(cli
, BASEDIR
)) {
585 printf("Testing RAW_WRITE_WRITECLOSE\n");
586 io
.generic
.level
= RAW_WRITE_WRITECLOSE
;
588 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
590 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
595 printf("Trying zero write\n");
596 io
.writeclose
.in
.file
.fnum
= fnum
;
597 io
.writeclose
.in
.count
= 0;
598 io
.writeclose
.in
.offset
= 0;
599 io
.writeclose
.in
.mtime
= 0;
600 io
.writeclose
.in
.data
= buf
;
601 status
= smb_raw_write(cli
->tree
, &io
);
602 CHECK_STATUS(status
, NT_STATUS_OK
);
603 CHECK_VALUE(io
.writeclose
.out
.nwritten
, io
.writeclose
.in
.count
);
605 status
= smb_raw_write(cli
->tree
, &io
);
606 CHECK_STATUS(status
, NT_STATUS_OK
);
607 CHECK_VALUE(io
.writeclose
.out
.nwritten
, io
.writeclose
.in
.count
);
609 setup_buffer(buf
, seed
, maxsize
);
611 printf("Trying small write\n");
612 io
.writeclose
.in
.count
= 9;
613 io
.writeclose
.in
.offset
= 4;
614 io
.writeclose
.in
.data
= buf
;
615 status
= smb_raw_write(cli
->tree
, &io
);
616 CHECK_STATUS(status
, NT_STATUS_OK
);
618 status
= smb_raw_write(cli
->tree
, &io
);
619 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
621 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
622 io
.writeclose
.in
.file
.fnum
= fnum
;
624 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
625 printf("read failed at %s\n", __location__
);
629 CHECK_BUFFER(buf
+4, seed
, 9);
630 CHECK_VALUE(IVAL(buf
,0), 0);
632 setup_buffer(buf
, seed
, maxsize
);
633 status
= smb_raw_write(cli
->tree
, &io
);
634 CHECK_STATUS(status
, NT_STATUS_OK
);
635 CHECK_VALUE(io
.writeclose
.out
.nwritten
, io
.writeclose
.in
.count
);
637 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
638 io
.writeclose
.in
.file
.fnum
= fnum
;
640 memset(buf
, 0, maxsize
);
641 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
642 printf("read failed at %s\n", __location__
);
646 CHECK_BUFFER(buf
+4, seed
, 9);
647 CHECK_VALUE(IVAL(buf
,0), 0);
649 setup_buffer(buf
, seed
, maxsize
);
651 printf("Trying large write\n");
652 io
.writeclose
.in
.count
= 4000;
653 io
.writeclose
.in
.offset
= 0;
654 io
.writeclose
.in
.data
= buf
;
655 status
= smb_raw_write(cli
->tree
, &io
);
656 CHECK_STATUS(status
, NT_STATUS_OK
);
657 CHECK_VALUE(io
.writeclose
.out
.nwritten
, 4000);
659 status
= smb_raw_write(cli
->tree
, &io
);
660 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
662 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
663 io
.writeclose
.in
.file
.fnum
= fnum
;
665 memset(buf
, 0, maxsize
);
666 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
667 printf("read failed at %s\n", __location__
);
671 CHECK_BUFFER(buf
, seed
, 4000);
673 printf("Trying bad fnum\n");
674 io
.writeclose
.in
.file
.fnum
= fnum
+1;
675 io
.writeclose
.in
.count
= 4000;
676 io
.writeclose
.in
.offset
= 0;
677 io
.writeclose
.in
.data
= buf
;
678 status
= smb_raw_write(cli
->tree
, &io
);
679 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
681 printf("Setting file as sparse\n");
682 status
= torture_set_sparse(cli
->tree
, fnum
);
683 CHECK_STATUS(status
, NT_STATUS_OK
);
685 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
686 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
690 printf("Trying 2^32 offset\n");
691 setup_buffer(buf
, seed
, maxsize
);
692 io
.writeclose
.in
.file
.fnum
= fnum
;
693 io
.writeclose
.in
.count
= 4000;
694 io
.writeclose
.in
.offset
= 0xFFFFFFFF - 2000;
695 io
.writeclose
.in
.data
= buf
;
696 status
= smb_raw_write(cli
->tree
, &io
);
697 CHECK_STATUS(status
, NT_STATUS_OK
);
698 CHECK_VALUE(io
.writeclose
.out
.nwritten
, 4000);
699 CHECK_ALL_INFO(io
.writeclose
.in
.count
+ (uint64_t)io
.writeclose
.in
.offset
, size
);
701 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
702 io
.writeclose
.in
.file
.fnum
= fnum
;
704 memset(buf
, 0, maxsize
);
705 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writeclose
.in
.offset
, 4000) != 4000) {
706 printf("read failed at %s\n", __location__
);
710 CHECK_BUFFER(buf
, seed
, 4000);
713 smbcli_close(cli
->tree
, fnum
);
714 smb_raw_exit(cli
->session
);
715 smbcli_deltree(cli
->tree
, BASEDIR
);
720 basic testing of write calls
722 struct torture_suite
*torture_raw_write(TALLOC_CTX
*mem_ctx
)
724 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "WRITE");
726 torture_suite_add_1smb_test(suite
, "write", test_write
);
727 torture_suite_add_1smb_test(suite
, "write unlock", test_writeunlock
);
728 torture_suite_add_1smb_test(suite
, "write close", test_writeclose
);
729 torture_suite_add_1smb_test(suite
, "writex", test_writex
);