diff options
author | Andreas Schneider <asn@samba.org> | 2010-05-26 11:27:28 +0200 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2010-07-27 10:27:06 -0400 |
commit | 71be0ec140c6e5cd3315fd20f6c8795fa0aaca63 (patch) | |
tree | 309f629a7674ffa2d17ec6dcf864229d84349969 /source3 | |
parent | 65eb38bc00a723052d8ac371cb2cf7fd68e0954b (diff) | |
download | samba-71be0ec140c6e5cd3315fd20f6c8795fa0aaca63.tar.gz samba-71be0ec140c6e5cd3315fd20f6c8795fa0aaca63.tar.bz2 samba-71be0ec140c6e5cd3315fd20f6c8795fa0aaca63.zip |
s3-registry: Redirect KEY_CONTROL_PRINTERS to KEY_WINNT_PRINTERS.
Signed-off-by: Jim McDonough <jmcd@samba.org>
Diffstat (limited to 'source3')
-rw-r--r-- | source3/registry/reg_backend_printing.c | 1059 |
1 files changed, 41 insertions, 1018 deletions
diff --git a/source3/registry/reg_backend_printing.c b/source3/registry/reg_backend_printing.c index e682af3b0b..ea6a6f61d4 100644 --- a/source3/registry/reg_backend_printing.c +++ b/source3/registry/reg_backend_printing.c @@ -2,6 +2,7 @@ * Unix SMB/CIFS implementation. * Virtual Windows Registry Layer * Copyright (C) Gerald Carter 2002-2005 + * Copyright (c) Andreas Schneider <asn@samba.org> 2010 * * 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 @@ -29,16 +30,9 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY -/* registrt paths used in the print_registry[] */ - -#define KEY_MONITORS "HKLM\\SYSTEM\\CURRENTCONTROLSET\\CONTROL\\PRINT\\MONITORS" -#define KEY_FORMS "HKLM\\SYSTEM\\CURRENTCONTROLSET\\CONTROL\\PRINT\\FORMS" +/* registry paths used in the print_registry[] */ #define KEY_CONTROL_PRINTERS "HKLM\\SYSTEM\\CURRENTCONTROLSET\\CONTROL\\PRINT\\PRINTERS" -#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" -#define KEY_WINNT_PRINT "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PRINT" -#define KEY_PORTS "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PORTS" /* callback table for various registry paths below the ones we service in this module */ @@ -55,147 +49,34 @@ struct reg_dyn_tree { /********************************************************************* ********************************************************************* - ** Utility Functions - ********************************************************************* - *********************************************************************/ - -/*********************************************************************** - simple function to prune a pathname down to the basename of a file - **********************************************************************/ - -static const char *dos_basename(const char *path) -{ - const char *p; - - if (!(p = strrchr( path, '\\'))) { - p = path; - } else { - p++; - } - - return p; -} - -/********************************************************************* - ********************************************************************* - ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" - ********************************************************************* - *********************************************************************/ - -static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys) -{ - char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS)); - - /* no keys below Forms */ - - if (p) { - return -1; - } - - return 0; -} - -/********************************************************************** - *********************************************************************/ - -static int key_forms_fetch_values(const char *key, struct 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, (uint8_t *)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, (uint8_t *)data, sizeof(data)); - } - - SAFE_FREE(forms_list); - - return regval_ctr_numvals(values); -} - -/********************************************************************* - ********************************************************************* ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" ********************************************************************* *********************************************************************/ -/********************************************************************* - strip off prefix for printers key. DOes return a pointer to static - memory. - *********************************************************************/ - -static char *strip_printers_prefix(const char *key) -{ - char *subkeypath = NULL; - char *path = NULL; - TALLOC_CTX *ctx = talloc_tos(); +static char *create_printer_registry_path(TALLOC_CTX *mem_ctx, const char *key) { + char *path; + char *subkey = NULL; - path = talloc_strdup(ctx, key); - if (!path) { + path = talloc_strdup(mem_ctx, key); + if (path == NULL) { return NULL; } - path = normalize_reg_path(ctx, path); - if (!path) { + + path = normalize_reg_path(mem_ctx, path); + if (path == NULL) { return NULL; } - /* normalizing the path does not change length, just key delimiters and case */ - - if (strncmp(path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS)) == 0) { - subkeypath = reg_remaining_path(ctx, key + strlen(KEY_WINNT_PRINTERS)); - } else { - subkeypath = reg_remaining_path(ctx, key + strlen(KEY_CONTROL_PRINTERS)); + if (strncmp(path, KEY_CONTROL_PRINTERS, strlen(KEY_CONTROL_PRINTERS)) == 0) { + subkey = reg_remaining_path(mem_ctx, key + strlen(KEY_CONTROL_PRINTERS)); + if (subkey == NULL) { + return NULL; + } + return talloc_asprintf(mem_ctx, "%s\\%s", KEY_WINNT_PRINTERS, subkey); } - TALLOC_FREE(path); - return subkeypath; + return NULL; } /********************************************************************* @@ -203,113 +84,16 @@ static char *strip_printers_prefix(const char *key) static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { - int n_services = lp_numservices(); - int snum; - fstring sname; - int i; - int num_subkeys = 0; + TALLOC_CTX *ctx = talloc_tos(); char *printers_key; - char *printername, *printerdatakey; - NT_PRINTER_INFO_LEVEL *printer = NULL; - fstring *subkey_names = NULL; - - DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" )); - - printers_key = strip_printers_prefix( key ); - - if ( !printers_key ) { - /* enumerate all printers */ - - for (snum=0; snum<n_services; snum++) { - if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) ) - continue; - - /* don't report the [printers] share */ - - if ( strequal( lp_servicename(snum), PRINTERS_NAME ) ) - continue; - fstrcpy( sname, lp_servicename(snum) ); - - regsubkey_ctr_addkey( subkeys, sname ); - } - - num_subkeys = regsubkey_ctr_numkeys( subkeys ); - goto done; - } - - /* get information for a specific printer */ - - if (!reg_split_path( printers_key, &printername, &printerdatakey )) { - return -1; - } - - /* validate the printer name */ - - 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] ); - - free_a_printer( &printer, 2 ); - - /* no other subkeys below here */ - -done: - SAFE_FREE( subkey_names ); - - 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( struct 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(talloc_tos(), NULL, &printer ) ) { - DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n", - printername)); - } - } + printers_key = create_printer_registry_path(ctx, key); + if (printers_key == NULL) { + /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */ + return regdb_fetch_keys(KEY_WINNT_PRINTERS, subkeys); } - unbecome_root(); - return True; + return regdb_fetch_keys(printers_key, subkeys); } /********************************************************************** @@ -317,145 +101,16 @@ static bool add_printers_by_registry( struct regsubkey_ctr *subkeys ) static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys ) { + TALLOC_CTX *ctx = talloc_tos(); 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] ); - } - } - - 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 */ - - free_a_printer( &printer, 2 ); - - SAFE_FREE( existing_subkeys ); - - return True; -} - -/********************************************************************** - *********************************************************************/ - -static void fill_in_printer_values(NT_PRINTER_INFO_LEVEL_2 *info2, struct regval_ctr *values) -{ - struct spoolss_DeviceMode *devmode; - char *p; - uint32 printer_status = PRINTER_STATUS_OK; - - regval_ctr_addvalue( values, "Attributes", REG_DWORD, (uint8_t *)&info2->attributes, sizeof(info2->attributes) ); - regval_ctr_addvalue( values, "Priority", REG_DWORD, (uint8_t *)&info2->priority, sizeof(info2->attributes) ); - regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (uint8_t *)&info2->changeid, sizeof(info2->changeid) ); - regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (uint8_t *)&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( values, "Status", REG_DWORD, (uint8_t *)&printer_status, sizeof(info2->status) ); - - regval_ctr_addvalue( values, "StartTime", REG_DWORD, (uint8_t *)&info2->starttime, sizeof(info2->starttime) ); - regval_ctr_addvalue( values, "UntilTime", REG_DWORD, (uint8_t *)&info2->untiltime, sizeof(info2->untiltime) ); - - /* strip the \\server\ from this string */ - if ( !(p = strrchr( info2->printername, '\\' ) ) ) - p = info2->printername; - else - p++; - - regval_ctr_addvalue_sz(values, "Name", p); - regval_ctr_addvalue_sz(values, "Location", info2->location); - regval_ctr_addvalue_sz(values, "Description", info2->comment); - regval_ctr_addvalue_sz(values, "Parameters", info2->parameters); - regval_ctr_addvalue_sz(values, "Port", info2->portname); - regval_ctr_addvalue_sz(values, "Share Name", info2->sharename); - regval_ctr_addvalue_sz(values, "Printer Driver", info2->drivername); - regval_ctr_addvalue_sz(values, "Separator File", info2->sepfile); - regval_ctr_addvalue_sz(values, "Print Processor", info2->printprocessor); - regval_ctr_addvalue_sz(values, "Datatype", info2->datatype); - - /* stream the device mode */ - - devmode = construct_dev_mode(values,info2->sharename); - if (devmode) { - DATA_BLOB blob; - enum ndr_err_code ndr_err; - - ndr_err = ndr_push_struct_blob(&blob, values, devmode, - (ndr_push_flags_fn_t)ndr_push_spoolss_DeviceMode); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - regval_ctr_addvalue(values, "Default Devmode", REG_BINARY, - blob.data, blob.length); - } - } - - /* stream the printer security descriptor */ - - if (info2->secdesc_buf && - info2->secdesc_buf->sd && - info2->secdesc_buf->sd_size) - { - NTSTATUS status; - DATA_BLOB blob; - - status = marshall_sec_desc(values, info2->secdesc_buf->sd, - &blob.data, &blob.length); - if (NT_STATUS_IS_OK(status)) { - regval_ctr_addvalue(values, "Security", REG_BINARY, - blob.data, blob.length); - } + printers_key = create_printer_registry_path(ctx, key); + if (printers_key == NULL) { + /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */ + return regdb_store_keys(KEY_WINNT_PRINTERS, subkeys); } - return; + return regdb_store_keys(printers_key, subkeys); } /********************************************************************** @@ -463,634 +118,33 @@ static void fill_in_printer_values(NT_PRINTER_INFO_LEVEL_2 *info2, struct regval static int key_printers_fetch_values(const char *key, struct regval_ctr *values) { - int num_values; - char *printers_key; - char *printername, *printerdatakey; - NT_PRINTER_INFO_LEVEL *printer = NULL; - NT_PRINTER_DATA *p_data; - int i, key_index; - - printers_key = strip_printers_prefix( key ); - - /* top level key values stored in the registry has no values */ - - if ( !printers_key ) { - /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' key */ - return regdb_fetch_values( KEY_WINNT_PRINTERS, values ); - } - - /* lookup the printer object */ - - if (!reg_split_path( printers_key, &printername, &printerdatakey )) { - return -1; - } - - if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) - goto done; - - if ( !printerdatakey ) { - fill_in_printer_values( printer->info_2, values ); - goto done; - } - - /* iterate over all printer data keys and fill the regval container */ - - 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_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey)); - free_a_printer( &printer, 2 ); - return -1; - } - - 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) ); - - -done: - if ( printer ) - free_a_printer( &printer, 2 ); - - return regval_ctr_numvals( 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 pull_reg_sz_fstring(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, fstring s) -{ - const char *str; - pull_reg_sz(mem_ctx, blob, &str); - fstrcpy(s, str); -} - -static void convert_values_to_printer_info_2(TALLOC_CTX *mem_ctx, - NT_PRINTER_INFO_LEVEL_2 *printer2, - struct regval_ctr *values) -{ - int num_values = regval_ctr_numvals( values ); - uint32 value_index; - struct regval_blob *val; - int i; - - for ( i=0; i<num_values; i++ ) { - DATA_BLOB blob; - val = regval_ctr_specific_value( values, i ); - value_index = find_valuename_index( regval_name( val ) ); - - blob = data_blob_const(regval_data_p(val), regval_size(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: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->printername); - break; - case REG_IDX_LOCATION: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->location); - break; - case REG_IDX_DESCRIPTION: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->comment); - break; - case REG_IDX_PARAMETERS: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->parameters); - break; - case REG_IDX_PORT: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->portname); - break; - case REG_IDX_SHARENAME: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->sharename); - break; - case REG_IDX_DRIVER: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->drivername); - break; - case REG_IDX_SEP_FILE: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->sepfile); - break; - case REG_IDX_PRINTPROC: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->printprocessor); - break; - case REG_IDX_DATATYPE: - pull_reg_sz_fstring(mem_ctx, &blob, printer2->datatype); - 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, struct regval_ctr *values) -{ + TALLOC_CTX *ctx = talloc_tos(); char *printers_key; - char *printername, *keyname; - NT_PRINTER_INFO_LEVEL *printer = NULL; - WERROR result; - TALLOC_CTX *mem_ctx = talloc_init("key_printers_store_values"); - printers_key = strip_printers_prefix( key ); - - /* values in the top level key get stored in the registry */ - - if ( !printers_key ) { + printers_key = create_printer_registry_path(ctx, key); + if (printers_key == NULL) { /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */ - return regdb_store_values( KEY_WINNT_PRINTERS, values ); - } - - 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(mem_ctx, printer->info_2, values ); - } - else { - int num_values = regval_ctr_numvals( values ); - int i; - struct regval_blob *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 ); - talloc_destroy(mem_ctx); - return False; - } - } - } - - result = mod_a_printer( printer, 2 ); - - free_a_printer( &printer, 2 ); - talloc_destroy(mem_ctx); - - return W_ERROR_IS_OK(result); -} - -/********************************************************************* - ********************************************************************* - ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS" - ********************************************************************* - *********************************************************************/ - -static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) -{ - const char *environments[] = { - "Windows 4.0", - "Windows NT x86", - "Windows NT R4000", - "Windows NT Alpha_AXP", - "Windows NT PowerPC", - "Windows IA64", - "Windows x64", - NULL }; - fstring *drivers = NULL; - int i, env_index, num_drivers; - char *keystr, *base, *subkeypath; - char *key2 = NULL; - int num_subkeys = -1; - int version; - TALLOC_CTX *ctx = talloc_tos(); - - DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" )); - - keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS) ); - - /* list all possible architectures */ - - if ( !keystr ) { - for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ ) - regsubkey_ctr_addkey( subkeys, environments[num_subkeys] ); - - return num_subkeys; - } - - /* we are dealing with a subkey of "Environments */ - key2 = talloc_strdup(ctx, keystr); - if (!key2) { - return -1; - } - keystr = key2; - if (!reg_split_path(keystr, &base, &subkeypath )) { - return -1; - } - - /* sanity check */ - - for ( env_index=0; environments[env_index]; env_index++ ) { - if ( strequal( environments[env_index], base ) ) - break; - } - if ( !environments[env_index] ) - return -1; - - /* ...\Print\Environements\...\ */ - - if ( !subkeypath ) { - regsubkey_ctr_addkey( subkeys, "Drivers" ); - regsubkey_ctr_addkey( subkeys, "Print Processors" ); - - return 2; - } - - /* more of the key path to process */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - /* ...\Print\Environements\...\Drivers\ */ - - if ( !subkeypath ) { - if ( strequal(base, "Drivers") ) { - switch ( env_index ) { - case 0: /* Win9x */ - regsubkey_ctr_addkey( subkeys, "Version-0" ); - break; - default: /* Windows NT based systems */ - regsubkey_ctr_addkey( subkeys, "Version-2" ); - regsubkey_ctr_addkey( subkeys, "Version-3" ); - break; - } - - return regsubkey_ctr_numkeys( subkeys ); - } else if ( strequal(base, "Print Processors") ) { - if ( env_index == 1 || env_index == 5 || env_index == 6 ) - - - return regsubkey_ctr_numkeys( subkeys ); - } else - return -1; /* bad path */ - } - - /* we finally get to enumerate the drivers */ - - /* only one possible subkey below PrintProc key */ - - if ( strequal(base, "Print Processors") ) { - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - /* no subkeys below this point */ - - if ( subkeypath ) - return -1; - - /* only allow one keyname here -- 'winprint' */ - - return strequal( base, "winprint" ) ? 0 : -1; - } - - /* only dealing with drivers from here on out */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - version = atoi(&base[strlen(base)-1]); - - switch (env_index) { - case 0: - if ( version != 0 ) - return -1; - break; - default: - if ( version != 2 && version != 3 ) - return -1; - break; - } - - - if ( !subkeypath ) { - num_drivers = get_ntdrivers( &drivers, environments[env_index], version ); - for ( i=0; i<num_drivers; i++ ) - regsubkey_ctr_addkey( subkeys, drivers[i] ); - - return regsubkey_ctr_numkeys( subkeys ); - } - - /* if anything else left, just say if has no subkeys */ - - DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s)\n", - key, subkeypath )); - - return 0; -} - - -/********************************************************************** - *********************************************************************/ - -static void fill_in_driver_values(const struct spoolss_DriverInfo8 *r, - struct regval_ctr *values) -{ - uint8_t *buffer = NULL; - int buffer_size = 0; - int i, length; - const char *filename; - DATA_BLOB data; - - filename = dos_basename(r->driver_path); - regval_ctr_addvalue_sz(values, "Driver", filename); - - filename = dos_basename(r->config_file); - regval_ctr_addvalue_sz(values, "Configuration File", filename); - - filename = dos_basename(r->data_file); - regval_ctr_addvalue_sz(values, "Data File", filename); - - filename = dos_basename(r->help_file); - regval_ctr_addvalue_sz(values, "Help File", filename); - - regval_ctr_addvalue_sz(values, "Datatype", r->default_datatype); - regval_ctr_addvalue_sz(values, "Monitor", r->monitor_name); - - regval_ctr_addvalue( values, "Version", REG_DWORD, (uint8_t *)&r->version, - sizeof(r->version) ); - - if (r->dependent_files) { - /* place the list of dependent files in a single - character buffer, separating each file name by - a NULL */ - - for (i=0; r->dependent_files[i] && strcmp(r->dependent_files[i], ""); i++) { - /* strip the path to only the file's base name */ - - filename = dos_basename(r->dependent_files[i]); - - length = strlen(filename); - - buffer = (uint8_t *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) ); - if ( !buffer ) { - break; - } - - push_reg_sz(talloc_tos(), &data, filename); - memcpy( buffer+buffer_size, data.data, data.length); - - buffer_size += (length + 1)*sizeof(uint16); - } - - /* terminated by double NULL. Add the final one here */ - - buffer = (uint8_t *)SMB_REALLOC( buffer, buffer_size + 2 ); - if ( !buffer ) { - buffer_size = 0; - } else { - buffer[buffer_size++] = (uint8_t)'\0'; - buffer[buffer_size++] = (uint8_t)'\0'; - } + return regdb_fetch_values(KEY_WINNT_PRINTERS, values); } - regval_ctr_addvalue( values, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size ); - - SAFE_FREE( buffer ); - - return; + return regdb_fetch_values(printers_key, values); } /********************************************************************** *********************************************************************/ -static int driver_arch_fetch_values(char *key, struct regval_ctr *values) -{ - char *keystr, *base, *subkeypath; - fstring arch_environment; - fstring driver; - int version; - struct spoolss_DriverInfo8 *driver_ctr; - WERROR w_result; - - if (!reg_split_path( key, &base, &subkeypath )) { - return -1; - } - - /* no values in 'Environments\Drivers\Windows NT x86' */ - - if ( !subkeypath ) - return 0; - - /* We have the Architecture string and some subkey name: - Currently we only support - * Drivers - * Print Processors - Anything else is an error. - */ - - fstrcpy( arch_environment, base ); - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - if ( strequal(base, "Print Processors") ) - return 0; - - /* only Drivers key can be left */ - - if ( !strequal(base, "Drivers") ) - return -1; - - if ( !subkeypath ) - return 0; - - /* We know that we have Architechure\Drivers with some subkey name - The subkey name has to be Version-XX */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - if ( !subkeypath ) - return 0; - - version = atoi(&base[strlen(base)-1]); - - /* BEGIN PRINTER DRIVER NAME BLOCK */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - /* don't go any deeper for now */ - - fstrcpy( driver, base ); - - w_result = get_a_printer_driver(talloc_tos(), &driver_ctr, driver, arch_environment, version); - - if ( !W_ERROR_IS_OK(w_result) ) - return -1; - - fill_in_driver_values(driver_ctr, values); - - free_a_printer_driver(driver_ctr); - - /* END PRINTER DRIVER NAME BLOCK */ - - - DEBUG(8,("key_driver_fetch_values: Exit\n")); - - return regval_ctr_numvals( values ); -} - -/********************************************************************** - *********************************************************************/ - -static int key_driver_fetch_values(const char *key, struct regval_ctr *values) +static bool key_printers_store_values(const char *key, struct regval_ctr *values) { - char *keystr = NULL; - char *subkey = NULL; TALLOC_CTX *ctx = talloc_tos(); + char *printers_key; - DEBUG(8,("key_driver_fetch_values: Enter key => [%s]\n", key ? key : "NULL")); - - /* no values in the Environments key */ - - if (!(keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS)))) - return 0; - - subkey = talloc_strdup(ctx, keystr); - if (!subkey) { - return 0; + printers_key = create_printer_registry_path(ctx, key); + if (printers_key == NULL) { + /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */ + return regdb_store_values(KEY_WINNT_PRINTERS, values); } - /* pass off to handle subkeys */ - - return driver_arch_fetch_values( subkey, values ); -} - -/********************************************************************* - ********************************************************************* - ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT" - ********************************************************************* - *********************************************************************/ - -static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) -{ - int key_len = strlen(key); - - /* no keys below 'Print' handled here */ - - if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) ) - return -1; - - regsubkey_ctr_addkey( subkeys, "Environments" ); - regsubkey_ctr_addkey( subkeys, "Monitors" ); - regsubkey_ctr_addkey( subkeys, "Forms" ); - regsubkey_ctr_addkey( subkeys, "Printers" ); - - return regsubkey_ctr_numkeys( subkeys ); + return regdb_store_values(printers_key, values); } /********************************************************************** @@ -1102,42 +156,11 @@ static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys *********************************************************************/ static struct reg_dyn_tree print_registry[] = { -/* just pass the monitor onto the registry tdb */ -{ KEY_MONITORS, - ®db_fetch_keys, - ®db_store_keys, - ®db_fetch_values, - ®db_store_values }, -{ KEY_FORMS, - &key_forms_fetch_keys, - NULL, - &key_forms_fetch_values, - NULL }, { KEY_CONTROL_PRINTERS, &key_printers_fetch_keys, &key_printers_store_keys, &key_printers_fetch_values, &key_printers_store_values }, -{ KEY_ENVIRONMENTS, - &key_driver_fetch_keys, - NULL, - &key_driver_fetch_values, - NULL }, -{ KEY_CONTROL_PRINT, - &key_print_fetch_keys, - NULL, - NULL, - NULL }, -{ KEY_WINNT_PRINTERS, - &key_printers_fetch_keys, - &key_printers_store_keys, - &key_printers_fetch_values, - &key_printers_store_values }, -{ KEY_PORTS, - ®db_fetch_keys, - ®db_store_keys, - ®db_fetch_values, - ®db_store_values }, { NULL, NULL, NULL, NULL, NULL } }; |