1998-03-12 00:11:04 +03:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
Samba memory buffer functions
Copyright ( C ) Andrew Tridgell 1992 - 1997
Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
extern int DEBUGLEVEL ;
# include "includes.h"
/*******************************************************************
debug output for parsing info .
XXXX side - effect of this function is to increase the debug depth XXXX
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void prs_debug ( prs_struct * ps , int depth , char * desc , char * fn_name )
{
DEBUG ( 5 + depth , ( " %s%06x %s %s \n " , tab_depth ( depth ) , ps - > offset , fn_name , desc ) ) ;
}
/*******************************************************************
initialise a parse structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void prs_init ( prs_struct * ps , uint32 size ,
uint8 align , uint32 margin ,
BOOL io )
{
ps - > io = io ;
ps - > align = align ;
ps - > offset = 0 ;
ps - > data = NULL ;
mem_buf_init ( & ( ps - > data ) , margin ) ;
if ( size ! = 0 )
{
mem_alloc_data ( ps - > data , size ) ;
ps - > data - > offset . start = 0 ;
ps - > data - > offset . end = 0xffffffff ;
}
}
/*******************************************************************
initialise a parse structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void prs_mem_free ( prs_struct * ps )
{
mem_buf_free ( & ( ps - > data ) ) ;
}
1998-10-07 19:22:49 +04:00
/*******************************************************************
link one parsing structure to another
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-08 01:42:24 +04:00
void prs_link ( prs_struct * prev , prs_struct * ps , prs_struct * next )
1998-10-07 19:22:49 +04:00
{
1998-10-08 01:42:24 +04:00
ps - > data - > offset . start = prev ! = NULL ? prev - > data - > offset . end : 0 ;
ps - > data - > offset . end = ps - > data - > offset . start + ps - > offset ;
ps - > data - > next = next ! = NULL ? next - > data : NULL ;
1998-10-07 19:22:49 +04:00
}
1998-03-12 00:11:04 +03:00
/*******************************************************************
align a pointer to a multiple of align_offset bytes . looks like it
will work for offsets of 0 , 2 and 4. . .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void prs_align ( prs_struct * ps )
{
int mod = ps - > offset & ( ps - > align - 1 ) ;
if ( ps - > align ! = 0 & & mod ! = 0 )
{
ps - > offset + = ps - > align - mod ;
}
}
/*******************************************************************
attempt , if appropriate , to grow a data buffer .
depends on the data stream mode ( io )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_grow ( prs_struct * ps )
{
1998-04-10 22:21:16 +04:00
return mem_grow_data ( & ( ps - > data ) , ps - > io , ps - > offset , False ) ;
1998-03-12 00:11:04 +03:00
}
/*******************************************************************
stream a uint8
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_uint8 ( char * name , prs_struct * ps , int depth , uint8 * data8 )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
DBG_RW_CVAL ( name , depth , ps - > offset , ps - > io , q , * data8 )
ps - > offset + = 1 ;
return True ;
}
/*******************************************************************
stream a uint16
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_uint16 ( char * name , prs_struct * ps , int depth , uint16 * data16 )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
DBG_RW_SVAL ( name , depth , ps - > offset , ps - > io , q , * data16 )
ps - > offset + = 2 ;
return True ;
}
/*******************************************************************
stream a uint32
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_uint32 ( char * name , prs_struct * ps , int depth , uint32 * data32 )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
DBG_RW_IVAL ( name , depth , ps - > offset , ps - > io , q , * data32 )
ps - > offset + = 4 ;
return True ;
}
/******************************************************************
stream an array of uint8s . length is number of uint8s
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_uint8s ( BOOL charmode , char * name , prs_struct * ps , int depth , uint8 * data8s , int len )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
DBG_RW_PCVAL ( charmode , name , depth , ps - > offset , ps - > io , q , data8s , len )
ps - > offset + = len ;
return True ;
}
/******************************************************************
stream an array of uint32s . length is number of uint32s
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_uint32s ( BOOL charmode , char * name , prs_struct * ps , int depth , uint32 * data32s , int len )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
DBG_RW_PIVAL ( charmode , name , depth , ps - > offset , ps - > io , q , data32s , len )
ps - > offset + = len * sizeof ( uint32 ) ;
return True ;
}
/******************************************************************
stream a " not " unicode string , length / buffer specified separately ,
in byte chars
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-10 22:05:00 +03:00
BOOL prs_buffer2 ( BOOL charmode , char * name , prs_struct * ps , int depth , BUFFER2 * str )
1998-03-12 00:11:04 +03:00
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
1998-11-10 22:05:00 +03:00
DBG_RW_PSVAL ( charmode , name , depth , ps - > offset , ps - > io , q , str - > buffer , str - > buf_len / 2 )
ps - > offset + = str - > buf_len ;
1998-03-12 00:11:04 +03:00
return True ;
}
/******************************************************************
stream a string , length / buffer specified separately ,
in uint8 chars .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_string2 ( BOOL charmode , char * name , prs_struct * ps , int depth , STRING2 * str )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
DBG_RW_PCVAL ( charmode , name , depth , ps - > offset , ps - > io , q , str - > buffer , str - > str_max_len )
ps - > offset + = str - > str_str_len * sizeof ( uint8 ) ;
return True ;
}
/******************************************************************
stream a unicode string , length / buffer specified separately ,
in uint16 chars .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_unistr2 ( BOOL charmode , char * name , prs_struct * ps , int depth , UNISTR2 * str )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
1998-11-10 22:05:00 +03:00
DBG_RW_PSVAL ( charmode , name , depth , ps - > offset , ps - > io , q , str - > buffer , str - > uni_str_len )
ps - > offset + = str - > uni_str_len * sizeof ( uint16 ) ;
return True ;
}
/******************************************************************
stream a unicode string , length / buffer specified separately ,
in uint16 chars .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_unistr3 ( BOOL charmode , char * name , UNISTR3 * str , prs_struct * ps , int depth )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
if ( q = = NULL ) return False ;
DBG_RW_PSVAL ( charmode , name , depth , ps - > offset , ps - > io , q , str - > str . buffer , str - > uni_str_len )
1998-03-12 00:11:04 +03:00
ps - > offset + = str - > uni_str_len * sizeof ( uint16 ) ;
return True ;
}
/*******************************************************************
stream a unicode null - terminated string
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_unistr ( char * name , prs_struct * ps , int depth , UNISTR * str )
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
int i = 0 ;
uint8 * start = ( uint8 * ) q ;
if ( q = = NULL ) return False ;
do
{
RW_SVAL ( ps - > io , q , str - > buffer [ i ] , 0 ) ;
q + = 2 ;
i + + ;
} while ( ( i < sizeof ( str - > buffer ) / sizeof ( str - > buffer [ 0 ] ) ) & &
( str - > buffer [ i ] ! = 0 ) ) ;
ps - > offset + = i * 2 ;
1998-10-08 01:42:24 +04:00
dump_data ( 5 + depth , ( char * ) start , i * 2 ) ;
1998-03-12 00:11:04 +03:00
return True ;
}
/*******************************************************************
stream a null - terminated string . len is strlen , and therefore does
not include the null - termination character .
len = = 0 indicates variable length string
( up to max size of pstring - 1024 chars ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-07 02:03:04 +04:00
BOOL prs_string ( char * name , prs_struct * ps , int depth , char * str , uint16 len , uint16 max_buf_size )
1998-03-12 00:11:04 +03:00
{
char * q = mem_data ( & ( ps - > data ) , ps - > offset ) ;
uint8 * start = ( uint8 * ) q ;
int i = - 1 ; /* start off at zero after 1st i++ */
if ( q = = NULL ) return False ;
do
{
i + + ;
if ( i < len | | len = = 0 )
{
RW_CVAL ( ps - > io , q , str [ i ] , 0 ) ;
}
else
{
uint8 dummy = 0 ;
RW_CVAL ( ps - > io , q , dummy , 0 ) ;
}
q + + ;
1998-10-07 02:03:04 +04:00
} while ( i < max_buf_size & & ( len = = 0 ? str [ i ] ! = 0 : i < len ) ) ;
1998-03-12 00:11:04 +03:00
ps - > offset + = i + 1 ;
1998-10-08 01:42:24 +04:00
dump_data ( 5 + depth , ( char * ) start , i ) ;
1998-03-12 00:11:04 +03:00
return True ;
}
1998-11-10 22:05:00 +03:00
/*******************************************************************
prs_uint16 wrapper . call this and it sets up a pointer to where the
uint16 should be stored , or gets the size if reading
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_uint16_pre ( char * name , prs_struct * ps , int depth , uint16 * data16 , uint32 * off_ptr )
{
( * off_ptr ) = ps - > offset ;
if ( ps - > io )
{
/* reading. */
return prs_uint16 ( name , ps , depth , data16 ) ;
}
return True ;
}
/*******************************************************************
prs_uint16 wrapper . call this and it retrospectively stores the size .
does nothing on reading , as that is already handled by . . . . _pre ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL prs_uint16_post ( char * name , prs_struct * ps , int depth ,
uint32 ptr_uint16 , uint32 start_offset )
{
if ( ! ps - > io )
{
/* storing: go back and do a retrospective job. i hate this */
uint16 data_size = ps - > offset - start_offset ;
uint32 old_offset = ps - > offset ;
ps - > offset = ptr_uint16 ;
prs_uint16 ( name , ps , depth , & data_size ) ;
ps - > offset = old_offset ;
}
return True ;
}