2005-05-23 16:25:31 +00:00
/*
* Unix SMB / CIFS implementation .
* Virtual Windows Registry Layer ( utility functions )
* Copyright ( C ) Gerald Carter 2002 - 2005
*
* 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-09 19:25:36 +00:00
* the Free Software Foundation ; either version 3 of the License , or
2005-05-23 16:25:31 +00:00
* ( at your option ) any later version .
2007-11-26 17:24:56 -08:00
*
2005-05-23 16:25:31 +00:00
* 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 .
2007-11-26 17:24:56 -08:00
*
2005-05-23 16:25:31 +00:00
* You should have received a copy of the GNU General Public License
2007-07-10 05:23:25 +00:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2005-05-23 16:25:31 +00:00
*/
/* Implementation of registry frontend view functions. */
# include "includes.h"
# undef DBGC_CLASS
2007-09-28 23:05:52 +00:00
# define DBGC_CLASS DBGC_REGISTRY
2005-05-23 16:25:31 +00:00
/***********************************************************************
Utility function for splitting the base path of a registry path off
by setting base and new_path to the apprapriate offsets withing the
path .
2007-11-26 17:24:56 -08:00
2005-05-23 16:25:31 +00:00
WARNING ! ! Does modify the original string !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-26 17:24:56 -08:00
bool reg_split_path ( char * path , char * * base , char * * new_path )
2005-05-23 16:25:31 +00:00
{
char * p ;
2007-11-26 17:24:56 -08:00
2005-05-23 16:25:31 +00:00
* new_path = * base = NULL ;
2007-11-26 17:24:56 -08:00
if ( ! path ) {
return false ;
}
2005-05-23 16:25:31 +00:00
* base = path ;
2007-11-26 17:24:56 -08:00
p = strchr ( path , ' \\ ' ) ;
2005-05-23 16:25:31 +00:00
if ( p ) {
* p = ' \0 ' ;
* new_path = p + 1 ;
}
2007-11-26 17:24:56 -08:00
return true ;
}
2005-05-23 16:25:31 +00:00
/***********************************************************************
Utility function for splitting the base path of a registry path off
by setting base and new_path to the appropriate offsets withing the
path .
2007-11-26 17:24:56 -08:00
2005-05-23 16:25:31 +00:00
WARNING ! ! Does modify the original string !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-26 17:24:56 -08:00
bool reg_split_key ( char * path , char * * base , char * * key )
2005-05-23 16:25:31 +00:00
{
char * p ;
2007-11-26 17:24:56 -08:00
2005-05-23 16:25:31 +00:00
* key = * base = NULL ;
2007-11-26 17:24:56 -08:00
if ( ! path ) {
return false ;
}
2005-05-23 16:25:31 +00:00
* base = path ;
2007-11-26 17:24:56 -08:00
p = strrchr ( path , ' \\ ' ) ;
if ( p ) {
2005-05-23 16:25:31 +00:00
* p = ' \0 ' ;
* key = p + 1 ;
}
2007-11-26 17:24:56 -08:00
return true ;
}
2005-05-23 16:25:31 +00:00
2008-05-06 22:20:49 +02:00
/**
* The full path to the registry key is used as database key
* after the \ ' s are converted to / ' s .
* Leading and trailing ' / ' and ' \ ' characters are stripped .
* Key string is also normalized to UPPER case .
*/
2005-06-27 03:40:03 +00:00
2007-11-26 17:24:56 -08:00
char * normalize_reg_path ( TALLOC_CTX * ctx , const char * keyname )
2005-06-27 03:40:03 +00:00
{
2008-05-06 22:20:49 +02:00
char * p ;
char * nkeyname ;
/* skip leading '/' and '\' chars */
p = ( char * ) keyname ;
while ( ( * p = = ' / ' ) | | ( * p = = ' \\ ' ) ) {
p + + ;
}
nkeyname = talloc_string_sub ( ctx , p , " \\ " , " / " ) ;
if ( nkeyname = = NULL ) {
2007-11-26 17:24:56 -08:00
return NULL ;
}
2008-05-06 22:20:49 +02:00
/* strip trailing '/' chars */
p = strrchr ( nkeyname , ' / ' ) ;
while ( ( p ! = NULL ) & & ( p [ 1 ] = = ' \0 ' ) ) {
* p = ' \0 ' ;
p = strrchr ( nkeyname , ' / ' ) ;
}
2007-11-26 17:24:56 -08:00
strupper_m ( nkeyname ) ;
2008-05-06 22:20:49 +02:00
2007-11-26 17:24:56 -08:00
return nkeyname ;
2005-06-27 03:40:03 +00:00
}
2005-05-23 16:25:31 +00:00
2008-04-11 21:38:06 +02:00
/**
* normalize ther registry path in place .
*/
void normalize_dbkey ( char * key )
{
size_t len = strlen ( key ) ;
string_sub ( key , " \\ " , " / " , len + 1 ) ;
strupper_m ( key ) ;
}
2005-09-30 17:13:37 +00:00
/**********************************************************************
move to next non - delimter character
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-26 17:24:56 -08:00
char * reg_remaining_path ( TALLOC_CTX * ctx , const char * key )
2005-09-30 17:13:37 +00:00
{
2007-11-26 17:24:56 -08:00
char * new_path = NULL ;
char * p = NULL ;
if ( ! key | | ! * key ) {
2005-09-30 17:13:37 +00:00
return NULL ;
2007-11-26 17:24:56 -08:00
}
2005-09-30 17:13:37 +00:00
2007-11-26 17:24:56 -08:00
new_path = talloc_strdup ( ctx , key ) ;
if ( ! new_path ) {
return NULL ;
}
2005-09-30 17:13:37 +00:00
/* normalize_reg_path( new_path ); */
2007-11-26 17:24:56 -08:00
if ( ! ( p = strchr ( new_path , ' \\ ' ) ) ) {
if ( ! ( p = strchr ( new_path , ' / ' ) ) ) {
2005-09-30 17:13:37 +00:00
p = new_path ;
2007-11-26 17:24:56 -08:00
} else {
2005-09-30 17:13:37 +00:00
p + + ;
2007-11-26 17:24:56 -08:00
}
} else {
2005-09-30 17:13:37 +00:00
p + + ;
2007-11-26 17:24:56 -08:00
}
return p ;
2005-09-30 17:13:37 +00:00
}
2005-10-14 21:43:13 +00:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-18 03:21:59 +00:00
int regval_convert_multi_sz ( uint16 * multi_string , size_t byte_len , char * * * values )
2005-10-14 21:43:13 +00:00
{
char * * sz ;
int i ;
int num_strings = 0 ;
fstring buffer ;
uint16 * wp ;
2005-10-18 03:21:59 +00:00
size_t multi_len = byte_len / 2 ;
2007-11-26 17:24:56 -08:00
2005-10-17 15:53:12 +00:00
if ( ! multi_string | | ! values )
2005-10-14 21:46:32 +00:00
return 0 ;
2005-10-18 03:21:59 +00:00
* values = NULL ;
2005-10-14 21:43:13 +00:00
/* just count the NULLs */
2007-11-26 17:24:56 -08:00
2005-10-18 03:21:59 +00:00
for ( i = 0 ; ( i < multi_len - 1 ) & & ! ( multi_string [ i ] = = 0x0 & & multi_string [ i + 1 ] = = 0x0 ) ; i + + ) {
/* peek ahead */
if ( multi_string [ i + 1 ] = = 0x0 )
2005-10-14 21:43:13 +00:00
num_strings + + ;
}
2005-10-18 03:21:59 +00:00
2005-10-14 21:43:13 +00:00
if ( num_strings = = 0 )
return 0 ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
if ( ! ( sz = TALLOC_ARRAY ( NULL , char * , num_strings + 1 ) ) ) {
DEBUG ( 0 , ( " reg_convert_multi_sz: talloc() failed! \n " ) ) ;
return - 1 ;
}
wp = multi_string ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
for ( i = 0 ; i < num_strings ; i + + ) {
rpcstr_pull ( buffer , wp , sizeof ( buffer ) , - 1 , STR_TERMINATE ) ;
sz [ i ] = talloc_strdup ( sz , buffer ) ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
/* skip to the next string NULL and then one more */
while ( * wp )
wp + + ;
wp + + ;
}
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
/* tag the array off with an empty string */
sz [ i ] = ' \0 ' ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
* values = sz ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
return num_strings ;
}
/**********************************************************************
Returns number of bytes , not number of unicode characters
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
size_t regval_build_multi_sz ( char * * values , uint16 * * buffer )
{
int i ;
size_t buf_size = 0 ;
uint16 * buf , * b ;
UNISTR2 sz ;
2005-10-14 21:46:32 +00:00
2005-10-17 15:53:12 +00:00
if ( ! values | | ! buffer )
2005-10-14 21:46:32 +00:00
return 0 ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
/* go ahead and alloc some space */
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
if ( ! ( buf = TALLOC_ARRAY ( NULL , uint16 , 2 ) ) ) {
DEBUG ( 0 , ( " regval_build_multi_sz: talloc() failed! \n " ) ) ;
return 0 ;
}
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
for ( i = 0 ; values [ i ] ; i + + ) {
ZERO_STRUCT ( sz ) ;
2005-10-17 15:53:12 +00:00
/* DEBUG(0,("regval_build_multi_sz: building [%s]\n",values[i])); */
2005-10-14 21:43:13 +00:00
init_unistr2 ( & sz , values [ i ] , UNI_STR_TERMINATE ) ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
/* Alloc some more memory. Always add one one to account for the
double NULL termination */
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
b = TALLOC_REALLOC_ARRAY ( NULL , buf , uint16 , buf_size + sz . uni_str_len + 1 ) ;
if ( ! b ) {
DEBUG ( 0 , ( " regval_build_multi_sz: talloc() reallocation error! \n " ) ) ;
TALLOC_FREE ( buffer ) ;
return 0 ;
}
buf = b ;
2007-11-26 17:24:56 -08:00
/* copy the unistring2 buffer and increment the size */
2005-10-17 15:53:12 +00:00
/* dump_data(1,sz.buffer,sz.uni_str_len*2); */
memcpy ( buf + buf_size , sz . buffer , sz . uni_str_len * 2 ) ;
2005-10-14 21:43:13 +00:00
buf_size + = sz . uni_str_len ;
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
/* cleanup rather than leaving memory hanging around */
TALLOC_FREE ( sz . buffer ) ;
}
2007-11-26 17:24:56 -08:00
2005-10-14 21:43:13 +00:00
buf [ buf_size + + ] = 0x0 ;
* buffer = buf ;
/* return number of bytes */
return buf_size * 2 ;
}