From 50d224a898fa130460bba4009e18fb54b1390168 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 18 Aug 2002 11:11:48 +0000 Subject: fix to allow EnumPrinterKey() to enumerate multiple levels of subkeys. Works on the top level. Needs more testing for levels > 1. (This used to be commit 32a7083843f2bf9a3f32027189dbb0ff92927cd4) --- source3/printing/nt_printing.c | 67 +++++++++++++++++++++++++--- source3/registry/reg_frontend.c | 3 +- source3/rpc_server/srv_spoolss_nt.c | 87 +++++++++++++++---------------------- 3 files changed, 99 insertions(+), 58 deletions(-) (limited to 'source3') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 3b85fce020..d51d3bc1bb 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2407,7 +2407,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, char *name ) for ( i=0; inum_keys; i++ ) { - if ( strcmp(data->keys[i].name, name) == 0 ) { + if ( strequal(data->keys[i].name, name) ) { DEBUG(12,("lookup_printerkey: Found [%s]!\n", name)); key_index = i; break; @@ -2418,6 +2418,66 @@ int lookup_printerkey( NT_PRINTER_DATA *data, char *name ) return key_index; } +/**************************************************************************** + ***************************************************************************/ + +uint32 get_printer_subkeys( NT_PRINTER_DATA *data, char* key, fstring **subkeys ) +{ + int i; + int key_len; + int num_subkeys = 0; + char *p; + fstring *ptr, *subkeys_ptr = NULL; + + if ( !data ) + return 0; + + 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 */ + + key_len = strlen( key ); + if ( strlen(data->keys[i].name) == key_len ) + continue; + + /* get subkey path */ + + p = data->keys[i].name + key_len; + + /* found a match, so allocate space and copy the name */ + + if ( !(ptr = Realloc( subkeys_ptr, (num_subkeys+2)*sizeof(fstring))) ) { + DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", + num_subkeys+1)); + SAFE_FREE( subkeys ); + return 0; + } + + subkeys_ptr = ptr; + + /* copy the subkey name and trim off any trailing + subkeys below it */ + + fstrcpy( subkeys_ptr[num_subkeys], p ); + p = strchr( subkeys_ptr[num_subkeys], '\\' ); + if ( p ) + *p = '\0'; + num_subkeys++; + } + + } + + /* tag of the end */ + + fstrcpy( subkeys_ptr[num_subkeys], "" ); + + *subkeys = subkeys_ptr; + + return num_subkeys; +} + /**************************************************************************** ***************************************************************************/ @@ -2465,11 +2525,8 @@ WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value key_index = lookup_printerkey( &p2->data, key ); if ( key_index == -1 ) - key_index = add_new_printer_key( &p2->data, key ); + return WERR_OK; - if ( key_index == -1 ) - return WERR_NOMEM; - regval_ctr_delvalue( &p2->data.keys[key_index].values, value ); DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n", diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 45c1f24001..994f03cf5a 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -332,9 +332,8 @@ REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, char *name ) /* search for the value */ for ( i=0; inum_values; i++ ) { - if ( strcmp( ctr->values[i]->valuename, name ) == 0) + if ( strequal( ctr->values[i]->valuename, name ) == 0) return ctr->values[i]; - } return NULL; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index cbafe982be..7286fef528 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4402,9 +4402,6 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, char *s v = ""; /* hack to handle null lists */ } - if ( !strlen(v) ) - break; - /* hack to allow this to be used in places other than when generating the list of dependent files */ @@ -4421,6 +4418,9 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, char *s } else *uni_array = tuary; + if ( !strlen(v) ) + break; + j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16)); i++; } @@ -7989,16 +7989,16 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u) { fstring key; - fstring *keynames; + fstring *keynames = NULL; uint16 *enumkeys = NULL; + int num_keys; int printerkey_len; - int i; POLICY_HND *handle = &q_u->handle; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); NT_PRINTER_DATA *data; NT_PRINTER_INFO_LEVEL *printer = NULL; int snum = 0; - WERROR status; + WERROR status = WERR_BADFILE; DEBUG(4,("_spoolss_enumprinterkey\n")); @@ -8015,56 +8015,42 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO if (!W_ERROR_IS_OK(status)) return status; + /* get the list of subkey names */ + unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 ); + data = &printer->info_2->data; - /* enumerating all keys if (key == "") */ + num_keys = get_printer_subkeys( data, key, &keynames ); - data = &printer->info_2->data; - - if ( !strlen( key ) ) - { - keynames = talloc_zero( p->mem_ctx, (data->num_keys+1)*sizeof(fstring) ); - - /* make an array of all the keynames */ - - for ( i=0; inum_keys; i++ ) - fstrcpy( keynames[i], data->keys[i].name ); - fstrcpy( keynames[i], "" ); - - printerkey_len = init_unistr_array( &enumkeys, keynames, NULL ); - - r_u->needed = printerkey_len*2; - - if ( q_u->size < r_u->needed ) - return WERR_MORE_DATA; - - if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) - return WERR_BADFILE; - - return WERR_OK; + if ( num_keys == -1 ) { + status = WERR_BADFILE; + goto done; } - - /* The "PrinterDriverData" key should have no subkeys */ - if ( strcmp(key, SPOOL_PRINTERDATA_KEY) == 0 ) - { - uint16 dummy_key = 0; - - r_u->needed = 2; - - if (q_u->size < r_u->needed) - return WERR_MORE_DATA; - - if ( !make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, &dummy_key ) ) - return WERR_BADFILE; - - return WERR_OK; + + printerkey_len = init_unistr_array( &enumkeys, keynames, NULL ); + + r_u->needed = printerkey_len*2; + + if ( q_u->size < r_u->needed ) { + status = WERR_MORE_DATA; + goto done; } - - /* The return value for an unknown key is documented in MSDN - EnumPrinterKey description */ - - return WERR_BADFILE; + if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) { + status = WERR_NOMEM; + goto done; + } + + status = WERR_OK; + + if ( q_u->size < r_u->needed ) + status = WERR_MORE_DATA; + +done: + free_a_printer( &printer, 2 ); + SAFE_FREE( keynames ); + + return status; } /******************************************************************** @@ -8126,7 +8112,6 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ return WERR_BADFID; } - /* first get the printer off of disk */ if (!get_printer_snum(p,handle, &snum)) -- cgit