RIP BOOL. Convert BOOL -> bool. I found a few interesting
[nivanova/samba-autobuild/.git] / source3 / registry / reg_printing.c
index f5562fcf5d86254a3519624a6b02ddf9c71adae8..47582c51f7def8d4e8ed361dc3f6bdc4cd4ae986 100644 (file)
@@ -5,7 +5,7 @@
  *
  *  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
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *  
  *  This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  *  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 02139, USA.
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /* Implementation of registry virtual views for printing information */
@@ -23,7 +22,7 @@
 #include "includes.h"
 
 #undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+#define DBGC_CLASS DBGC_REGISTRY
 
 /* registrt paths used in the print_registry[] */
 
@@ -44,9 +43,9 @@ struct reg_dyn_tree {
        
        /* callbscks for fetch/store operations */
        int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys );
-       BOOL (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys );
+       bool (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys );
        int  (*fetch_values)  ( const char *path, REGVAL_CTR *values );
-       BOOL (*store_values)  ( const char *path, REGVAL_CTR *values );
+       bool (*store_values)  ( const char *path, REGVAL_CTR *values );
 };
 
 /*********************************************************************
@@ -55,35 +54,6 @@ struct reg_dyn_tree {
  *********************************************************************
  *********************************************************************/
 
-
-/**********************************************************************
- 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 
  **********************************************************************/
@@ -108,7 +78,7 @@ static char* dos_basename ( char *path )
 
 static int key_forms_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
-       char *p = remaining_path( key + strlen(KEY_FORMS) );
+       char *p = reg_remaining_path( key + strlen(KEY_FORMS) );
        
        /* no keys below Forms */
        
@@ -205,9 +175,9 @@ static char* strip_printers_prefix( const char *key )
        /* normalizing the path does not change length, just key delimiters and case */
 
        if ( strncmp( path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS) ) == 0 )
-               subkeypath = remaining_path( key + strlen(KEY_WINNT_PRINTERS) );
+               subkeypath = reg_remaining_path( key + strlen(KEY_WINNT_PRINTERS) );
        else
-               subkeypath = remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
+               subkeypath = reg_remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
                
        return subkeypath;
 }
@@ -215,7 +185,7 @@ static char* strip_printers_prefix( const char *key )
 /*********************************************************************
  *********************************************************************/
  
-static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
        int n_services = lp_numservices();      
        int snum;
@@ -223,11 +193,11 @@ static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        int i;
        int num_subkeys = 0;
        char *printers_key;
-       char *base, *new_path;
+       char *printername, *printerdatakey;
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        fstring *subkey_names = NULL;
        
-       DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" ));
+       DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" ));
        
        printers_key = strip_printers_prefix( key );    
        
@@ -254,12 +224,26 @@ static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 
        /* get information for a specific printer */
        
-       reg_split_path( printers_key, &base, &new_path );
+       if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
+               return -1;
+       }
 
-               if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) )
-               goto done;
+       /* validate the printer name */
 
-       num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names );
+       for (snum=0; snum<n_services; snum++) {
+               if ( !lp_snum_ok(snum) || !lp_print_ok(snum) )
+                       continue;
+               if (strequal( lp_servicename(snum), printername ) )
+                       break;
+       }
+
+       if ( snum>=n_services
+               || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) 
+       {
+               return -1;
+       }
+
+       num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
        
        for ( i=0; i<num_subkeys; i++ )
                regsubkey_ctr_addkey( subkeys, subkey_names[i] );
@@ -274,21 +258,116 @@ done:
        return num_subkeys;
 }
 
+/**********************************************************************
+ Take a list of names and call add_printer_hook() if necessary
+ Note that we do this a little differently from Windows since the 
+ keyname is the sharename and not the printer name.
+ *********************************************************************/
+
+static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys )
+{
+       int i, num_keys, snum;
+       char *printername;
+       NT_PRINTER_INFO_LEVEL_2 info2;
+       NT_PRINTER_INFO_LEVEL printer;
+       
+       ZERO_STRUCT( info2 );
+       printer.info_2 = &info2;
+       
+       num_keys = regsubkey_ctr_numkeys( subkeys );
+       
+       become_root();
+       for ( i=0; i<num_keys; i++ ) {
+               printername = regsubkey_ctr_specific_key( subkeys, i );
+               snum = find_service( printername );
+               
+               /* just verify a valied snum for now */
+               if ( snum == -1 ) {
+                       fstrcpy( info2.printername, printername );
+                       fstrcpy( info2.sharename, printername );
+                       if ( !add_printer_hook( NULL, &printer ) ) {
+                               DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n",
+                                       printername));
+                       }       
+               }
+       }
+       unbecome_root();
+
+       return True;
+}
+
 /**********************************************************************
  *********************************************************************/
 
-static BOOL key_printer_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static bool key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
        char *printers_key;
+       char *printername, *printerdatakey;
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       int i, num_subkeys, num_existing_keys;
+       char *subkeyname;
+       fstring *existing_subkeys = NULL;
        
        printers_key = strip_printers_prefix( key );
        
        if ( !printers_key ) {
                /* have to deal with some new or deleted printer */
+               return add_printers_by_registry( subkeys );
+       }
+       
+       if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
                return False;
        }
+       
+       /* lookup the printer */
+       
+       if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) {
+               DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n", 
+                       printername));
+               return False;
+       }
+       
+       /* get the top level printer keys */
+       
+       num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys );
+       
+       for ( i=0; i<num_existing_keys; i++ ) {
+       
+               /* remove the key if it has been deleted */
+               
+               if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) {
+                       DEBUG(5,("key_printers_store_keys: deleting key %s\n", 
+                               existing_subkeys[i]));
+                       delete_printer_key( printer->info_2->data, existing_subkeys[i] );
+               }
+       }
 
-       return False;
+       num_subkeys = regsubkey_ctr_numkeys( subkeys );
+       for ( i=0; i<num_subkeys; i++ ) {
+               subkeyname = regsubkey_ctr_specific_key(subkeys, i);
+               /* add any missing printer keys */
+               if ( lookup_printerkey(printer->info_2->data, subkeyname) == -1 ) {
+                       DEBUG(5,("key_printers_store_keys: adding key %s\n", 
+                               existing_subkeys[i]));
+                       if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) {
+                               SAFE_FREE( existing_subkeys );
+                               return False;
+                       }
+               }
+       }
+       
+       /* write back to disk */
+       
+       mod_a_printer( printer, 2 );
+       
+       /* cleanup */
+       
+       if ( printer )
+               free_a_printer( &printer, 2 );
+
+       SAFE_FREE( existing_subkeys );
+
+       return True;
 }
 
 /**********************************************************************
@@ -302,7 +381,6 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
        UNISTR2         data;
        char            *p;
        uint32 printer_status = PRINTER_STATUS_OK;
-       int snum;
        
        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) );
@@ -354,12 +432,11 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
        /* use a prs_struct for converting the devmode and security 
           descriptor to REG_BINARY */
        
-       prs_init( &prs, MAX_PDU_FRAG_LEN, regval_ctr_getctx(values), MARSHALL);
+       prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL);
 
        /* stream the device mode */
                
-       snum = lp_servicenumber(info2->sharename);
-       if ( (devmode = construct_dev_mode( snum )) != NULL ) {                 
+       if ( (devmode = construct_dev_mode( info2->sharename )) != NULL ) {
                if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) {
                        offset = prs_offset( &prs );
                        regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
@@ -371,8 +448,11 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
                
        /* stream the printer security descriptor */
        
-       if ( info2->secdesc_buf && info2->secdesc_buf->len )  {
-               if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) {
+       if ( info2->secdesc_buf &&
+            info2->secdesc_buf->sd &&
+            info2->secdesc_buf->sd_size )  
+       {
+               if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sd, &prs, 0 ) ) {
                        offset = prs_offset( &prs );
                        regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset );
                }
@@ -386,7 +466,7 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
 /**********************************************************************
  *********************************************************************/
 
-static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
+static int key_printers_fetch_values( const char *key, REGVAL_CTR *values )
 {
        int             num_values;
        char            *printers_key;
@@ -400,13 +480,16 @@ static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
        /* top level key values stored in the registry has no values */
        
        if ( !printers_key ) {
-               /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' ket */
+               /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' key */
                return regdb_fetch_values( KEY_WINNT_PRINTERS, values );
        }
        
        /* lookup the printer object */
        
-       reg_split_path( printers_key, &printername, &printerdatakey );
+       if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
+               return -1;
+       }
+       
        if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
                goto done;
                
@@ -417,18 +500,18 @@ static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
                
        /* iterate over all printer data keys and fill the regval container */
        
-       p_data = &printer->info_2->data;
+       p_data = printer->info_2->data;
        if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1  ) {
                /* failure....should never happen if the client has a valid open handle first */
-               DEBUG(10,("key_printer_fetch_values: Unknown keyname [%s]\n", printerdatakey));
+               DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey));
                if ( printer )
                        free_a_printer( &printer, 2 );
                return -1;
        }
        
-       num_values = regval_ctr_numvals( &p_data->keys[key_index].values );     
+       num_values = regval_ctr_numvals( p_data->keys[key_index].values );      
        for ( i=0; i<num_values; i++ )
-               regval_ctr_copyvalue( values, 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:
@@ -441,20 +524,202 @@ done:
 /**********************************************************************
  *********************************************************************/
 
-static BOOL key_printer_store_values( const char *key, REGVAL_CTR *values )
+#define REG_IDX_ATTRIBUTES             1
+#define REG_IDX_PRIORITY               2
+#define REG_IDX_DEFAULT_PRIORITY       3
+#define REG_IDX_CHANGEID               4
+#define REG_IDX_STATUS                 5
+#define REG_IDX_STARTTIME              6
+#define REG_IDX_NAME                   7
+#define REG_IDX_LOCATION               8
+#define REG_IDX_DESCRIPTION            9
+#define REG_IDX_PARAMETERS             10
+#define REG_IDX_PORT                   12
+#define REG_IDX_SHARENAME              13
+#define REG_IDX_DRIVER                 14
+#define REG_IDX_SEP_FILE               15
+#define REG_IDX_PRINTPROC              16
+#define REG_IDX_DATATYPE               17
+#define REG_IDX_DEVMODE                        18
+#define REG_IDX_SECDESC                        19
+#define REG_IDX_UNTILTIME              20
+
+struct {
+       const char *name;
+       int index;      
+} printer_values_map[] = {
+       { "Attributes",         REG_IDX_ATTRIBUTES },
+       { "Priority",           REG_IDX_PRIORITY },
+       { "Default Priority",   REG_IDX_DEFAULT_PRIORITY },
+       { "ChangeID",           REG_IDX_CHANGEID },
+       { "Status",             REG_IDX_STATUS },
+       { "StartTime",          REG_IDX_STARTTIME },
+       { "UntilTime",          REG_IDX_UNTILTIME },
+       { "Name",               REG_IDX_NAME },
+       { "Location",           REG_IDX_LOCATION },
+       { "Description",        REG_IDX_DESCRIPTION },
+       { "Parameters",         REG_IDX_PARAMETERS },
+       { "Port",               REG_IDX_PORT },
+       { "Share Name",         REG_IDX_SHARENAME },
+       { "Printer Driver",     REG_IDX_DRIVER },
+       { "Separator File",     REG_IDX_SEP_FILE },
+       { "Print Processor",    REG_IDX_PRINTPROC },
+       { "Datatype",           REG_IDX_DATATYPE },
+       { "Default Devmode",    REG_IDX_DEVMODE },
+       { "Security",           REG_IDX_SECDESC },
+       { NULL, -1 }
+};
+
+
+static int find_valuename_index( const char *valuename )
+{
+       int i;
+       
+       for ( i=0; printer_values_map[i].name; i++ ) {
+               if ( strequal( valuename, printer_values_map[i].name ) )
+                       return printer_values_map[i].index;
+       }
+       
+       return -1;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static void convert_values_to_printer_info_2( NT_PRINTER_INFO_LEVEL_2 *printer2, REGVAL_CTR *values )
+{
+       int num_values = regval_ctr_numvals( values );
+       uint32 value_index;
+       REGISTRY_VALUE *val;
+       int i;
+       
+       for ( i=0; i<num_values; i++ ) {
+               val = regval_ctr_specific_value( values, i );
+               value_index = find_valuename_index( regval_name( val ) );
+               
+               switch( value_index ) {
+                       case REG_IDX_ATTRIBUTES:
+                               printer2->attributes = (uint32)(*regval_data_p(val));
+                               break;
+                       case REG_IDX_PRIORITY:
+                               printer2->priority = (uint32)(*regval_data_p(val));
+                               break;
+                       case REG_IDX_DEFAULT_PRIORITY:
+                               printer2->default_priority = (uint32)(*regval_data_p(val));
+                               break;
+                       case REG_IDX_CHANGEID:
+                               printer2->changeid = (uint32)(*regval_data_p(val));
+                               break;
+                       case REG_IDX_STARTTIME:
+                               printer2->starttime = (uint32)(*regval_data_p(val));
+                               break;
+                       case REG_IDX_UNTILTIME:
+                               printer2->untiltime = (uint32)(*regval_data_p(val));
+                               break;
+                       case REG_IDX_NAME:
+                               rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_LOCATION:
+                               rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_DESCRIPTION:
+                               rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_PARAMETERS:
+                               rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_PORT:
+                               rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_SHARENAME:
+                               rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_DRIVER:
+                               rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_SEP_FILE:
+                               rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_PRINTPROC:
+                               rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_DATATYPE:
+                               rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               break;
+                       case REG_IDX_DEVMODE:
+                               break;
+                       case REG_IDX_SECDESC:
+                               break;          
+                       default:
+                               /* unsupported value...throw away */
+                               DEBUG(8,("convert_values_to_printer_info_2: Unsupported registry value [%s]\n", 
+                                       regval_name( val ) ));
+               }
+       }
+       
+       return;
+}      
+
+/**********************************************************************
+ *********************************************************************/
+
+static bool key_printers_store_values( const char *key, REGVAL_CTR *values )
 {
        char *printers_key;
+       char *printername, *keyname;
+       NT_PRINTER_INFO_LEVEL   *printer = NULL;
+       WERROR result;
        
        printers_key = strip_printers_prefix( key );
        
        /* values in the top level key get stored in the registry */
 
        if ( !printers_key ) {
-               /* normalize on thw 'HKLM\SOFTWARE\....\Print\Printers' ket */
+               /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
                return regdb_store_values( KEY_WINNT_PRINTERS, values );
        }
        
-       return False;
+       if (!reg_split_path( printers_key, &printername, &keyname )) {
+               return False;
+       }
+
+       if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername) ) )
+               return False;
+
+       /* deal with setting values directly under the printername */
+
+       if ( !keyname ) {
+               convert_values_to_printer_info_2( printer->info_2, values );
+       }
+       else {
+               int num_values = regval_ctr_numvals( values );
+               int i;
+               REGISTRY_VALUE *val;
+               
+               delete_printer_key( printer->info_2->data, keyname );
+               
+               /* deal with any subkeys */
+               for ( i=0; i<num_values; i++ ) {
+                       val = regval_ctr_specific_value( values, i );
+                       result = set_printer_dataex( printer, keyname, 
+                               regval_name( val ),
+                               regval_type( val ),
+                               regval_data_p( val ),
+                               regval_size( val ) );
+                       if ( !W_ERROR_IS_OK(result) ) {
+                               DEBUG(0,("key_printers_store_values: failed to set printer data [%s]!\n",
+                                       keyname));
+                               free_a_printer( &printer, 2 );
+                               return False;
+                       }
+               }
+       }
+
+       result = mod_a_printer( printer, 2 );
+
+       free_a_printer( &printer, 2 );
+
+       return W_ERROR_IS_OK(result);
 }
 
 /*********************************************************************
@@ -483,7 +748,7 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 
        DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" ));
        
-       keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) );      
+       keystr = reg_remaining_path( key + strlen(KEY_ENVIRONMENTS) );  
        
        /* list all possible architectures */
        
@@ -498,7 +763,9 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        
        pstrcpy( key2, keystr );
        keystr = key2;
-       reg_split_path( keystr, &base, &subkeypath );
+       if (!reg_split_path( keystr, &base, &subkeypath )) {
+               return -1;
+       }
        
        /* sanity check */
        
@@ -521,7 +788,9 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        /* more of the key path to process */
        
        keystr = subkeypath;
-       reg_split_path( keystr, &base, &subkeypath );   
+       if (!reg_split_path( keystr, &base, &subkeypath )) {
+               return -1;
+       }
                
        /* ...\Print\Environements\...\Drivers\ */
        
@@ -553,7 +822,9 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 
        if ( strequal(base, "Print Processors") ) {
                keystr = subkeypath;
-               reg_split_path( keystr, &base, &subkeypath );
+               if (!reg_split_path( keystr, &base, &subkeypath )) {
+                       return -1;
+               }
 
                /* no subkeys below this point */
 
@@ -568,7 +839,10 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        /* only dealing with drivers from here on out */
 
        keystr = subkeypath;
-       reg_split_path( keystr, &base, &subkeypath );
+       if (!reg_split_path( keystr, &base, &subkeypath )) {
+               return -1;
+       }
+
        version = atoi(&base[strlen(base)-1]);
                        
        switch (env_index) {
@@ -606,7 +880,6 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL_CTR *values )
 {
        char *buffer = NULL;
-       char *buffer2 = NULL;
        int buffer_size = 0;
        int i, length;
        char *filename;
@@ -651,10 +924,10 @@ static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL
                        
                        length = strlen(filename);
                
-                       buffer2 = SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) );
-                       if ( !buffer2 )
+                       buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) );
+                       if ( !buffer ) {
                                break;
-                       buffer = buffer2;
+                       }
                        
                        init_unistr2( &data, filename, UNI_STR_TERMINATE);
                        memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
@@ -664,12 +937,10 @@ static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL
                
                /* terminated by double NULL.  Add the final one here */
                
-               buffer2 = SMB_REALLOC( buffer, buffer_size + 2 );
-               if ( !buffer2 ) {
-                       SAFE_FREE( buffer );
+               buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 );
+               if ( !buffer ) {
                        buffer_size = 0;
                } else {
-                       buffer = buffer2;
                        buffer[buffer_size++] = '\0';
                        buffer[buffer_size++] = '\0';
                }
@@ -694,7 +965,9 @@ static int driver_arch_fetch_values( char *key, REGVAL_CTR *values )
        NT_PRINTER_DRIVER_INFO_LEVEL    driver_ctr;
        WERROR          w_result;
 
-       reg_split_path( key, &base, &subkeypath );
+       if (!reg_split_path( key, &base, &subkeypath )) {
+               return -1;
+       }
        
        /* no values in 'Environments\Drivers\Windows NT x86' */
        
@@ -711,7 +984,9 @@ static int driver_arch_fetch_values( char *key, REGVAL_CTR *values )
        fstrcpy( arch_environment, base );
        
        keystr = subkeypath;
-       reg_split_path( keystr, &base, &subkeypath );
+       if (!reg_split_path( keystr, &base, &subkeypath )) {
+               return -1;
+       }
 
        if ( strequal(base, "Print Processors") )
                return 0;
@@ -728,7 +1003,9 @@ static int driver_arch_fetch_values( char *key, REGVAL_CTR *values )
           The subkey name has to be Version-XX */
        
        keystr = subkeypath;
-       reg_split_path( keystr, &base, &subkeypath );
+       if (!reg_split_path( keystr, &base, &subkeypath )) {
+               return -1;
+       }
 
        if ( !subkeypath )
                return 0;
@@ -738,7 +1015,9 @@ static int driver_arch_fetch_values( char *key, REGVAL_CTR *values )
        /* BEGIN PRINTER DRIVER NAME BLOCK */
        
        keystr = subkeypath;
-       reg_split_path( keystr, &base, &subkeypath );
+       if (!reg_split_path( keystr, &base, &subkeypath )) {
+               return -1;
+       }
        
        /* don't go any deeper for now */
        
@@ -773,7 +1052,7 @@ static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
 
        /* no values in the Environments key */
        
-       if ( !(keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) )) )
+       if ( !(keystr = reg_remaining_path( key + strlen(KEY_ENVIRONMENTS) )) )
                return 0;
        
        pstrcpy( subkey, keystr);
@@ -827,10 +1106,10 @@ static struct reg_dyn_tree print_registry[] = {
        &key_forms_fetch_values,
        NULL },
 { KEY_CONTROL_PRINTERS, 
-       &key_printer_fetch_keys,
-       &key_printer_store_keys,
-       &key_printer_fetch_values,
-       &key_printer_store_values },
+       &key_printers_fetch_keys,
+       &key_printers_store_keys,
+       &key_printers_fetch_values,
+       &key_printers_store_values },
 { KEY_ENVIRONMENTS,
        &key_driver_fetch_keys,
        NULL,
@@ -842,10 +1121,10 @@ static struct reg_dyn_tree print_registry[] = {
        NULL,
        NULL },
 { KEY_WINNT_PRINTERS,
-       &key_printer_fetch_keys,
-       &key_printer_store_keys,
-       &key_printer_fetch_values,
-       &key_printer_store_values },
+       &key_printers_fetch_keys,
+       &key_printers_store_keys,
+       &key_printers_fetch_values,
+       &key_printers_store_values },
 { KEY_PORTS,
        &regdb_fetch_keys, 
        &regdb_store_keys,
@@ -905,7 +1184,7 @@ static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
 /**********************************************************************
  *********************************************************************/
 
-static BOOL regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
        int i = match_registry_path( key );
        
@@ -940,7 +1219,7 @@ static int regprint_fetch_reg_values( const char *key, REGVAL_CTR *values )
 /**********************************************************************
  *********************************************************************/
 
-static BOOL regprint_store_reg_values( const char *key, REGVAL_CTR *values )
+static bool regprint_store_reg_values( const char *key, REGVAL_CTR *values )
 {
        int i = match_registry_path( key );
        
@@ -962,7 +1241,7 @@ REGISTRY_OPS printing_ops = {
        regprint_fetch_reg_values,
        regprint_store_reg_keys,
        regprint_store_reg_values,
-       NULL
+       NULL, NULL, NULL
 };