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