expanded the RAW-READ test to make it clearer that all locks conflict
[samba.git] / source4 / torture / raw / read.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for various read 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 BASEDIR "\\testread"
46
47
48 /*
49   setup a random buffer based on a seed
50 */
51 static void setup_buffer(char *buf, unsigned seed, int len)
52 {
53         int i;
54         srandom(seed);
55         for (i=0;i<len;i++) buf[i] = random();
56 }
57
58 /*
59   check a random buffer based on a seed
60 */
61 static BOOL check_buffer(char *buf, unsigned seed, int len, int line)
62 {
63         int i;
64         srandom(seed);
65         for (i=0;i<len;i++) {
66                 char v = random();
67                 if (buf[i] != v) {
68                         printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n", 
69                                line, i, buf[i], v);
70                         return False;
71                 }
72         }
73         return True;
74 }
75
76 /*
77   test read ops
78 */
79 static BOOL test_read(struct cli_state *cli, TALLOC_CTX *mem_ctx)
80 {
81         union smb_read io;
82         NTSTATUS status;
83         BOOL ret = True;
84         int fnum;
85         char *buf;
86         const int maxsize = 90000;
87         const char *fname = BASEDIR "\\test.txt";
88         const char *test_data = "TEST DATA";
89         unsigned seed = time(NULL);
90
91         buf = talloc_zero(mem_ctx, maxsize);
92
93         if (cli_deltree(cli, BASEDIR) == -1 ||
94             !cli_mkdir(cli, BASEDIR)) {
95                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli));
96                 return False;
97         }
98
99         printf("Testing RAW_READ_READ\n");
100         io.generic.level = RAW_READ_READ;
101         
102         fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
103         if (fnum == -1) {
104                 printf("Failed to create %s - %s\n", fname, cli_errstr(cli));
105                 ret = False;
106                 goto done;
107         }
108
109         printf("Trying empty file read\n");
110         io.read.in.fnum = fnum;
111         io.read.in.count = 1;
112         io.read.in.offset = 0;
113         io.read.in.remaining = 0;
114         io.read.out.data = buf;
115         status = smb_raw_read(cli->tree, &io);
116
117         CHECK_STATUS(status, NT_STATUS_OK);
118         CHECK_VALUE(io.read.out.nread, 0);
119
120         printf("Trying zero file read\n");
121         io.read.in.count = 0;
122         status = smb_raw_read(cli->tree, &io);
123         CHECK_STATUS(status, NT_STATUS_OK);
124         CHECK_VALUE(io.read.out.nread, 0);
125
126         printf("Trying bad fnum\n");
127         io.read.in.fnum = fnum+1;
128         status = smb_raw_read(cli->tree, &io);
129         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
130         io.read.in.fnum = fnum;
131
132         cli_write(cli, fnum, 0, test_data, 0, strlen(test_data));
133
134         printf("Trying small read\n");
135         io.read.in.fnum = fnum;
136         io.read.in.offset = 0;
137         io.read.in.remaining = 0;
138         io.read.in.count = strlen(test_data);
139         status = smb_raw_read(cli->tree, &io);
140         CHECK_STATUS(status, NT_STATUS_OK);
141         CHECK_VALUE(io.read.out.nread, strlen(test_data));
142         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
143                 ret = False;
144                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
145                 goto done;
146         }
147
148         printf("Trying short read\n");
149         io.read.in.offset = 1;
150         io.read.in.count = strlen(test_data);
151         status = smb_raw_read(cli->tree, &io);
152         CHECK_STATUS(status, NT_STATUS_OK);
153         CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
154         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
155                 ret = False;
156                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
157                 goto done;
158         }
159
160         printf("Trying max offset\n");
161         io.read.in.offset = ~0;
162         io.read.in.count = strlen(test_data);
163         status = smb_raw_read(cli->tree, &io);
164         CHECK_STATUS(status, NT_STATUS_OK);
165         CHECK_VALUE(io.read.out.nread, 0);
166
167         setup_buffer(buf, seed, maxsize);
168         cli_write(cli, fnum, 0, buf, 0, maxsize);
169         memset(buf, 0, maxsize);
170
171         printf("Trying large read\n");
172         io.read.in.offset = 0;
173         io.read.in.count = ~0;
174         status = smb_raw_read(cli->tree, &io);
175         CHECK_STATUS(status, NT_STATUS_OK);
176         CHECK_BUFFER(buf, seed, io.read.out.nread);
177
178
179         printf("Trying locked region\n");
180         cli->session->pid++;
181         if (!cli_lock(cli, fnum, 103, 1, 0, WRITE_LOCK)) {
182                 printf("Failed to lock file at %d\n", __LINE__);
183                 ret = False;
184                 goto done;
185         }
186         cli->session->pid--;
187         memset(buf, 0, maxsize);
188         io.read.in.offset = 0;
189         io.read.in.count = ~0;
190         status = smb_raw_read(cli->tree, &io);
191         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
192         
193
194 done:
195         cli_close(cli, fnum);
196         smb_raw_exit(cli->session);
197         cli_deltree(cli, BASEDIR);
198         return ret;
199 }
200
201
202 /*
203   test lockread ops
204 */
205 static BOOL test_lockread(struct cli_state *cli, TALLOC_CTX *mem_ctx)
206 {
207         union smb_read io;
208         NTSTATUS status;
209         BOOL ret = True;
210         int fnum;
211         char *buf;
212         const int maxsize = 90000;
213         const char *fname = BASEDIR "\\test.txt";
214         const char *test_data = "TEST DATA";
215         unsigned seed = time(NULL);
216
217         buf = talloc_zero(mem_ctx, maxsize);
218
219         if (cli_deltree(cli, BASEDIR) == -1 ||
220             !cli_mkdir(cli, BASEDIR)) {
221                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli));
222                 return False;
223         }
224
225         printf("Testing RAW_READ_LOCKREAD\n");
226         io.generic.level = RAW_READ_LOCKREAD;
227         
228         fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
229         if (fnum == -1) {
230                 printf("Failed to create %s - %s\n", fname, cli_errstr(cli));
231                 ret = False;
232                 goto done;
233         }
234
235         printf("Trying empty file read\n");
236         io.lockread.in.fnum = fnum;
237         io.lockread.in.count = 1;
238         io.lockread.in.offset = 0;
239         io.lockread.in.remaining = 0;
240         io.lockread.out.data = buf;
241         status = smb_raw_read(cli->tree, &io);
242
243         CHECK_STATUS(status, NT_STATUS_OK);
244         CHECK_VALUE(io.lockread.out.nread, 0);
245
246         status = smb_raw_read(cli->tree, &io);
247         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
248
249         status = smb_raw_read(cli->tree, &io);
250         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
251
252         printf("Trying zero file read\n");
253         io.lockread.in.count = 0;
254         status = smb_raw_read(cli->tree, &io);
255         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
256
257         printf("Trying bad fnum\n");
258         io.lockread.in.fnum = fnum+1;
259         status = smb_raw_read(cli->tree, &io);
260         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
261         io.lockread.in.fnum = fnum;
262
263         cli_write(cli, fnum, 0, test_data, 0, strlen(test_data));
264
265         printf("Trying small read\n");
266         io.lockread.in.fnum = fnum;
267         io.lockread.in.offset = 0;
268         io.lockread.in.remaining = 0;
269         io.lockread.in.count = strlen(test_data);
270         status = smb_raw_read(cli->tree, &io);
271         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
272
273         cli_unlock(cli, fnum, 0, 1);
274
275         status = smb_raw_read(cli->tree, &io);
276         CHECK_STATUS(status, NT_STATUS_OK);
277         CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
278         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
279                 ret = False;
280                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
281                 goto done;
282         }
283
284         printf("Trying short read\n");
285         io.lockread.in.offset = 1;
286         io.lockread.in.count = strlen(test_data);
287         status = smb_raw_read(cli->tree, &io);
288         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
289         cli_unlock(cli, fnum, 0, strlen(test_data));
290         status = smb_raw_read(cli->tree, &io);
291         CHECK_STATUS(status, NT_STATUS_OK);
292
293         CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
294         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
295                 ret = False;
296                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
297                 goto done;
298         }
299
300         printf("Trying max offset\n");
301         io.lockread.in.offset = ~0;
302         io.lockread.in.count = strlen(test_data);
303         status = smb_raw_read(cli->tree, &io);
304         CHECK_STATUS(status, NT_STATUS_OK);
305         CHECK_VALUE(io.lockread.out.nread, 0);
306
307         setup_buffer(buf, seed, maxsize);
308         cli_write(cli, fnum, 0, buf, 0, maxsize);
309         memset(buf, 0, maxsize);
310
311         printf("Trying large read\n");
312         io.lockread.in.offset = 0;
313         io.lockread.in.count = ~0;
314         status = smb_raw_read(cli->tree, &io);
315         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
316         cli_unlock(cli, fnum, 1, strlen(test_data));
317         status = smb_raw_read(cli->tree, &io);
318         CHECK_STATUS(status, NT_STATUS_OK);
319         CHECK_BUFFER(buf, seed, io.lockread.out.nread);
320         cli_unlock(cli, fnum, 0, 0xFFFF);
321
322
323         printf("Trying locked region\n");
324         cli->session->pid++;
325         if (!cli_lock(cli, fnum, 103, 1, 0, WRITE_LOCK)) {
326                 printf("Failed to lock file at %d\n", __LINE__);
327                 ret = False;
328                 goto done;
329         }
330         cli->session->pid--;
331         memset(buf, 0, maxsize);
332         io.lockread.in.offset = 0;
333         io.lockread.in.count = ~0;
334         status = smb_raw_read(cli->tree, &io);
335         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
336         
337
338 done:
339         cli_close(cli, fnum);
340         cli_deltree(cli, BASEDIR);
341         return ret;
342 }
343
344
345 /*
346   test readx ops
347 */
348 static BOOL test_readx(struct cli_state *cli, TALLOC_CTX *mem_ctx)
349 {
350         union smb_read io;
351         NTSTATUS status;
352         BOOL ret = True;
353         int fnum;
354         char *buf;
355         const int maxsize = 90000;
356         const char *fname = BASEDIR "\\test.txt";
357         const char *test_data = "TEST DATA";
358         unsigned seed = time(NULL);
359
360         buf = talloc_zero(mem_ctx, maxsize);
361
362         if (cli_deltree(cli, BASEDIR) == -1 ||
363             !cli_mkdir(cli, BASEDIR)) {
364                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli));
365                 return False;
366         }
367
368         printf("Testing RAW_READ_READX\n");
369         
370         fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
371         if (fnum == -1) {
372                 printf("Failed to create %s - %s\n", fname, cli_errstr(cli));
373                 ret = False;
374                 goto done;
375         }
376
377         printf("Trying empty file read\n");
378         io.generic.level = RAW_READ_READX;
379         io.readx.in.fnum = fnum;
380         io.readx.in.mincnt = 1;
381         io.readx.in.maxcnt = 1;
382         io.readx.in.offset = 0;
383         io.readx.in.remaining = 0;
384         io.readx.out.data = buf;
385         status = smb_raw_read(cli->tree, &io);
386
387         CHECK_STATUS(status, NT_STATUS_OK);
388         CHECK_VALUE(io.readx.out.nread, 0);
389         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
390         CHECK_VALUE(io.readx.out.compaction_mode, 0);
391
392         printf("Trying zero file read\n");
393         io.readx.in.mincnt = 0;
394         io.readx.in.maxcnt = 0;
395         status = smb_raw_read(cli->tree, &io);
396         CHECK_STATUS(status, NT_STATUS_OK);
397         CHECK_VALUE(io.readx.out.nread, 0);
398         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
399         CHECK_VALUE(io.readx.out.compaction_mode, 0);
400
401         printf("Trying bad fnum\n");
402         io.readx.in.fnum = fnum+1;
403         status = smb_raw_read(cli->tree, &io);
404         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
405         io.readx.in.fnum = fnum;
406
407         cli_write(cli, fnum, 0, test_data, 0, strlen(test_data));
408
409         printf("Trying small read\n");
410         io.readx.in.fnum = fnum;
411         io.readx.in.offset = 0;
412         io.readx.in.remaining = 0;
413         io.readx.in.mincnt = strlen(test_data);
414         io.readx.in.maxcnt = strlen(test_data);
415         status = smb_raw_read(cli->tree, &io);
416         CHECK_STATUS(status, NT_STATUS_OK);
417         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
418         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
419         CHECK_VALUE(io.readx.out.compaction_mode, 0);
420         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
421                 ret = False;
422                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
423                 goto done;
424         }
425
426         printf("Trying short read\n");
427         io.readx.in.offset = 1;
428         io.readx.in.mincnt = strlen(test_data);
429         io.readx.in.maxcnt = strlen(test_data);
430         status = smb_raw_read(cli->tree, &io);
431         CHECK_STATUS(status, NT_STATUS_OK);
432         CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
433         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
434         CHECK_VALUE(io.readx.out.compaction_mode, 0);
435         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
436                 ret = False;
437                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
438                 goto done;
439         }
440
441         printf("Trying max offset\n");
442         io.readx.in.offset = 0xffffffff;
443         io.readx.in.mincnt = strlen(test_data);
444         io.readx.in.maxcnt = strlen(test_data);
445         status = smb_raw_read(cli->tree, &io);
446         CHECK_STATUS(status, NT_STATUS_OK);
447         CHECK_VALUE(io.readx.out.nread, 0);
448         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
449         CHECK_VALUE(io.readx.out.compaction_mode, 0);
450
451         setup_buffer(buf, seed, maxsize);
452         cli_write(cli, fnum, 0, buf, 0, maxsize);
453         memset(buf, 0, maxsize);
454
455         printf("Trying large read\n");
456         io.readx.in.offset = 0;
457         io.readx.in.mincnt = ~0;
458         io.readx.in.maxcnt = ~0;
459         status = smb_raw_read(cli->tree, &io);
460         CHECK_STATUS(status, NT_STATUS_OK);
461         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
462         CHECK_VALUE(io.readx.out.compaction_mode, 0);
463         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
464         CHECK_BUFFER(buf, seed, io.readx.out.nread);
465
466         printf("Trying mincnt > maxcnt\n");
467         memset(buf, 0, maxsize);
468         io.readx.in.offset = 0;
469         io.readx.in.mincnt = 30000;
470         io.readx.in.maxcnt = 20000;
471         status = smb_raw_read(cli->tree, &io);
472         CHECK_STATUS(status, NT_STATUS_OK);
473         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
474         CHECK_VALUE(io.readx.out.compaction_mode, 0);
475         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
476         CHECK_BUFFER(buf, seed, io.readx.out.nread);
477
478         printf("Trying mincnt < maxcnt\n");
479         memset(buf, 0, maxsize);
480         io.readx.in.offset = 0;
481         io.readx.in.mincnt = 20000;
482         io.readx.in.maxcnt = 30000;
483         status = smb_raw_read(cli->tree, &io);
484         CHECK_STATUS(status, NT_STATUS_OK);
485         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
486         CHECK_VALUE(io.readx.out.compaction_mode, 0);
487         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
488         CHECK_BUFFER(buf, seed, io.readx.out.nread);
489
490         printf("Trying locked region\n");
491         cli->session->pid++;
492         if (!cli_lock(cli, fnum, 103, 1, 0, WRITE_LOCK)) {
493                 printf("Failed to lock file at %d\n", __LINE__);
494                 ret = False;
495                 goto done;
496         }
497         cli->session->pid--;
498         memset(buf, 0, maxsize);
499         io.readx.in.offset = 0;
500         io.readx.in.mincnt = 100;
501         io.readx.in.maxcnt = 200;
502         status = smb_raw_read(cli->tree, &io);
503         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
504
505 #ifdef LARGE_SMB_OFF_T
506         printf("Trying large offset read\n");
507         io.readx.in.offset = ((SMB_BIG_UINT)0x2) << 32;
508         io.readx.in.mincnt = 10;
509         io.readx.in.maxcnt = 10;
510         status = smb_raw_read(cli->tree, &io);
511         CHECK_STATUS(status, NT_STATUS_OK);
512         CHECK_VALUE(io.readx.out.nread, 0);
513
514         if (!cli_lock64(cli, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK)) {
515                 printf("Failed to lock file at %d\n", __LINE__);
516                 ret = False;
517                 goto done;
518         }
519
520         status = smb_raw_read(cli->tree, &io);
521         CHECK_STATUS(status, NT_STATUS_OK);
522         CHECK_VALUE(io.readx.out.nread, 0);
523 #endif
524
525 done:
526         cli_close(cli, fnum);
527         cli_deltree(cli, BASEDIR);
528         return ret;
529 }
530
531
532 /*
533   test readbraw ops
534 */
535 static BOOL test_readbraw(struct cli_state *cli, TALLOC_CTX *mem_ctx)
536 {
537         union smb_read io;
538         NTSTATUS status;
539         BOOL ret = True;
540         int fnum;
541         char *buf;
542         const int maxsize = 90000;
543         const char *fname = BASEDIR "\\test.txt";
544         const char *test_data = "TEST DATA";
545         unsigned seed = time(NULL);
546
547         buf = talloc_zero(mem_ctx, maxsize);
548
549         if (cli_deltree(cli, BASEDIR) == -1 ||
550             !cli_mkdir(cli, BASEDIR)) {
551                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli));
552                 return False;
553         }
554
555         printf("Testing RAW_READ_READBRAW\n");
556         
557         fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
558         if (fnum == -1) {
559                 printf("Failed to create %s - %s\n", fname, cli_errstr(cli));
560                 ret = False;
561                 goto done;
562         }
563
564         printf("Trying empty file read\n");
565         io.generic.level = RAW_READ_READBRAW;
566         io.readbraw.in.fnum = fnum;
567         io.readbraw.in.mincnt = 1;
568         io.readbraw.in.maxcnt = 1;
569         io.readbraw.in.offset = 0;
570         io.readbraw.in.timeout = 0;
571         io.readbraw.out.data = buf;
572         status = smb_raw_read(cli->tree, &io);
573
574         CHECK_STATUS(status, NT_STATUS_OK);
575         CHECK_VALUE(io.readbraw.out.nread, 0);
576
577         printf("Trying zero file read\n");
578         io.readbraw.in.mincnt = 0;
579         io.readbraw.in.maxcnt = 0;
580         status = smb_raw_read(cli->tree, &io);
581         CHECK_STATUS(status, NT_STATUS_OK);
582         CHECK_VALUE(io.readbraw.out.nread, 0);
583
584         printf("Trying bad fnum\n");
585         io.readbraw.in.fnum = fnum+1;
586         status = smb_raw_read(cli->tree, &io);
587         CHECK_STATUS(status, NT_STATUS_OK);
588         CHECK_VALUE(io.readbraw.out.nread, 0);
589         io.readbraw.in.fnum = fnum;
590
591         cli_write(cli, fnum, 0, test_data, 0, strlen(test_data));
592
593         printf("Trying small read\n");
594         io.readbraw.in.fnum = fnum;
595         io.readbraw.in.offset = 0;
596         io.readbraw.in.mincnt = strlen(test_data);
597         io.readbraw.in.maxcnt = strlen(test_data);
598         status = smb_raw_read(cli->tree, &io);
599         CHECK_STATUS(status, NT_STATUS_OK);
600         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
601         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
602                 ret = False;
603                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
604                 goto done;
605         }
606
607         printf("Trying short read\n");
608         io.readbraw.in.offset = 1;
609         io.readbraw.in.mincnt = strlen(test_data);
610         io.readbraw.in.maxcnt = strlen(test_data);
611         status = smb_raw_read(cli->tree, &io);
612         CHECK_STATUS(status, NT_STATUS_OK);
613         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
614         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
615                 ret = False;
616                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
617                 goto done;
618         }
619
620         printf("Trying max offset\n");
621         io.readbraw.in.offset = ~0;
622         io.readbraw.in.mincnt = strlen(test_data);
623         io.readbraw.in.maxcnt = strlen(test_data);
624         status = smb_raw_read(cli->tree, &io);
625         CHECK_STATUS(status, NT_STATUS_OK);
626         CHECK_VALUE(io.readbraw.out.nread, 0);
627
628         setup_buffer(buf, seed, maxsize);
629         cli_write(cli, fnum, 0, buf, 0, maxsize);
630         memset(buf, 0, maxsize);
631
632         printf("Trying large read\n");
633         io.readbraw.in.offset = 0;
634         io.readbraw.in.mincnt = ~0;
635         io.readbraw.in.maxcnt = ~0;
636         status = smb_raw_read(cli->tree, &io);
637         CHECK_STATUS(status, NT_STATUS_OK);
638         CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
639         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
640
641         printf("Trying mincnt > maxcnt\n");
642         memset(buf, 0, maxsize);
643         io.readbraw.in.offset = 0;
644         io.readbraw.in.mincnt = 30000;
645         io.readbraw.in.maxcnt = 20000;
646         status = smb_raw_read(cli->tree, &io);
647         CHECK_STATUS(status, NT_STATUS_OK);
648         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
649         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
650
651         printf("Trying mincnt < maxcnt\n");
652         memset(buf, 0, maxsize);
653         io.readbraw.in.offset = 0;
654         io.readbraw.in.mincnt = 20000;
655         io.readbraw.in.maxcnt = 30000;
656         status = smb_raw_read(cli->tree, &io);
657         CHECK_STATUS(status, NT_STATUS_OK);
658         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
659         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
660
661         printf("Trying locked region\n");
662         cli->session->pid++;
663         if (!cli_lock(cli, fnum, 103, 1, 0, WRITE_LOCK)) {
664                 printf("Failed to lock file at %d\n", __LINE__);
665                 ret = False;
666                 goto done;
667         }
668         cli->session->pid--;
669         memset(buf, 0, maxsize);
670         io.readbraw.in.offset = 0;
671         io.readbraw.in.mincnt = 100;
672         io.readbraw.in.maxcnt = 200;
673         status = smb_raw_read(cli->tree, &io);
674         CHECK_STATUS(status, NT_STATUS_OK);
675         CHECK_VALUE(io.readbraw.out.nread, 0);
676
677         printf("Trying locked region with timeout\n");
678         memset(buf, 0, maxsize);
679         io.readbraw.in.offset = 0;
680         io.readbraw.in.mincnt = 100;
681         io.readbraw.in.maxcnt = 200;
682         io.readbraw.in.timeout = 10000;
683         status = smb_raw_read(cli->tree, &io);
684         CHECK_STATUS(status, NT_STATUS_OK);
685         CHECK_VALUE(io.readbraw.out.nread, 0);
686
687 #ifdef LARGE_SMB_OFF_T
688         printf("Trying large offset read\n");
689         io.readbraw.in.offset = ((SMB_BIG_UINT)0x2) << 32;
690         io.readbraw.in.mincnt = 10;
691         io.readbraw.in.maxcnt = 10;
692         io.readbraw.in.timeout = 0;
693         status = smb_raw_read(cli->tree, &io);
694         CHECK_STATUS(status, NT_STATUS_OK);
695         CHECK_VALUE(io.readbraw.out.nread, 0);
696 #endif
697
698 done:
699         cli_close(cli, fnum);
700         cli_deltree(cli, BASEDIR);
701         return ret;
702 }
703
704
705 /* 
706    basic testing of read calls
707 */
708 BOOL torture_raw_read(int dummy)
709 {
710         struct cli_state *cli;
711         BOOL ret = True;
712         TALLOC_CTX *mem_ctx;
713
714         if (!torture_open_connection(&cli)) {
715                 return False;
716         }
717
718         mem_ctx = talloc_init("torture_raw_read");
719
720         if (!test_read(cli, mem_ctx)) {
721                 ret = False;
722         }
723
724         if (!test_readx(cli, mem_ctx)) {
725                 ret = False;
726         }
727
728         if (!test_lockread(cli, mem_ctx)) {
729                 ret = False;
730         }
731
732         if (!test_readbraw(cli, mem_ctx)) {
733                 ret = False;
734         }
735
736         torture_close_connection(cli);
737         talloc_destroy(mem_ctx);
738         return ret;
739 }