summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/printing/nt_printing.c73
-rw-r--r--source3/registry/reg_printing.c79
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c2
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; 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.
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; 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,
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 ) {