2003-08-13 01:53:07 +00:00
/*
Unix SMB / CIFS implementation .
test suite for various write operations
2004-11-12 09:37:59 +00:00
2003-08-13 01:53:07 +00:00
Copyright ( C ) Andrew Tridgell 2003
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 01:53:07 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 01:53:07 +00:00
*/
# include "includes.h"
2006-01-03 13:41:17 +00:00
# include "torture/torture.h"
2004-11-01 01:03:22 +00:00
# include "libcli/raw/libcliraw.h"
2004-11-02 00:24:21 +00:00
# include "system/time.h"
2005-02-10 05:09:35 +00:00
# include "system/filesys.h"
2006-01-03 15:40:05 +00:00
# include "libcli/libcli.h"
2006-03-17 17:59:58 +00:00
# include "torture/util.h"
2003-08-13 01:53:07 +00:00
# define CHECK_STATUS(status, correct) do { \
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
2004-10-26 08:32:16 +00:00
printf ( " (%s) Incorrect status %s - should be %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
goto done ; \
} } while ( 0 )
# define CHECK_VALUE(v, correct) do { \
if ( ( v ) ! = ( correct ) ) { \
2004-10-26 08:32:16 +00:00
printf ( " (%s) Incorrect value %s=%d - should be %d \n " , \
__location__ , # v , v , correct ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
goto done ; \
} } while ( 0 )
# define CHECK_BUFFER(buf, seed, len) do { \
2004-10-26 08:32:16 +00:00
if ( ! check_buffer ( buf , seed , len , __location__ ) ) { \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
goto done ; \
} } while ( 0 )
# define CHECK_ALL_INFO(v, field) do { \
finfo . all_info . level = RAW_FILEINFO_ALL_INFO ; \
2006-03-12 22:48:25 +00:00
finfo . all_info . in . file . path = fname ; \
2007-08-28 12:54:27 +00:00
status = smb_raw_pathinfo ( cli - > tree , tctx , & finfo ) ; \
2003-08-13 01:53:07 +00:00
CHECK_STATUS ( status , NT_STATUS_OK ) ; \
if ( ( v ) ! = finfo . all_info . out . field ) { \
2004-10-26 08:32:16 +00:00
printf ( " (%s) wrong value for field %s %.0f - %.0f \n " , \
__location__ , # field , ( double ) v , ( double ) finfo . all_info . out . field ) ; \
2007-08-28 12:54:27 +00:00
dump_all_info ( tctx , & finfo ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} } while ( 0 )
# define BASEDIR "\\testwrite"
/*
setup a random buffer based on a seed
*/
2004-12-04 13:56:25 +00:00
static void setup_buffer ( uint8_t * buf , uint_t seed , int len )
2003-08-13 01:53:07 +00:00
{
int i ;
srandom ( seed ) ;
for ( i = 0 ; i < len ; i + + ) buf [ i ] = random ( ) ;
}
/*
check a random buffer based on a seed
*/
2007-10-06 22:28:14 +00:00
static bool check_buffer ( uint8_t * buf , uint_t seed , int len , const char * location )
2003-08-13 01:53:07 +00:00
{
int i ;
srandom ( seed ) ;
for ( i = 0 ; i < len ; i + + ) {
2004-12-04 13:56:25 +00:00
uint8_t v = random ( ) ;
2003-08-13 01:53:07 +00:00
if ( buf [ i ] ! = v ) {
2004-10-26 08:32:16 +00:00
printf ( " Buffer incorrect at %s! ofs=%d buf=0x%x correct=0x%x \n " ,
location , i , buf [ i ] , v ) ;
2007-10-06 22:28:14 +00:00
return false ;
2003-08-13 01:53:07 +00:00
}
}
2007-10-06 22:28:14 +00:00
return true ;
2003-08-13 01:53:07 +00:00
}
/*
test write ops
*/
2007-08-28 12:54:27 +00:00
static bool test_write ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
union smb_write io ;
NTSTATUS status ;
2007-10-06 22:28:14 +00:00
bool ret = true ;
2003-08-13 01:53:07 +00:00
int fnum ;
2004-12-04 13:56:25 +00:00
uint8_t * buf ;
2003-08-13 01:53:07 +00:00
const int maxsize = 90000 ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-06-01 10:12:52 +00:00
uint_t seed = time ( NULL ) ;
2003-08-13 01:53:07 +00:00
union smb_fileinfo finfo ;
2007-09-07 15:08:14 +00:00
buf = talloc_zero_array ( tctx , uint8_t , maxsize ) ;
2003-08-13 01:53:07 +00:00
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2003-08-13 01:53:07 +00:00
}
printf ( " Testing RAW_WRITE_WRITE \n " ) ;
io . generic . level = RAW_WRITE_WRITE ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
printf ( " Trying zero write \n " ) ;
2006-03-12 22:48:25 +00:00
io . write . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . write . in . count = 0 ;
io . write . in . offset = 0 ;
io . write . in . remaining = 0 ;
io . write . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . write . out . nwritten , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying small write \n " ) ;
io . write . in . count = 9 ;
io . write . in . offset = 4 ;
io . write . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . write . out . nwritten , io . write . in . count ) ;
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 13 ) ! = 13 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf + 4 , seed , 9 ) ;
CHECK_VALUE ( IVAL ( buf , 0 ) , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying large write \n " ) ;
io . write . in . count = 4000 ;
io . write . in . offset = 0 ;
io . write . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . write . out . nwritten , 4000 ) ;
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
printf ( " Trying bad fnum \n " ) ;
2006-03-12 22:48:25 +00:00
io . write . in . file . fnum = fnum + 1 ;
2003-08-13 01:53:07 +00:00
io . write . in . count = 4000 ;
io . write . in . offset = 0 ;
io . write . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_INVALID_HANDLE ) ;
printf ( " Setting file as sparse \n " ) ;
status = torture_set_sparse ( cli - > tree , fnum ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-10-28 06:06:15 +00:00
if ( ! ( cli - > transport - > negotiate . capabilities & CAP_LARGE_FILES ) ) {
printf ( " skipping large file tests - CAP_LARGE_FILES not set \n " ) ;
goto done ;
}
2003-08-13 01:53:07 +00:00
2006-10-29 05:01:36 +00:00
if ( ! ( cli - > transport - > negotiate . capabilities & CAP_LARGE_FILES ) ) {
printf ( " skipping large file tests - CAP_LARGE_FILES not set \n " ) ;
goto done ;
}
2003-08-13 01:53:07 +00:00
printf ( " Trying 2^32 offset \n " ) ;
setup_buffer ( buf , seed , maxsize ) ;
2006-03-12 22:48:25 +00:00
io . write . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . write . in . count = 4000 ;
io . write . in . offset = 0xFFFFFFFF - 2000 ;
io . write . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . write . out . nwritten , 4000 ) ;
2004-05-25 13:57:39 +00:00
CHECK_ALL_INFO ( io . write . in . count + ( uint64_t ) io . write . in . offset , size ) ;
2006-10-29 05:01:36 +00:00
2003-08-13 01:53:07 +00:00
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , io . write . in . offset , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
done :
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
/*
test writex ops
*/
2007-08-28 12:54:27 +00:00
static bool test_writex ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
union smb_write io ;
NTSTATUS status ;
2007-10-06 22:28:14 +00:00
bool ret = true ;
2003-08-13 02:04:44 +00:00
int fnum , i ;
2004-12-04 13:56:25 +00:00
uint8_t * buf ;
2003-08-13 01:53:07 +00:00
const int maxsize = 90000 ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-06-01 10:12:52 +00:00
uint_t seed = time ( NULL ) ;
2003-08-13 01:53:07 +00:00
union smb_fileinfo finfo ;
2006-09-10 08:08:20 +00:00
int max_bits = 63 ;
2007-08-28 14:42:37 +00:00
if ( ! torture_setting_bool ( tctx , " dangerous " , false ) ) {
2006-09-10 08:08:20 +00:00
max_bits = 33 ;
2007-08-28 14:42:37 +00:00
torture_comment ( tctx , " dangerous not set - limiting range of test to 2^%d \n " , max_bits ) ;
2006-09-10 08:08:20 +00:00
}
2003-08-13 01:53:07 +00:00
2007-09-07 15:08:14 +00:00
buf = talloc_zero_array ( tctx , uint8_t , maxsize ) ;
2003-08-13 01:53:07 +00:00
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2003-08-13 01:53:07 +00:00
}
printf ( " Testing RAW_WRITE_WRITEX \n " ) ;
io . generic . level = RAW_WRITE_WRITEX ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
printf ( " Trying zero write \n " ) ;
2006-03-12 22:48:25 +00:00
io . writex . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . writex . in . offset = 0 ;
io . writex . in . wmode = 0 ;
io . writex . in . remaining = 0 ;
io . writex . in . count = 0 ;
io . writex . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writex . out . nwritten , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying small write \n " ) ;
io . writex . in . count = 9 ;
io . writex . in . offset = 4 ;
io . writex . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writex . out . nwritten , io . writex . in . count ) ;
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 13 ) ! = 13 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf + 4 , seed , 9 ) ;
CHECK_VALUE ( IVAL ( buf , 0 ) , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying large write \n " ) ;
io . writex . in . count = 4000 ;
io . writex . in . offset = 0 ;
io . writex . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writex . out . nwritten , 4000 ) ;
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
printf ( " Trying bad fnum \n " ) ;
2006-03-12 22:48:25 +00:00
io . writex . in . file . fnum = fnum + 1 ;
2003-08-13 01:53:07 +00:00
io . writex . in . count = 4000 ;
io . writex . in . offset = 0 ;
io . writex . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_INVALID_HANDLE ) ;
printf ( " Testing wmode \n " ) ;
2006-03-12 22:48:25 +00:00
io . writex . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . writex . in . count = 1 ;
io . writex . in . offset = 0 ;
io . writex . in . wmode = 1 ;
io . writex . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writex . out . nwritten , io . writex . in . count ) ;
io . writex . in . wmode = 2 ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writex . out . nwritten , io . writex . in . count ) ;
printf ( " Trying locked region \n " ) ;
cli - > session - > pid + + ;
2004-08-04 13:23:35 +00:00
if ( NT_STATUS_IS_ERR ( smbcli_lock ( cli - > tree , fnum , 3 , 1 , 0 , WRITE_LOCK ) ) ) {
2004-10-26 08:32:16 +00:00
printf ( " Failed to lock file at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
cli - > session - > pid - - ;
io . writex . in . wmode = 0 ;
io . writex . in . count = 4 ;
io . writex . in . offset = 0 ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
printf ( " Setting file as sparse \n " ) ;
status = torture_set_sparse ( cli - > tree , fnum ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-10-29 05:01:36 +00:00
if ( ! ( cli - > transport - > negotiate . capabilities & CAP_LARGE_FILES ) ) {
printf ( " skipping large file tests - CAP_LARGE_FILES not set \n " ) ;
goto done ;
}
2003-08-13 01:53:07 +00:00
printf ( " Trying 2^32 offset \n " ) ;
setup_buffer ( buf , seed , maxsize ) ;
2006-03-12 22:48:25 +00:00
io . writex . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . writex . in . count = 4000 ;
io . writex . in . offset = 0xFFFFFFFF - 2000 ;
io . writex . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writex . out . nwritten , 4000 ) ;
2004-05-25 13:57:39 +00:00
CHECK_ALL_INFO ( io . writex . in . count + ( uint64_t ) io . writex . in . offset , size ) ;
2003-08-13 01:53:07 +00:00
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , io . writex . in . offset , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
2006-09-10 08:08:20 +00:00
for ( i = 33 ; i < max_bits ; i + + ) {
2003-08-13 02:04:44 +00:00
printf ( " Trying 2^%d offset \n " , i ) ;
setup_buffer ( buf , seed + 1 , maxsize ) ;
2006-03-12 22:48:25 +00:00
io . writex . in . file . fnum = fnum ;
2003-08-13 02:04:44 +00:00
io . writex . in . count = 4000 ;
2004-05-25 13:57:39 +00:00
io . writex . in . offset = ( ( uint64_t ) 1 ) < < i ;
2003-08-13 02:04:44 +00:00
io . writex . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
2005-07-15 11:32:08 +00:00
if ( i > 33 & &
2004-10-26 08:32:16 +00:00
NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_PARAMETER ) ) {
break ;
}
2003-08-13 02:04:44 +00:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writex . out . nwritten , 4000 ) ;
2004-05-25 13:57:39 +00:00
CHECK_ALL_INFO ( io . writex . in . count + ( uint64_t ) io . writex . in . offset , size ) ;
2003-08-13 02:04:44 +00:00
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , io . writex . in . offset , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 02:04:44 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed + 1 , 4000 ) ;
2003-08-13 01:53:07 +00:00
}
2004-10-26 08:32:16 +00:00
printf ( " limit is 2^%d \n " , i ) ;
2003-08-13 01:53:07 +00:00
setup_buffer ( buf , seed , maxsize ) ;
done :
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
/*
test write unlock ops
*/
2007-08-28 12:54:27 +00:00
static bool test_writeunlock ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
union smb_write io ;
NTSTATUS status ;
2007-10-06 22:28:14 +00:00
bool ret = true ;
2003-08-13 01:53:07 +00:00
int fnum ;
2004-12-04 13:56:25 +00:00
uint8_t * buf ;
2003-08-13 01:53:07 +00:00
const int maxsize = 90000 ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-06-01 10:12:52 +00:00
uint_t seed = time ( NULL ) ;
2003-08-13 01:53:07 +00:00
union smb_fileinfo finfo ;
2007-09-07 15:08:14 +00:00
buf = talloc_zero_array ( tctx , uint8_t , maxsize ) ;
2003-08-13 01:53:07 +00:00
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2003-08-13 01:53:07 +00:00
}
printf ( " Testing RAW_WRITE_WRITEUNLOCK \n " ) ;
io . generic . level = RAW_WRITE_WRITEUNLOCK ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
printf ( " Trying zero write \n " ) ;
2006-03-12 22:48:25 +00:00
io . writeunlock . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . writeunlock . in . count = 0 ;
io . writeunlock . in . offset = 0 ;
io . writeunlock . in . remaining = 0 ;
io . writeunlock . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeunlock . out . nwritten , io . writeunlock . in . count ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying small write \n " ) ;
io . writeunlock . in . count = 9 ;
io . writeunlock . in . offset = 4 ;
io . writeunlock . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 13 ) ! = 13 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf + 4 , seed , 9 ) ;
CHECK_VALUE ( IVAL ( buf , 0 ) , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
2004-08-04 13:23:35 +00:00
smbcli_lock ( cli - > tree , fnum , io . writeunlock . in . offset , io . writeunlock . in . count ,
2003-08-13 01:53:07 +00:00
0 , WRITE_LOCK ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeunlock . out . nwritten , io . writeunlock . in . count ) ;
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 13 ) ! = 13 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf + 4 , seed , 9 ) ;
CHECK_VALUE ( IVAL ( buf , 0 ) , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying large write \n " ) ;
io . writeunlock . in . count = 4000 ;
io . writeunlock . in . offset = 0 ;
io . writeunlock . in . data = buf ;
2004-08-04 13:23:35 +00:00
smbcli_lock ( cli - > tree , fnum , io . writeunlock . in . offset , io . writeunlock . in . count ,
2003-08-13 01:53:07 +00:00
0 , WRITE_LOCK ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeunlock . out . nwritten , 4000 ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
printf ( " Trying bad fnum \n " ) ;
2006-03-12 22:48:25 +00:00
io . writeunlock . in . file . fnum = fnum + 1 ;
2003-08-13 01:53:07 +00:00
io . writeunlock . in . count = 4000 ;
io . writeunlock . in . offset = 0 ;
io . writeunlock . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_INVALID_HANDLE ) ;
printf ( " Setting file as sparse \n " ) ;
status = torture_set_sparse ( cli - > tree , fnum ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-10-29 05:01:36 +00:00
if ( ! ( cli - > transport - > negotiate . capabilities & CAP_LARGE_FILES ) ) {
printf ( " skipping large file tests - CAP_LARGE_FILES not set \n " ) ;
goto done ;
}
2003-08-13 01:53:07 +00:00
printf ( " Trying 2^32 offset \n " ) ;
setup_buffer ( buf , seed , maxsize ) ;
2006-03-12 22:48:25 +00:00
io . writeunlock . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . writeunlock . in . count = 4000 ;
io . writeunlock . in . offset = 0xFFFFFFFF - 2000 ;
io . writeunlock . in . data = buf ;
2004-08-04 13:23:35 +00:00
smbcli_lock ( cli - > tree , fnum , io . writeunlock . in . offset , io . writeunlock . in . count ,
2003-08-13 01:53:07 +00:00
0 , WRITE_LOCK ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeunlock . out . nwritten , 4000 ) ;
2004-05-25 13:57:39 +00:00
CHECK_ALL_INFO ( io . writeunlock . in . count + ( uint64_t ) io . writeunlock . in . offset , size ) ;
2003-08-13 01:53:07 +00:00
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , io . writeunlock . in . offset , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
done :
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
/*
test write close ops
*/
2007-08-28 12:54:27 +00:00
static bool test_writeclose ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
union smb_write io ;
NTSTATUS status ;
2007-10-06 22:28:14 +00:00
bool ret = true ;
2003-08-13 01:53:07 +00:00
int fnum ;
2004-12-04 13:56:25 +00:00
uint8_t * buf ;
2003-08-13 01:53:07 +00:00
const int maxsize = 90000 ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-06-01 10:12:52 +00:00
uint_t seed = time ( NULL ) ;
2003-08-13 01:53:07 +00:00
union smb_fileinfo finfo ;
2007-09-07 15:08:14 +00:00
buf = talloc_zero_array ( tctx , uint8_t , maxsize ) ;
2003-08-13 01:53:07 +00:00
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2003-08-13 01:53:07 +00:00
}
printf ( " Testing RAW_WRITE_WRITECLOSE \n " ) ;
io . generic . level = RAW_WRITE_WRITECLOSE ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
printf ( " Trying zero write \n " ) ;
2006-03-12 22:48:25 +00:00
io . writeclose . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . writeclose . in . count = 0 ;
io . writeclose . in . offset = 0 ;
io . writeclose . in . mtime = 0 ;
io . writeclose . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeclose . out . nwritten , io . writeclose . in . count ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeclose . out . nwritten , io . writeclose . in . count ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying small write \n " ) ;
io . writeclose . in . count = 9 ;
io . writeclose . in . offset = 4 ;
io . writeclose . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_INVALID_HANDLE ) ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR , DENY_NONE ) ;
2006-03-12 22:48:25 +00:00
io . writeclose . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 13 ) ! = 13 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf + 4 , seed , 9 ) ;
CHECK_VALUE ( IVAL ( buf , 0 ) , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeclose . out . nwritten , io . writeclose . in . count ) ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR , DENY_NONE ) ;
2006-03-12 22:48:25 +00:00
io . writeclose . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 13 ) ! = 13 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf + 4 , seed , 9 ) ;
CHECK_VALUE ( IVAL ( buf , 0 ) , 0 ) ;
setup_buffer ( buf , seed , maxsize ) ;
printf ( " Trying large write \n " ) ;
io . writeclose . in . count = 4000 ;
io . writeclose . in . offset = 0 ;
io . writeclose . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeclose . out . nwritten , 4000 ) ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_INVALID_HANDLE ) ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR , DENY_NONE ) ;
2006-03-12 22:48:25 +00:00
io . writeclose . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , 0 , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
printf ( " Trying bad fnum \n " ) ;
2006-03-12 22:48:25 +00:00
io . writeclose . in . file . fnum = fnum + 1 ;
2003-08-13 01:53:07 +00:00
io . writeclose . in . count = 4000 ;
io . writeclose . in . offset = 0 ;
io . writeclose . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_INVALID_HANDLE ) ;
printf ( " Setting file as sparse \n " ) ;
status = torture_set_sparse ( cli - > tree , fnum ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-10-29 05:01:36 +00:00
if ( ! ( cli - > transport - > negotiate . capabilities & CAP_LARGE_FILES ) ) {
printf ( " skipping large file tests - CAP_LARGE_FILES not set \n " ) ;
goto done ;
}
2003-08-13 01:53:07 +00:00
printf ( " Trying 2^32 offset \n " ) ;
setup_buffer ( buf , seed , maxsize ) ;
2006-03-12 22:48:25 +00:00
io . writeclose . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . writeclose . in . count = 4000 ;
io . writeclose . in . offset = 0xFFFFFFFF - 2000 ;
io . writeclose . in . data = buf ;
status = smb_raw_write ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( io . writeclose . out . nwritten , 4000 ) ;
2004-05-25 13:57:39 +00:00
CHECK_ALL_INFO ( io . writeclose . in . count + ( uint64_t ) io . writeclose . in . offset , size ) ;
2003-08-13 01:53:07 +00:00
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR , DENY_NONE ) ;
2006-03-12 22:48:25 +00:00
io . writeclose . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
memset ( buf , 0 , maxsize ) ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , buf , io . writeclose . in . offset , 4000 ) ! = 4000 ) {
2004-10-26 08:32:16 +00:00
printf ( " read failed at %s \n " , __location__ ) ;
2007-10-06 22:28:14 +00:00
ret = false ;
2003-08-13 01:53:07 +00:00
goto done ;
}
CHECK_BUFFER ( buf , seed , 4000 ) ;
done :
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
/*
basic testing of write calls
*/
2007-08-28 12:54:27 +00:00
struct torture_suite * torture_raw_write ( TALLOC_CTX * mem_ctx )
2003-08-13 01:53:07 +00:00
{
2007-08-28 12:54:27 +00:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " WRITE " ) ;
2003-08-13 01:53:07 +00:00
2007-08-28 12:54:27 +00:00
torture_suite_add_1smb_test ( suite , " write " , test_write ) ;
torture_suite_add_1smb_test ( suite , " write unlock " , test_writeunlock ) ;
torture_suite_add_1smb_test ( suite , " write close " , test_writeclose ) ;
torture_suite_add_1smb_test ( suite , " writex " , test_writex ) ;
2003-08-13 01:53:07 +00:00
2007-08-28 12:54:27 +00:00
return suite ;
2003-08-13 01:53:07 +00:00
}