r12694: Move some headers to the directory of the subsystem they belong to.
[gd/samba-autobuild/.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 2 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, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "system/time.h"
26 #include "system/filesys.h"
27 #include "libcli/libcli.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.fname = 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.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.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         printf("Trying 2^32 offset\n");
186         setup_buffer(buf, seed, maxsize);
187         io.write.in.fnum = fnum;
188         io.write.in.count = 4000;
189         io.write.in.offset = 0xFFFFFFFF - 2000;
190         io.write.in.data = buf;
191         status = smb_raw_write(cli->tree, &io);
192         CHECK_STATUS(status, NT_STATUS_OK);
193         CHECK_VALUE(io.write.out.nwritten, 4000);
194         CHECK_ALL_INFO(io.write.in.count + (uint64_t)io.write.in.offset, size);
195
196         memset(buf, 0, maxsize);
197         if (smbcli_read(cli->tree, fnum, buf, io.write.in.offset, 4000) != 4000) {
198                 printf("read failed at %s\n", __location__);
199                 ret = False;
200                 goto done;
201         }
202         CHECK_BUFFER(buf, seed, 4000);
203
204 done:
205         smbcli_close(cli->tree, fnum);
206         smb_raw_exit(cli->session);
207         smbcli_deltree(cli->tree, BASEDIR);
208         return ret;
209 }
210
211
212 /*
213   test writex ops
214 */
215 static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
216 {
217         union smb_write io;
218         NTSTATUS status;
219         BOOL ret = True;
220         int fnum, i;
221         uint8_t *buf;
222         const int maxsize = 90000;
223         const char *fname = BASEDIR "\\test.txt";
224         uint_t seed = time(NULL);
225         union smb_fileinfo finfo;
226
227         buf = talloc_zero_size(mem_ctx, maxsize);
228
229         if (!torture_setup_dir(cli, BASEDIR)) {
230                 return False;
231         }
232
233         printf("Testing RAW_WRITE_WRITEX\n");
234         io.generic.level = RAW_WRITE_WRITEX;
235         
236         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
237         if (fnum == -1) {
238                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
239                 ret = False;
240                 goto done;
241         }
242
243         printf("Trying zero write\n");
244         io.writex.in.fnum = fnum;
245         io.writex.in.offset = 0;
246         io.writex.in.wmode = 0;
247         io.writex.in.remaining = 0;
248         io.writex.in.count = 0;
249         io.writex.in.data = buf;
250         status = smb_raw_write(cli->tree, &io);
251         CHECK_STATUS(status, NT_STATUS_OK);
252         CHECK_VALUE(io.writex.out.nwritten, 0);
253
254         setup_buffer(buf, seed, maxsize);
255
256         printf("Trying small write\n");
257         io.writex.in.count = 9;
258         io.writex.in.offset = 4;
259         io.writex.in.data = buf;
260         status = smb_raw_write(cli->tree, &io);
261         CHECK_STATUS(status, NT_STATUS_OK);
262         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
263
264         memset(buf, 0, maxsize);
265         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
266                 printf("read failed at %s\n", __location__);
267                 ret = False;
268                 goto done;
269         }
270         CHECK_BUFFER(buf+4, seed, 9);
271         CHECK_VALUE(IVAL(buf,0), 0);
272
273         setup_buffer(buf, seed, maxsize);
274
275         printf("Trying large write\n");
276         io.writex.in.count = 4000;
277         io.writex.in.offset = 0;
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, 4000);
282
283         memset(buf, 0, maxsize);
284         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
285                 printf("read failed at %s\n", __location__);
286                 ret = False;
287                 goto done;
288         }
289         CHECK_BUFFER(buf, seed, 4000);
290
291         printf("Trying bad fnum\n");
292         io.writex.in.fnum = fnum+1;
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_INVALID_HANDLE);
298
299         printf("Testing wmode\n");
300         io.writex.in.fnum = fnum;
301         io.writex.in.count = 1;
302         io.writex.in.offset = 0;
303         io.writex.in.wmode = 1;
304         io.writex.in.data = buf;
305         status = smb_raw_write(cli->tree, &io);
306         CHECK_STATUS(status, NT_STATUS_OK);
307         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
308
309         io.writex.in.wmode = 2;
310         status = smb_raw_write(cli->tree, &io);
311         CHECK_STATUS(status, NT_STATUS_OK);
312         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
313
314
315         printf("Trying locked region\n");
316         cli->session->pid++;
317         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 3, 1, 0, WRITE_LOCK))) {
318                 printf("Failed to lock file at %s\n", __location__);
319                 ret = False;
320                 goto done;
321         }
322         cli->session->pid--;
323         io.writex.in.wmode = 0;
324         io.writex.in.count = 4;
325         io.writex.in.offset = 0;
326         status = smb_raw_write(cli->tree, &io);
327         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
328
329         printf("Setting file as sparse\n");
330         status = torture_set_sparse(cli->tree, fnum);
331         CHECK_STATUS(status, NT_STATUS_OK);
332         
333         printf("Trying 2^32 offset\n");
334         setup_buffer(buf, seed, maxsize);
335         io.writex.in.fnum = fnum;
336         io.writex.in.count = 4000;
337         io.writex.in.offset = 0xFFFFFFFF - 2000;
338         io.writex.in.data = buf;
339         status = smb_raw_write(cli->tree, &io);
340         CHECK_STATUS(status, NT_STATUS_OK);
341         CHECK_VALUE(io.writex.out.nwritten, 4000);
342         CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);
343
344         memset(buf, 0, maxsize);
345         if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
346                 printf("read failed at %s\n", __location__);
347                 ret = False;
348                 goto done;
349         }
350         CHECK_BUFFER(buf, seed, 4000);
351
352         for (i=33;i<64;i++) {
353                 printf("Trying 2^%d offset\n", i);
354                 setup_buffer(buf, seed+1, maxsize);
355                 io.writex.in.fnum = fnum;
356                 io.writex.in.count = 4000;
357                 io.writex.in.offset = ((uint64_t)1) << i;
358                 io.writex.in.data = buf;
359                 status = smb_raw_write(cli->tree, &io);
360                 if (i>33 &&
361                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
362                         break;
363                 }
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);
367
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__);
371                         ret = False;
372                         goto done;
373                 }
374                 CHECK_BUFFER(buf, seed+1, 4000);
375         }
376         printf("limit is 2^%d\n", i);
377
378         setup_buffer(buf, seed, maxsize);
379
380 done:
381         smbcli_close(cli->tree, fnum);
382         smb_raw_exit(cli->session);
383         smbcli_deltree(cli->tree, BASEDIR);
384         return ret;
385 }
386
387
388 /*
389   test write unlock ops
390 */
391 static BOOL test_writeunlock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
392 {
393         union smb_write io;
394         NTSTATUS status;
395         BOOL ret = True;
396         int fnum;
397         uint8_t *buf;
398         const int maxsize = 90000;
399         const char *fname = BASEDIR "\\test.txt";
400         uint_t seed = time(NULL);
401         union smb_fileinfo finfo;
402
403         buf = talloc_zero_size(mem_ctx, maxsize);
404
405         if (!torture_setup_dir(cli, BASEDIR)) {
406                 return False;
407         }
408
409         printf("Testing RAW_WRITE_WRITEUNLOCK\n");
410         io.generic.level = RAW_WRITE_WRITEUNLOCK;
411         
412         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
413         if (fnum == -1) {
414                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
415                 ret = False;
416                 goto done;
417         }
418
419         printf("Trying zero write\n");
420         io.writeunlock.in.fnum = fnum;
421         io.writeunlock.in.count = 0;
422         io.writeunlock.in.offset = 0;
423         io.writeunlock.in.remaining = 0;
424         io.writeunlock.in.data = buf;
425         status = smb_raw_write(cli->tree, &io);
426         CHECK_STATUS(status, NT_STATUS_OK);
427         CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
428
429         setup_buffer(buf, seed, maxsize);
430
431         printf("Trying small write\n");
432         io.writeunlock.in.count = 9;
433         io.writeunlock.in.offset = 4;
434         io.writeunlock.in.data = buf;
435         status = smb_raw_write(cli->tree, &io);
436         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
437         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
438                 printf("read failed at %s\n", __location__);
439                 ret = False;
440                 goto done;
441         }
442         CHECK_BUFFER(buf+4, seed, 9);
443         CHECK_VALUE(IVAL(buf,0), 0);
444
445         setup_buffer(buf, seed, maxsize);
446         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
447                  0, WRITE_LOCK);
448         status = smb_raw_write(cli->tree, &io);
449         CHECK_STATUS(status, NT_STATUS_OK);
450         CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
451
452         memset(buf, 0, maxsize);
453         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
454                 printf("read failed at %s\n", __location__);
455                 ret = False;
456                 goto done;
457         }
458         CHECK_BUFFER(buf+4, seed, 9);
459         CHECK_VALUE(IVAL(buf,0), 0);
460
461         setup_buffer(buf, seed, maxsize);
462
463         printf("Trying large write\n");
464         io.writeunlock.in.count = 4000;
465         io.writeunlock.in.offset = 0;
466         io.writeunlock.in.data = buf;
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, 4000);
472
473         status = smb_raw_write(cli->tree, &io);
474         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
475
476         memset(buf, 0, maxsize);
477         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
478                 printf("read failed at %s\n", __location__);
479                 ret = False;
480                 goto done;
481         }
482         CHECK_BUFFER(buf, seed, 4000);
483
484         printf("Trying bad fnum\n");
485         io.writeunlock.in.fnum = fnum+1;
486         io.writeunlock.in.count = 4000;
487         io.writeunlock.in.offset = 0;
488         io.writeunlock.in.data = buf;
489         status = smb_raw_write(cli->tree, &io);
490         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
491
492         printf("Setting file as sparse\n");
493         status = torture_set_sparse(cli->tree, fnum);
494         CHECK_STATUS(status, NT_STATUS_OK);
495         
496         printf("Trying 2^32 offset\n");
497         setup_buffer(buf, seed, maxsize);
498         io.writeunlock.in.fnum = fnum;
499         io.writeunlock.in.count = 4000;
500         io.writeunlock.in.offset = 0xFFFFFFFF - 2000;
501         io.writeunlock.in.data = buf;
502         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
503                  0, WRITE_LOCK);
504         status = smb_raw_write(cli->tree, &io);
505         CHECK_STATUS(status, NT_STATUS_OK);
506         CHECK_VALUE(io.writeunlock.out.nwritten, 4000);
507         CHECK_ALL_INFO(io.writeunlock.in.count + (uint64_t)io.writeunlock.in.offset, size);
508
509         memset(buf, 0, maxsize);
510         if (smbcli_read(cli->tree, fnum, buf, io.writeunlock.in.offset, 4000) != 4000) {
511                 printf("read failed at %s\n", __location__);
512                 ret = False;
513                 goto done;
514         }
515         CHECK_BUFFER(buf, seed, 4000);
516
517 done:
518         smbcli_close(cli->tree, fnum);
519         smb_raw_exit(cli->session);
520         smbcli_deltree(cli->tree, BASEDIR);
521         return ret;
522 }
523
524
525 /*
526   test write close ops
527 */
528 static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
529 {
530         union smb_write io;
531         NTSTATUS status;
532         BOOL ret = True;
533         int fnum;
534         uint8_t *buf;
535         const int maxsize = 90000;
536         const char *fname = BASEDIR "\\test.txt";
537         uint_t seed = time(NULL);
538         union smb_fileinfo finfo;
539
540         buf = talloc_zero_size(mem_ctx, maxsize);
541
542         if (!torture_setup_dir(cli, BASEDIR)) {
543                 return False;
544         }
545
546         printf("Testing RAW_WRITE_WRITECLOSE\n");
547         io.generic.level = RAW_WRITE_WRITECLOSE;
548         
549         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
550         if (fnum == -1) {
551                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
552                 ret = False;
553                 goto done;
554         }
555
556         printf("Trying zero write\n");
557         io.writeclose.in.fnum = fnum;
558         io.writeclose.in.count = 0;
559         io.writeclose.in.offset = 0;
560         io.writeclose.in.mtime = 0;
561         io.writeclose.in.data = buf;
562         status = smb_raw_write(cli->tree, &io);
563         CHECK_STATUS(status, NT_STATUS_OK);
564         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
565
566         status = smb_raw_write(cli->tree, &io);
567         CHECK_STATUS(status, NT_STATUS_OK);
568         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
569
570         setup_buffer(buf, seed, maxsize);
571
572         printf("Trying small write\n");
573         io.writeclose.in.count = 9;
574         io.writeclose.in.offset = 4;
575         io.writeclose.in.data = buf;
576         status = smb_raw_write(cli->tree, &io);
577         CHECK_STATUS(status, NT_STATUS_OK);
578
579         status = smb_raw_write(cli->tree, &io);
580         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
581
582         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
583         io.writeclose.in.fnum = fnum;
584
585         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
586                 printf("read failed at %s\n", __location__);
587                 ret = False;
588                 goto done;
589         }
590         CHECK_BUFFER(buf+4, seed, 9);
591         CHECK_VALUE(IVAL(buf,0), 0);
592
593         setup_buffer(buf, seed, maxsize);
594         status = smb_raw_write(cli->tree, &io);
595         CHECK_STATUS(status, NT_STATUS_OK);
596         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
597
598         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
599         io.writeclose.in.fnum = fnum;
600
601         memset(buf, 0, maxsize);
602         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
603                 printf("read failed at %s\n", __location__);
604                 ret = False;
605                 goto done;
606         }
607         CHECK_BUFFER(buf+4, seed, 9);
608         CHECK_VALUE(IVAL(buf,0), 0);
609
610         setup_buffer(buf, seed, maxsize);
611
612         printf("Trying large write\n");
613         io.writeclose.in.count = 4000;
614         io.writeclose.in.offset = 0;
615         io.writeclose.in.data = buf;
616         status = smb_raw_write(cli->tree, &io);
617         CHECK_STATUS(status, NT_STATUS_OK);
618         CHECK_VALUE(io.writeclose.out.nwritten, 4000);
619
620         status = smb_raw_write(cli->tree, &io);
621         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
622
623         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
624         io.writeclose.in.fnum = fnum;
625
626         memset(buf, 0, maxsize);
627         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
628                 printf("read failed at %s\n", __location__);
629                 ret = False;
630                 goto done;
631         }
632         CHECK_BUFFER(buf, seed, 4000);
633
634         printf("Trying bad fnum\n");
635         io.writeclose.in.fnum = fnum+1;
636         io.writeclose.in.count = 4000;
637         io.writeclose.in.offset = 0;
638         io.writeclose.in.data = buf;
639         status = smb_raw_write(cli->tree, &io);
640         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
641
642         printf("Setting file as sparse\n");
643         status = torture_set_sparse(cli->tree, fnum);
644         CHECK_STATUS(status, NT_STATUS_OK);
645         
646         printf("Trying 2^32 offset\n");
647         setup_buffer(buf, seed, maxsize);
648         io.writeclose.in.fnum = fnum;
649         io.writeclose.in.count = 4000;
650         io.writeclose.in.offset = 0xFFFFFFFF - 2000;
651         io.writeclose.in.data = buf;
652         status = smb_raw_write(cli->tree, &io);
653         CHECK_STATUS(status, NT_STATUS_OK);
654         CHECK_VALUE(io.writeclose.out.nwritten, 4000);
655         CHECK_ALL_INFO(io.writeclose.in.count + (uint64_t)io.writeclose.in.offset, size);
656
657         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
658         io.writeclose.in.fnum = fnum;
659
660         memset(buf, 0, maxsize);
661         if (smbcli_read(cli->tree, fnum, buf, io.writeclose.in.offset, 4000) != 4000) {
662                 printf("read failed at %s\n", __location__);
663                 ret = False;
664                 goto done;
665         }
666         CHECK_BUFFER(buf, seed, 4000);
667
668 done:
669         smbcli_close(cli->tree, fnum);
670         smb_raw_exit(cli->session);
671         smbcli_deltree(cli->tree, BASEDIR);
672         return ret;
673 }
674
675 /* 
676    basic testing of write calls
677 */
678 BOOL torture_raw_write(void)
679 {
680         struct smbcli_state *cli;
681         BOOL ret = True;
682         TALLOC_CTX *mem_ctx;
683
684         if (!torture_open_connection(&cli)) {
685                 return False;
686         }
687
688         mem_ctx = talloc_init("torture_raw_write");
689
690         ret &= test_write(cli, mem_ctx);
691         ret &= test_writeunlock(cli, mem_ctx);
692         ret &= test_writeclose(cli, mem_ctx);
693         ret &= test_writex(cli, mem_ctx);
694
695         torture_close_connection(cli);
696         talloc_free(mem_ctx);
697         return ret;
698 }