r3242: make the RAW-READ test not exercise the 0-0 lock, which is not deterministic
[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("(%s) Incorrect status %s - should be %s\n", \
26                        __location__, 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("(%s) Incorrect value %s=%d - should be %d\n", \
34                        __location__, #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, uint_t 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, uint_t 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 smbcli_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         uint_t seed = time(NULL);
90
91         buf = talloc_zero(mem_ctx, maxsize);
92
93         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
94             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
95                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
96                 return False;
97         }
98
99         printf("Testing RAW_READ_READ\n");
100         io.generic.level = RAW_READ_READ;
101         
102         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
103         if (fnum == -1) {
104                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
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         smbcli_write(cli->tree, 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         smbcli_write(cli->tree, 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 (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, 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         smbcli_close(cli->tree, fnum);
196         smb_raw_exit(cli->session);
197         smbcli_deltree(cli->tree, BASEDIR);
198         return ret;
199 }
200
201
202 /*
203   test lockread ops
204 */
205 static BOOL test_lockread(struct smbcli_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         uint_t seed = time(NULL);
216
217         buf = talloc_zero(mem_ctx, maxsize);
218
219         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
220             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
221                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
222                 return False;
223         }
224
225         printf("Testing RAW_READ_LOCKREAD\n");
226         io.generic.level = RAW_READ_LOCKREAD;
227         
228         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
229         if (fnum == -1) {
230                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
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 = 1;
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_OK);
256
257         smbcli_unlock(cli->tree, fnum, 1, 1);
258
259         printf("Trying bad fnum\n");
260         io.lockread.in.fnum = fnum+1;
261         status = smb_raw_read(cli->tree, &io);
262         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
263         io.lockread.in.fnum = fnum;
264
265         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
266
267         printf("Trying small read\n");
268         io.lockread.in.fnum = fnum;
269         io.lockread.in.offset = 0;
270         io.lockread.in.remaining = 0;
271         io.lockread.in.count = strlen(test_data);
272         status = smb_raw_read(cli->tree, &io);
273         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
274
275         smbcli_unlock(cli->tree, fnum, 1, 0);
276
277         status = smb_raw_read(cli->tree, &io);
278         CHECK_STATUS(status, NT_STATUS_OK);
279         CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
280         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
281                 ret = False;
282                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
283                 goto done;
284         }
285
286         printf("Trying short read\n");
287         io.lockread.in.offset = 1;
288         io.lockread.in.count = strlen(test_data);
289         status = smb_raw_read(cli->tree, &io);
290         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
291         smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
292         status = smb_raw_read(cli->tree, &io);
293         CHECK_STATUS(status, NT_STATUS_OK);
294
295         CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
296         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
297                 ret = False;
298                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
299                 goto done;
300         }
301
302         printf("Trying max offset\n");
303         io.lockread.in.offset = ~0;
304         io.lockread.in.count = strlen(test_data);
305         status = smb_raw_read(cli->tree, &io);
306         CHECK_STATUS(status, NT_STATUS_OK);
307         CHECK_VALUE(io.lockread.out.nread, 0);
308
309         setup_buffer(buf, seed, maxsize);
310         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
311         memset(buf, 0, maxsize);
312
313         printf("Trying large read\n");
314         io.lockread.in.offset = 0;
315         io.lockread.in.count = ~0;
316         status = smb_raw_read(cli->tree, &io);
317         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
318         smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
319         status = smb_raw_read(cli->tree, &io);
320         CHECK_STATUS(status, NT_STATUS_OK);
321         CHECK_BUFFER(buf, seed, io.lockread.out.nread);
322         smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
323
324
325         printf("Trying locked region\n");
326         cli->session->pid++;
327         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
328                 printf("Failed to lock file at %d\n", __LINE__);
329                 ret = False;
330                 goto done;
331         }
332         cli->session->pid--;
333         memset(buf, 0, maxsize);
334         io.lockread.in.offset = 0;
335         io.lockread.in.count = ~0;
336         status = smb_raw_read(cli->tree, &io);
337         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
338         
339
340 done:
341         smbcli_close(cli->tree, fnum);
342         smbcli_deltree(cli->tree, BASEDIR);
343         return ret;
344 }
345
346
347 /*
348   test readx ops
349 */
350 static BOOL test_readx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
351 {
352         union smb_read io;
353         NTSTATUS status;
354         BOOL ret = True;
355         int fnum;
356         char *buf;
357         const int maxsize = 90000;
358         const char *fname = BASEDIR "\\test.txt";
359         const char *test_data = "TEST DATA";
360         uint_t seed = time(NULL);
361
362         buf = talloc_zero(mem_ctx, maxsize);
363
364         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
365             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
366                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
367                 return False;
368         }
369
370         printf("Testing RAW_READ_READX\n");
371         
372         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
373         if (fnum == -1) {
374                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
375                 ret = False;
376                 goto done;
377         }
378
379         printf("Trying empty file read\n");
380         io.generic.level = RAW_READ_READX;
381         io.readx.in.fnum = fnum;
382         io.readx.in.mincnt = 1;
383         io.readx.in.maxcnt = 1;
384         io.readx.in.offset = 0;
385         io.readx.in.remaining = 0;
386         io.readx.out.data = buf;
387         status = smb_raw_read(cli->tree, &io);
388
389         CHECK_STATUS(status, NT_STATUS_OK);
390         CHECK_VALUE(io.readx.out.nread, 0);
391         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
392         CHECK_VALUE(io.readx.out.compaction_mode, 0);
393
394         printf("Trying zero file read\n");
395         io.readx.in.mincnt = 0;
396         io.readx.in.maxcnt = 0;
397         status = smb_raw_read(cli->tree, &io);
398         CHECK_STATUS(status, NT_STATUS_OK);
399         CHECK_VALUE(io.readx.out.nread, 0);
400         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
401         CHECK_VALUE(io.readx.out.compaction_mode, 0);
402
403         printf("Trying bad fnum\n");
404         io.readx.in.fnum = fnum+1;
405         status = smb_raw_read(cli->tree, &io);
406         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
407         io.readx.in.fnum = fnum;
408
409         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
410
411         printf("Trying small read\n");
412         io.readx.in.fnum = fnum;
413         io.readx.in.offset = 0;
414         io.readx.in.remaining = 0;
415         io.readx.in.mincnt = strlen(test_data);
416         io.readx.in.maxcnt = strlen(test_data);
417         status = smb_raw_read(cli->tree, &io);
418         CHECK_STATUS(status, NT_STATUS_OK);
419         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
420         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
421         CHECK_VALUE(io.readx.out.compaction_mode, 0);
422         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
423                 ret = False;
424                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
425                 goto done;
426         }
427
428         printf("Trying short read\n");
429         io.readx.in.offset = 1;
430         io.readx.in.mincnt = strlen(test_data);
431         io.readx.in.maxcnt = strlen(test_data);
432         status = smb_raw_read(cli->tree, &io);
433         CHECK_STATUS(status, NT_STATUS_OK);
434         CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
435         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
436         CHECK_VALUE(io.readx.out.compaction_mode, 0);
437         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
438                 ret = False;
439                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
440                 goto done;
441         }
442
443         printf("Trying max offset\n");
444         io.readx.in.offset = 0xffffffff;
445         io.readx.in.mincnt = strlen(test_data);
446         io.readx.in.maxcnt = strlen(test_data);
447         status = smb_raw_read(cli->tree, &io);
448         CHECK_STATUS(status, NT_STATUS_OK);
449         CHECK_VALUE(io.readx.out.nread, 0);
450         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
451         CHECK_VALUE(io.readx.out.compaction_mode, 0);
452
453         setup_buffer(buf, seed, maxsize);
454         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
455         memset(buf, 0, maxsize);
456
457         printf("Trying large read\n");
458         io.readx.in.offset = 0;
459         io.readx.in.mincnt = 0xFFFF;
460         io.readx.in.maxcnt = 0xFFFF;
461         status = smb_raw_read(cli->tree, &io);
462         CHECK_STATUS(status, NT_STATUS_OK);
463         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
464         CHECK_VALUE(io.readx.out.compaction_mode, 0);
465         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
466         CHECK_BUFFER(buf, seed, io.readx.out.nread);
467
468         printf("Trying extra large read\n");
469         io.readx.in.offset = 0;
470         io.readx.in.mincnt = 100;
471         io.readx.in.maxcnt = 80000;
472         status = smb_raw_read(cli->tree, &io);
473         CHECK_STATUS(status, NT_STATUS_OK);
474         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
475         CHECK_VALUE(io.readx.out.compaction_mode, 0);
476         CHECK_VALUE(io.readx.out.nread, 0);
477         CHECK_BUFFER(buf, seed, io.readx.out.nread);
478
479         printf("Trying mincnt > maxcnt\n");
480         memset(buf, 0, maxsize);
481         io.readx.in.offset = 0;
482         io.readx.in.mincnt = 30000;
483         io.readx.in.maxcnt = 20000;
484         status = smb_raw_read(cli->tree, &io);
485         CHECK_STATUS(status, NT_STATUS_OK);
486         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
487         CHECK_VALUE(io.readx.out.compaction_mode, 0);
488         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
489         CHECK_BUFFER(buf, seed, io.readx.out.nread);
490
491         printf("Trying mincnt < maxcnt\n");
492         memset(buf, 0, maxsize);
493         io.readx.in.offset = 0;
494         io.readx.in.mincnt = 20000;
495         io.readx.in.maxcnt = 30000;
496         status = smb_raw_read(cli->tree, &io);
497         CHECK_STATUS(status, NT_STATUS_OK);
498         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
499         CHECK_VALUE(io.readx.out.compaction_mode, 0);
500         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
501         CHECK_BUFFER(buf, seed, io.readx.out.nread);
502
503         printf("Trying locked region\n");
504         cli->session->pid++;
505         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
506                 printf("Failed to lock file at %d\n", __LINE__);
507                 ret = False;
508                 goto done;
509         }
510         cli->session->pid--;
511         memset(buf, 0, maxsize);
512         io.readx.in.offset = 0;
513         io.readx.in.mincnt = 100;
514         io.readx.in.maxcnt = 200;
515         status = smb_raw_read(cli->tree, &io);
516         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
517
518         printf("Trying large offset read\n");
519         io.readx.in.offset = ((uint64_t)0x2) << 32;
520         io.readx.in.mincnt = 10;
521         io.readx.in.maxcnt = 10;
522         status = smb_raw_read(cli->tree, &io);
523         CHECK_STATUS(status, NT_STATUS_OK);
524         CHECK_VALUE(io.readx.out.nread, 0);
525
526         if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
527                 printf("Failed to lock file at %d\n", __LINE__);
528                 ret = False;
529                 goto done;
530         }
531
532         status = smb_raw_read(cli->tree, &io);
533         CHECK_STATUS(status, NT_STATUS_OK);
534         CHECK_VALUE(io.readx.out.nread, 0);
535
536 done:
537         smbcli_close(cli->tree, fnum);
538         smbcli_deltree(cli->tree, BASEDIR);
539         return ret;
540 }
541
542
543 /*
544   test readbraw ops
545 */
546 static BOOL test_readbraw(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
547 {
548         union smb_read io;
549         NTSTATUS status;
550         BOOL ret = True;
551         int fnum;
552         char *buf;
553         const int maxsize = 90000;
554         const char *fname = BASEDIR "\\test.txt";
555         const char *test_data = "TEST DATA";
556         uint_t seed = time(NULL);
557
558         buf = talloc_zero(mem_ctx, maxsize);
559
560         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
561             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
562                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
563                 return False;
564         }
565
566         printf("Testing RAW_READ_READBRAW\n");
567         
568         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
569         if (fnum == -1) {
570                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
571                 ret = False;
572                 goto done;
573         }
574
575         printf("Trying empty file read\n");
576         io.generic.level = RAW_READ_READBRAW;
577         io.readbraw.in.fnum = fnum;
578         io.readbraw.in.mincnt = 1;
579         io.readbraw.in.maxcnt = 1;
580         io.readbraw.in.offset = 0;
581         io.readbraw.in.timeout = 0;
582         io.readbraw.out.data = buf;
583         status = smb_raw_read(cli->tree, &io);
584
585         CHECK_STATUS(status, NT_STATUS_OK);
586         CHECK_VALUE(io.readbraw.out.nread, 0);
587
588         printf("Trying zero file read\n");
589         io.readbraw.in.mincnt = 0;
590         io.readbraw.in.maxcnt = 0;
591         status = smb_raw_read(cli->tree, &io);
592         CHECK_STATUS(status, NT_STATUS_OK);
593         CHECK_VALUE(io.readbraw.out.nread, 0);
594
595         printf("Trying bad fnum\n");
596         io.readbraw.in.fnum = fnum+1;
597         status = smb_raw_read(cli->tree, &io);
598         CHECK_STATUS(status, NT_STATUS_OK);
599         CHECK_VALUE(io.readbraw.out.nread, 0);
600         io.readbraw.in.fnum = fnum;
601
602         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
603
604         printf("Trying small read\n");
605         io.readbraw.in.fnum = fnum;
606         io.readbraw.in.offset = 0;
607         io.readbraw.in.mincnt = strlen(test_data);
608         io.readbraw.in.maxcnt = strlen(test_data);
609         status = smb_raw_read(cli->tree, &io);
610         CHECK_STATUS(status, NT_STATUS_OK);
611         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
612         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
613                 ret = False;
614                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
615                 goto done;
616         }
617
618         printf("Trying short read\n");
619         io.readbraw.in.offset = 1;
620         io.readbraw.in.mincnt = strlen(test_data);
621         io.readbraw.in.maxcnt = strlen(test_data);
622         status = smb_raw_read(cli->tree, &io);
623         CHECK_STATUS(status, NT_STATUS_OK);
624         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
625         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
626                 ret = False;
627                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
628                 goto done;
629         }
630
631         printf("Trying max offset\n");
632         io.readbraw.in.offset = ~0;
633         io.readbraw.in.mincnt = strlen(test_data);
634         io.readbraw.in.maxcnt = strlen(test_data);
635         status = smb_raw_read(cli->tree, &io);
636         CHECK_STATUS(status, NT_STATUS_OK);
637         CHECK_VALUE(io.readbraw.out.nread, 0);
638
639         setup_buffer(buf, seed, maxsize);
640         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
641         memset(buf, 0, maxsize);
642
643         printf("Trying large read\n");
644         io.readbraw.in.offset = 0;
645         io.readbraw.in.mincnt = ~0;
646         io.readbraw.in.maxcnt = ~0;
647         status = smb_raw_read(cli->tree, &io);
648         CHECK_STATUS(status, NT_STATUS_OK);
649         CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
650         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
651
652         printf("Trying mincnt > maxcnt\n");
653         memset(buf, 0, maxsize);
654         io.readbraw.in.offset = 0;
655         io.readbraw.in.mincnt = 30000;
656         io.readbraw.in.maxcnt = 20000;
657         status = smb_raw_read(cli->tree, &io);
658         CHECK_STATUS(status, NT_STATUS_OK);
659         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
660         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
661
662         printf("Trying mincnt < maxcnt\n");
663         memset(buf, 0, maxsize);
664         io.readbraw.in.offset = 0;
665         io.readbraw.in.mincnt = 20000;
666         io.readbraw.in.maxcnt = 30000;
667         status = smb_raw_read(cli->tree, &io);
668         CHECK_STATUS(status, NT_STATUS_OK);
669         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
670         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
671
672         printf("Trying locked region\n");
673         cli->session->pid++;
674         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
675                 printf("Failed to lock file at %d\n", __LINE__);
676                 ret = False;
677                 goto done;
678         }
679         cli->session->pid--;
680         memset(buf, 0, maxsize);
681         io.readbraw.in.offset = 0;
682         io.readbraw.in.mincnt = 100;
683         io.readbraw.in.maxcnt = 200;
684         status = smb_raw_read(cli->tree, &io);
685         CHECK_STATUS(status, NT_STATUS_OK);
686         CHECK_VALUE(io.readbraw.out.nread, 0);
687
688         printf("Trying locked region with timeout\n");
689         memset(buf, 0, maxsize);
690         io.readbraw.in.offset = 0;
691         io.readbraw.in.mincnt = 100;
692         io.readbraw.in.maxcnt = 200;
693         io.readbraw.in.timeout = 10000;
694         status = smb_raw_read(cli->tree, &io);
695         CHECK_STATUS(status, NT_STATUS_OK);
696         CHECK_VALUE(io.readbraw.out.nread, 0);
697
698         printf("Trying large offset read\n");
699         io.readbraw.in.offset = ((uint64_t)0x2) << 32;
700         io.readbraw.in.mincnt = 10;
701         io.readbraw.in.maxcnt = 10;
702         io.readbraw.in.timeout = 0;
703         status = smb_raw_read(cli->tree, &io);
704         CHECK_STATUS(status, NT_STATUS_OK);
705         CHECK_VALUE(io.readbraw.out.nread, 0);
706
707 done:
708         smbcli_close(cli->tree, fnum);
709         smbcli_deltree(cli->tree, BASEDIR);
710         return ret;
711 }
712
713
714 /* 
715    basic testing of read calls
716 */
717 BOOL torture_raw_read(int dummy)
718 {
719         struct smbcli_state *cli;
720         BOOL ret = True;
721         TALLOC_CTX *mem_ctx;
722
723         if (!torture_open_connection(&cli)) {
724                 return False;
725         }
726
727         mem_ctx = talloc_init("torture_raw_read");
728
729         if (!test_read(cli, mem_ctx)) {
730                 ret = False;
731         }
732
733         if (!test_readx(cli, mem_ctx)) {
734                 ret = False;
735         }
736
737         if (!test_lockread(cli, mem_ctx)) {
738                 ret = False;
739         }
740
741         if (!test_readbraw(cli, mem_ctx)) {
742                 ret = False;
743         }
744
745         torture_close_connection(cli);
746         talloc_destroy(mem_ctx);
747         return ret;
748 }