summaryrefslogtreecommitdiff
path: root/source3/registry
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2002-07-24 06:42:09 +0000
committerGerald Carter <jerry@samba.org>2002-07-24 06:42:09 +0000
commitc808cc3643f06c72f870d0b14a37c7a46627e2fa (patch)
treeba307c845f17a592388770b115322855d56fe888 /source3/registry
parent84f2875d7bac30e75397bbf89d3d5e79ba790ddc (diff)
downloadsamba-c808cc3643f06c72f870d0b14a37c7a46627e2fa.tar.gz
samba-c808cc3643f06c72f870d0b14a37c7a46627e2fa.tar.bz2
samba-c808cc3643f06c72f870d0b14a37c7a46627e2fa.zip
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 419d7208e8384e4ad2c4dd328ad5e630971bc76c)
Diffstat (limited to 'source3/registry')
-rw-r--r--source3/registry/reg_db.c9
-rw-r--r--source3/registry/reg_frontend.c138
-rw-r--r--source3/registry/reg_printing.c258
3 files changed, 346 insertions, 59 deletions
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c
index 714e14e48b..773a4f7fb5 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_db.c
@@ -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;
}
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index a282207376..db612709d1 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -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;
}
diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c
index f4c1feb281..d8e0f18953 100644
--- a/source3/registry/reg_printing.c
+++ b/source3/registry/reg_printing.c
@@ -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" ));
+ /* listed architectures of installed drivers */
+
+ if ( !key )
+ {
+ /* 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 */
+
+ 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 )
{
- /* listed architectures of installed drivers */
+ /* 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 );
- return 0;
+ 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: