r8066: * had to modify the printer data storage slightly in ntprinters.tdb
authorGerald Carter <jerry@samba.org>
Sat, 2 Jul 2005 01:23:21 +0000 (01:23 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:58:10 +0000 (10:58 -0500)
  when packing values.  It is a compatible change though and will
  not require a tdb version upgrade
* Can successfully create new printer subkeys via winreg that
  are immediately available via spoolss calls.  Still cannot delete
  keys yet though.  That comes next.

source/printing/nt_printing.c
source/registry/reg_printing.c
source/rpc_server/srv_spoolss_nt.c

index dc74f885226fcfdcb0b910f6b4d1a5a82c1a29aa..47e0af963344d7e7ed57e89f4206fbb85652cd50 100644 (file)
@@ -2125,8 +2125,17 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
        for ( i=0; i<data->num_keys; i++ ) {    
                val_ctr = &data->keys[i].values;
                num_values = regval_ctr_numvals( val_ctr );
+
+               /* pack the keyname followed by a empty value */
+
+               len += tdb_pack(buf+len, buflen-len, "pPdB", 
+                               &data->keys[i].name,
+                               data->keys[i].name, 
+                               REG_NONE,
+                               0,
+                               NULL);
                
-               /* loop over all values */
+               /* now loop over all values */
                
                for ( j=0; j<num_values; j++ ) {
                        /* pathname should be stored as <key>\<value> */
@@ -2520,7 +2529,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
  Allocate and initialize a new slot.
 ***************************************************************************/
  
-static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
+int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
 {
        NT_PRINTER_KEY  *d;
        int             key_index;
@@ -2530,9 +2539,12 @@ static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
        
        /* allocate another slot in the NT_PRINTER_KEY array */
        
-       d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1);
-       if ( d )
-               data->keys = d;
+       if ( !(d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
+               DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
+               return -1;
+       }
+
+       data->keys = d;
        
        key_index = data->num_keys;
        
@@ -2579,7 +2591,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
 /****************************************************************************
  ***************************************************************************/
 
-uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
+int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
 {
        int     i, j;
        int     key_len;
@@ -2590,14 +2602,42 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su
        
        if ( !data )
                return 0;
+
+       if ( !key )
+               return -1;
+
+       /* special case of asking for the top level printer data registry key names */
+
+       if ( strlen(key) == 0 ) {
+               for ( i=0; i<data->num_keys; i++ ) {
+               
+                       /* found a match, so allocate space and copy the name */
+                       
+                       if ( !(ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
+                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 
+                                       num_subkeys+1));
+                               SAFE_FREE( subkeys );
+                               return -1;
+                       }
+                       
+                       subkeys_ptr = ptr;
+                       fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
+                       num_subkeys++;
+               }
+
+               goto done;
+       }
                
+       /* asking for the subkeys of some key */
+       /* subkey paths are stored in the key name using '\' as the delimiter */
+
        for ( i=0; i<data->num_keys; i++ ) {
                if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
-                       /* match sure it is a subkey and not the key itself */
                        
+                       /* if we found the exact key, then break */
                        key_len = strlen( key );
                        if ( strlen(data->keys[i].name) == key_len )
-                               continue;
+                               break;
                        
                        /* get subkey path */
 
@@ -2634,7 +2674,13 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su
                
        }
        
-       /* tag of the end */
+       /* return error if the key was not found */
+       
+       if ( i == data->num_keys )
+               return -1;
+       
+done:
+       /* tag off the end */
        
        if (num_subkeys)
                fstrcpy(subkeys_ptr[num_subkeys], "" );
@@ -3275,6 +3321,15 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
                                  &type,
                                  &size,
                                  &data_p);
+
+               /* lookup for subkey names which have a type of REG_NONE */
+               /* there's no data with this entry */
+
+               if ( type == REG_NONE ) {
+                       if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
+                               add_new_printer_key( printer_data, string );
+                       continue;
+               }
        
                /*
                 * break of the keyname from the value name.  
index f5562fcf5d86254a3519624a6b02ddf9c71adae8..09a0dd0c34698a7d973c9296839876c20c8fbe4f 100644 (file)
@@ -215,7 +215,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 +223,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 +254,12 @@ 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 );
+       reg_split_path( printers_key, &printername, &printerdatakey );
 
-               if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) )
+       if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
                goto done;
 
-       num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names );
+       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] );
@@ -277,18 +277,59 @@ done:
 /**********************************************************************
  *********************************************************************/
 
-static BOOL key_printer_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static BOOL add_printers_by_registry( REGSUBKEY_CTR *subkeys )
+{
+       return False;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+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;
+       char *subkeyname;
        
        printers_key = strip_printers_prefix( key );
        
        if ( !printers_key ) {
                /* have to deal with some new or deleted printer */
+               return add_printers_by_registry( subkeys );
+       }
+       
+       reg_split_path( printers_key, &printername, &printerdatakey );
+       
+       /* 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;
        }
 
-       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 ) {
+                       if ( add_new_printer_key( &printer->info_2->data, subkeyname ) == -1 ) 
+                               return False;
+               }
+       }
+       
+       /* write back to disk */
+       
+       mod_a_printer( printer, 2 );
+       
+       /* cleanup */
+       
+       if ( printer )
+               free_a_printer( &printer, 2 );
+
+       return True;
 }
 
 /**********************************************************************
@@ -386,7 +427,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;
@@ -420,7 +461,7 @@ static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
        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;
@@ -441,7 +482,7 @@ done:
 /**********************************************************************
  *********************************************************************/
 
-static BOOL key_printer_store_values( const char *key, REGVAL_CTR *values )
+static BOOL key_printers_store_values( const char *key, REGVAL_CTR *values )
 {
        char *printers_key;
        
@@ -827,10 +868,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 +883,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,
index 12e8e2bd414f9f3a016ecc667608d540e442bb8d..19ef3700e6dbc3ef938ba2858185916d959f7d71 100644 (file)
@@ -583,7 +583,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
                
                DEBUGADD(10, ("printername: %s\n", printername));
                
-                       free_a_printer( &printer, 2);
+               free_a_printer( &printer, 2);
        }
 
        if ( !found ) {