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