1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

several changes in this checkin

* added REG_OPEN_HKCR for supporting regedit.exe

* All data n a REGISTRY_VALUE is stored to a pointer now

* fixed REG_INFO to correctly display data when double clicking on
  and entry in the registry editor

* Will now enumerate installed driver_info_3 data

* fixed numerous bugs related to pointer offsets, memory issues, etc..
  in the registry routines

* added a simple caching mechanism to fetch_reg_[keys|values]_specific()

All that is left now is to enumerate PrinterData and I will have finished
what I started out to do....
(This used to be commit 419d7208e8)
This commit is contained in:
Gerald Carter 2002-07-24 06:42:09 +00:00
parent 84f2875d7b
commit c808cc3643
7 changed files with 629 additions and 150 deletions

View File

@ -26,7 +26,6 @@
/* winreg pipe defines
NOT IMPLEMENTED !!
#define REG_OPEN_HKCR 0x00
#define _REG_UNK_01 0x01
#define _REG_UNK_03 0x03
#define REG_CREATE_KEY 0x06
@ -45,6 +44,7 @@
*/
/* Implemented */
#define REG_OPEN_HKCR 0x00
#define REG_OPEN_HKLM 0x02
#define REG_OPEN_HKU 0x04
#define REG_CLOSE 0x05
@ -65,6 +65,7 @@
#define KEY_HKLM "HKLM"
#define KEY_HKU "HKU"
#define KEY_HKCR "HKCR"
#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
#define KEY_TREE_ROOT ""
@ -93,12 +94,16 @@ typedef struct {
fstring valuename;
uint16 type;
uint32 size; /* in bytes */
void *data_p;
#if 0
union {
char *string;
uint32 dword;
uint32 *dword;
uint8 *binary;
void *void_ptr; /* for casting only */
} data;
#endif
} REGISTRY_VALUE;
/* container for regostry values */
@ -145,7 +150,7 @@ typedef struct _RegistryKey {
struct _RegistryKey *prev, *next;
POLICY_HND hnd;
fstring name; /* full name of registry key */
pstring name; /* full name of registry key */
REGISTRY_HOOK *hook;
} REGISTRY_KEY;
@ -551,7 +556,7 @@ typedef struct r_reg_info_info
uint32 type; /* key datatype */
uint32 ptr_uni_val; /* key value pointer */
BUFFER2 *uni_val; /* key value */
BUFFER2 uni_val; /* key value */
uint32 ptr_max_len;
uint32 buf_max_len;

View File

@ -106,6 +106,12 @@ static BOOL init_registry_data( void )
if ( !regdb_store_reg_keys( keyname, &subkeys ) )
return False;
/* HKEY_CLASSES_ROOT*/
pstrcpy( keyname, KEY_HKCR );
if ( !regdb_store_reg_keys( keyname, &subkeys ) )
return False;
return True;
}
@ -233,6 +239,7 @@ int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
int i;
fstring subkeyname;
DEBUG(10,("regdb_fetch_reg_keys: Enter key => [%s]\n", key ? key : "NULL"));
pstrcpy( path, key );
@ -258,6 +265,8 @@ int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
SAFE_FREE( dbuf.dptr );
DEBUG(10,("regdb_fetch_reg_keys: Exit [%d] items\n", num_items));
return num_items;
}

View File

@ -149,7 +149,6 @@ int regval_ctr_numvals( REGVAL_CTR *ctr )
REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
{
REGISTRY_VALUE *copy = NULL;
BOOL fail = True;
if ( !val )
return NULL;
@ -162,35 +161,15 @@ REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
/* copy all the non-pointer initial data */
memcpy( copy, val, sizeof(REGISTRY_VALUE) );
if ( val->data_p )
{
if ( !(copy->data_p = memdup( val->data_p, val->size )) ) {
DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
val->size));
SAFE_FREE( copy );
}
}
switch ( val->type ) {
case REG_SZ:
if ( !(copy->data.string = strdup( val->data.string )) ) {
DEBUG(0,("dup_registry_value: strdup() failed for [%s]!\n",
val->data.string));
goto done;
}
break;
case REG_DWORD:
/* nothing to be done; already copied by memcpy() */
break;
case REG_BINARY:
if ( !(copy->data.string = memdup( val->data.binary, val->size )) ) {
DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
val->size));
goto done;
}
break;
}
fail = False;
done:
if ( fail )
SAFE_FREE( copy );
return copy;
}
@ -203,16 +182,7 @@ void free_registry_value( REGISTRY_VALUE *val )
if ( !val )
return;
switch ( val->type )
{
case REG_SZ:
SAFE_FREE( val->data.string );
break;
case REG_BINARY:
SAFE_FREE( val->data.binary );
break;
}
SAFE_FREE( val->data_p );
SAFE_FREE( val );
return;
@ -263,19 +233,26 @@ int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
fstrcpy( ctr->values[ctr->num_values]->valuename, name );
ctr->values[ctr->num_values]->type = type;
ctr->values[ctr->num_values]->data_p = talloc_memdup( ctr->ctx, data_p, size );
ctr->values[ctr->num_values]->size = size;
#if 0
switch ( type )
{
case REG_SZ:
ctr->values[ctr->num_values]->data.string = talloc_strdup( ctr->ctx, data_p );
break;
case REG_MULTI_SZ:
ctr->values[ctr->num_values]->data.string = talloc_memdup( ctr->ctx, data_p, size );
break;
case REG_DWORD:
ctr->values[ctr->num_values]->data.dword = *(uint32*)data_p;
break;
case REG_BINARY:
ctr->values[ctr->num_values]->data.binary = talloc_memdup( ctr->ctx, data_p, size );
break;
}
ctr->values[ctr->num_values]->size = size;
#endif
ctr->num_values++;
}
@ -374,23 +351,46 @@ int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
{
static REGSUBKEY_CTR ctr;
static pstring save_path;
static BOOL ctr_init = False;
char *s;
REGSUBKEY_CTR ctr;
ZERO_STRUCTP( &ctr );
*subkey = NULL;
regsubkey_ctr_init( &ctr );
/* simple caching for performance; very basic heuristic */
if ( fetch_reg_keys( key, &ctr) == -1 )
return False;
if ( !ctr_init ) {
DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
ZERO_STRUCTP( &ctr );
regsubkey_ctr_init( &ctr );
pstrcpy( save_path, key->name );
if ( fetch_reg_keys( key, &ctr) == -1 )
return False;
ctr_init = True;
}
/* clear the cache when key_index == 0 or the path has changed */
else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
regsubkey_ctr_destroy( &ctr );
regsubkey_ctr_init( &ctr );
pstrcpy( save_path, key->name );
if ( fetch_reg_keys( key, &ctr) == -1 )
return False;
}
if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
return False;
*subkey = strdup( s );
regsubkey_ctr_destroy( &ctr );
return True;
}
@ -416,25 +416,49 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
responsible for freeing memory
***********************************************************************/
BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 key_index )
BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
{
REGVAL_CTR ctr;
REGISTRY_VALUE *v;
static REGVAL_CTR ctr;
static pstring save_path;
static BOOL ctr_init = False;
REGISTRY_VALUE *v;
ZERO_STRUCTP( &ctr );
*val = NULL;
regval_ctr_init( &ctr );
/* simple caching for performance; very basic heuristic */
if ( fetch_reg_values( key, &ctr) == -1 )
return False;
if ( !ctr_init ) {
DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
if ( !(v = regval_ctr_specific_value( &ctr, key_index )) )
ZERO_STRUCTP( &ctr );
regval_ctr_init( &ctr );
pstrcpy( save_path, key->name );
if ( fetch_reg_values( key, &ctr) == -1 )
return False;
ctr_init = True;
}
/* clear the cache when val_index == 0 or the path has changed */
else if ( !val_index || StrCaseCmp(save_path, key->name) ) {
DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));
regval_ctr_destroy( &ctr );
regval_ctr_init( &ctr );
pstrcpy( save_path, key->name );
if ( fetch_reg_values( key, &ctr) == -1 )
return False;
}
if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
return False;
*val = dup_registry_value( v );
regval_ctr_destroy( &ctr );
return True;
}

View File

@ -84,18 +84,270 @@ static char* trim_reg_path( char *path )
static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys )
{
char *environments[] = {
"Windows 4.0",
"Windows NT x86",
"Windows NT R4000",
"Windows NT Alpha_AXP",
"Windows NT PowerPC",
NULL };
fstring *drivers = NULL;
int i, env_index, num_drivers;
BOOL valid_env = False;
char *base, *new_path;
char *keystr;
char *key2 = NULL;
int num_subkeys = -1;
DEBUG(10,("print_subpath_environments: key=>[%s]\n", key ? key : "NULL" ));
if ( !key )
/* listed architectures of installed drivers */
if ( !key )
{
/* listed architectures of installed drivers */
/* Windows 9x drivers */
if ( get_ntdrivers( &drivers, environments[0], 0 ) )
regsubkey_ctr_addkey( subkeys, environments[0] );
SAFE_FREE( drivers );
/* Windows NT/2k intel drivers */
if ( get_ntdrivers( &drivers, environments[1], 2 )
|| get_ntdrivers( &drivers, environments[1], 3 ) )
{
regsubkey_ctr_addkey( subkeys, environments[1] );
}
SAFE_FREE( drivers );
/* Windows NT 4.0; non-intel drivers */
for ( i=2; environments[i]; i++ ) {
if ( get_ntdrivers( &drivers, environments[i], 2 ) )
regsubkey_ctr_addkey( subkeys, environments[i] );
}
SAFE_FREE( drivers );
num_subkeys = regsubkey_ctr_numkeys( subkeys );
goto done;
}
/* we are dealing with a subkey of "Environments */
return 0;
key2 = strdup( key );
keystr = key2;
reg_split_path( keystr, &base, &new_path );
/* sanity check */
for ( env_index=0; environments[env_index]; env_index++ ) {
if ( StrCaseCmp( environments[env_index], base ) == 0 ) {
valid_env = True;
break;
}
}
if ( !valid_env )
return -1;
/* enumerate driver versions; environment is environments[env_index] */
if ( !new_path ) {
switch ( env_index ) {
case 0: /* Win9x */
if ( get_ntdrivers( &drivers, environments[0], 0 ) ) {
regsubkey_ctr_addkey( subkeys, "0" );
SAFE_FREE( drivers );
}
break;
case 1: /* Windows NT/2k - intel */
if ( get_ntdrivers( &drivers, environments[1], 2 ) ) {
regsubkey_ctr_addkey( subkeys, "2" );
SAFE_FREE( drivers );
}
if ( get_ntdrivers( &drivers, environments[1], 3 ) ) {
regsubkey_ctr_addkey( subkeys, "3" );
SAFE_FREE( drivers );
}
break;
default: /* Windows NT - nonintel */
if ( get_ntdrivers( &drivers, environments[env_index], 2 ) ) {
regsubkey_ctr_addkey( subkeys, "2" );
SAFE_FREE( drivers );
}
}
num_subkeys = regsubkey_ctr_numkeys( subkeys );
goto done;
}
/* we finally get to enumerate the drivers */
keystr = new_path;
reg_split_path( keystr, &base, &new_path );
if ( !new_path ) {
num_drivers = get_ntdrivers( &drivers, environments[env_index], atoi(base) );
for ( i=0; i<num_drivers; i++ )
regsubkey_ctr_addkey( subkeys, drivers[i] );
num_subkeys = regsubkey_ctr_numkeys( subkeys );
goto done;
}
done:
SAFE_FREE( key2 );
return num_subkeys;
}
/***********************************************************************
simple function to prune a pathname down to the basename of a file
**********************************************************************/
static char* dos_basename ( char *path )
{
char *p;
p = strrchr( path, '\\' );
if ( p )
p++;
else
p = path;
return p;
}
/**********************************************************************
handle enumeration of values below
KEY_PRINTING\Environments\<arch>\<version>\<drivername>
*********************************************************************/
static int print_subpath_values_environments( char *key, REGVAL_CTR *val )
{
char *keystr;
char *key2 = NULL;
char *base, *new_path;
fstring env;
fstring driver;
int version;
NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr;
NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
WERROR w_result;
char *buffer = NULL;
char *buffer2 = NULL;
int buffer_size = 0;
int i, length;
char *filename;
DEBUG(8,("print_subpath_values_environments: Enter key => [%s]\n", key ? key : "NULL"));
if ( !key )
return 0;
/*
* The only key below KEY_PRINTING\Environments that
* posseses values is each specific printer driver
* First get the arch, version, & driver name
*/
/* env */
key2 = strdup( key );
keystr = key2;
reg_split_path( keystr, &base, &new_path );
if ( !base || !new_path )
return 0;
fstrcpy( env, base );
/* version */
keystr = new_path;
reg_split_path( keystr, &base, &new_path );
if ( !base || !new_path )
return 0;
version = atoi( base );
/* printer driver name */
keystr = new_path;
reg_split_path( keystr, &base, &new_path );
/* new_path should be NULL here since this must be the last key */
if ( !base || new_path )
return 0;
fstrcpy( driver, base );
w_result = get_a_printer_driver( &driver_ctr, 3, driver, env, version );
if ( !W_ERROR_IS_OK(w_result) )
return -1;
/* build the values out of the driver information */
info3 = driver_ctr.info_3;
filename = dos_basename( info3->driverpath );
regval_ctr_addvalue( val, "Driver", REG_SZ, filename, strlen(filename)+1 );
filename = dos_basename( info3->configfile );
regval_ctr_addvalue( val, "Configuration File", REG_SZ, filename, strlen(filename)+1 );
filename = dos_basename( info3->datafile );
regval_ctr_addvalue( val, "Data File", REG_SZ, filename, strlen(filename)+1 );
filename = dos_basename( info3->helpfile );
regval_ctr_addvalue( val, "Help File", REG_SZ, filename, strlen(filename)+1 );
regval_ctr_addvalue( val, "Data Type", REG_SZ, info3->defaultdatatype, strlen(info3->defaultdatatype)+1 );
regval_ctr_addvalue( val, "Version", REG_DWORD, (char*)&info3->cversion, sizeof(info3->cversion) );
if ( info3->dependentfiles )
{
/* place the list of dependent files in a single
character buffer, separating each file name by
a NULL */
for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ )
{
/* strip the path to only the file's base name */
filename = dos_basename( info3->dependentfiles[i] );
length = strlen(filename);
buffer2 = Realloc( buffer, buffer_size + length + 1 );
if ( !buffer2 )
break;
buffer = buffer2;
memcpy( buffer+buffer_size, filename, length+1 );
buffer_size += length + 1;
}
/* terminated by double NULL. Add the final one here */
buffer2 = Realloc( buffer, buffer_size + 1 );
if ( !buffer2 ) {
SAFE_FREE( buffer );
buffer_size = 0;
}
else {
buffer = buffer2;
buffer[buffer_size++] = '\0';
}
}
regval_ctr_addvalue( val, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size );
free_a_printer_driver( driver_ctr, 3 );
SAFE_FREE( key2 );
SAFE_FREE( buffer );
DEBUG(8,("print_subpath_values_environments: Exit\n"));
return regval_ctr_numvals( val );
}
/**********************************************************************
handle enumeration of subkeys below KEY_PRINTING\Forms
Really just a stub function, but left here in case it needs to
@ -263,6 +515,8 @@ static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys, REGVAL_CT
case KEY_INDEX_ENVIR:
if ( subkeys )
print_subpath_environments( p, subkeys );
if ( val )
print_subpath_values_environments( p, val );
break;
case KEY_INDEX_FORMS:

View File

@ -6,6 +6,7 @@
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Marc Jacobsen 1999.
* Copyright (C) Simo Sorce 2000.
* Copyright (C) Gerald Carter 2002.
*
* 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
@ -27,6 +28,89 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
/*******************************************************************
Fill in a BUFFER2 for the data given a REGISTRY_VALUE
*******************************************************************/
static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
{
UNISTR2 unistr;
uint32 real_size = 0;
char *string;
char *list = NULL;
char *list2 = NULL;
if ( !buf2 || !val )
return 0;
real_size = val->size;
switch (val->type )
{
case REG_SZ:
string = (char*)val->data_p;
DEBUG(10,("reg_init_buffer2: REG_SZ string => [%s]\n", string));
init_unistr2( &unistr, (char*)val->data_p, strlen((char*)val->data_p)+1 );
init_buffer2( buf2, (char*)unistr.buffer, unistr.uni_str_len*2 );
real_size = unistr.uni_str_len*2;
break;
case REG_MULTI_SZ:
string = (char*)val->data_p;
real_size = 0;
while ( string && *string )
{
DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ string => [%s], size => [%d]\n", string, real_size ));
init_unistr2( &unistr, string, strlen(string)+1 );
list2 = Realloc( list, real_size + unistr.uni_str_len*2 );
if ( !list2 )
break;
list = list2;
memcpy( list+real_size, unistr.buffer, unistr.uni_str_len*2 );
real_size += unistr.uni_str_len*2;
string += strlen(string)+1;
}
list2 = Realloc( list, real_size + 2 );
if ( !list2 )
break;
list = list2;
list[real_size++] = 0x0;
list[real_size++] = 0x0;
init_buffer2( buf2, (char*)list, real_size );
DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ size => [%d]\n", real_size ));
break;
case REG_BINARY:
DEBUG(10,("reg_init_buffer2: REG_BINARY size => [%d]\n", val->size ));
init_buffer2( buf2, val->data_p, val->size );
break;
case REG_DWORD:
DEBUG(10,("reg_init_buffer2: REG_DWORD value => [%d]\n", *(uint32*)val->data_p));
init_buffer2( buf2, val->data_p, val->size );
break;
default:
DEBUG(0,("reg_init_buffer2: Unsupported registry data type [%d]\n", val->type));
break;
}
SAFE_FREE( list );
return real_size;
}
/*******************************************************************
Inits a structure.
********************************************************************/
@ -165,6 +249,8 @@ BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
}
/*******************************************************************
Inits a structure.
********************************************************************/
@ -1023,6 +1109,45 @@ BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
return True;
}
/*******************************************************************
Inits a structure.
New version to replace older init_reg_r_info()
********************************************************************/
BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
REGISTRY_VALUE *val, NTSTATUS status)
{
uint32 buf_len = 0;
if(r_r == NULL)
return False;
if ( !val )
return False;
r_r->ptr_type = 1;
r_r->type = val->type;
/* if include_keyval is not set, don't send the key value, just
the buflen data. probably used by NT5 to allocate buffer space - SK */
if ( include_keyval ) {
r_r->ptr_uni_val = 1;
buf_len = reg_init_buffer2( &r_r->uni_val, val );
}
r_r->ptr_max_len = 1;
r_r->buf_max_len = buf_len;
r_r->ptr_len = 1;
r_r->buf_len = buf_len;
r_r->status = status;
return True;
}
/*******************************************************************
Inits a structure.
********************************************************************/
@ -1030,28 +1155,27 @@ BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
BUFFER2* buf, uint32 type, NTSTATUS status)
{
if(r_r == NULL)
return False;
if(r_r == NULL)
return False;
r_r->ptr_type = 1;
r_r->type = type;
r_r->ptr_type = 1;
r_r->type = type;
/* if include_keyval is not set, don't send the key value, just
the buflen data. probably used by NT5 to allocate buffer space - SK */
r_r->ptr_uni_val = include_keyval ? 1:0;
r_r->uni_val = buf;
/* if include_keyval is not set, don't send the key value, just
the buflen data. probably used by NT5 to allocate buffer space - SK */
r_r->ptr_max_len = 1;
r_r->buf_max_len = r_r->uni_val->buf_max_len;
r_r->ptr_uni_val = include_keyval ? 1:0;
r_r->uni_val = *buf;
r_r->ptr_len = 1;
r_r->buf_len = r_r->uni_val->buf_len;
r_r->ptr_max_len = 1;
r_r->buf_max_len = r_r->uni_val.buf_max_len;
r_r->status = status;
r_r->ptr_len = 1;
r_r->buf_len = r_r->uni_val.buf_len;
return True;
r_r->status = status;
return True;
}
/*******************************************************************
@ -1081,7 +1205,7 @@ BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
return False;
if(r_r->ptr_uni_val != 0) {
if(!smb_io_buffer2("uni_val", r_r->uni_val, r_r->ptr_uni_val, ps, depth))
if(!smb_io_buffer2("uni_val", &r_r->uni_val, r_r->ptr_uni_val, ps, depth))
return False;
}
@ -1144,10 +1268,16 @@ makes a structure.
void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
{
uint32 real_size;
DEBUG(8,("init_reg_r_enum_val: Enter\n"));
ZERO_STRUCTP(r_u);
/* value name */
DEBUG(10,("init_reg_r_enum_val: Valuename => [%s]\n", val->valuename));
init_uni_hdr( &r_u->hdr_name, strlen(val->valuename)+1 );
init_unistr2( &r_u->uni_name, val->valuename, strlen(val->valuename)+1 );
@ -1156,18 +1286,20 @@ void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
r_u->ptr_type = 1;
r_u->type = val->type;
/* data */
/* REG_SZ & REG_MULTI_SZ must be converted to UNICODE */
r_u->ptr_value = 1;
init_buffer2( &r_u->buf_value, val->data.void_ptr, val->size );
real_size = reg_init_buffer2( &r_u->buf_value, val );
/* lengths */
r_u->ptr1 = 1;
r_u->len_value1 = val->size;
r_u->len_value1 = real_size;
r_u->ptr2 = 1;
r_u->len_value2 = val->size;
r_u->len_value2 = real_size;
DEBUG(8,("init_reg_r_enum_val: Exit\n"));
}
/*******************************************************************

View File

@ -83,7 +83,7 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
}
/*******************************************************************
api_reg_open_khlm
api_reg_open_khu
********************************************************************/
static BOOL api_reg_open_hku(pipes_struct *p)
@ -108,6 +108,32 @@ static BOOL api_reg_open_hku(pipes_struct *p)
return True;
}
/*******************************************************************
api_reg_open_khcr
********************************************************************/
static BOOL api_reg_open_hkcr(pipes_struct *p)
{
REG_Q_OPEN_HKCR q_u;
REG_R_OPEN_HKCR r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
/* grab the reg open */
if(!reg_io_q_open_hkcr("", &q_u, data, 0))
return False;
r_u.status = _reg_open_hkcr(p, &q_u, &r_u);
if(!reg_io_r_open_hkcr("", &r_u, rdata, 0))
return False;
return True;
}
/*******************************************************************
api_reg_open_entry
@ -324,6 +350,7 @@ static struct api_struct api_reg_cmds[] =
{
{ "REG_CLOSE" , REG_CLOSE , api_reg_close },
{ "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
{ "REG_OPEN_HKCR" , REG_OPEN_HKCR , api_reg_open_hkcr },
{ "REG_OPEN_HKLM" , REG_OPEN_HKLM , api_reg_open_hklm },
{ "REG_OPEN_HKU" , REG_OPEN_HKU , api_reg_open_hku },
{ "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key },

View File

@ -78,33 +78,35 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
char *subkeyname, uint32 access_granted )
{
REGISTRY_KEY *regkey = NULL;
pstring parent_keyname;
NTSTATUS result = NT_STATUS_OK;
REGSUBKEY_CTR subkeys;
if ( parent ) {
pstrcpy( parent_keyname, parent->name );
pstrcat( parent_keyname, "\\" );
}
else
*parent_keyname = '\0';
DEBUG(7,("open_registry_key: name = [%s][%s]\n",
parent ? parent->name : "NULL", subkeyname));
DEBUG(7,("open_registry_key: name = [%s][%s]\n", parent_keyname, subkeyname));
/* All registry keys **must** have a name of non-zero length */
if (!subkeyname || !*subkeyname )
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
if ((regkey=(REGISTRY_KEY*)malloc(sizeof(REGISTRY_KEY))) == NULL)
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP( regkey );
/* copy the name */
/*
* very crazy, but regedit.exe on Win2k will attempt to call
* REG_OPEN_ENTRY with a keyname of "". We should return a new
* (second) handle here on the key->name. regedt32.exe does
* not do this stupidity. --jerry
*/
pstrcpy( regkey->name, parent_keyname );
pstrcat( regkey->name, subkeyname );
if (!subkeyname || !*subkeyname ) {
pstrcpy( regkey->name, parent->name );
}
else {
pstrcpy( regkey->name, "" );
if ( parent ) {
pstrcat( regkey->name, parent->name );
pstrcat( regkey->name, "\\" );
}
pstrcat( regkey->name, subkeyname );
}
/* Look up the table of registry I/O operations */
@ -227,7 +229,8 @@ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
if ( !key )
return False;
ZERO_STRUCTP( &val );
ZERO_STRUCTP( &values );
regval_ctr_init( &values );
@ -274,7 +277,6 @@ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
}
/*******************************************************************
reg_reply_open
********************************************************************/
NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
@ -283,7 +285,14 @@ NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *
}
/*******************************************************************
reg_reply_open
********************************************************************/
NTSTATUS _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
}
/*******************************************************************
********************************************************************/
NTSTATUS _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
@ -310,7 +319,7 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
DEBUG(5,("reg_open_entry: Enter\n"));
result = open_registry_key( p, &pol, key, name, 0x0 );
init_reg_r_open_entry( r_u, &pol, result );
@ -326,64 +335,83 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
{
NTSTATUS status = NT_STATUS_OK;
char *value = NULL;
uint32 type = 0x1; /* key type: REG_SZ */
UNISTR2 *uni_key = NULL;
BUFFER2 *buf = NULL;
fstring name;
REGISTRY_KEY *key = find_regkey_index_by_hnd( p, &q_u->pol );
NTSTATUS status = NT_STATUS_NO_SUCH_FILE;
fstring name;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
REGISTRY_VALUE *val = NULL;
REGISTRY_VALUE emptyval;
REGVAL_CTR regvals;
int i;
DEBUG(5,("_reg_info: Enter\n"));
if ( !key )
if ( !regkey )
return NT_STATUS_INVALID_HANDLE;
DEBUG(7,("_reg_info: policy key name = [%s]\n", key->name));
DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
rpcstr_pull(name, q_u->uni_type.buffer, sizeof(name), q_u->uni_type.uni_str_len*2, 0);
DEBUG(5,("reg_info: checking subkey: %s\n", name));
DEBUG(5,("reg_info: looking up value: [%s]\n", name));
uni_key = (UNISTR2 *)talloc_zero(p->mem_ctx, sizeof(UNISTR2));
buf = (BUFFER2 *)talloc_zero(p->mem_ctx, sizeof(BUFFER2));
if (!uni_key || !buf)
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP( &regvals );
regval_ctr_init( &regvals );
/* couple of hard coded registry values */
if ( strequal(name, "RefusePasswordChange") ) {
type=0xF770;
status = NT_STATUS_NO_SUCH_FILE;
init_unistr2(uni_key, "", 0);
init_buffer2(buf, (uint8*) uni_key->buffer, uni_key->uni_str_len*2);
buf->buf_max_len=4;
ZERO_STRUCTP( &emptyval );
val = &emptyval;
goto out;
}
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
value = "LanmanNT";
break;
case ROLE_STANDALONE:
value = "ServerNT";
break;
case ROLE_DOMAIN_MEMBER:
value = "WinNT";
break;
if ( strequal(name, "ProductType") ) {
/* This makes the server look like a member server to clients */
/* which tells clients that we have our own local user and */
/* group databases and helps with ACL support. */
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
regval_ctr_addvalue( &regvals, "ProductType", REG_SZ, "LanmanNT", strlen("LanmanNT")+1 );
break;
case ROLE_STANDALONE:
regval_ctr_addvalue( &regvals, "ProductType", REG_SZ, "ServerNT", strlen("ServerNT")+1 );
break;
case ROLE_DOMAIN_MEMBER:
regval_ctr_addvalue( &regvals, "ProductType", REG_SZ, "WinNT", strlen("WinNT")+1 );
break;
}
val = regval_ctr_specific_value( &regvals, 0 );
status = NT_STATUS_OK;
goto out;
}
/* This makes the server look like a member server to clients */
/* which tells clients that we have our own local user and */
/* group databases and helps with ACL support. */
/* else fall back to actually looking up the value */
for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
{
DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename));
if ( StrCaseCmp( val->valuename, name ) == 0 ) {
DEBUG(10,("_reg_info: Found match for value [%s]\n", name));
status = NT_STATUS_OK;
break;
}
free_registry_value( val );
}
init_unistr2(uni_key, value, strlen(value)+1);
init_buffer2(buf, (uint8*)uni_key->buffer, uni_key->uni_str_len*2);
out:
init_reg_r_info(q_u->ptr_buf, r_u, buf, type, status);
out:
new_init_reg_r_info(q_u->ptr_buf, r_u, val, status);
regval_ctr_destroy( &regvals );
free_registry_value( val );
DEBUG(5,("_reg_info: Exit\n"));
@ -455,7 +483,7 @@ NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u
{
NTSTATUS status = NT_STATUS_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
char *subkey;
char *subkey = NULL;
DEBUG(5,("_reg_enum_key: Enter\n"));
@ -518,7 +546,7 @@ NTSTATUS _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALU
DEBUG(5,("_reg_enum_value: Exit\n"));
done:
SAFE_FREE( val );
free_registry_value( val );
return status;
}