root/source4/torture/raw/write.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setup_buffer
  2. check_buffer
  3. test_write
  4. test_writex
  5. test_writeunlock
  6. test_writeclose
  7. torture_raw_write

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    test suite for various write operations
   4 
   5    Copyright (C) Andrew Tridgell 2003
   6    
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11    
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16    
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 #include "torture/torture.h"
  23 #include "libcli/raw/libcliraw.h"
  24 #include "libcli/raw/raw_proto.h"
  25 #include "system/time.h"
  26 #include "system/filesys.h"
  27 #include "libcli/libcli.h"
  28 #include "torture/util.h"
  29 
  30 #define CHECK_STATUS(status, correct) do { \
  31         if (!NT_STATUS_EQUAL(status, correct)) { \
  32                 printf("(%s) Incorrect status %s - should be %s\n", \
  33                        __location__, nt_errstr(status), nt_errstr(correct)); \
  34                 ret = false; \
  35                 goto done; \
  36         }} while (0)
  37 
  38 #define CHECK_VALUE(v, correct) do { \
  39         if ((v) != (correct)) { \
  40                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
  41                        __location__, #v, v, correct); \
  42                 ret = false; \
  43                 goto done; \
  44         }} while (0)
  45 
  46 #define CHECK_BUFFER(buf, seed, len) do { \
  47         if (!check_buffer(buf, seed, len, __location__)) { \
  48                 ret = false; \
  49                 goto done; \
  50         }} while (0)
  51 
  52 #define CHECK_ALL_INFO(v, field) do { \
  53         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
  54         finfo.all_info.in.file.path = fname; \
  55         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
  56         CHECK_STATUS(status, NT_STATUS_OK); \
  57         if ((v) != finfo.all_info.out.field) { \
  58                 printf("(%s) wrong value for field %s  %.0f - %.0f\n", \
  59                        __location__, #field, (double)v, (double)finfo.all_info.out.field); \
  60                 dump_all_info(tctx, &finfo); \
  61                 ret = false; \
  62         }} while (0)
  63 
  64 
  65 #define BASEDIR "\\testwrite"
  66 
  67 
  68 /*
  69   setup a random buffer based on a seed
  70 */
  71 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
     /* [<][>][^][v][top][bottom][index][help] */
  72 {
  73         int i;
  74         srandom(seed);
  75         for (i=0;i<len;i++) buf[i] = random();
  76 }
  77 
  78 /*
  79   check a random buffer based on a seed
  80 */
  81 static bool check_buffer(uint8_t *buf, uint_t seed, int len, const char *location)
     /* [<][>][^][v][top][bottom][index][help] */
  82 {
  83         int i;
  84         srandom(seed);
  85         for (i=0;i<len;i++) {
  86                 uint8_t v = random();
  87                 if (buf[i] != v) {
  88                         printf("Buffer incorrect at %s! ofs=%d buf=0x%x correct=0x%x\n", 
  89                                location, i, buf[i], v);
  90                         return false;
  91                 }
  92         }
  93         return true;
  94 }
  95 
  96 /*
  97   test write ops
  98 */
  99 static bool test_write(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 100                                            struct smbcli_state *cli)
 101 {
 102         union smb_write io;
 103         NTSTATUS status;
 104         bool ret = true;
 105         int fnum;
 106         uint8_t *buf;
 107         const int maxsize = 90000;
 108         const char *fname = BASEDIR "\\test.txt";
 109         uint_t seed = time(NULL);
 110         union smb_fileinfo finfo;
 111 
 112         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 113 
 114         if (!torture_setup_dir(cli, BASEDIR)) {
 115                 return false;
 116         }
 117 
 118         printf("Testing RAW_WRITE_WRITE\n");
 119         io.generic.level = RAW_WRITE_WRITE;
 120         
 121         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 122         if (fnum == -1) {
 123                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 124                 ret = false;
 125                 goto done;
 126         }
 127 
 128         printf("Trying zero write\n");
 129         io.write.in.file.fnum = fnum;
 130         io.write.in.count = 0;
 131         io.write.in.offset = 0;
 132         io.write.in.remaining = 0;
 133         io.write.in.data = buf;
 134         status = smb_raw_write(cli->tree, &io);
 135         CHECK_STATUS(status, NT_STATUS_OK);
 136         CHECK_VALUE(io.write.out.nwritten, 0);
 137 
 138         setup_buffer(buf, seed, maxsize);
 139 
 140         printf("Trying small write\n");
 141         io.write.in.count = 9;
 142         io.write.in.offset = 4;
 143         io.write.in.data = buf;
 144         status = smb_raw_write(cli->tree, &io);
 145         CHECK_STATUS(status, NT_STATUS_OK);
 146         CHECK_VALUE(io.write.out.nwritten, io.write.in.count);
 147 
 148         memset(buf, 0, maxsize);
 149         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
 150                 printf("read failed at %s\n", __location__);
 151                 ret = false;
 152                 goto done;
 153         }
 154         CHECK_BUFFER(buf+4, seed, 9);
 155         CHECK_VALUE(IVAL(buf,0), 0);
 156 
 157         setup_buffer(buf, seed, maxsize);
 158 
 159         printf("Trying large write\n");
 160         io.write.in.count = 4000;
 161         io.write.in.offset = 0;
 162         io.write.in.data = buf;
 163         status = smb_raw_write(cli->tree, &io);
 164         CHECK_STATUS(status, NT_STATUS_OK);
 165         CHECK_VALUE(io.write.out.nwritten, 4000);
 166 
 167         memset(buf, 0, maxsize);
 168         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
 169                 printf("read failed at %s\n", __location__);
 170                 ret = false;
 171                 goto done;
 172         }
 173         CHECK_BUFFER(buf, seed, 4000);
 174 
 175         printf("Trying bad fnum\n");
 176         io.write.in.file.fnum = fnum+1;
 177         io.write.in.count = 4000;
 178         io.write.in.offset = 0;
 179         io.write.in.data = buf;
 180         status = smb_raw_write(cli->tree, &io);
 181         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 182 
 183         printf("Setting file as sparse\n");
 184         status = torture_set_sparse(cli->tree, fnum);
 185         CHECK_STATUS(status, NT_STATUS_OK);
 186 
 187         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
 188                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
 189                 goto done;
 190         }
 191         
 192         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
 193                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
 194                 goto done;
 195         }
 196 
 197         printf("Trying 2^32 offset\n");
 198         setup_buffer(buf, seed, maxsize);
 199         io.write.in.file.fnum = fnum;
 200         io.write.in.count = 4000;
 201         io.write.in.offset = 0xFFFFFFFF - 2000;
 202         io.write.in.data = buf;
 203         status = smb_raw_write(cli->tree, &io);
 204         CHECK_STATUS(status, NT_STATUS_OK);
 205         CHECK_VALUE(io.write.out.nwritten, 4000);
 206         CHECK_ALL_INFO(io.write.in.count + (uint64_t)io.write.in.offset, size);
 207         
 208         memset(buf, 0, maxsize);
 209         if (smbcli_read(cli->tree, fnum, buf, io.write.in.offset, 4000) != 4000) {
 210                 printf("read failed at %s\n", __location__);
 211                 ret = false;
 212                 goto done;
 213         }
 214         CHECK_BUFFER(buf, seed, 4000);
 215 
 216 done:
 217         smbcli_close(cli->tree, fnum);
 218         smb_raw_exit(cli->session);
 219         smbcli_deltree(cli->tree, BASEDIR);
 220         return ret;
 221 }
 222 
 223 
 224 /*
 225   test writex ops
 226 */
 227 static bool test_writex(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 228                                                 struct smbcli_state *cli)
 229 {
 230         union smb_write io;
 231         NTSTATUS status;
 232         bool ret = true;
 233         int fnum, i;
 234         uint8_t *buf;
 235         const int maxsize = 90000;
 236         const char *fname = BASEDIR "\\test.txt";
 237         uint_t seed = time(NULL);
 238         union smb_fileinfo finfo;
 239         int max_bits=63;
 240 
 241         if (!torture_setting_bool(tctx, "dangerous", false)) {
 242                 max_bits=33;
 243                 torture_comment(tctx, "dangerous not set - limiting range of test to 2^%d\n", max_bits);
 244         }
 245 
 246         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 247 
 248         if (!torture_setup_dir(cli, BASEDIR)) {
 249                 return false;
 250         }
 251 
 252         printf("Testing RAW_WRITE_WRITEX\n");
 253         io.generic.level = RAW_WRITE_WRITEX;
 254         
 255         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 256         if (fnum == -1) {
 257                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 258                 ret = false;
 259                 goto done;
 260         }
 261 
 262         printf("Trying zero write\n");
 263         io.writex.in.file.fnum = fnum;
 264         io.writex.in.offset = 0;
 265         io.writex.in.wmode = 0;
 266         io.writex.in.remaining = 0;
 267         io.writex.in.count = 0;
 268         io.writex.in.data = buf;
 269         status = smb_raw_write(cli->tree, &io);
 270         CHECK_STATUS(status, NT_STATUS_OK);
 271         CHECK_VALUE(io.writex.out.nwritten, 0);
 272 
 273         setup_buffer(buf, seed, maxsize);
 274 
 275         printf("Trying small write\n");
 276         io.writex.in.count = 9;
 277         io.writex.in.offset = 4;
 278         io.writex.in.data = buf;
 279         status = smb_raw_write(cli->tree, &io);
 280         CHECK_STATUS(status, NT_STATUS_OK);
 281         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
 282 
 283         memset(buf, 0, maxsize);
 284         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
 285                 printf("read failed at %s\n", __location__);
 286                 ret = false;
 287                 goto done;
 288         }
 289         CHECK_BUFFER(buf+4, seed, 9);
 290         CHECK_VALUE(IVAL(buf,0), 0);
 291 
 292         setup_buffer(buf, seed, maxsize);
 293 
 294         printf("Trying large write\n");
 295         io.writex.in.count = 4000;
 296         io.writex.in.offset = 0;
 297         io.writex.in.data = buf;
 298         status = smb_raw_write(cli->tree, &io);
 299         CHECK_STATUS(status, NT_STATUS_OK);
 300         CHECK_VALUE(io.writex.out.nwritten, 4000);
 301 
 302         memset(buf, 0, maxsize);
 303         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
 304                 printf("read failed at %s\n", __location__);
 305                 ret = false;
 306                 goto done;
 307         }
 308         CHECK_BUFFER(buf, seed, 4000);
 309 
 310         printf("Trying bad fnum\n");
 311         io.writex.in.file.fnum = fnum+1;
 312         io.writex.in.count = 4000;
 313         io.writex.in.offset = 0;
 314         io.writex.in.data = buf;
 315         status = smb_raw_write(cli->tree, &io);
 316         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 317 
 318         printf("Testing wmode\n");
 319         io.writex.in.file.fnum = fnum;
 320         io.writex.in.count = 1;
 321         io.writex.in.offset = 0;
 322         io.writex.in.wmode = 1;
 323         io.writex.in.data = buf;
 324         status = smb_raw_write(cli->tree, &io);
 325         CHECK_STATUS(status, NT_STATUS_OK);
 326         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
 327 
 328         io.writex.in.wmode = 2;
 329         status = smb_raw_write(cli->tree, &io);
 330         CHECK_STATUS(status, NT_STATUS_OK);
 331         CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
 332 
 333 
 334         printf("Trying locked region\n");
 335         cli->session->pid++;
 336         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 3, 1, 0, WRITE_LOCK))) {
 337                 printf("Failed to lock file at %s\n", __location__);
 338                 ret = false;
 339                 goto done;
 340         }
 341         cli->session->pid--;
 342         io.writex.in.wmode = 0;
 343         io.writex.in.count = 4;
 344         io.writex.in.offset = 0;
 345         status = smb_raw_write(cli->tree, &io);
 346         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
 347 
 348         printf("Setting file as sparse\n");
 349         status = torture_set_sparse(cli->tree, fnum);
 350         CHECK_STATUS(status, NT_STATUS_OK);
 351         
 352         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
 353                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
 354                 goto done;
 355         }
 356 
 357         printf("Trying 2^32 offset\n");
 358         setup_buffer(buf, seed, maxsize);
 359         io.writex.in.file.fnum = fnum;
 360         io.writex.in.count = 4000;
 361         io.writex.in.offset = 0xFFFFFFFF - 2000;
 362         io.writex.in.data = buf;
 363         status = smb_raw_write(cli->tree, &io);
 364         CHECK_STATUS(status, NT_STATUS_OK);
 365         CHECK_VALUE(io.writex.out.nwritten, 4000);
 366         CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);
 367 
 368         memset(buf, 0, maxsize);
 369         if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
 370                 printf("read failed at %s\n", __location__);
 371                 ret = false;
 372                 goto done;
 373         }
 374         CHECK_BUFFER(buf, seed, 4000);
 375 
 376         for (i=33;i<max_bits;i++) {
 377                 printf("Trying 2^%d offset\n", i);
 378                 setup_buffer(buf, seed+1, maxsize);
 379                 io.writex.in.file.fnum = fnum;
 380                 io.writex.in.count = 4000;
 381                 io.writex.in.offset = ((uint64_t)1) << i;
 382                 io.writex.in.data = buf;
 383                 status = smb_raw_write(cli->tree, &io);
 384                 if (i>33 &&
 385                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
 386                         break;
 387                 }
 388                 CHECK_STATUS(status, NT_STATUS_OK);
 389                 CHECK_VALUE(io.writex.out.nwritten, 4000);
 390                 CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);
 391 
 392                 memset(buf, 0, maxsize);
 393                 if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
 394                         printf("read failed at %s\n", __location__);
 395                         ret = false;
 396                         goto done;
 397                 }
 398                 CHECK_BUFFER(buf, seed+1, 4000);
 399         }
 400         printf("limit is 2^%d\n", i);
 401 
 402         setup_buffer(buf, seed, maxsize);
 403 
 404 done:
 405         smbcli_close(cli->tree, fnum);
 406         smb_raw_exit(cli->session);
 407         smbcli_deltree(cli->tree, BASEDIR);
 408         return ret;
 409 }
 410 
 411 
 412 /*
 413   test write unlock ops
 414 */
 415 static bool test_writeunlock(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 416                                                          struct smbcli_state *cli)
 417 {
 418         union smb_write io;
 419         NTSTATUS status;
 420         bool ret = true;
 421         int fnum;
 422         uint8_t *buf;
 423         const int maxsize = 90000;
 424         const char *fname = BASEDIR "\\test.txt";
 425         uint_t seed = time(NULL);
 426         union smb_fileinfo finfo;
 427 
 428         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 429 
 430         if (!torture_setup_dir(cli, BASEDIR)) {
 431                 return false;
 432         }
 433 
 434         printf("Testing RAW_WRITE_WRITEUNLOCK\n");
 435         io.generic.level = RAW_WRITE_WRITEUNLOCK;
 436         
 437         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 438         if (fnum == -1) {
 439                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 440                 ret = false;
 441                 goto done;
 442         }
 443 
 444         printf("Trying zero write\n");
 445         io.writeunlock.in.file.fnum = fnum;
 446         io.writeunlock.in.count = 0;
 447         io.writeunlock.in.offset = 0;
 448         io.writeunlock.in.remaining = 0;
 449         io.writeunlock.in.data = buf;
 450         status = smb_raw_write(cli->tree, &io);
 451         CHECK_STATUS(status, NT_STATUS_OK);
 452         CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
 453 
 454         setup_buffer(buf, seed, maxsize);
 455 
 456         printf("Trying small write\n");
 457         io.writeunlock.in.count = 9;
 458         io.writeunlock.in.offset = 4;
 459         io.writeunlock.in.data = buf;
 460         status = smb_raw_write(cli->tree, &io);
 461         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
 462         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
 463                 printf("read failed at %s\n", __location__);
 464                 ret = false;
 465                 goto done;
 466         }
 467         CHECK_BUFFER(buf+4, seed, 9);
 468         CHECK_VALUE(IVAL(buf,0), 0);
 469 
 470         setup_buffer(buf, seed, maxsize);
 471         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
 472                  0, WRITE_LOCK);
 473         status = smb_raw_write(cli->tree, &io);
 474         CHECK_STATUS(status, NT_STATUS_OK);
 475         CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
 476 
 477         memset(buf, 0, maxsize);
 478         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
 479                 printf("read failed at %s\n", __location__);
 480                 ret = false;
 481                 goto done;
 482         }
 483         CHECK_BUFFER(buf+4, seed, 9);
 484         CHECK_VALUE(IVAL(buf,0), 0);
 485 
 486         setup_buffer(buf, seed, maxsize);
 487 
 488         printf("Trying large write\n");
 489         io.writeunlock.in.count = 4000;
 490         io.writeunlock.in.offset = 0;
 491         io.writeunlock.in.data = buf;
 492         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
 493                  0, WRITE_LOCK);
 494         status = smb_raw_write(cli->tree, &io);
 495         CHECK_STATUS(status, NT_STATUS_OK);
 496         CHECK_VALUE(io.writeunlock.out.nwritten, 4000);
 497 
 498         status = smb_raw_write(cli->tree, &io);
 499         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
 500 
 501         memset(buf, 0, maxsize);
 502         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
 503                 printf("read failed at %s\n", __location__);
 504                 ret = false;
 505                 goto done;
 506         }
 507         CHECK_BUFFER(buf, seed, 4000);
 508 
 509         printf("Trying bad fnum\n");
 510         io.writeunlock.in.file.fnum = fnum+1;
 511         io.writeunlock.in.count = 4000;
 512         io.writeunlock.in.offset = 0;
 513         io.writeunlock.in.data = buf;
 514         status = smb_raw_write(cli->tree, &io);
 515         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 516 
 517         printf("Setting file as sparse\n");
 518         status = torture_set_sparse(cli->tree, fnum);
 519         CHECK_STATUS(status, NT_STATUS_OK);
 520         
 521         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
 522                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
 523                 goto done;
 524         }
 525 
 526         printf("Trying 2^32 offset\n");
 527         setup_buffer(buf, seed, maxsize);
 528         io.writeunlock.in.file.fnum = fnum;
 529         io.writeunlock.in.count = 4000;
 530         io.writeunlock.in.offset = 0xFFFFFFFF - 2000;
 531         io.writeunlock.in.data = buf;
 532         smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count, 
 533                  0, WRITE_LOCK);
 534         status = smb_raw_write(cli->tree, &io);
 535         CHECK_STATUS(status, NT_STATUS_OK);
 536         CHECK_VALUE(io.writeunlock.out.nwritten, 4000);
 537         CHECK_ALL_INFO(io.writeunlock.in.count + (uint64_t)io.writeunlock.in.offset, size);
 538 
 539         memset(buf, 0, maxsize);
 540         if (smbcli_read(cli->tree, fnum, buf, io.writeunlock.in.offset, 4000) != 4000) {
 541                 printf("read failed at %s\n", __location__);
 542                 ret = false;
 543                 goto done;
 544         }
 545         CHECK_BUFFER(buf, seed, 4000);
 546 
 547 done:
 548         smbcli_close(cli->tree, fnum);
 549         smb_raw_exit(cli->session);
 550         smbcli_deltree(cli->tree, BASEDIR);
 551         return ret;
 552 }
 553 
 554 
 555 /*
 556   test write close ops
 557 */
 558 static bool test_writeclose(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 559                                                         struct smbcli_state *cli)
 560 {
 561         union smb_write io;
 562         NTSTATUS status;
 563         bool ret = true;
 564         int fnum;
 565         uint8_t *buf;
 566         const int maxsize = 90000;
 567         const char *fname = BASEDIR "\\test.txt";
 568         uint_t seed = time(NULL);
 569         union smb_fileinfo finfo;
 570 
 571         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 572 
 573         if (!torture_setup_dir(cli, BASEDIR)) {
 574                 return false;
 575         }
 576 
 577         printf("Testing RAW_WRITE_WRITECLOSE\n");
 578         io.generic.level = RAW_WRITE_WRITECLOSE;
 579         
 580         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 581         if (fnum == -1) {
 582                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 583                 ret = false;
 584                 goto done;
 585         }
 586 
 587         printf("Trying zero write\n");
 588         io.writeclose.in.file.fnum = fnum;
 589         io.writeclose.in.count = 0;
 590         io.writeclose.in.offset = 0;
 591         io.writeclose.in.mtime = 0;
 592         io.writeclose.in.data = buf;
 593         status = smb_raw_write(cli->tree, &io);
 594         CHECK_STATUS(status, NT_STATUS_OK);
 595         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
 596 
 597         status = smb_raw_write(cli->tree, &io);
 598         CHECK_STATUS(status, NT_STATUS_OK);
 599         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
 600 
 601         setup_buffer(buf, seed, maxsize);
 602 
 603         printf("Trying small write\n");
 604         io.writeclose.in.count = 9;
 605         io.writeclose.in.offset = 4;
 606         io.writeclose.in.data = buf;
 607         status = smb_raw_write(cli->tree, &io);
 608         CHECK_STATUS(status, NT_STATUS_OK);
 609 
 610         status = smb_raw_write(cli->tree, &io);
 611         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 612 
 613         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
 614         io.writeclose.in.file.fnum = fnum;
 615 
 616         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
 617                 printf("read failed at %s\n", __location__);
 618                 ret = false;
 619                 goto done;
 620         }
 621         CHECK_BUFFER(buf+4, seed, 9);
 622         CHECK_VALUE(IVAL(buf,0), 0);
 623 
 624         setup_buffer(buf, seed, maxsize);
 625         status = smb_raw_write(cli->tree, &io);
 626         CHECK_STATUS(status, NT_STATUS_OK);
 627         CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
 628 
 629         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
 630         io.writeclose.in.file.fnum = fnum;
 631 
 632         memset(buf, 0, maxsize);
 633         if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
 634                 printf("read failed at %s\n", __location__);
 635                 ret = false;
 636                 goto done;
 637         }
 638         CHECK_BUFFER(buf+4, seed, 9);
 639         CHECK_VALUE(IVAL(buf,0), 0);
 640 
 641         setup_buffer(buf, seed, maxsize);
 642 
 643         printf("Trying large write\n");
 644         io.writeclose.in.count = 4000;
 645         io.writeclose.in.offset = 0;
 646         io.writeclose.in.data = buf;
 647         status = smb_raw_write(cli->tree, &io);
 648         CHECK_STATUS(status, NT_STATUS_OK);
 649         CHECK_VALUE(io.writeclose.out.nwritten, 4000);
 650 
 651         status = smb_raw_write(cli->tree, &io);
 652         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 653 
 654         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
 655         io.writeclose.in.file.fnum = fnum;
 656 
 657         memset(buf, 0, maxsize);
 658         if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
 659                 printf("read failed at %s\n", __location__);
 660                 ret = false;
 661                 goto done;
 662         }
 663         CHECK_BUFFER(buf, seed, 4000);
 664 
 665         printf("Trying bad fnum\n");
 666         io.writeclose.in.file.fnum = fnum+1;
 667         io.writeclose.in.count = 4000;
 668         io.writeclose.in.offset = 0;
 669         io.writeclose.in.data = buf;
 670         status = smb_raw_write(cli->tree, &io);
 671         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 672 
 673         printf("Setting file as sparse\n");
 674         status = torture_set_sparse(cli->tree, fnum);
 675         CHECK_STATUS(status, NT_STATUS_OK);
 676         
 677         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
 678                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
 679                 goto done;
 680         }
 681 
 682         printf("Trying 2^32 offset\n");
 683         setup_buffer(buf, seed, maxsize);
 684         io.writeclose.in.file.fnum = fnum;
 685         io.writeclose.in.count = 4000;
 686         io.writeclose.in.offset = 0xFFFFFFFF - 2000;
 687         io.writeclose.in.data = buf;
 688         status = smb_raw_write(cli->tree, &io);
 689         CHECK_STATUS(status, NT_STATUS_OK);
 690         CHECK_VALUE(io.writeclose.out.nwritten, 4000);
 691         CHECK_ALL_INFO(io.writeclose.in.count + (uint64_t)io.writeclose.in.offset, size);
 692 
 693         fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
 694         io.writeclose.in.file.fnum = fnum;
 695 
 696         memset(buf, 0, maxsize);
 697         if (smbcli_read(cli->tree, fnum, buf, io.writeclose.in.offset, 4000) != 4000) {
 698                 printf("read failed at %s\n", __location__);
 699                 ret = false;
 700                 goto done;
 701         }
 702         CHECK_BUFFER(buf, seed, 4000);
 703 
 704 done:
 705         smbcli_close(cli->tree, fnum);
 706         smb_raw_exit(cli->session);
 707         smbcli_deltree(cli->tree, BASEDIR);
 708         return ret;
 709 }
 710 
 711 /* 
 712    basic testing of write calls
 713 */
 714 struct torture_suite *torture_raw_write(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 715 {
 716         struct torture_suite *suite = torture_suite_create(mem_ctx, "WRITE");
 717 
 718         torture_suite_add_1smb_test(suite, "write", test_write);
 719         torture_suite_add_1smb_test(suite, "write unlock", test_writeunlock);
 720         torture_suite_add_1smb_test(suite, "write close", test_writeclose);
 721         torture_suite_add_1smb_test(suite, "writex", test_writex);
 722 
 723         return suite;
 724 }

/* [<][>][^][v][top][bottom][index][help] */