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