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