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 "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "system/time.h"
26 #include "system/filesys.h"
27 #include "libcli/libcli.h"
28 #include "torture/util.h"
30 #define CHECK_STATUS(status, correct) do { \
31 if (!NT_STATUS_EQUAL(status, correct)) { \
32 printf("(%s) Incorrect status %s - should be %s\n", \
33 __location__, nt_errstr(status), nt_errstr(correct)); \
38 #define CHECK_VALUE(v, correct) do { \
39 if ((v) != (correct)) { \
40 printf("(%s) Incorrect value %s=%d - should be %d\n", \
41 __location__, #v, v, correct); \
46 #define CHECK_BUFFER(buf, seed, len) do { \
47 if (!check_buffer(buf, seed, len, __location__)) { \
52 #define CHECK_ALL_INFO(v, field) do { \
53 finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
54 finfo.all_info.in.file.path = fname; \
55 status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
56 CHECK_STATUS(status, NT_STATUS_OK); \
57 if ((v) != finfo.all_info.out.field) { \
58 printf("(%s) wrong value for field %s %.0f - %.0f\n", \
59 __location__, #field, (double)v, (double)finfo.all_info.out.field); \
60 dump_all_info(tctx, &finfo); \
65 #define BASEDIR "\\testwrite"
69 setup a random buffer based on a seed
71 static void setup_buffer(uint8_t *buf
, uint_t seed
, int len
)
75 for (i
=0;i
<len
;i
++) buf
[i
] = random();
79 check a random buffer based on a seed
81 static bool check_buffer(uint8_t *buf
, uint_t seed
, int len
, const char *location
)
88 printf("Buffer incorrect at %s! ofs=%d buf=0x%x correct=0x%x\n",
89 location
, i
, buf
[i
], v
);
99 static bool test_write(struct torture_context
*tctx
,
100 struct smbcli_state
*cli
)
107 const int maxsize
= 90000;
108 const char *fname
= BASEDIR
"\\test.txt";
109 uint_t seed
= time(NULL
);
110 union smb_fileinfo finfo
;
112 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
114 if (!torture_setup_dir(cli
, BASEDIR
)) {
118 printf("Testing RAW_WRITE_WRITE\n");
119 io
.generic
.level
= RAW_WRITE_WRITE
;
121 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
123 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
128 printf("Trying zero write\n");
129 io
.write
.in
.file
.fnum
= fnum
;
130 io
.write
.in
.count
= 0;
131 io
.write
.in
.offset
= 0;
132 io
.write
.in
.remaining
= 0;
133 io
.write
.in
.data
= buf
;
134 status
= smb_raw_write(cli
->tree
, &io
);
135 CHECK_STATUS(status
, NT_STATUS_OK
);
136 CHECK_VALUE(io
.write
.out
.nwritten
, 0);
138 setup_buffer(buf
, seed
, maxsize
);
140 printf("Trying small write\n");
141 io
.write
.in
.count
= 9;
142 io
.write
.in
.offset
= 4;
143 io
.write
.in
.data
= buf
;
144 status
= smb_raw_write(cli
->tree
, &io
);
145 CHECK_STATUS(status
, NT_STATUS_OK
);
146 CHECK_VALUE(io
.write
.out
.nwritten
, io
.write
.in
.count
);
148 memset(buf
, 0, maxsize
);
149 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
150 printf("read failed at %s\n", __location__
);
154 CHECK_BUFFER(buf
+4, seed
, 9);
155 CHECK_VALUE(IVAL(buf
,0), 0);
157 setup_buffer(buf
, seed
, maxsize
);
159 printf("Trying large write\n");
160 io
.write
.in
.count
= 4000;
161 io
.write
.in
.offset
= 0;
162 io
.write
.in
.data
= buf
;
163 status
= smb_raw_write(cli
->tree
, &io
);
164 CHECK_STATUS(status
, NT_STATUS_OK
);
165 CHECK_VALUE(io
.write
.out
.nwritten
, 4000);
167 memset(buf
, 0, maxsize
);
168 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
169 printf("read failed at %s\n", __location__
);
173 CHECK_BUFFER(buf
, seed
, 4000);
175 printf("Trying bad fnum\n");
176 io
.write
.in
.file
.fnum
= fnum
+1;
177 io
.write
.in
.count
= 4000;
178 io
.write
.in
.offset
= 0;
179 io
.write
.in
.data
= buf
;
180 status
= smb_raw_write(cli
->tree
, &io
);
181 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
183 printf("Setting file as sparse\n");
184 status
= torture_set_sparse(cli
->tree
, fnum
);
185 CHECK_STATUS(status
, NT_STATUS_OK
);
187 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
188 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
192 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
193 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
197 printf("Trying 2^32 offset\n");
198 setup_buffer(buf
, seed
, maxsize
);
199 io
.write
.in
.file
.fnum
= fnum
;
200 io
.write
.in
.count
= 4000;
201 io
.write
.in
.offset
= 0xFFFFFFFF - 2000;
202 io
.write
.in
.data
= buf
;
203 status
= smb_raw_write(cli
->tree
, &io
);
204 CHECK_STATUS(status
, NT_STATUS_OK
);
205 CHECK_VALUE(io
.write
.out
.nwritten
, 4000);
206 CHECK_ALL_INFO(io
.write
.in
.count
+ (uint64_t)io
.write
.in
.offset
, size
);
208 memset(buf
, 0, maxsize
);
209 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.write
.in
.offset
, 4000) != 4000) {
210 printf("read failed at %s\n", __location__
);
214 CHECK_BUFFER(buf
, seed
, 4000);
217 smbcli_close(cli
->tree
, fnum
);
218 smb_raw_exit(cli
->session
);
219 smbcli_deltree(cli
->tree
, BASEDIR
);
227 static bool test_writex(struct torture_context
*tctx
,
228 struct smbcli_state
*cli
)
235 const int maxsize
= 90000;
236 const char *fname
= BASEDIR
"\\test.txt";
237 uint_t seed
= time(NULL
);
238 union smb_fileinfo finfo
;
241 if (!torture_setting_bool(tctx
, "dangerous", false)) {
243 torture_comment(tctx
, "dangerous not set - limiting range of test to 2^%d\n", max_bits
);
246 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
248 if (!torture_setup_dir(cli
, BASEDIR
)) {
252 printf("Testing RAW_WRITE_WRITEX\n");
253 io
.generic
.level
= RAW_WRITE_WRITEX
;
255 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
257 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
262 printf("Trying zero write\n");
263 io
.writex
.in
.file
.fnum
= fnum
;
264 io
.writex
.in
.offset
= 0;
265 io
.writex
.in
.wmode
= 0;
266 io
.writex
.in
.remaining
= 0;
267 io
.writex
.in
.count
= 0;
268 io
.writex
.in
.data
= buf
;
269 status
= smb_raw_write(cli
->tree
, &io
);
270 CHECK_STATUS(status
, NT_STATUS_OK
);
271 CHECK_VALUE(io
.writex
.out
.nwritten
, 0);
273 setup_buffer(buf
, seed
, maxsize
);
275 printf("Trying small write\n");
276 io
.writex
.in
.count
= 9;
277 io
.writex
.in
.offset
= 4;
278 io
.writex
.in
.data
= buf
;
279 status
= smb_raw_write(cli
->tree
, &io
);
280 CHECK_STATUS(status
, NT_STATUS_OK
);
281 CHECK_VALUE(io
.writex
.out
.nwritten
, io
.writex
.in
.count
);
283 memset(buf
, 0, maxsize
);
284 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
285 printf("read failed at %s\n", __location__
);
289 CHECK_BUFFER(buf
+4, seed
, 9);
290 CHECK_VALUE(IVAL(buf
,0), 0);
292 setup_buffer(buf
, seed
, maxsize
);
294 printf("Trying large write\n");
295 io
.writex
.in
.count
= 4000;
296 io
.writex
.in
.offset
= 0;
297 io
.writex
.in
.data
= buf
;
298 status
= smb_raw_write(cli
->tree
, &io
);
299 CHECK_STATUS(status
, NT_STATUS_OK
);
300 CHECK_VALUE(io
.writex
.out
.nwritten
, 4000);
302 memset(buf
, 0, maxsize
);
303 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
304 printf("read failed at %s\n", __location__
);
308 CHECK_BUFFER(buf
, seed
, 4000);
310 printf("Trying bad fnum\n");
311 io
.writex
.in
.file
.fnum
= fnum
+1;
312 io
.writex
.in
.count
= 4000;
313 io
.writex
.in
.offset
= 0;
314 io
.writex
.in
.data
= buf
;
315 status
= smb_raw_write(cli
->tree
, &io
);
316 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
318 printf("Testing wmode\n");
319 io
.writex
.in
.file
.fnum
= fnum
;
320 io
.writex
.in
.count
= 1;
321 io
.writex
.in
.offset
= 0;
322 io
.writex
.in
.wmode
= 1;
323 io
.writex
.in
.data
= buf
;
324 status
= smb_raw_write(cli
->tree
, &io
);
325 CHECK_STATUS(status
, NT_STATUS_OK
);
326 CHECK_VALUE(io
.writex
.out
.nwritten
, io
.writex
.in
.count
);
328 io
.writex
.in
.wmode
= 2;
329 status
= smb_raw_write(cli
->tree
, &io
);
330 CHECK_STATUS(status
, NT_STATUS_OK
);
331 CHECK_VALUE(io
.writex
.out
.nwritten
, io
.writex
.in
.count
);
334 printf("Trying locked region\n");
336 if (NT_STATUS_IS_ERR(smbcli_lock(cli
->tree
, fnum
, 3, 1, 0, WRITE_LOCK
))) {
337 printf("Failed to lock file at %s\n", __location__
);
342 io
.writex
.in
.wmode
= 0;
343 io
.writex
.in
.count
= 4;
344 io
.writex
.in
.offset
= 0;
345 status
= smb_raw_write(cli
->tree
, &io
);
346 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
348 printf("Setting file as sparse\n");
349 status
= torture_set_sparse(cli
->tree
, fnum
);
350 CHECK_STATUS(status
, NT_STATUS_OK
);
352 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
353 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
357 printf("Trying 2^32 offset\n");
358 setup_buffer(buf
, seed
, maxsize
);
359 io
.writex
.in
.file
.fnum
= fnum
;
360 io
.writex
.in
.count
= 4000;
361 io
.writex
.in
.offset
= 0xFFFFFFFF - 2000;
362 io
.writex
.in
.data
= buf
;
363 status
= smb_raw_write(cli
->tree
, &io
);
364 CHECK_STATUS(status
, NT_STATUS_OK
);
365 CHECK_VALUE(io
.writex
.out
.nwritten
, 4000);
366 CHECK_ALL_INFO(io
.writex
.in
.count
+ (uint64_t)io
.writex
.in
.offset
, size
);
368 memset(buf
, 0, maxsize
);
369 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writex
.in
.offset
, 4000) != 4000) {
370 printf("read failed at %s\n", __location__
);
374 CHECK_BUFFER(buf
, seed
, 4000);
376 for (i
=33;i
<max_bits
;i
++) {
377 printf("Trying 2^%d offset\n", i
);
378 setup_buffer(buf
, seed
+1, maxsize
);
379 io
.writex
.in
.file
.fnum
= fnum
;
380 io
.writex
.in
.count
= 4000;
381 io
.writex
.in
.offset
= ((uint64_t)1) << i
;
382 io
.writex
.in
.data
= buf
;
383 status
= smb_raw_write(cli
->tree
, &io
);
385 NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
388 CHECK_STATUS(status
, NT_STATUS_OK
);
389 CHECK_VALUE(io
.writex
.out
.nwritten
, 4000);
390 CHECK_ALL_INFO(io
.writex
.in
.count
+ (uint64_t)io
.writex
.in
.offset
, size
);
392 memset(buf
, 0, maxsize
);
393 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writex
.in
.offset
, 4000) != 4000) {
394 printf("read failed at %s\n", __location__
);
398 CHECK_BUFFER(buf
, seed
+1, 4000);
400 printf("limit is 2^%d\n", i
);
402 setup_buffer(buf
, seed
, maxsize
);
405 smbcli_close(cli
->tree
, fnum
);
406 smb_raw_exit(cli
->session
);
407 smbcli_deltree(cli
->tree
, BASEDIR
);
413 test write unlock ops
415 static bool test_writeunlock(struct torture_context
*tctx
,
416 struct smbcli_state
*cli
)
423 const int maxsize
= 90000;
424 const char *fname
= BASEDIR
"\\test.txt";
425 uint_t seed
= time(NULL
);
426 union smb_fileinfo finfo
;
428 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
430 if (!torture_setup_dir(cli
, BASEDIR
)) {
434 printf("Testing RAW_WRITE_WRITEUNLOCK\n");
435 io
.generic
.level
= RAW_WRITE_WRITEUNLOCK
;
437 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
439 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
444 printf("Trying zero write\n");
445 io
.writeunlock
.in
.file
.fnum
= fnum
;
446 io
.writeunlock
.in
.count
= 0;
447 io
.writeunlock
.in
.offset
= 0;
448 io
.writeunlock
.in
.remaining
= 0;
449 io
.writeunlock
.in
.data
= buf
;
450 status
= smb_raw_write(cli
->tree
, &io
);
451 CHECK_STATUS(status
, NT_STATUS_OK
);
452 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, io
.writeunlock
.in
.count
);
454 setup_buffer(buf
, seed
, maxsize
);
456 printf("Trying small write\n");
457 io
.writeunlock
.in
.count
= 9;
458 io
.writeunlock
.in
.offset
= 4;
459 io
.writeunlock
.in
.data
= buf
;
460 status
= smb_raw_write(cli
->tree
, &io
);
461 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
462 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
463 printf("read failed at %s\n", __location__
);
467 CHECK_BUFFER(buf
+4, seed
, 9);
468 CHECK_VALUE(IVAL(buf
,0), 0);
470 setup_buffer(buf
, seed
, maxsize
);
471 smbcli_lock(cli
->tree
, fnum
, io
.writeunlock
.in
.offset
, io
.writeunlock
.in
.count
,
473 status
= smb_raw_write(cli
->tree
, &io
);
474 CHECK_STATUS(status
, NT_STATUS_OK
);
475 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, io
.writeunlock
.in
.count
);
477 memset(buf
, 0, maxsize
);
478 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
479 printf("read failed at %s\n", __location__
);
483 CHECK_BUFFER(buf
+4, seed
, 9);
484 CHECK_VALUE(IVAL(buf
,0), 0);
486 setup_buffer(buf
, seed
, maxsize
);
488 printf("Trying large write\n");
489 io
.writeunlock
.in
.count
= 4000;
490 io
.writeunlock
.in
.offset
= 0;
491 io
.writeunlock
.in
.data
= buf
;
492 smbcli_lock(cli
->tree
, fnum
, io
.writeunlock
.in
.offset
, io
.writeunlock
.in
.count
,
494 status
= smb_raw_write(cli
->tree
, &io
);
495 CHECK_STATUS(status
, NT_STATUS_OK
);
496 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, 4000);
498 status
= smb_raw_write(cli
->tree
, &io
);
499 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
501 memset(buf
, 0, maxsize
);
502 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
503 printf("read failed at %s\n", __location__
);
507 CHECK_BUFFER(buf
, seed
, 4000);
509 printf("Trying bad fnum\n");
510 io
.writeunlock
.in
.file
.fnum
= fnum
+1;
511 io
.writeunlock
.in
.count
= 4000;
512 io
.writeunlock
.in
.offset
= 0;
513 io
.writeunlock
.in
.data
= buf
;
514 status
= smb_raw_write(cli
->tree
, &io
);
515 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
517 printf("Setting file as sparse\n");
518 status
= torture_set_sparse(cli
->tree
, fnum
);
519 CHECK_STATUS(status
, NT_STATUS_OK
);
521 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
522 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
526 printf("Trying 2^32 offset\n");
527 setup_buffer(buf
, seed
, maxsize
);
528 io
.writeunlock
.in
.file
.fnum
= fnum
;
529 io
.writeunlock
.in
.count
= 4000;
530 io
.writeunlock
.in
.offset
= 0xFFFFFFFF - 2000;
531 io
.writeunlock
.in
.data
= buf
;
532 smbcli_lock(cli
->tree
, fnum
, io
.writeunlock
.in
.offset
, io
.writeunlock
.in
.count
,
534 status
= smb_raw_write(cli
->tree
, &io
);
535 CHECK_STATUS(status
, NT_STATUS_OK
);
536 CHECK_VALUE(io
.writeunlock
.out
.nwritten
, 4000);
537 CHECK_ALL_INFO(io
.writeunlock
.in
.count
+ (uint64_t)io
.writeunlock
.in
.offset
, size
);
539 memset(buf
, 0, maxsize
);
540 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writeunlock
.in
.offset
, 4000) != 4000) {
541 printf("read failed at %s\n", __location__
);
545 CHECK_BUFFER(buf
, seed
, 4000);
548 smbcli_close(cli
->tree
, fnum
);
549 smb_raw_exit(cli
->session
);
550 smbcli_deltree(cli
->tree
, BASEDIR
);
558 static bool test_writeclose(struct torture_context
*tctx
,
559 struct smbcli_state
*cli
)
566 const int maxsize
= 90000;
567 const char *fname
= BASEDIR
"\\test.txt";
568 uint_t seed
= time(NULL
);
569 union smb_fileinfo finfo
;
571 buf
= talloc_zero_array(tctx
, uint8_t, maxsize
);
573 if (!torture_setup_dir(cli
, BASEDIR
)) {
577 printf("Testing RAW_WRITE_WRITECLOSE\n");
578 io
.generic
.level
= RAW_WRITE_WRITECLOSE
;
580 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
582 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
587 printf("Trying zero write\n");
588 io
.writeclose
.in
.file
.fnum
= fnum
;
589 io
.writeclose
.in
.count
= 0;
590 io
.writeclose
.in
.offset
= 0;
591 io
.writeclose
.in
.mtime
= 0;
592 io
.writeclose
.in
.data
= buf
;
593 status
= smb_raw_write(cli
->tree
, &io
);
594 CHECK_STATUS(status
, NT_STATUS_OK
);
595 CHECK_VALUE(io
.writeclose
.out
.nwritten
, io
.writeclose
.in
.count
);
597 status
= smb_raw_write(cli
->tree
, &io
);
598 CHECK_STATUS(status
, NT_STATUS_OK
);
599 CHECK_VALUE(io
.writeclose
.out
.nwritten
, io
.writeclose
.in
.count
);
601 setup_buffer(buf
, seed
, maxsize
);
603 printf("Trying small write\n");
604 io
.writeclose
.in
.count
= 9;
605 io
.writeclose
.in
.offset
= 4;
606 io
.writeclose
.in
.data
= buf
;
607 status
= smb_raw_write(cli
->tree
, &io
);
608 CHECK_STATUS(status
, NT_STATUS_OK
);
610 status
= smb_raw_write(cli
->tree
, &io
);
611 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
613 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
614 io
.writeclose
.in
.file
.fnum
= fnum
;
616 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
617 printf("read failed at %s\n", __location__
);
621 CHECK_BUFFER(buf
+4, seed
, 9);
622 CHECK_VALUE(IVAL(buf
,0), 0);
624 setup_buffer(buf
, seed
, maxsize
);
625 status
= smb_raw_write(cli
->tree
, &io
);
626 CHECK_STATUS(status
, NT_STATUS_OK
);
627 CHECK_VALUE(io
.writeclose
.out
.nwritten
, io
.writeclose
.in
.count
);
629 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
630 io
.writeclose
.in
.file
.fnum
= fnum
;
632 memset(buf
, 0, maxsize
);
633 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 13) != 13) {
634 printf("read failed at %s\n", __location__
);
638 CHECK_BUFFER(buf
+4, seed
, 9);
639 CHECK_VALUE(IVAL(buf
,0), 0);
641 setup_buffer(buf
, seed
, maxsize
);
643 printf("Trying large write\n");
644 io
.writeclose
.in
.count
= 4000;
645 io
.writeclose
.in
.offset
= 0;
646 io
.writeclose
.in
.data
= buf
;
647 status
= smb_raw_write(cli
->tree
, &io
);
648 CHECK_STATUS(status
, NT_STATUS_OK
);
649 CHECK_VALUE(io
.writeclose
.out
.nwritten
, 4000);
651 status
= smb_raw_write(cli
->tree
, &io
);
652 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
654 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
655 io
.writeclose
.in
.file
.fnum
= fnum
;
657 memset(buf
, 0, maxsize
);
658 if (smbcli_read(cli
->tree
, fnum
, buf
, 0, 4000) != 4000) {
659 printf("read failed at %s\n", __location__
);
663 CHECK_BUFFER(buf
, seed
, 4000);
665 printf("Trying bad fnum\n");
666 io
.writeclose
.in
.file
.fnum
= fnum
+1;
667 io
.writeclose
.in
.count
= 4000;
668 io
.writeclose
.in
.offset
= 0;
669 io
.writeclose
.in
.data
= buf
;
670 status
= smb_raw_write(cli
->tree
, &io
);
671 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
673 printf("Setting file as sparse\n");
674 status
= torture_set_sparse(cli
->tree
, fnum
);
675 CHECK_STATUS(status
, NT_STATUS_OK
);
677 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
678 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
682 printf("Trying 2^32 offset\n");
683 setup_buffer(buf
, seed
, maxsize
);
684 io
.writeclose
.in
.file
.fnum
= fnum
;
685 io
.writeclose
.in
.count
= 4000;
686 io
.writeclose
.in
.offset
= 0xFFFFFFFF - 2000;
687 io
.writeclose
.in
.data
= buf
;
688 status
= smb_raw_write(cli
->tree
, &io
);
689 CHECK_STATUS(status
, NT_STATUS_OK
);
690 CHECK_VALUE(io
.writeclose
.out
.nwritten
, 4000);
691 CHECK_ALL_INFO(io
.writeclose
.in
.count
+ (uint64_t)io
.writeclose
.in
.offset
, size
);
693 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
, DENY_NONE
);
694 io
.writeclose
.in
.file
.fnum
= fnum
;
696 memset(buf
, 0, maxsize
);
697 if (smbcli_read(cli
->tree
, fnum
, buf
, io
.writeclose
.in
.offset
, 4000) != 4000) {
698 printf("read failed at %s\n", __location__
);
702 CHECK_BUFFER(buf
, seed
, 4000);
705 smbcli_close(cli
->tree
, fnum
);
706 smb_raw_exit(cli
->session
);
707 smbcli_deltree(cli
->tree
, BASEDIR
);
712 basic testing of write calls
714 struct torture_suite
*torture_raw_write(TALLOC_CTX
*mem_ctx
)
716 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "WRITE");
718 torture_suite_add_1smb_test(suite
, "write", test_write
);
719 torture_suite_add_1smb_test(suite
, "write unlock", test_writeunlock
);
720 torture_suite_add_1smb_test(suite
, "write close", test_writeclose
);
721 torture_suite_add_1smb_test(suite
, "writex", test_writex
);