r23792: convert Samba4 to GPLv3
[tprouty/samba.git] / source4 / torture / raw / write.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for various write operations
4
5    Copyright (C) Andrew Tridgell 2003
6    
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.
11    
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.
16    
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/>.
19 */
20
21 #include "includes.h"
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/filesys.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
28
29 #define CHECK_STATUS(status, correct) do { \
30         if (!NT_STATUS_EQUAL(status, correct)) { \
31                 printf("(%s) Incorrect status %s - should be %s\n", \
32                        __location__, nt_errstr(status), nt_errstr(correct)); \
33                 ret = False; \
34                 goto done; \
35         }} while (0)
36
37 #define CHECK_VALUE(v, correct) do { \
38         if ((v) != (correct)) { \
39                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
40                        __location__, #v, v, correct); \
41                 ret = False; \
42                 goto done; \
43         }} while (0)
44
45 #define CHECK_BUFFER(buf, seed, len) do { \
46         if (!check_buffer(buf, seed, len, __location__)) { \
47                 ret = False; \
48                 goto done; \
49         }} while (0)
50
51 #define CHECK_ALL_INFO(v, field) do { \
52         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
53         finfo.all_info.in.file.path = fname; \
54         status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
55         CHECK_STATUS(status, NT_STATUS_OK); \
56         if ((v) != finfo.all_info.out.field) { \
57                 printf("(%s) wrong value for field %s  %.0f - %.0f\n", \
58                        __location__, #field, (double)v, (double)finfo.all_info.out.field); \
59                 dump_all_info(mem_ctx, &finfo); \
60                 ret = False; \
61         }} while (0)
62
63
64 #define BASEDIR "\\testwrite"
65
66
67 /*
68   setup a random buffer based on a seed
69 */
70 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
71 {
72         int i;
73         srandom(seed);
74         for (i=0;i<len;i++) buf[i] = random();
75 }
76
77 /*
78   check a random buffer based on a seed
79 */
80 static BOOL check_buffer(uint8_t *buf, uint_t seed, int len, const char *location)
81 {
82         int i;
83         srandom(seed);
84         for (i=0;i<len;i++) {
85                 uint8_t v = random();
86                 if (buf[i] != v) {
87                         printf("Buffer incorrect at %s! ofs=%d buf=0x%x correct=0x%x\n", 
88                                location, i, buf[i], v);
89                         return False;
90                 }
91         }
92         return True;
93 }
94
95 /*
96   test write ops
97 */
98 static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
99 {
100         union smb_write io;
101         NTSTATUS status;
102         BOOL ret = True;
103         int fnum;
104         uint8_t *buf;
105         const int maxsize = 90000;
106         const char *fname = BASEDIR "\\test.txt";
107         uint_t seed = time(NULL);
108         union smb_fileinfo finfo;
109
110         buf = talloc_zero_size(mem_ctx, maxsize);
111
112         if (!torture_setup_dir(cli, BASEDIR)) {
113                 return False;
114         }
115
116         printf("Testing RAW_WRITE_WRITE\n");
117         io.generic.level = RAW_WRITE_WRITE;
118         
119         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
120         if (fnum == -1) {
121                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
122                 ret = False;
123                 goto done;
124         }
125
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);
135
136         setup_buffer(buf, seed, maxsize);
137
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);
145
146         memset(buf, 0, maxsize);
147         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
148                 printf("read failed at %s\n", __location__);
149                 ret = False;
150                 goto done;
151         }
152         CHECK_BUFFER(buf+4, seed, 9);
153         CHECK_VALUE(IVAL(buf,0), 0);
154
155         setup_buffer(buf, seed, maxsize);
156
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);
164
165         memset(buf, 0, maxsize);
166         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
167                 printf("read failed at %s\n", __location__);
168                 ret = False;
169                 goto done;
170         }
171         CHECK_BUFFER(buf, seed, 4000);
172
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);
180
181         printf("Setting file as sparse\n");
182         status = torture_set_sparse(cli->tree, fnum);
183         CHECK_STATUS(status, NT_STATUS_OK);
184
185         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
186                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
187                 goto done;
188         }
189         
190         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
191                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
192                 goto done;
193         }
194
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);
205         
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__);
209                 ret = False;
210                 goto done;
211         }
212         CHECK_BUFFER(buf, seed, 4000);
213
214 done:
215         smbcli_close(cli->tree, fnum);
216         smb_raw_exit(cli->session);
217         smbcli_deltree(cli->tree, BASEDIR);
218         return ret;
219 }
220
221
222 /*
223   test writex ops
224 */
225 static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
226 {
227         union smb_write io;
228         NTSTATUS status;
229         BOOL ret = True;
230         int fnum, i;
231         uint8_t *buf;
232         const int maxsize = 90000;
233         const char *fname = BASEDIR "\\test.txt";
234         uint_t seed = time(NULL);
235         union smb_fileinfo finfo;
236         int max_bits=63;
237
238         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
239                 max_bits=33;
240                 printf("dangerous not set - limiting range of test to 2^%d\n", max_bits);
241         }
242
243         buf = talloc_zero_size(mem_ctx, maxsize);
244
245         if (!torture_setup_dir(cli, BASEDIR)) {
246                 return False;
247         }
248
249         printf("Testing RAW_WRITE_WRITEX\n");
250         io.generic.level = RAW_WRITE_WRITEX;
251         
252         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
253         if (fnum == -1) {
254                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
255                 ret = False;
256                 goto done;
257         }
258
259         printf("Trying zero write\n");
260         io.writex.in.file.fnum = fnum;
261         io.writex.in.offset = 0;
262         io.writex.in.wmode = 0;
263         io.writex.in.remaining = 0;
264         io.writex.in.count = 0;
265         io.writex.in.data = buf;
266         status = smb_raw_write(cli->tree, &io);
267         CHECK_STATUS(status, NT_STATUS_OK);
268         CHECK_VALUE(io.writex.out.nwritten, 0);
269
270         setup_buffer(buf, seed, maxsize);
271
272         printf("Trying small write\n");
273         io.writex.in.count = 9;
274         io.writex.in.offset = 4;
275         io.writex.in.data = buf;
276         status = smb_raw_write(cli->tree, &io);
277         CHECK_STATUS(status, NT_STATUS_OK);
278         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
279
280         memset(buf, 0, maxsize);
281         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
282                 printf("read failed at %s\n", __location__);
283                 ret = False;
284                 goto done;
285         }
286         CHECK_BUFFER(buf+4, seed, 9);
287         CHECK_VALUE(IVAL(buf,0), 0);
288
289         setup_buffer(buf, seed, maxsize);
290
291         printf("Trying large write\n");
292         io.writex.in.count = 4000;
293         io.writex.in.offset = 0;
294         io.writex.in.data = buf;
295         status = smb_raw_write(cli->tree, &io);
296         CHECK_STATUS(status, NT_STATUS_OK);
297         CHECK_VALUE(io.writex.out.nwritten, 4000);
298
299         memset(buf, 0, maxsize);
300         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
301                 printf("read failed at %s\n", __location__);
302                 ret = False;
303                 goto done;
304         }
305         CHECK_BUFFER(buf, seed, 4000);
306
307         printf("Trying bad fnum\n");
308         io.writex.in.file.fnum = fnum+1;
309         io.writex.in.count = 4000;
310         io.writex.in.offset = 0;
311         io.writex.in.data = buf;
312         status = smb_raw_write(cli->tree, &io);
313         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
314
315         printf("Testing wmode\n");
316         io.writex.in.file.fnum = fnum;
317         io.writex.in.count = 1;
318         io.writex.in.offset = 0;
319         io.writex.in.wmode = 1;
320         io.writex.in.data = buf;
321         status = smb_raw_write(cli->tree, &io);
322         CHECK_STATUS(status, NT_STATUS_OK);
323         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
324
325         io.writex.in.wmode = 2;
326         status = smb_raw_write(cli->tree, &io);
327         CHECK_STATUS(status, NT_STATUS_OK);
328         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
329
330
331         printf("Trying locked region\n");
332         cli->session->pid++;
333         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 3, 1, 0, WRITE_LOCK))) {
334                 printf("Failed to lock file at %s\n", __location__);
335                 ret = False;
336                 goto done;
337         }
338         cli->session->pid--;
339         io.writex.in.wmode = 0;
340         io.writex.in.count = 4;
341         io.writex.in.offset = 0;
342         status = smb_raw_write(cli->tree, &io);
343         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
344
345         printf("Setting file as sparse\n");
346         status = torture_set_sparse(cli->tree, fnum);
347         CHECK_STATUS(status, NT_STATUS_OK);
348         
349         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
350                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
351                 goto done;
352         }
353
354         printf("Trying 2^32 offset\n");
355         setup_buffer(buf, seed, maxsize);
356         io.writex.in.file.fnum = fnum;
357         io.writex.in.count = 4000;
358         io.writex.in.offset = 0xFFFFFFFF - 2000;
359         io.writex.in.data = buf;
360         status = smb_raw_write(cli->tree, &io);
361         CHECK_STATUS(status, NT_STATUS_OK);
362         CHECK_VALUE(io.writex.out.nwritten, 4000);
363         CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);
364
365         memset(buf, 0, maxsize);
366         if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
367                 printf("read failed at %s\n", __location__);
368                 ret = False;
369                 goto done;
370         }
371         CHECK_BUFFER(buf, seed, 4000);
372
373         for (i=33;i<max_bits;i++) {
374                 printf("Trying 2^%d offset\n", i);
375                 setup_buffer(buf, seed+1, maxsize);
376                 io.writex.in.file.fnum = fnum;
377                 io.writex.in.count = 4000;
378                 io.writex.in.offset = ((uint64_t)1) << i;
379                 io.writex.in.data = buf;
380                 status = smb_raw_write(cli->tree, &io);
381                 if (i>33 &&
382                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
383                         break;
384                 }
385                 CHECK_STATUS(status, NT_STATUS_OK);
386                 CHECK_VALUE(io.writex.out.nwritten, 4000);
387                 CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);
388
389                 memset(buf, 0, maxsize);
390                 if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
391                         printf("read failed at %s\n", __location__);
392                         ret = False;
393                         goto done;
394                 }
395                 CHECK_BUFFER(buf, seed+1, 4000);
396         }
397         printf("limit is 2^%d\n", i);
398
399         setup_buffer(buf, seed, maxsize);
400
401 done:
402         smbcli_close(cli->tree, fnum);
403         smb_raw_exit(cli->session);
404         smbcli_deltree(cli->tree, BASEDIR);
405         return ret;
406 }
407
408
409 /*
410   test write unlock ops
411 */
412 static BOOL test_writeunlock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
413 {
414         union smb_write io;
415         NTSTATUS status;
416         BOOL ret = True;
417         int fnum;
418         uint8_t *buf;
419         const int maxsize = 90000;
420         const char *fname = BASEDIR "\\test.txt";
421         uint_t seed = time(NULL);
422         union smb_fileinfo finfo;
423
424         buf = talloc_zero_size(mem_ctx, maxsize);
425
426         if (!torture_setup_dir(cli, BASEDIR)) {
427                 return False;
428         }
429
430         printf("Testing RAW_WRITE_WRITEUNLOCK\n");
431         io.generic.level = RAW_WRITE_WRITEUNLOCK;
432         
433         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
434         if (fnum == -1) {
435                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
436                 ret = False;
437                 goto done;
438         }
439
440         printf("Trying zero write\n");
441         io.writeunlock.in.file.fnum = fnum;
442         io.writeunlock.in.count = 0;
443         io.writeunlock.in.offset = 0;
444         io.writeunlock.in.remaining = 0;
445         io.writeunlock.in.data = buf;
446         status = smb_raw_write(cli->tree, &io);
447         CHECK_STATUS(status, NT_STATUS_OK);
448         CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
449
450         setup_buffer(buf, seed, maxsize);
451
452         printf("Trying small write\n");
453         io.writeunlock.in.count = 9;
454         io.writeunlock.in.offset = 4;
455         io.writeunlock.in.data = buf;
456         status = smb_raw_write(cli->tree, &io);
457         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
458         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
459                 printf("read failed at %s\n", __location__);
460                 ret = False;
461                 goto done;
462         }
463         CHECK_BUFFER(buf+4, seed, 9);
464         CHECK_VALUE(IVAL(buf,0), 0);
465
466         setup_buffer(buf, seed, maxsize);
467         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
468                  0, WRITE_LOCK);
469         status = smb_raw_write(cli->tree, &io);
470         CHECK_STATUS(status, NT_STATUS_OK);
471         CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
472
473         memset(buf, 0, maxsize);
474         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
475                 printf("read failed at %s\n", __location__);
476                 ret = False;
477                 goto done;
478         }
479         CHECK_BUFFER(buf+4, seed, 9);
480         CHECK_VALUE(IVAL(buf,0), 0);
481
482         setup_buffer(buf, seed, maxsize);
483
484         printf("Trying large write\n");
485         io.writeunlock.in.count = 4000;
486         io.writeunlock.in.offset = 0;
487         io.writeunlock.in.data = buf;
488         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
489                  0, WRITE_LOCK);
490         status = smb_raw_write(cli->tree, &io);
491         CHECK_STATUS(status, NT_STATUS_OK);
492         CHECK_VALUE(io.writeunlock.out.nwritten, 4000);
493
494         status = smb_raw_write(cli->tree, &io);
495         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
496
497         memset(buf, 0, maxsize);
498         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
499                 printf("read failed at %s\n", __location__);
500                 ret = False;
501                 goto done;
502         }
503         CHECK_BUFFER(buf, seed, 4000);
504
505         printf("Trying bad fnum\n");
506         io.writeunlock.in.file.fnum = fnum+1;
507         io.writeunlock.in.count = 4000;
508         io.writeunlock.in.offset = 0;
509         io.writeunlock.in.data = buf;
510         status = smb_raw_write(cli->tree, &io);
511         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
512
513         printf("Setting file as sparse\n");
514         status = torture_set_sparse(cli->tree, fnum);
515         CHECK_STATUS(status, NT_STATUS_OK);
516         
517         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
518                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
519                 goto done;
520         }
521
522         printf("Trying 2^32 offset\n");
523         setup_buffer(buf, seed, maxsize);
524         io.writeunlock.in.file.fnum = fnum;
525         io.writeunlock.in.count = 4000;
526         io.writeunlock.in.offset = 0xFFFFFFFF - 2000;
527         io.writeunlock.in.data = buf;
528         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
529                  0, WRITE_LOCK);
530         status = smb_raw_write(cli->tree, &io);
531         CHECK_STATUS(status, NT_STATUS_OK);
532         CHECK_VALUE(io.writeunlock.out.nwritten, 4000);
533         CHECK_ALL_INFO(io.writeunlock.in.count + (uint64_t)io.writeunlock.in.offset, size);
534
535         memset(buf, 0, maxsize);
536         if (smbcli_read(cli->tree, fnum, buf, io.writeunlock.in.offset, 4000) != 4000) {
537                 printf("read failed at %s\n", __location__);
538                 ret = False;
539                 goto done;
540         }
541         CHECK_BUFFER(buf, seed, 4000);
542
543 done:
544         smbcli_close(cli->tree, fnum);
545         smb_raw_exit(cli->session);
546         smbcli_deltree(cli->tree, BASEDIR);
547         return ret;
548 }
549
550
551 /*
552   test write close ops
553 */
554 static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
555 {
556         union smb_write io;
557         NTSTATUS status;
558         BOOL ret = True;
559         int fnum;
560         uint8_t *buf;
561         const int maxsize = 90000;
562         const char *fname = BASEDIR "\\test.txt";
563         uint_t seed = time(NULL);
564         union smb_fileinfo finfo;
565
566         buf = talloc_zero_size(mem_ctx, maxsize);
567
568         if (!torture_setup_dir(cli, BASEDIR)) {
569                 return False;
570         }
571
572         printf("Testing RAW_WRITE_WRITECLOSE\n");
573         io.generic.level = RAW_WRITE_WRITECLOSE;
574         
575         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
576         if (fnum == -1) {
577                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
578                 ret = False;
579                 goto done;
580         }
581
582         printf("Trying zero write\n");
583         io.writeclose.in.file.fnum = fnum;
584         io.writeclose.in.count = 0;
585         io.writeclose.in.offset = 0;
586         io.writeclose.in.mtime = 0;
587         io.writeclose.in.data = buf;
588         status = smb_raw_write(cli->tree, &io);
589         CHECK_STATUS(status, NT_STATUS_OK);
590         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
591
592         status = smb_raw_write(cli->tree, &io);
593         CHECK_STATUS(status, NT_STATUS_OK);
594         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
595
596         setup_buffer(buf, seed, maxsize);
597
598         printf("Trying small write\n");
599         io.writeclose.in.count = 9;
600         io.writeclose.in.offset = 4;
601         io.writeclose.in.data = buf;
602         status = smb_raw_write(cli->tree, &io);
603         CHECK_STATUS(status, NT_STATUS_OK);
604
605         status = smb_raw_write(cli->tree, &io);
606         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
607
608         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
609         io.writeclose.in.file.fnum = fnum;
610
611         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
612                 printf("read failed at %s\n", __location__);
613                 ret = False;
614                 goto done;
615         }
616         CHECK_BUFFER(buf+4, seed, 9);
617         CHECK_VALUE(IVAL(buf,0), 0);
618
619         setup_buffer(buf, seed, maxsize);
620         status = smb_raw_write(cli->tree, &io);
621         CHECK_STATUS(status, NT_STATUS_OK);
622         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
623
624         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
625         io.writeclose.in.file.fnum = fnum;
626
627         memset(buf, 0, maxsize);
628         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
629                 printf("read failed at %s\n", __location__);
630                 ret = False;
631                 goto done;
632         }
633         CHECK_BUFFER(buf+4, seed, 9);
634         CHECK_VALUE(IVAL(buf,0), 0);
635
636         setup_buffer(buf, seed, maxsize);
637
638         printf("Trying large write\n");
639         io.writeclose.in.count = 4000;
640         io.writeclose.in.offset = 0;
641         io.writeclose.in.data = buf;
642         status = smb_raw_write(cli->tree, &io);
643         CHECK_STATUS(status, NT_STATUS_OK);
644         CHECK_VALUE(io.writeclose.out.nwritten, 4000);
645
646         status = smb_raw_write(cli->tree, &io);
647         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
648
649         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
650         io.writeclose.in.file.fnum = fnum;
651
652         memset(buf, 0, maxsize);
653         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
654                 printf("read failed at %s\n", __location__);
655                 ret = False;
656                 goto done;
657         }
658         CHECK_BUFFER(buf, seed, 4000);
659
660         printf("Trying bad fnum\n");
661         io.writeclose.in.file.fnum = fnum+1;
662         io.writeclose.in.count = 4000;
663         io.writeclose.in.offset = 0;
664         io.writeclose.in.data = buf;
665         status = smb_raw_write(cli->tree, &io);
666         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
667
668         printf("Setting file as sparse\n");
669         status = torture_set_sparse(cli->tree, fnum);
670         CHECK_STATUS(status, NT_STATUS_OK);
671         
672         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
673                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
674                 goto done;
675         }
676
677         printf("Trying 2^32 offset\n");
678         setup_buffer(buf, seed, maxsize);
679         io.writeclose.in.file.fnum = fnum;
680         io.writeclose.in.count = 4000;
681         io.writeclose.in.offset = 0xFFFFFFFF - 2000;
682         io.writeclose.in.data = buf;
683         status = smb_raw_write(cli->tree, &io);
684         CHECK_STATUS(status, NT_STATUS_OK);
685         CHECK_VALUE(io.writeclose.out.nwritten, 4000);
686         CHECK_ALL_INFO(io.writeclose.in.count + (uint64_t)io.writeclose.in.offset, size);
687
688         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
689         io.writeclose.in.file.fnum = fnum;
690
691         memset(buf, 0, maxsize);
692         if (smbcli_read(cli->tree, fnum, buf, io.writeclose.in.offset, 4000) != 4000) {
693                 printf("read failed at %s\n", __location__);
694                 ret = False;
695                 goto done;
696         }
697         CHECK_BUFFER(buf, seed, 4000);
698
699 done:
700         smbcli_close(cli->tree, fnum);
701         smb_raw_exit(cli->session);
702         smbcli_deltree(cli->tree, BASEDIR);
703         return ret;
704 }
705
706 /* 
707    basic testing of write calls
708 */
709 BOOL torture_raw_write(struct torture_context *torture)
710 {
711         struct smbcli_state *cli;
712         BOOL ret = True;
713         TALLOC_CTX *mem_ctx;
714
715         if (!torture_open_connection(&cli, 0)) {
716                 return False;
717         }
718
719         mem_ctx = talloc_init("torture_raw_write");
720
721         ret &= test_write(cli, mem_ctx);
722         ret &= test_writeunlock(cli, mem_ctx);
723         ret &= test_writeclose(cli, mem_ctx);
724         ret &= test_writex(cli, mem_ctx);
725
726         torture_close_connection(cli);
727         talloc_free(mem_ctx);
728         return ret;
729 }