r8026: * more fixes to the printing registry interface
authorGerald Carter <jerry@samba.org>
Thu, 30 Jun 2005 19:43:53 +0000 (19:43 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:58:09 +0000 (10:58 -0500)
  (still not completely back to the read functionality
  we previously had but the cleanup is progressing)
(This used to be commit 04431372a698433b4936392047228908a64ff382)

source3/include/rpc_reg.h
source3/registry/reg_db.c
source3/registry/reg_printing.c

index a35e534952e96d01da1b933b14e22518ac8a9574..bbbb1acf8c1ed45574f5a402911bf3b937a47a3e 100644 (file)
@@ -64,7 +64,7 @@
 #define KEY_HKU                        "HKU"
 #define KEY_HKCR               "HKCR"
 #define KEY_PRINTING           "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
-#define KEY_PRINTING_2K                "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
+#define KEY_PRINTING_2K                "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"
 #define KEY_PRINTING_PORTS     "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports"
 #define KEY_EVENTLOG           "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Eventlog"
 #define KEY_SHARES             "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares"
index ce9d68a26431af9e4ed709cdd6c55760d1169556..4bb605ade015734758ce5c5c6152a55a9762b59a 100644 (file)
@@ -40,12 +40,12 @@ static TDB_CONTEXT *tdb_reg;
    KEY_PRINTING_2K in include/rpc_reg.h)   --jerry */
 
 static const char *builtin_registry_paths[] = {
-       "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print",
-       "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports",
-       "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print",
+       KEY_PRINTING_2K,
+       KEY_PRINTING_PORTS,
+       KEY_PRINTING,
+       KEY_SHARES,
+       KEY_EVENTLOG,
        "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
-       "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares",
-       "HKLM\\SYSTEM\\CurrentControlSet\\Services\\EventLog",
        "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
        "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters",
        "HKU",
index c5898f8e7550f3f4c0fd321de621e482d872b7a6..8a0557125c3af2840a55076fc47d5084f7a22912 100644 (file)
@@ -30,8 +30,6 @@
 #define KEY_MONITORS           "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS"
 #define KEY_FORMS              "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"
 #define KEY_CONTROL_PRINTERS   "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
-#define KEY_DRIVERS            "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS/.../DRIVERS"
-#define KEY_PRINTPROC          "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS/.../PRINTPROC"
 #define KEY_ENVIRONMENTS       "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"
 #define KEY_CONTROL_PRINT      "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"
 #define KEY_WINNT_PRINTERS     "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
@@ -51,28 +49,157 @@ struct reg_dyn_tree {
        BOOL (*store_values)  ( const char *path, REGVAL_CTR *values );
 };
 
-#if 0  /* UNUSED */
 
 /**********************************************************************
- handle enumeration of subkeys below KEY_PRINTING\Printers
- *********************************************************************/
+ move to next non-delimter character
+*********************************************************************/
+
+static char* remaining_path( const char *key )
+{
+       static pstring new_path;
+       char *p;
+       
+       if ( !key || !*key )
+               return NULL;
+
+       pstrcpy( new_path, key );
+       /* normalize_reg_path( new_path ); */
+       
+       if ( !(p = strchr( new_path, '\\' )) ) 
+       {
+               if ( !(p = strchr( new_path, '/' )) )
+                       p = new_path;
+               else 
+                       p++;
+       }
+       else
+               p++;
+               
+       return p;
+}
+
+/***********************************************************************
+ simple function to prune a pathname down to the basename of a file 
+ **********************************************************************/
  
-static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys )
+static char* dos_basename ( char *path )
+{
+       char *p;
+       
+       if ( !(p = strrchr( path, '\\' )) )
+               p = path;
+       else
+               p++;
+               
+       return p;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static int key_forms_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
+{
+       char *p = remaining_path( key + strlen(KEY_FORMS) );
+       
+       /* no keys below Forms */
+       
+       if ( p )
+               return -1;
+               
+       return 0;
+}
+
+static int key_forms_fetch_values( const char *key, REGVAL_CTR *values )
+{
+       uint32          data[8];
+       int             i, num_values, form_index = 1;
+       nt_forms_struct *forms_list = NULL;
+       nt_forms_struct *form;
+               
+       DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
+       
+       num_values = get_ntforms( &forms_list );
+               
+       DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n",
+               num_values));
+
+       /* handle user defined forms */
+                               
+       for ( i=0; i<num_values; i++ ) {
+               form = &forms_list[i];
+                       
+               data[0] = form->width;
+               data[1] = form->length;
+               data[2] = form->left;
+               data[3] = form->top;
+               data[4] = form->right;
+               data[5] = form->bottom;
+               data[6] = form_index++;
+               data[7] = form->flag;
+                       
+               regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );       
+       }
+               
+       SAFE_FREE( forms_list );
+       forms_list = NULL;
+               
+       /* handle built-on forms */
+               
+       num_values = get_builtin_ntforms( &forms_list );
+               
+       DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n",
+               num_values));
+                       
+       for ( i=0; i<num_values; i++ ) {
+               form = &forms_list[i];
+                       
+               data[0] = form->width;
+               data[1] = form->length;
+               data[2] = form->left;
+               data[3] = form->top;
+               data[4] = form->right;
+               data[5] = form->bottom;
+               data[6] = form_index++;
+               data[7] = form->flag;
+                                       
+               regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );
+       }
+               
+       SAFE_FREE( forms_list );
+       
+       return regval_ctr_numvals( values );
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
        int n_services = lp_numservices();      
        int snum;
        fstring sname;
        int i;
        int num_subkeys = 0;
-       char *keystr, *key2 = NULL;
+       char *keystr;
        char *base, *new_path;
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        fstring *subkey_names = NULL;
+       pstring path;
        
        DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" ));
        
-       if ( !key )
-       {
+       pstrcpy( path, key );
+       normalize_reg_path( path );
+
+       /* normalizing the path does not change length, just key delimiters and case */
+
+       if ( strncmp( path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS) ) == 0 )
+               keystr = remaining_path( key + strlen(KEY_WINNT_PRINTERS) );
+       else
+               keystr = remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
+       
+       
+       if ( !keystr ) {
                /* enumerate all printers */
                
                for (snum=0; snum<n_services; snum++) {
@@ -95,8 +222,6 @@ static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys )
 
        /* get information for a specific printer */
        
-       key2 = SMB_STRDUP( key );
-       keystr = key2;
        reg_split_path( keystr, &base, &new_path );
 
                if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) )
@@ -112,17 +237,17 @@ static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys )
        /* no other subkeys below here */
 
 done:  
-       SAFE_FREE( key2 );
        SAFE_FREE( subkey_names );
        
        return num_subkeys;
 }
 
-/**********************************************************************
- handle enumeration of values below KEY_PRINTING\Printers
- *********************************************************************/
-static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
+static BOOL key_printer_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
+{
+       return True;
+}
+
+static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
 {
        int             num_values = 0;
        char            *keystr, *key2 = NULL;
@@ -137,6 +262,7 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
        NT_PRINTER_DATA *p_data;
        int             i, key_index;
        UNISTR2         data;
+       pstring         path;
        
        /* 
         * Theres are tw cases to deal with here
@@ -144,12 +270,22 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
         * (2) enumeration of the PrinterDriverData subney
         */
         
-       if ( !key ) {
+       pstrcpy( path, key );
+       normalize_reg_path( path );
+
+       /* normalizing the path does not change length, just key delimiters and case */
+
+       if ( strncmp( path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS) ) == 0 )
+               keystr = remaining_path( key + strlen(KEY_WINNT_PRINTERS) );
+       else
+               keystr = remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
+       
+       if ( !keystr ) {
                /* top level key has no values */
                goto done;
        }
        
-       key2 = SMB_STRDUP( key );
+       key2 = SMB_STRDUP( keystr );
        keystr = key2;
        reg_split_path( keystr, &base, &new_path );
        
@@ -167,16 +303,16 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
                info2 = printer->info_2;
                
 
-               regval_ctr_addvalue( val, "Attributes",       REG_DWORD, (char*)&info2->attributes,       sizeof(info2->attributes) );
-               regval_ctr_addvalue( val, "Priority",         REG_DWORD, (char*)&info2->priority,         sizeof(info2->attributes) );
-               regval_ctr_addvalue( val, "ChangeID",         REG_DWORD, (char*)&info2->changeid,         sizeof(info2->changeid) );
-               regval_ctr_addvalue( val, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
+               regval_ctr_addvalue( values, "Attributes",       REG_DWORD, (char*)&info2->attributes,       sizeof(info2->attributes) );
+               regval_ctr_addvalue( values, "Priority",         REG_DWORD, (char*)&info2->priority,         sizeof(info2->attributes) );
+               regval_ctr_addvalue( values, "ChangeID",         REG_DWORD, (char*)&info2->changeid,         sizeof(info2->changeid) );
+               regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
 
                /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */
-               regval_ctr_addvalue( val, "Status",           REG_DWORD, (char*)&printer_status,          sizeof(info2->status) );
+               regval_ctr_addvalue( values, "Status",           REG_DWORD, (char*)&printer_status,          sizeof(info2->status) );
 
-               regval_ctr_addvalue( val, "StartTime",        REG_DWORD, (char*)&info2->starttime,        sizeof(info2->starttime) );
-               regval_ctr_addvalue( val, "UntilTime",        REG_DWORD, (char*)&info2->untiltime,        sizeof(info2->untiltime) );
+               regval_ctr_addvalue( values, "StartTime",        REG_DWORD, (char*)&info2->starttime,        sizeof(info2->starttime) );
+               regval_ctr_addvalue( values, "UntilTime",        REG_DWORD, (char*)&info2->untiltime,        sizeof(info2->untiltime) );
 
                /* strip the \\server\ from this string */
                if ( !(p = strrchr( info2->printername, '\\' ) ) )
@@ -184,40 +320,40 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
                else
                        p++;
                init_unistr2( &data, p, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, info2->location, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, info2->comment, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Print Processor",  REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Print Processor",  REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                init_unistr2( &data, "RAW", UNI_STR_TERMINATE);
-               regval_ctr_addvalue( val, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+               regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
                
                /* use a prs_struct for converting the devmode and security 
                   descriptor to REG_BINARY */
                
-               prs_init( &prs, MAX_PDU_FRAG_LEN, regval_ctr_getctx(val), MARSHALL);
+               prs_init( &prs, MAX_PDU_FRAG_LEN, regval_ctr_getctx(values), MARSHALL);
 
                /* stream the device mode */
                
@@ -228,7 +364,7 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
                        
                                offset = prs_offset( &prs );
                                
-                               regval_ctr_addvalue( val, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
+                               regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
                        }
                        
                        
@@ -243,13 +379,13 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
                        
                                offset = prs_offset( &prs );
                        
-                               regval_ctr_addvalue( val, "Security", REG_BINARY, prs_data_p(&prs), offset );
+                               regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset );
                        }
                }
 
                prs_mem_free( &prs );
                
-               num_values = regval_ctr_numvals( val ); 
+               num_values = regval_ctr_numvals( values );      
                
                goto done;
                
@@ -264,14 +400,14 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
        
        p_data = &printer->info_2->data;
        if ( (key_index = lookup_printerkey( p_data, new_path )) == -1  ) {
-               DEBUG(10,("print_subpath_values_printer: Unknown keyname [%s]\n", new_path));
+               DEBUG(10,("key_printer_fetch_values: Unknown keyname [%s]\n", new_path));
                goto done;
        }
        
        num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
        
        for ( i=0; i<num_values; i++ )
-               regval_ctr_copyvalue( val, regval_ctr_specific_value(&p_data->keys[key_index].values, i) );
+               regval_ctr_copyvalue( values, regval_ctr_specific_value(&p_data->keys[key_index].values, i) );
                        
 
 done:
@@ -283,255 +419,6 @@ done:
        return num_values;
 }
 
-/**********************************************************************
- Routine to handle enumeration of subkeys and values 
- below KEY_PRINTING (depending on whether or not subkeys/val are 
- valid pointers. 
- *********************************************************************/
-static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys, REGVAL_CTR *val )
-{
-       int result = 0;
-       char *p, *base;
-       int i;
-       
-       DEBUG(10,("handle_printing_subpath: key=>[%s]\n", key ));
-       
-       /* 
-        * break off the first part of the path 
-        * topmost base **must** be one of the strings 
-        * in top_level_keys[]
-        */
-       
-       reg_split_path( key, &base, &p);
-               
-       for ( i=0; i<MAX_TOP_LEVEL_KEYS; i++ ) {
-               if ( StrCaseCmp( top_level_keys[i], base ) == 0 )
-                       break;
-       }
-       
-       DEBUG(10,("handle_printing_subpath: base=>[%s], i==[%d]\n", base, i));  
-               
-       if ( !(i < MAX_TOP_LEVEL_KEYS) )
-               return -1;
-                                               
-       /* Call routine to handle each top level key */
-       switch ( i )
-       {
-               case KEY_INDEX_ENVIR:
-                       if ( subkeys )
-                               print_subpath_environments( p, subkeys );
-                       if ( val )
-                               print_subpath_values_environments( p, val );
-                       break;
-               
-               case KEY_INDEX_FORMS:
-                       if ( subkeys )
-                               print_subpath_forms( p, subkeys );
-                       if ( val )
-                               print_subpath_values_forms( p, val );
-                       break;
-                       
-               case KEY_INDEX_PRINTER:
-                       if ( subkeys )
-                               print_subpath_printers( p, subkeys );
-                       if ( val )
-                               print_subpath_values_printers( p, val );
-                       break;
-       
-               /* default case for top level key that has no handler */
-               
-               default:
-                       break;
-       }
-       
-       
-       
-       return result;
-
-}
-
-/**********************************************************************
- Enumerate registry subkey names given a registry path.  
- Caller is responsible for freeing memory to **subkeys
- *********************************************************************/
-static int printing_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr )
-{
-       char            *path;
-       int             num_subkeys = 0;
-       
-       DEBUG(10,("printing_subkey_info: key=>[%s]\n", key));
-       
-       path = trim_reg_path( key );
-       
-       /* check to see if we are dealing with the top level key */
-       
-       if ( path ) {
-               num_subkeys = handle_printing_subpath( path, subkey_ctr, NULL );
-               SAFE_FREE( path );
-               return num_subkeys;
-       }
-       
-       /* handle top level keys here */
-               
-       if ( strequal( KEY_PRINTING, key ) ) {
-               regsubkey_ctr_addkey( subkey_ctr, "Environments" );
-               regsubkey_ctr_addkey( subkey_ctr, "Forms" );
-       }
-       else if ( strequal( KEY_PRINTING_2K, key ) ) {
-               regsubkey_ctr_addkey( subkey_ctr, "Printers" );
-       }
-
-       return num_subkeys;
-}
-
-#endif /* UNUSED */
-
-/**********************************************************************
- move to next non-delimter character
-*********************************************************************/
-
-static char* remaining_path( const char *key )
-{
-       static pstring new_path;
-       char *p;
-       
-       if ( !key || !*key )
-               return NULL;
-
-       pstrcpy( new_path, key );
-       normalize_reg_path( new_path );
-       
-       p = strchr( new_path, '/' );
-       
-       if ( p )
-               p++;
-       else
-               p = new_path;
-               
-       return p;
-}
-
-/***********************************************************************
- 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;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static int key_forms_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
-{
-       return 0;
-}
-
-static BOOL key_forms_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
-{
-       return True;
-}
-
-static int key_forms_fetch_values( const char *key, REGVAL_CTR *values )
-{
-       int             num_values = 0;
-       uint32          data[8];
-       int             form_index = 1;
-       int i;
-       
-       DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
-       
-       nt_forms_struct *forms_list = NULL;
-       nt_forms_struct *form = NULL;
-               
-       if ( (num_values = get_ntforms( &forms_list )) == 0 ) 
-               return 0;
-               
-       DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n",
-               num_values));
-
-       /* handle user defined forms */
-                               
-       for ( i=0; i<num_values; i++ ) {
-               form = &forms_list[i];
-                       
-               data[0] = form->width;
-               data[1] = form->length;
-               data[2] = form->left;
-               data[3] = form->top;
-               data[4] = form->right;
-               data[5] = form->bottom;
-               data[6] = form_index++;
-               data[7] = form->flag;
-                       
-               regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );       
-       }
-               
-       SAFE_FREE( forms_list );
-       forms_list = NULL;
-               
-       /* handle built-on forms */
-               
-       if ( (num_values = get_builtin_ntforms( &forms_list )) == 0 ) 
-               return 0;
-               
-       DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n",
-               num_values));
-                       
-       for ( i=0; i<num_values; i++ ) {
-               form = &forms_list[i];
-                       
-               data[0] = form->width;
-               data[1] = form->length;
-               data[2] = form->left;
-               data[3] = form->top;
-               data[4] = form->right;
-               data[5] = form->bottom;
-               data[6] = form_index++;
-               data[7] = form->flag;
-                                       
-               regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );
-       }
-               
-       SAFE_FREE( forms_list );
-       
-       return regval_ctr_numvals( values );
-}
-
-static BOOL key_forms_store_values( const char *key, REGVAL_CTR *values )
-{
-       return True;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
-{
-       return 0;
-}
-
-static BOOL key_printer_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
-{
-       return True;
-}
-
-static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
-{
-       return 0;
-}
-
 static BOOL key_printer_store_values( const char *key, REGVAL_CTR *values )
 {
        return True;
@@ -561,11 +448,13 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        int env_subkey_type = 0;
        int version;
 
-       DEBUG(10,("print_subpath_environments: key=>[%s]\n", key ? key : "NULL" ));
+       DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" ));
+       
+       keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) );      
        
        /* list all possible architectures */
        
-       if ( !key ) {
+       if ( !keystr ) {
                for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ ) 
                        regsubkey_ctr_addkey( subkeys,  environments[num_subkeys] );
 
@@ -574,7 +463,7 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        
        /* we are dealing with a subkey of "Environments */
        
-       pstrcpy( key2, key );
+       pstrcpy( key2, keystr );
        keystr = key2;
        reg_split_path( keystr, &base, &subkeypath );
        
@@ -672,7 +561,7 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        
        /* if anything else left, just say if has no subkeys */
        
-       DEBUG(1,("print_subpath_environments: unhandled key [%s] (subkey == %s\n", 
+       DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s\n", 
                key, subkeypath ));
        
        return 0;
@@ -703,8 +592,10 @@ static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
        
        
        DEBUG(8,("print_subpath_values_environments: Enter key => [%s]\n", key ? key : "NULL"));
+
+       keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) );      
        
-       if ( !key )
+       if ( !keystr )
                return 0;
                
        /* The only keys below KEY_PRINTING\Environments is the 
@@ -712,7 +603,7 @@ static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
        
        /* environment */
        
-       pstrcpy( key2, key );
+       pstrcpy( key2, keystr);
        keystr = key2;
        reg_split_path( keystr, &base, &subkeypath );
        if ( !subkeypath ) 
@@ -858,14 +749,15 @@ static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 }
 
 /**********************************************************************
+ If I can get rid of the 'enumports command', this code becomes 
+ a tdb lookup.
  *********************************************************************/
 
 static int key_ports_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
-       char *p = remaining_path( key + strlen(KEY_PORTS) );
-       
        /* no keys below ports */
-       if ( p )
+       
+       if ( remaining_path( key + strlen(KEY_PORTS) ) )
                return -1;
                
        return 0;
@@ -910,7 +802,7 @@ static BOOL key_ports_store_values( const char *key, REGVAL_CTR *values )
  *********************************************************************/
 
 static struct reg_dyn_tree print_registry[] = {
-/* just pass the monitor onto the regostry tdb */
+/* just pass the monitor onto the registry tdb */
 { KEY_MONITORS,
        &regdb_fetch_keys, 
        &regdb_store_keys,
@@ -918,9 +810,9 @@ static struct reg_dyn_tree print_registry[] = {
        &regdb_store_values },
 { KEY_FORMS, 
        &key_forms_fetch_keys, 
-       &key_forms_store_keys
+       NULL
        &key_forms_fetch_values,
-       &key_forms_store_values },
+       NULL },
 { KEY_CONTROL_PRINTERS, 
        &key_printer_fetch_keys,
        &key_printer_store_keys,
@@ -941,11 +833,6 @@ static struct reg_dyn_tree print_registry[] = {
        &key_printer_store_keys,
        &key_printer_fetch_values,
        &key_printer_store_values },
-{ KEY_WINNT_PRINT,
-       &key_print_fetch_keys,
-       NULL,
-       NULL,
-       NULL },
 { KEY_PORTS,
        &key_ports_fetch_keys,
        &key_ports_store_keys,