r12693: Move core data structures out of smb.h into core.h
[jelmer/samba4-debian.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 "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/filesys.h"
26
27 #define CHECK_STATUS(status, correct) do { \
28         if (!NT_STATUS_EQUAL(status, correct)) { \
29                 printf("(%s) Incorrect status %s - should be %s\n", \
30                        __location__, nt_errstr(status), nt_errstr(correct)); \
31                 ret = False; \
32                 goto done; \
33         }} while (0)
34
35 #define CHECK_VALUE(v, correct) do { \
36         if ((v) != (correct)) { \
37                 printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
38                        __location__, #v, (long)v, (long)correct); \
39                 ret = False; \
40                 goto done; \
41         }} while (0)
42
43 #define CHECK_BUFFER(buf, seed, len) do { \
44         if (!check_buffer(buf, seed, len, __LINE__)) { \
45                 ret = False; \
46                 goto done; \
47         }} while (0)
48
49 #define BASEDIR "\\testread"
50
51
52 /*
53   setup a random buffer based on a seed
54 */
55 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
56 {
57         int i;
58         srandom(seed);
59         for (i=0;i<len;i++) buf[i] = random();
60 }
61
62 /*
63   check a random buffer based on a seed
64 */
65 static BOOL check_buffer(uint8_t *buf, uint_t seed, int len, int line)
66 {
67         int i;
68         srandom(seed);
69         for (i=0;i<len;i++) {
70                 uint8_t v = random();
71                 if (buf[i] != v) {
72                         printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n", 
73                                line, i, buf[i], v);
74                         return False;
75                 }
76         }
77         return True;
78 }
79
80 /*
81   test read ops
82 */
83 static BOOL test_read(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
84 {
85         union smb_read io;
86         NTSTATUS status;
87         BOOL ret = True;
88         int fnum;
89         uint8_t *buf;
90         const int maxsize = 90000;
91         const char *fname = BASEDIR "\\test.txt";
92         const char *test_data = "TEST DATA";
93         uint_t seed = time(NULL);
94
95         buf = talloc_zero_size(mem_ctx, maxsize);
96
97         if (!torture_setup_dir(cli, BASEDIR)) {
98                 return False;
99         }
100
101         printf("Testing RAW_READ_READ\n");
102         io.generic.level = RAW_READ_READ;
103         
104         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
105         if (fnum == -1) {
106                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
107                 ret = False;
108                 goto done;
109         }
110
111         printf("Trying empty file read\n");
112         io.read.in.fnum = fnum;
113         io.read.in.count = 1;
114         io.read.in.offset = 0;
115         io.read.in.remaining = 0;
116         io.read.out.data = buf;
117         status = smb_raw_read(cli->tree, &io);
118
119         CHECK_STATUS(status, NT_STATUS_OK);
120         CHECK_VALUE(io.read.out.nread, 0);
121
122         printf("Trying zero file read\n");
123         io.read.in.count = 0;
124         status = smb_raw_read(cli->tree, &io);
125         CHECK_STATUS(status, NT_STATUS_OK);
126         CHECK_VALUE(io.read.out.nread, 0);
127
128         printf("Trying bad fnum\n");
129         io.read.in.fnum = fnum+1;
130         status = smb_raw_read(cli->tree, &io);
131         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
132         io.read.in.fnum = fnum;
133
134         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
135
136         printf("Trying small read\n");
137         io.read.in.fnum = fnum;
138         io.read.in.offset = 0;
139         io.read.in.remaining = 0;
140         io.read.in.count = strlen(test_data);
141         status = smb_raw_read(cli->tree, &io);
142         CHECK_STATUS(status, NT_STATUS_OK);
143         CHECK_VALUE(io.read.out.nread, strlen(test_data));
144         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
145                 ret = False;
146                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
147                 goto done;
148         }
149
150         printf("Trying short read\n");
151         io.read.in.offset = 1;
152         io.read.in.count = strlen(test_data);
153         status = smb_raw_read(cli->tree, &io);
154         CHECK_STATUS(status, NT_STATUS_OK);
155         CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
156         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
157                 ret = False;
158                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
159                 goto done;
160         }
161
162         printf("Trying max offset\n");
163         io.read.in.offset = ~0;
164         io.read.in.count = strlen(test_data);
165         status = smb_raw_read(cli->tree, &io);
166         CHECK_STATUS(status, NT_STATUS_OK);
167         CHECK_VALUE(io.read.out.nread, 0);
168
169         setup_buffer(buf, seed, maxsize);
170         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
171         memset(buf, 0, maxsize);
172
173         printf("Trying large read\n");
174         io.read.in.offset = 0;
175         io.read.in.count = ~0;
176         status = smb_raw_read(cli->tree, &io);
177         CHECK_STATUS(status, NT_STATUS_OK);
178         CHECK_BUFFER(buf, seed, io.read.out.nread);
179
180
181         printf("Trying locked region\n");
182         cli->session->pid++;
183         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
184                 printf("Failed to lock file at %d\n", __LINE__);
185                 ret = False;
186                 goto done;
187         }
188         cli->session->pid--;
189         memset(buf, 0, maxsize);
190         io.read.in.offset = 0;
191         io.read.in.count = ~0;
192         status = smb_raw_read(cli->tree, &io);
193         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
194         
195
196 done:
197         smbcli_close(cli->tree, fnum);
198         smb_raw_exit(cli->session);
199         smbcli_deltree(cli->tree, BASEDIR);
200         return ret;
201 }
202
203
204 /*
205   test lockread ops
206 */
207 static BOOL test_lockread(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
208 {
209         union smb_read io;
210         NTSTATUS status;
211         BOOL ret = True;
212         int fnum;
213         uint8_t *buf;
214         const int maxsize = 90000;
215         const char *fname = BASEDIR "\\test.txt";
216         const char *test_data = "TEST DATA";
217         uint_t seed = time(NULL);
218
219         buf = talloc_zero_size(mem_ctx, maxsize);
220
221         if (!torture_setup_dir(cli, BASEDIR)) {
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         uint8_t *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_size(mem_ctx, maxsize);
363
364         if (!torture_setup_dir(cli, BASEDIR)) {
365                 return False;
366         }
367
368         printf("Testing RAW_READ_READX\n");
369         
370         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
371         if (fnum == -1) {
372                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
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         smbcli_write(cli->tree, 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         smbcli_write(cli->tree, 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 = 0xFFFF;
458         io.readx.in.maxcnt = 0xFFFF;
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 extra large read\n");
467         io.readx.in.offset = 0;
468         io.readx.in.mincnt = 100;
469         io.readx.in.maxcnt = 80000;
470         status = smb_raw_read(cli->tree, &io);
471         CHECK_STATUS(status, NT_STATUS_OK);
472         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
473         CHECK_VALUE(io.readx.out.compaction_mode, 0);
474         CHECK_VALUE(io.readx.out.nread, 0);
475         CHECK_BUFFER(buf, seed, io.readx.out.nread);
476
477         printf("Trying mincnt > maxcnt\n");
478         memset(buf, 0, maxsize);
479         io.readx.in.offset = 0;
480         io.readx.in.mincnt = 30000;
481         io.readx.in.maxcnt = 20000;
482         status = smb_raw_read(cli->tree, &io);
483         CHECK_STATUS(status, NT_STATUS_OK);
484         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
485         CHECK_VALUE(io.readx.out.compaction_mode, 0);
486         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
487         CHECK_BUFFER(buf, seed, io.readx.out.nread);
488
489         printf("Trying mincnt < maxcnt\n");
490         memset(buf, 0, maxsize);
491         io.readx.in.offset = 0;
492         io.readx.in.mincnt = 20000;
493         io.readx.in.maxcnt = 30000;
494         status = smb_raw_read(cli->tree, &io);
495         CHECK_STATUS(status, NT_STATUS_OK);
496         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
497         CHECK_VALUE(io.readx.out.compaction_mode, 0);
498         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
499         CHECK_BUFFER(buf, seed, io.readx.out.nread);
500
501         printf("Trying locked region\n");
502         cli->session->pid++;
503         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
504                 printf("Failed to lock file at %d\n", __LINE__);
505                 ret = False;
506                 goto done;
507         }
508         cli->session->pid--;
509         memset(buf, 0, maxsize);
510         io.readx.in.offset = 0;
511         io.readx.in.mincnt = 100;
512         io.readx.in.maxcnt = 200;
513         status = smb_raw_read(cli->tree, &io);
514         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
515
516         printf("Trying large offset read\n");
517         io.readx.in.offset = ((uint64_t)0x2) << 32;
518         io.readx.in.mincnt = 10;
519         io.readx.in.maxcnt = 10;
520         status = smb_raw_read(cli->tree, &io);
521         CHECK_STATUS(status, NT_STATUS_OK);
522         CHECK_VALUE(io.readx.out.nread, 0);
523
524         if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
525                 printf("Failed to lock file at %d\n", __LINE__);
526                 ret = False;
527                 goto done;
528         }
529
530         status = smb_raw_read(cli->tree, &io);
531         CHECK_STATUS(status, NT_STATUS_OK);
532         CHECK_VALUE(io.readx.out.nread, 0);
533
534 done:
535         smbcli_close(cli->tree, fnum);
536         smbcli_deltree(cli->tree, BASEDIR);
537         return ret;
538 }
539
540
541 /*
542   test readbraw ops
543 */
544 static BOOL test_readbraw(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
545 {
546         union smb_read io;
547         NTSTATUS status;
548         BOOL ret = True;
549         int fnum;
550         uint8_t *buf;
551         const int maxsize = 90000;
552         const char *fname = BASEDIR "\\test.txt";
553         const char *test_data = "TEST DATA";
554         uint_t seed = time(NULL);
555
556         buf = talloc_zero_size(mem_ctx, maxsize);
557
558         if (!torture_setup_dir(cli, BASEDIR)) {
559                 return False;
560         }
561
562         printf("Testing RAW_READ_READBRAW\n");
563         
564         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
565         if (fnum == -1) {
566                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
567                 ret = False;
568                 goto done;
569         }
570
571         printf("Trying empty file read\n");
572         io.generic.level = RAW_READ_READBRAW;
573         io.readbraw.in.fnum = fnum;
574         io.readbraw.in.mincnt = 1;
575         io.readbraw.in.maxcnt = 1;
576         io.readbraw.in.offset = 0;
577         io.readbraw.in.timeout = 0;
578         io.readbraw.out.data = buf;
579         status = smb_raw_read(cli->tree, &io);
580
581         CHECK_STATUS(status, NT_STATUS_OK);
582         CHECK_VALUE(io.readbraw.out.nread, 0);
583
584         printf("Trying zero file read\n");
585         io.readbraw.in.mincnt = 0;
586         io.readbraw.in.maxcnt = 0;
587         status = smb_raw_read(cli->tree, &io);
588         CHECK_STATUS(status, NT_STATUS_OK);
589         CHECK_VALUE(io.readbraw.out.nread, 0);
590
591         printf("Trying bad fnum\n");
592         io.readbraw.in.fnum = fnum+1;
593         status = smb_raw_read(cli->tree, &io);
594         CHECK_STATUS(status, NT_STATUS_OK);
595         CHECK_VALUE(io.readbraw.out.nread, 0);
596         io.readbraw.in.fnum = fnum;
597
598         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
599
600         printf("Trying small read\n");
601         io.readbraw.in.fnum = fnum;
602         io.readbraw.in.offset = 0;
603         io.readbraw.in.mincnt = strlen(test_data);
604         io.readbraw.in.maxcnt = strlen(test_data);
605         status = smb_raw_read(cli->tree, &io);
606         CHECK_STATUS(status, NT_STATUS_OK);
607         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
608         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
609                 ret = False;
610                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
611                 goto done;
612         }
613
614         printf("Trying short read\n");
615         io.readbraw.in.offset = 1;
616         io.readbraw.in.mincnt = strlen(test_data);
617         io.readbraw.in.maxcnt = strlen(test_data);
618         status = smb_raw_read(cli->tree, &io);
619         CHECK_STATUS(status, NT_STATUS_OK);
620         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
621         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
622                 ret = False;
623                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
624                 goto done;
625         }
626
627         printf("Trying max offset\n");
628         io.readbraw.in.offset = ~0;
629         io.readbraw.in.mincnt = strlen(test_data);
630         io.readbraw.in.maxcnt = strlen(test_data);
631         status = smb_raw_read(cli->tree, &io);
632         CHECK_STATUS(status, NT_STATUS_OK);
633         CHECK_VALUE(io.readbraw.out.nread, 0);
634
635         setup_buffer(buf, seed, maxsize);
636         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
637         memset(buf, 0, maxsize);
638
639         printf("Trying large read\n");
640         io.readbraw.in.offset = 0;
641         io.readbraw.in.mincnt = ~0;
642         io.readbraw.in.maxcnt = ~0;
643         status = smb_raw_read(cli->tree, &io);
644         CHECK_STATUS(status, NT_STATUS_OK);
645         CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
646         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
647
648         printf("Trying mincnt > maxcnt\n");
649         memset(buf, 0, maxsize);
650         io.readbraw.in.offset = 0;
651         io.readbraw.in.mincnt = 30000;
652         io.readbraw.in.maxcnt = 20000;
653         status = smb_raw_read(cli->tree, &io);
654         CHECK_STATUS(status, NT_STATUS_OK);
655         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
656         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
657
658         printf("Trying mincnt < maxcnt\n");
659         memset(buf, 0, maxsize);
660         io.readbraw.in.offset = 0;
661         io.readbraw.in.mincnt = 20000;
662         io.readbraw.in.maxcnt = 30000;
663         status = smb_raw_read(cli->tree, &io);
664         CHECK_STATUS(status, NT_STATUS_OK);
665         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
666         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
667
668         printf("Trying locked region\n");
669         cli->session->pid++;
670         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
671                 printf("Failed to lock file at %d\n", __LINE__);
672                 ret = False;
673                 goto done;
674         }
675         cli->session->pid--;
676         memset(buf, 0, maxsize);
677         io.readbraw.in.offset = 0;
678         io.readbraw.in.mincnt = 100;
679         io.readbraw.in.maxcnt = 200;
680         status = smb_raw_read(cli->tree, &io);
681         CHECK_STATUS(status, NT_STATUS_OK);
682         CHECK_VALUE(io.readbraw.out.nread, 0);
683
684         printf("Trying locked region with timeout\n");
685         memset(buf, 0, maxsize);
686         io.readbraw.in.offset = 0;
687         io.readbraw.in.mincnt = 100;
688         io.readbraw.in.maxcnt = 200;
689         io.readbraw.in.timeout = 10000;
690         status = smb_raw_read(cli->tree, &io);
691         CHECK_STATUS(status, NT_STATUS_OK);
692         CHECK_VALUE(io.readbraw.out.nread, 0);
693
694         printf("Trying large offset read\n");
695         io.readbraw.in.offset = ((uint64_t)0x2) << 32;
696         io.readbraw.in.mincnt = 10;
697         io.readbraw.in.maxcnt = 10;
698         io.readbraw.in.timeout = 0;
699         status = smb_raw_read(cli->tree, &io);
700         CHECK_STATUS(status, NT_STATUS_OK);
701         CHECK_VALUE(io.readbraw.out.nread, 0);
702
703 done:
704         smbcli_close(cli->tree, fnum);
705         smbcli_deltree(cli->tree, BASEDIR);
706         return ret;
707 }
708
709
710 /* 
711    basic testing of read calls
712 */
713 BOOL torture_raw_read(void)
714 {
715         struct smbcli_state *cli;
716         BOOL ret = True;
717         TALLOC_CTX *mem_ctx;
718
719         if (!torture_open_connection(&cli)) {
720                 return False;
721         }
722
723         mem_ctx = talloc_init("torture_raw_read");
724
725         if (!test_read(cli, mem_ctx)) {
726                 ret = False;
727         }
728
729         if (!test_readx(cli, mem_ctx)) {
730                 ret = False;
731         }
732
733         if (!test_lockread(cli, mem_ctx)) {
734                 ret = False;
735         }
736
737         if (!test_readbraw(cli, mem_ctx)) {
738                 ret = False;
739         }
740
741         torture_close_connection(cli);
742         talloc_free(mem_ctx);
743         return ret;
744 }