From c296f858ef61acd6c749db768670453f436f78f2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 2 Jul 2005 01:23:21 +0000 Subject: r8066: * had to modify the printer data storage slightly in ntprinters.tdb 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. (This used to be commit 00bce2b3bb78a44842a258b1737076281297d247) --- source3/printing/nt_printing.c | 73 +++++++++++++++++++++++++++++----- source3/registry/reg_printing.c | 79 ++++++++++++++++++++++++++++--------- source3/rpc_server/srv_spoolss_nt.c | 2 +- 3 files changed, 125 insertions(+), 29 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index dc74f88522..47e0af9633 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2125,8 +2125,17 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen) for ( i=0; inum_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\ */ @@ -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; inum_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; inum_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. diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c index f5562fcf5d..09a0dd0c34 100644 --- a/source3/registry/reg_printing.c +++ b/source3/registry/reg_printing.c @@ -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; iinfo_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, ®db_fetch_keys, ®db_store_keys, diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 12e8e2bd41..19ef3700e6 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -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 ) { -- cgit