summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/nt_printing.h31
-rw-r--r--source3/printing/nt_printing.c746
-rw-r--r--source3/registry/reg_frontend.c91
-rw-r--r--source3/registry/reg_printing.c6
-rw-r--r--source3/rpc_parse/parse_spoolss.c36
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c710
6 files changed, 669 insertions, 951 deletions
diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index 57181c6659..6303136894 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -174,14 +174,26 @@ typedef struct nt_printer_driver_info_level
NT_PRINTER_DRIVER_INFO_LEVEL_6 *info_6;
} NT_PRINTER_DRIVER_INFO_LEVEL;
-typedef struct nt_printer_param
-{
- fstring value;
- uint32 type;
- uint8 *data;
- int data_len;
- struct nt_printer_param *next;
-} NT_PRINTER_PARAM;
+/* predefined registry key names for printer data */
+
+#define SPOOL_PRINTERDATA_KEY "PrinterDriverData"
+#define SPOOL_DSSPOOLER_KEY "DsSpooler"
+#define SPOOL_DSDRIVER_KEY "DsDriver"
+#define SPOOL_DSUSER_KEY "DsUser"
+
+/* container for a single registry key */
+
+typedef struct {
+ char *name;
+ REGVAL_CTR values;
+} NT_PRINTER_KEY;
+
+/* container for all printer data */
+
+typedef struct {
+ int num_keys;
+ NT_PRINTER_KEY *keys;
+} NT_PRINTER_DATA;
typedef struct ntdevicemode
{
@@ -246,9 +258,8 @@ typedef struct nt_printer_info_level_2
fstring printprocessor;
fstring datatype;
fstring parameters;
- NT_PRINTER_PARAM *specific;
+ NT_PRINTER_DATA data;
SEC_DESC_BUF *secdesc_buf;
- /* not used but ... and how ??? */
uint32 changeid;
uint32 c_setprinter;
uint32 setuptime;
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index e9ebb89d60..c497c65bfe 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1962,22 +1962,52 @@ static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
}
/****************************************************************************
-****************************************************************************/
-static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
+ Pack all values in all printer keys
+ ***************************************************************************/
+
+static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
{
- int len = 0;
+ int len = 0;
+ int i, j;
+ REGISTRY_VALUE *val;
+ REGVAL_CTR *val_ctr;
+ pstring path;
+ int num_values;
- while (param != NULL) {
- len += tdb_pack(buf+len, buflen-len, "pfdB",
- param,
- param->value,
- param->type,
- param->data_len,
- param->data);
- param=param->next;
+ if ( !data )
+ return 0;
+
+ /* loop over all keys */
+
+ for ( i=0; i<data->num_keys; i++ )
+ {
+ val_ctr = &data->keys[i].values;
+ num_values = regval_ctr_numvals( val_ctr );
+
+ /* loop over all values */
+
+ for ( j=0; j<num_values; j++ )
+ {
+ /* pathname should be stored as <key>\<value> */
+
+ val = regval_ctr_specific_value( val_ctr, j );
+ pstrcpy( path, data->keys[i].name );
+ pstrcat( path, "\\" );
+ pstrcat( path, regval_name(val) );
+
+ len += tdb_pack(buf+len, buflen-len, "pPdB",
+ val,
+ path,
+ regval_type(val),
+ regval_size(val),
+ regval_data_p(val) );
+ }
+
}
- len += tdb_pack(buf+len, buflen-len, "p", param);
+ /* terminator */
+
+ len += tdb_pack(buf+len, buflen-len, "p", NULL);
return len;
}
@@ -2071,7 +2101,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
len += pack_devicemode(info->devmode, buf+len, buflen-len);
- len += pack_specifics(info->specific, buf+len, buflen-len);
+ len += pack_values( &info->data, buf+len, buflen-len );
if (buflen != len) {
char *tb;
@@ -2111,89 +2141,6 @@ done:
/****************************************************************************
-****************************************************************************/
-void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
-{
- NT_PRINTER_PARAM *current;
-
- DEBUG(108,("add_a_specific_param\n"));
-
- (*param)->next=NULL;
-
- if (info_2->specific == NULL)
- {
- info_2->specific=*param;
- }
- else
- {
- current=info_2->specific;
- while (current->next != NULL) {
- current=current->next;
- }
- current->next=*param;
- }
-
- *param = NULL;
-}
-
-/****************************************************************************
-****************************************************************************/
-BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
-{
- NT_PRINTER_PARAM *current;
- NT_PRINTER_PARAM *previous;
-
- current=info_2->specific;
- previous=current;
-
- if (current==NULL) return (False);
-
- if ( !strcmp(current->value, param->value) &&
- (strlen(current->value)==strlen(param->value)) ) {
- DEBUG(109,("deleting first value\n"));
- info_2->specific=current->next;
- SAFE_FREE(current->data);
- SAFE_FREE(current);
- DEBUG(109,("deleted first value\n"));
- return (True);
- }
-
- current=previous->next;
-
- while ( current!=NULL ) {
- if (!strcmp(current->value, param->value) &&
- strlen(current->value)==strlen(param->value) ) {
- DEBUG(109,("deleting current value\n"));
- previous->next=current->next;
- SAFE_FREE(current->data);
- SAFE_FREE(current);
- DEBUG(109,("deleted current value\n"));
- return(True);
- }
-
- previous=previous->next;
- current=current->next;
- }
- return (False);
-}
-
-/****************************************************************************
- Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
-****************************************************************************/
-void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
-{
- NT_PRINTER_PARAM *param = *param_ptr;
-
- if(param == NULL)
- return;
-
- DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
-
- SAFE_FREE(param->data);
- SAFE_FREE(*param_ptr);
-}
-
-/****************************************************************************
Malloc and return an NT devicemode.
****************************************************************************/
@@ -2294,7 +2241,7 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
- SAFE_FREE(nt_devmode->private);
+ SAFE_FREE(nt_devmode->private);
SAFE_FREE(*devmode_ptr);
}
@@ -2304,23 +2251,29 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
{
NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
- NT_PRINTER_PARAM *param_ptr;
+ NT_PRINTER_DATA *data;
+ int i;
- if(info == NULL)
+ if ( !info )
return;
DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
free_nt_devicemode(&info->devmode);
- for(param_ptr = info->specific; param_ptr; ) {
- NT_PRINTER_PARAM *tofree = param_ptr;
-
- param_ptr = param_ptr->next;
- free_nt_printer_param(&tofree);
+ /* clean up all registry keys */
+
+ data = &info->data;
+ for ( i=0; i<data->num_keys; i++ )
+ {
+ SAFE_FREE( data->keys[i].name );
+ regval_ctr_destroy( &data->keys[i].values );
}
+ SAFE_FREE( data->keys );
- SAFE_FREE(*info_ptr);
+ /* finally the top level structure */
+
+ SAFE_FREE( *info_ptr );
}
@@ -2400,32 +2353,257 @@ static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
}
/****************************************************************************
-****************************************************************************/
-static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
+ allocate and initialize a new slot in
+ ***************************************************************************/
+
+static int add_new_printer_key( NT_PRINTER_DATA *data, char *name )
{
- int len = 0;
- NT_PRINTER_PARAM param, *p;
+ NT_PRINTER_KEY *d;
+ int key_index;
+
+ if ( !data || !name )
+ return -1;
+
+ /* allocate another slot in the NT_PRINTER_KEY array */
+
+ d = Realloc( data->keys, sizeof(NT_PRINTER_KEY)*(data->num_keys+1) );
+ if ( d )
+ data->keys = d;
+
+ key_index = data->num_keys;
+
+ /* initialze new key */
+
+ data->num_keys++;
+ data->keys[key_index].name = strdup( name );
+
+ ZERO_STRUCTP( &data->keys[key_index].values );
+
+ regval_ctr_init( &data->keys[key_index].values );
+
+ DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
+
+ return key_index;
+}
+
+/****************************************************************************
+ search for a registry key name in the existing printer data
+ ***************************************************************************/
+
+int lookup_printerkey( NT_PRINTER_DATA *data, char *name )
+{
+ int key_index = -1;
+ int i;
+
+ if ( !data || !name )
+ return -1;
+
+ DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
- *list = NULL;
+ /* loop over all existing keys */
+
+ for ( i=0; i<data->num_keys; i++ )
+ {
+ if ( strcmp(data->keys[i].name, name) == 0 ) {
+ DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
+ key_index = i;
+ break;
+
+ }
+ }
+
+ return key_index;
+}
+
+/****************************************************************************
+ ***************************************************************************/
+
+WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2 )
+{
+ WERROR result = WERR_OK;
+ NT_PRINTER_DATA *data;
+ int i;
+
+ data = &p2->data;
+
+ for ( i=0; i<data->num_keys; i++ )
+ {
+ DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
+ data->keys[i].name));
+
+ SAFE_FREE( data->keys[i].name );
+ regval_ctr_destroy( &data->keys[i].values );
+ }
+
+ SAFE_FREE( data->keys );
+
+ DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
+ p2->printername ));
+
+ ZERO_STRUCTP( data );
+
+ return result;
+}
+
+/****************************************************************************
+ ***************************************************************************/
+
+WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value )
+{
+ WERROR result = WERR_OK;
+ int key_index;
+
+ /* we must have names on non-zero length */
+
+ if ( !key || !*key|| !value || !*value )
+ return WERR_INVALID_NAME;
+
+ /* find the printer key first */
+
+ key_index = lookup_printerkey( &p2->data, key );
+ if ( key_index == -1 )
+ key_index = add_new_printer_key( &p2->data, key );
+
+ 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",
+ key, value ));
+
+ return result;
+}
+
+/****************************************************************************
+ ***************************************************************************/
+
+WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value,
+ uint32 type, uint8 *data, int real_len )
+{
+ WERROR result = WERR_OK;
+ int key_index;
- while (1) {
- len += tdb_unpack(buf+len, buflen-len, "p", &p);
- if (!p) break;
+ /* we must have names on non-zero length */
+
+ if ( !key || !*key|| !value || !*value )
+ return WERR_INVALID_NAME;
+
+ /* find the printer key first */
+
+ key_index = lookup_printerkey( &p2->data, key );
+ if ( key_index == -1 )
+ key_index = add_new_printer_key( &p2->data, key );
+
+ if ( key_index == -1 )
+ return WERR_NOMEM;
+
+ regval_ctr_addvalue( &p2->data.keys[key_index].values, value,
+ type, data, real_len );
+
+ DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], size => [%d]\n",
+ key, value, real_len ));
+
+ return result;
+}
+
+/****************************************************************************
+ ***************************************************************************/
+
+REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value )
+{
+ int key_index;
+
+ if ( (key_index = lookup_printerkey( &p2->data, key )) == -1 )
+ return NULL;
+ DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
+ key, value ));
+
+ return regval_ctr_getvalue( &p2->data.keys[key_index].values, value );
+}
+
+/****************************************************************************
+ Unpack a list of registry values frem the TDB
+ ***************************************************************************/
+
+static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
+{
+ int len = 0;
+ uint32 type;
+ pstring string, valuename, keyname;
+ char *str;
+ int size;
+ uint8 *data_p;
+ REGISTRY_VALUE *regval_p;
+ int key_index;
+
+ /* add the "PrinterDriverData" key first for performance reasons */
+
+ add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
+
+ /* loop and unpack the rest of the registry values */
+
+ while ( True )
+ {
+
+ /* check to see if there are any more registry values */
+
+ len += tdb_unpack(buf+len, buflen-len, "p", &regval_p);
+ if ( !regval_p )
+ break;
+
+ /* unpack the next regval */
+
len += tdb_unpack(buf+len, buflen-len, "fdB",
- param.value,
- &param.type,
- &param.data_len,
- &param.data);
- param.next = *list;
- *list = memdup(&param, sizeof(param));
+ string,
+ &type,
+ &size,
+ &data_p);
+
+ /*
+ * break of the keyname from the value name.
+ * Should only be one '\' in the string returned.
+ */
+
+ str = strchr( string, '\\');
+
+ /* Put in "PrinterDriverData" is no key specified */
+
+ if ( !str ) {
+ pstrcpy( keyname, SPOOL_PRINTERDATA_KEY );
+ pstrcpy( valuename, string );
+ }
+ else {
+ *str = '\0';
+ pstrcpy( keyname, string );
+ pstrcpy( valuename, str+1 );
+ }
+
+ /* see if we need a new key */
+
+ if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
+ key_index = add_new_printer_key( printer_data, keyname );
+
+ if ( key_index == -1 ) {
+ DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
+ keyname));
+ break;
+ }
+
+ /* add the new value */
+
+ regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, data_p, size );
- DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
+ DEBUG(8,("specific: [%s\\%s], len: %d\n", keyname, valuename, size));
}
return len;
}
+/****************************************************************************
+ ***************************************************************************/
+
static void map_to_os2_driver(fstring drivername)
{
static BOOL initialised=False;
@@ -2659,10 +2837,10 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
info.devmode = construct_nt_devicemode(printername);
}
- len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
+ len += unpack_values( &info.data, dbuf.dptr+len, dbuf.dsize-len );
/* This will get the current RPC talloc context, but we should be
- passing this as a parameter... fixme... JRA ! */
+ passing this as a parameter... fixme... JRA ! */
nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
@@ -2849,24 +3027,19 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
Initialize printer devmode & data with previously saved driver init values.
****************************************************************************/
-static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
+static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
{
int len = 0;
pstring key;
TDB_DATA kbuf, dbuf;
- NT_PRINTER_PARAM *current;
NT_PRINTER_INFO_LEVEL_2 info;
/*
- * Delete any printer data 'specifics' already set. When called for driver
+ * Delete any printer data 'values' already set. When called for driver
* replace, there will generally be some, but during an add printer, there
* should not be any (if there are delete them).
*/
- while ( (current=info_ptr->specific) != NULL ) {
- info_ptr->specific=current->next;
- SAFE_FREE(current->data);
- SAFE_FREE(current);
- }
+ delete_all_printer_data( info_ptr );
ZERO_STRUCT(info);
@@ -2876,7 +3049,7 @@ static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
kbuf.dsize = strlen(key)+1;
dbuf = tdb_fetch(tdb_drivers, kbuf);
- if (!dbuf.dptr) {
+ if (!dbuf.dptr) {
/*
* When changing to a driver that has no init info in the tdb, remove
* the previous drivers init info and leave the new on blank.
@@ -2945,9 +3118,10 @@ static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
info_ptr->printername, info_ptr->drivername));
/*
- * Add the printer data 'specifics' to the new printer
+ * Add the printer data 'values' to the new printer
*/
- len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
+ len += unpack_values( &info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
+
SAFE_FREE(dbuf.dptr);
@@ -3005,7 +3179,7 @@ BOOL del_driver_init(char *drivername)
}
/****************************************************************************
- Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
+ Pack up the DEVMODE and values for a printer into a 'driver init' entry
in the tdb. Note: this is different from the driver entry and the printer
entry. There should be a single driver init entry for each driver regardless
of whether it was installed from NT or 2K. Technically, they should be
@@ -3026,7 +3200,7 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
len = 0;
len += pack_devicemode(info->devmode, buf+len, buflen-len);
- len += pack_specifics(info->specific, buf+len, buflen-len);
+ len += pack_values( &info->data, buf+len, buflen-len );
if (buflen != len) {
char *tb;
@@ -3057,14 +3231,14 @@ done:
SAFE_FREE(buf);
- DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
+ DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n",
info->sharename, info->drivername));
return ret;
}
/****************************************************************************
- Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
+ Update (i.e. save) the driver init info (DEVMODE and values) for a printer
****************************************************************************/
uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
@@ -3089,154 +3263,6 @@ uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
}
/****************************************************************************
- Convert the printer data value, a REG_BINARY array, into an initialization
- DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
- got to keep the endians happy :).
-****************************************************************************/
-
-static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
-{
- BOOL result = False;
- prs_struct ps;
- DEVICEMODE devmode;
-
- ZERO_STRUCT(devmode);
-
- prs_init(&ps, 0, ctx, UNMARSHALL);
- ps.data_p = (char *)param->data;
- ps.buffer_size = param->data_len;
-
- if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
- result = convert_devicemode("", &devmode, &nt_devmode);
- else
- DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
-
- return result;
-}
-
-/****************************************************************************
- Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
-
- 1. Use the driver's config DLL to this UNC printername and:
- a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
- b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
- 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
-
- The last step triggers saving the "driver initialization" information for
- this printer into the tdb. Later, new printers that use this driver will
- have this initialization information bound to them. This simulates the
- driver initialization, as if it had run on the Samba server (as it would
- have done on NT).
-
- The Win32 client side code requirement sucks! But until we can run arbitrary
- Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
-
- It would have been easier to use SetPrinter because all the UNMARSHALLING of
- the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
- about it and you will realize why. JRR 010720
-****************************************************************************/
-
-static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
-{
- WERROR status = WERR_OK;
- TALLOC_CTX *ctx = NULL;
- NT_DEVICEMODE *nt_devmode = NULL;
- NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
-
- /*
- * When the DEVMODE is already set on the printer, don't try to unpack it.
- */
-
- if (!printer->info_2->devmode && param->data_len) {
- /*
- * Set devmode on printer info, so entire printer initialization can be
- * saved to tdb.
- */
-
- if ((ctx = talloc_init()) == NULL)
- return WERR_NOMEM;
-
- if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
- status = WERR_NOMEM;
- goto done;
- }
-
- ZERO_STRUCTP(nt_devmode);
-
- /*
- * The DEVMODE is held in the 'data' component of the param in raw binary.
- * Convert it to to a devmode structure
- */
- if (!convert_driver_init(param, ctx, nt_devmode)) {
- DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
- status = WERR_INVALID_PARAM;
- goto done;
- }
-
- printer->info_2->devmode = nt_devmode;
- }
-
- /*
- * Pack up and add (or update) the DEVMODE and any current printer data to
- * a 'driver init' element in the tdb
- *
- */
-
- if (update_driver_init(*printer, 2)!=0) {
- DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
- status = WERR_NOMEM;
- goto done;
- }
-
- /*
- * If driver initialization info was successfully saved, set the current
- * printer to match it. This allows initialization of the current printer
- * as well as the driver.
- */
- status = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(status)) {
- DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
- printer->info_2->printername));
- }
-
-#if 0 /* JERRY */
- srv_spoolss_sendnotify(p, handle);
-#endif
-
- done:
- talloc_destroy(ctx);
- if (nt_devmode)
- SAFE_FREE(nt_devmode->private);
- SAFE_FREE(nt_devmode);
- printer->info_2->devmode = tmp_devmode;
-
- return status;
-}
-
-/****************************************************************************
- Update the driver init info (DEVMODE and specifics) for a printer
-****************************************************************************/
-
-WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
-{
- WERROR status = WERR_OK;
-
- switch (level)
- {
- case 2:
- {
- status=save_driver_init_2(printer, param);
- break;
- }
- default:
- status=WERR_UNKNOWN_LEVEL;
- break;
- }
-
- return status;
-}
-
-/****************************************************************************
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
****************************************************************************/
@@ -3851,83 +3877,6 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_
return delete_printer_driver_internal(i, user, version, delete_files );
}
-
-/****************************************************************************
-****************************************************************************/
-
-BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
- fstring value, uint8 **data, uint32 *type, uint32 *len)
-{
- /* right now that's enough ! */
- NT_PRINTER_PARAM *param;
- int i=0;
-
- param=printer.info_2->specific;
-
- while (param != NULL && i < param_index) {
- param=param->next;
- i++;
- }
-
- if (param == NULL)
- return False;
-
- /* exited because it exist */
- *type=param->type;
- StrnCpy(value, param->value, sizeof(fstring)-1);
- *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
- if(*data == NULL)
- return False;
- ZERO_STRUCTP(*data);
- memcpy(*data, param->data, param->data_len);
- *len=param->data_len;
- return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
- fstring value, uint8 **data, uint32 *type, uint32 *len)
-{
- /* right now that's enough ! */
- NT_PRINTER_PARAM *param;
-
- DEBUG(10, ("get_specific_param\n"));
-
- param=printer.info_2->specific;
-
- while (param != NULL)
- {
-#if 1 /* JRA - I think this should be case insensitive.... */
- if ( strequal(value, param->value)
-#else
- if ( !strcmp(value, param->value)
-#endif
- && strlen(value)==strlen(param->value))
- break;
-
- param=param->next;
- }
-
- if (param != NULL)
- {
- DEBUGADD(10, ("get_specific_param: found one param\n"));
- /* exited because it exist */
- *type=param->type;
-
- *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
- if(*data == NULL)
- return False;
- memcpy(*data, param->data, param->data_len);
- *len=param->data_len;
-
- DEBUGADD(10, ("get_specific_param: exit true\n"));
- return (True);
- }
- DEBUGADD(10, ("get_specific_param: exit false\n"));
- return (False);
-}
-
/****************************************************************************
Store a security desc for a printer.
****************************************************************************/
@@ -4363,76 +4312,3 @@ BOOL print_time_access_check(int snum)
return ok;
}
-#if 0 /* JERRY - not used */
-/****************************************************************************
- Attempt to write a default device.
-*****************************************************************************/
-
-WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- WERROR result;
-
- /*
- * Don't bother if no default devicemode was sent.
- */
-
- if (printer_default->devmode_cont.devmode == NULL)
- return WERR_OK;
-
- result = get_a_printer(&printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(result)) return result;
-
- /*
- * Just ignore it if we already have a devmode.
- */
-#if 0
- if (printer->info_2->devmode != NULL)
- goto done;
-#endif
- /*
- * We don't have a devicemode and we're trying to write
- * one. Check we have the access needed.
- */
- DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
-
- if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
- PRINTER_ACCESS_ADMINISTER) {
- DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
- if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
- DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
- lp_servicename(snum) ));
- result = WERR_ACCESS_DENIED;
- /*result = NT_STATUS_NO_PROBLEMO;*/
- goto done;
- }
-
- DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
-
- /*
- * Convert the on the wire devicemode format to the internal one.
- */
-
- if (!convert_devicemode(printer->info_2->printername,
- printer_default->devmode_cont.devmode,
- &printer->info_2->devmode)) {
- result = WERR_NOMEM;
- goto done;
- }
-
- /*
- * Finally write back to the tdb.
- */
-
- result = mod_a_printer(*printer, 2);
-
- done:
-
- free_a_printer(&printer, 2);
- return result;
-}
-#endif /* JERRY */
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index c0788c1b75..45c1f24001 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -188,6 +188,38 @@ void free_registry_value( REGISTRY_VALUE *val )
return;
}
+/**********************************************************************
+ *********************************************************************/
+
+uint8* regval_data_p( REGISTRY_VALUE *val )
+{
+ return val->data_p;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+int regval_size( REGISTRY_VALUE *val )
+{
+ return val->size;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+char* regval_name( REGISTRY_VALUE *val )
+{
+ return val->valuename;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+uint32 regval_type( REGISTRY_VALUE *val )
+{
+ return val->type;
+}
+
/***********************************************************************
Retreive a pointer to a specific value. Caller shoud dup the structure
since this memory may go away with a regval_ctr_destroy()
@@ -214,7 +246,7 @@ TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
}
/***********************************************************************
- Add a new regostry value to the array
+ Add a new registry value to the array
**********************************************************************/
int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
@@ -237,7 +269,7 @@ int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
ctr->values = ppreg;
}
- /* allocate a new valuie and store the pointer in the arrya */
+ /* allocate a new value and store the pointer in the arrya */
ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
@@ -254,6 +286,61 @@ int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
}
/***********************************************************************
+ Delete a single value from the registry container.
+ No need to free memory since it is talloc'd.
+ **********************************************************************/
+
+int regval_ctr_delvalue( REGVAL_CTR *ctr, char *name )
+{
+ int i;
+
+ /* search for the value */
+
+ for ( i=0; i<ctr->num_values; i++ ) {
+ if ( strcmp( ctr->values[i]->valuename, name ) == 0)
+ break;
+ }
+
+ /* just return if we don't find it */
+
+ if ( i == ctr->num_values )
+ return ctr->num_values;
+
+ /* just shift everything down one */
+
+ for ( /* use previous i */; i<(ctr->num_values-1); i++ )
+ memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) );
+
+ /* paranoia */
+
+ ZERO_STRUCTP( ctr->values[i] );
+
+ ctr->num_values--;
+
+ return ctr->num_values;
+}
+
+/***********************************************************************
+ Delete a single value from the registry container.
+ No need to free memory since it is talloc'd.
+ **********************************************************************/
+
+REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, char *name )
+{
+ int i;
+
+ /* search for the value */
+
+ for ( i=0; i<ctr->num_values; i++ ) {
+ if ( strcmp( ctr->values[i]->valuename, name ) == 0)
+ return ctr->values[i];
+
+ }
+
+ return NULL;
+}
+
+/***********************************************************************
free memory held by a REGVAL_CTR structure
**********************************************************************/
diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c
index 3fd3680489..8f53fe9ea5 100644
--- a/source3/registry/reg_printing.c
+++ b/source3/registry/reg_printing.c
@@ -492,7 +492,7 @@ static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys )
free_a_printer( &printer, 2 );
- regsubkey_ctr_addkey( subkeys, "PrinterDriverData" );
+ regsubkey_ctr_addkey( subkeys, SPOOL_PRINTERDATA_KEY );
}
/* no other subkeys below here */
@@ -620,7 +620,7 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
/* here should be no more path components here */
- if ( new_path || strcmp(base, "PrinterDriverData") )
+ if ( new_path || strcmp(base, SPOOL_PRINTERDATA_KEY) )
goto done;
/* now enumerate the PrinterDriverData key */
@@ -632,10 +632,12 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
/* iterate over all printer data and fill the regval container */
+#if 0 /* JERRY */
for ( i=0; get_specific_param_by_index(*printer, 2, i, valuename, &data, &type, &data_len); i++ )
{
regval_ctr_addvalue( val, valuename, type, data, data_len );
}
+#endif
free_a_printer( &printer, 2 );
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 79760ff37e..ac41a81a5a 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -6188,42 +6188,6 @@ BOOL spoolss_io_r_resetprinter(char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct
/*******************************************************************
********************************************************************/
-BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
- uint32 type, const uint8 *data, uint32 len)
-{
- DEBUG(5,("converting a specific param struct\n"));
-
- if (*param == NULL)
- {
- *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
- if(*param == NULL)
- return False;
- memset((char *)*param, '\0', sizeof(NT_PRINTER_PARAM));
- DEBUGADD(6,("Allocated a new PARAM struct\n"));
- }
- unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1);
- (*param)->type = type;
-
- /* le champ data n'est pas NULL termine */
- /* on stocke donc la longueur */
-
- (*param)->data_len=len;
-
- if (len) {
- (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
- if((*param)->data == NULL)
- return False;
- memcpy((*param)->data, data, len);
- }
-
- DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
- dump_data(10, (char *)(*param)->data, (*param)->data_len);
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
{
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index d04aff8b15..2aa11530f8 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -1798,51 +1798,56 @@ static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND
uint8 **data, uint32 *needed, uint32 in_size )
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum=0;
- uint8 *idata=NULL;
- uint32 len;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ int snum=0;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ REGISTRY_VALUE *val;
+ int size = 0;
DEBUG(5,("getprinterdata_printer\n"));
- if (!Printer) {
+ if ( !Printer ) {
DEBUG(2,("getprinterdata_printer: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
return False;
}
- if(!get_printer_snum(p, handle, &snum))
+ if ( !get_printer_snum(p, handle, &snum) )
return False;
- if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
+ if ( !W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) )
return False;
- if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
+ if ( !(val = get_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, value)) )
+ {
free_a_printer(&printer, 2);
return False;
}
+
+ *type = regval_type( val );
- free_a_printer(&printer, 2);
DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
- if (in_size) {
- if((*data = (uint8 *)talloc(ctx, in_size *sizeof(uint8) )) == NULL) {
+ if (in_size)
+ {
+ if ( (*data = (uint8 *)talloc(ctx, in_size * sizeof(uint8))) == NULL )
return False;
- }
- memset(*data, 0, in_size *sizeof(uint8));
+ memset( *data, 0, in_size *sizeof(uint8) );
+
/* copy the min(in_size, len) */
- memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
- } else {
- *data = NULL;
+
+ size = regval_size( val );
+ memcpy( *data, regval_data_p(val), (size > in_size) ? in_size : size*sizeof(uint8) );
}
+ else
+ *data = NULL;
- *needed = len;
+ *needed = size;
DEBUG(5,("getprinterdata_printer:copy done\n"));
- SAFE_FREE(idata);
+ free_a_printer(&printer, 2);
return True;
}
@@ -1871,11 +1876,12 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
* JFM, 4/19/1999
*/
- *out_size=in_size;
+ *out_size = in_size;
/* in case of problem, return some default values */
- *needed=0;
- *type=0;
+
+ *needed = 0;
+ *type = 0;
DEBUG(4,("_spoolss_getprinterdata\n"));
@@ -1889,13 +1895,16 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
unistr2_to_ascii(value, valuename, sizeof(value)-1);
if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
- found=getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
+ found = getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
else
- found= getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
+ found = getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
- if (found==False) {
+ if ( !found )
+ {
DEBUG(5, ("value not found, allocating %d\n", *out_size));
+
/* reply this param doesn't exist */
+
if (*out_size) {
if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
return WERR_NOMEM;
@@ -5219,254 +5228,6 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
return True;
}
-#if 0 /* JERRY */
-
-/* Return true if two devicemodes are equal */
-
-#define DEVMODE_CHECK_INT(field) \
- if (d1->field != d2->field) { \
- DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
- d1->field, d2->field)); \
- return False; \
- }
-
-/************************************************************************
- Handy, but currently unused functions
- ***********************************************************************/
-
-static BOOL nt_devicemode_equal(NT_DEVICEMODE *d1, NT_DEVICEMODE *d2)
-{
- if (!d1 && !d2) goto equal; /* if both are NULL they are equal */
-
- if (!d1 ^ !d2) {
- DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
- return False; /* if either is exclusively NULL are not equal */
- }
-
- if (!strequal(d1->devicename, d2->devicename)) {
- DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1->devicename, d2->devicename));
- return False;
- }
-
- if (!strequal(d1->formname, d2->formname)) {
- DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1->formname, d2->formname));
- return False;
- }
-
- DEVMODE_CHECK_INT(specversion);
- DEVMODE_CHECK_INT(driverversion);
- DEVMODE_CHECK_INT(driverextra);
- DEVMODE_CHECK_INT(orientation);
- DEVMODE_CHECK_INT(papersize);
- DEVMODE_CHECK_INT(paperlength);
- DEVMODE_CHECK_INT(paperwidth);
- DEVMODE_CHECK_INT(scale);
- DEVMODE_CHECK_INT(copies);
- DEVMODE_CHECK_INT(defaultsource);
- DEVMODE_CHECK_INT(printquality);
- DEVMODE_CHECK_INT(color);
- DEVMODE_CHECK_INT(duplex);
- DEVMODE_CHECK_INT(yresolution);
- DEVMODE_CHECK_INT(ttoption);
- DEVMODE_CHECK_INT(collate);
- DEVMODE_CHECK_INT(logpixels);
-
- DEVMODE_CHECK_INT(fields);
- DEVMODE_CHECK_INT(bitsperpel);
- DEVMODE_CHECK_INT(pelswidth);
- DEVMODE_CHECK_INT(pelsheight);
- DEVMODE_CHECK_INT(displayflags);
- DEVMODE_CHECK_INT(displayfrequency);
- DEVMODE_CHECK_INT(icmmethod);
- DEVMODE_CHECK_INT(icmintent);
- DEVMODE_CHECK_INT(mediatype);
- DEVMODE_CHECK_INT(dithertype);
- DEVMODE_CHECK_INT(reserved1);
- DEVMODE_CHECK_INT(reserved2);
- DEVMODE_CHECK_INT(panningwidth);
- DEVMODE_CHECK_INT(panningheight);
-
- /* compare the private data if it exists */
- if (!d1->driverextra && !d2->driverextra) goto equal;
-
-
- DEVMODE_CHECK_INT(driverextra);
-
- if (memcmp(d1->private, d2->private, d1->driverextra)) {
- DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
- return False;
- }
-
- equal:
- DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
- return True;
-}
-
-/* Return true if two NT_PRINTER_PARAM structures are equal */
-
-static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
- NT_PRINTER_PARAM *p2)
-{
- if (!p1 && !p2) goto equal;
-
- if ((!p1 && p2) || (p1 && !p2)) {
- DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
- return False;
- }
-
- /* Compare lists of printer parameters */
-
- while (p1) {
- BOOL found = False;
- NT_PRINTER_PARAM *q = p1;
-
- /* Find the parameter in the second structure */
-
- while(q) {
-
- if (strequal(p1->value, q->value)) {
-
- if (p1->type != q->type) {
- DEBUG(10, ("nt_printer_param_equal():"
- "types for %s differ (%d != %d)\n",
- p1->value, p1->type,
- q->type));
- break;
- }
-
- if (p1->data_len != q->data_len) {
- DEBUG(10, ("nt_printer_param_equal():"
- "len for %s differs (%d != %d)\n",
- p1->value, p1->data_len,
- q->data_len));
- break;
- }
-
- if (memcmp(p1->data, q->data, p1->data_len) == 0) {
- found = True;
- } else {
- DEBUG(10, ("nt_printer_param_equal():"
- "data for %s differs\n", p1->value));
- }
-
- break;
- }
-
- q = q->next;
- }
-
- if (!found) {
- DEBUG(10, ("nt_printer_param_equal(): param %s "
- "does not exist\n", p1->value));
- return False;
- }
-
- p1 = p1->next;
- }
-
- equal:
-
- DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
- return True;
-}
-
-/********************************************************************
- * Called by update_printer when trying to work out whether to
- * actually update printer info.
- ********************************************************************/
-
-#define PI_CHECK_INT(field) \
- if (pi1->field != pi2->field) { \
- DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
- pi1->field, pi2->field)); \
- return False; \
- }
-
-#define PI_CHECK_STR(field) \
- if (!strequal(pi1->field, pi2->field)) { \
- DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
- pi1->field, pi2->field)); \
- return False; \
- }
-
-static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
- NT_PRINTER_INFO_LEVEL *p2)
-{
- NT_PRINTER_INFO_LEVEL_2 *pi1, *pi2;
-
- /* Trivial conditions */
-
- if ((!p1 && !p2) || (!p1->info_2 && !p2->info_2)) {
- goto equal;
- }
-
- if ((!p1 && p2) || (p1 && !p2) ||
- (!p1->info_2 && p2->info_2) ||
- (p1->info_2 && !p2->info_2)) {
- DEBUG(10, ("nt_printer_info_level_equal(): info levels "
- "differ\n"));
- return False;
- }
-
- /* Compare two nt_printer_info_level structures. Don't compare
- status or cjobs as they seem to have something to do with the
- printer queue. */
-
- pi1 = p1->info_2;
- pi2 = p2->info_2;
-
- /* Don't check the attributes as we stomp on the value in
- check_printer_ok() anyway. */
-
-#if 0
- PI_CHECK_INT(attributes);
-#endif
-
- PI_CHECK_INT(priority);
- PI_CHECK_INT(default_priority);
- PI_CHECK_INT(starttime);
- PI_CHECK_INT(untiltime);
- PI_CHECK_INT(averageppm);
-
- /* Yuck - don't check the printername or servername as the
- mod_a_printer() code plays games with them. You can't
- change the printername or the sharename through this interface
- in Samba. */
-
- PI_CHECK_STR(sharename);
- PI_CHECK_STR(portname);
- PI_CHECK_STR(drivername);
- PI_CHECK_STR(comment);
- PI_CHECK_STR(location);
-
- if (!nt_devicemode_equal(pi1->devmode, pi2->devmode)) {
- return False;
- }
-
- PI_CHECK_STR(sepfile);
- PI_CHECK_STR(printprocessor);
- PI_CHECK_STR(datatype);
- PI_CHECK_STR(parameters);
-
- if (!nt_printer_param_equal(pi1->specific, pi2->specific)) {
- return False;
- }
-
- if (!sec_desc_equal(pi1->secdesc_buf->sec, pi2->secdesc_buf->sec)) {
- return False;
- }
-
- PI_CHECK_INT(changeid);
- PI_CHECK_INT(c_setprinter);
- PI_CHECK_INT(setuptime);
-
- equal:
- DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
- return True;
-}
-
-#endif
-
/********************************************************************
* Called by spoolss_api_setprinter
* when updating a printer description.
@@ -7121,38 +6882,38 @@ WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
{
POLICY_HND *handle = &q_u->handle;
- uint32 idx = q_u->index;
- uint32 in_value_len = q_u->valuesize;
- uint32 in_data_len = q_u->datasize;
- uint32 *out_max_value_len = &r_u->valuesize;
- uint16 **out_value = &r_u->value;
- uint32 *out_value_len = &r_u->realvaluesize;
- uint32 *out_type = &r_u->type;
+ uint32 idx = q_u->index;
+ uint32 in_value_len = q_u->valuesize;
+ uint32 in_data_len = q_u->datasize;
+ uint32 *out_max_value_len= &r_u->valuesize;
+ uint16 **out_value = &r_u->value;
+ uint32 *out_value_len = &r_u->realvaluesize;
+ uint32 *out_type = &r_u->type;
uint32 *out_max_data_len = &r_u->datasize;
- uint8 **data_out = &r_u->data;
- uint32 *out_data_len = &r_u->realdatasize;
+ uint8 **data_out = &r_u->data;
+ uint32 *out_data_len = &r_u->realdatasize;
NT_PRINTER_INFO_LEVEL *printer = NULL;
- fstring value;
+ uint32 param_index;
+ uint32 biggest_valuesize;
+ uint32 biggest_datasize;
+ uint32 data_len;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ int snum;
+ WERROR result;
+ REGISTRY_VALUE *val;
+ NT_PRINTER_DATA *p_data;
+ int i, key_index, num_values;
+ int name_length;
- uint32 param_index;
- uint32 biggest_valuesize;
- uint32 biggest_datasize;
- uint32 data_len;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- int snum;
- uint8 *data=NULL;
- uint32 type;
- WERROR result;
-
- ZERO_STRUCT(printer);
+ ZERO_STRUCT( printer );
- *out_type=0;
+ *out_type = 0;
- *out_max_data_len=0;
- *data_out=NULL;
- *out_data_len=0;
+ *out_max_data_len = 0;
+ *data_out = NULL;
+ *out_data_len = 0;
DEBUG(5,("spoolss_enumprinterdata\n"));
@@ -7167,103 +6928,133 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
result = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(result))
return result;
+
+ p_data = &printer->info_2->data;
+ key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
+
+ result = WERR_OK;
/*
* The NT machine wants to know the biggest size of value and data
*
* cf: MSDN EnumPrinterData remark section
*/
- if ( (in_value_len==0) && (in_data_len==0) ) {
+
+ if ( !in_value_len && !in_data_len )
+ {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
- SAFE_FREE(data);
-
- param_index=0;
- biggest_valuesize=0;
- biggest_datasize=0;
+ param_index = 0;
+ biggest_valuesize = 0;
+ biggest_datasize = 0;
+
+ num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
- while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
- if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
- if (data_len > biggest_datasize) biggest_datasize=data_len;
-
- DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
-
- SAFE_FREE(data);
- param_index++;
+ for ( i=0; i<num_values; i++ )
+ {
+ val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
+
+ name_length = strlen(val->valuename);
+ if ( strlen(val->valuename) > biggest_valuesize )
+ biggest_valuesize = name_length;
+
+ if ( val->size > biggest_datasize )
+ biggest_datasize = val->size;
+
+ DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
+ biggest_datasize));
}
- /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
- *out_value_len=2*(1+biggest_valuesize);
- *out_data_len=biggest_datasize;
+ /* the value is an UNICODE string but real_value_size is the length
+ in bytes including the trailing 0 */
+
+ *out_value_len = 2 * (1+biggest_valuesize);
+ *out_data_len = biggest_datasize;
DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
- free_a_printer(&printer, 2);
- return WERR_OK;
+ goto done;
}
/*
* the value len is wrong in NT sp3
* that's the number of bytes not the number of unicode chars
*/
+
+ val = regval_ctr_specific_value( &p_data->keys[key_index].values, idx );
- if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
-
- SAFE_FREE(data);
- free_a_printer(&printer, 2);
+ if ( !val )
+ {
/* out_value should default to "" or else NT4 has
problems unmarshalling the response */
- *out_max_value_len=(in_value_len/sizeof(uint16));
- if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
- return WERR_NOMEM;
+ *out_max_value_len = (in_value_len/sizeof(uint16));
+
+ if ( (*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
+ {
+ result = WERR_NOMEM;
+ goto done;
+ }
*out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
/* the data is counted in bytes */
+
*out_max_data_len = in_data_len;
- *out_data_len = in_data_len;
- if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
- return WERR_NOMEM;
+ *out_data_len = in_data_len;
+
+ /* only allocate when given a non-zero data_len */
+
+ if ( in_data_len && ((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
+ {
+ result = WERR_NOMEM;
+ goto done;
+ }
- return WERR_NO_MORE_ITEMS;
+ result = WERR_NO_MORE_ITEMS;
}
-
- free_a_printer(&printer, 2);
-
- /*
- * the value is:
- * - counted in bytes in the request
- * - counted in UNICODE chars in the max reply
- * - counted in bytes in the real size
- *
- * take a pause *before* coding not *during* coding
- */
+ else
+ {
+ /*
+ * the value is:
+ * - counted in bytes in the request
+ * - counted in UNICODE chars in the max reply
+ * - counted in bytes in the real size
+ *
+ * take a pause *before* coding not *during* coding
+ */
- *out_max_value_len=(in_value_len/sizeof(uint16));
- if((*out_value=(uint16 *)talloc_zero(p->mem_ctx,in_value_len*sizeof(uint8))) == NULL) {
- SAFE_FREE(data);
- return WERR_NOMEM;
- }
+ /* name */
+ *out_max_value_len = ( in_value_len / sizeof(uint16) );
+ if ( (*out_value = (uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
+ {
+ result = WERR_NOMEM;
+ goto done;
+ }
- *out_value_len = (uint32)rpcstr_push((char *)*out_value,value, in_value_len, 0);
+ *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), in_value_len, 0);
+
+ /* type */
+
+ *out_type = regval_type( val );
- *out_type=type;
+ /* data - counted in bytes */
- /* the data is counted in bytes */
- *out_max_data_len=in_data_len;
- if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) {
- SAFE_FREE(data);
- return WERR_NOMEM;
+ *out_max_data_len = in_data_len;
+ if ( (*data_out = (uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
+ {
+ result = WERR_NOMEM;
+ goto done;
+ }
+ data_len = (size_t)regval_size(val);
+ memcpy( *data_out, regval_data_p(val), data_len );
+ *out_data_len = data_len;
}
-
- memcpy(*data_out, data, (size_t)data_len);
- *out_data_len=data_len;
- SAFE_FREE(data);
-
- return WERR_OK;
+done:
+ free_a_printer(&printer, 2);
+ return result;
}
/****************************************************************************
@@ -7271,17 +7062,17 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *value = &q_u->value;
- uint32 type = q_u->type;
- uint8 *data = q_u->data;
- uint32 real_len = q_u->real_len;
+ POLICY_HND *handle = &q_u->handle;
+ UNISTR2 *value = &q_u->value;
+ uint32 type = q_u->type;
+ uint8 *data = q_u->data;
+ uint32 real_len = q_u->real_len;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- NT_PRINTER_PARAM *param = NULL, old_param;
- int snum=0;
- WERROR status = WERR_OK;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ int snum=0;
+ WERROR status = WERR_OK;
+ Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+ fstring valuename;
DEBUG(5,("spoolss_setprinterdata\n"));
@@ -7293,8 +7084,6 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
- ZERO_STRUCT(old_param);
-
/*
* Access check : NT returns "access denied" if you make a
* SetPrinterData call without the necessary privildge.
@@ -7309,40 +7098,22 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
goto done;
}
- /* Check if we are making any changes or not. Return true if
- nothing is actually changing. This is not needed anymore but
- has been left in as an optimization to keep from from
- writing to disk as often --jerry */
-
status = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(status))
return status;
- convert_specific_param(&param, value , type, data, real_len);
+ /* save the registry data */
+
+ unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
+ delete_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename );
+ add_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename, type, data, real_len );
- unlink_specific_param_if_exist(printer->info_2, param);
+ /* write the **entire** printer out to disk.... :-( */
- /*
- * When client side code sets a magic printer data key, detect it and save
- * the current printer data and the magic key's data (its the DEVMODE) for
- * future printer/driver initializations.
- */
- if (param->type==3 && !strcmp( param->value, PHANTOM_DEVMODE_KEY)) {
- /*
- * Set devmode and printer initialization info
- */
- status = save_driver_init(printer, 2, param);
- }
- else {
- add_a_specific_param(printer->info_2, &param);
- status = mod_a_printer(*printer, 2);
- }
+ status = mod_a_printer(*printer, 2);
- done:
+done:
free_a_printer(&printer, 2);
- if (param)
- free_nt_printer_param(&param);
- SAFE_FREE(old_param.data);
return status;
}
@@ -7352,9 +7123,9 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- int snum;
+ POLICY_HND *handle = &q_u->handle;
+ Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+ int snum;
DEBUG(5,("_spoolss_resetprinter\n"));
@@ -7378,16 +7149,19 @@ WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R
}
+/****************************************************************************
+****************************************************************************/
+
WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *value = &q_u->valuename;
+ POLICY_HND *handle = &q_u->handle;
+ UNISTR2 *value = &q_u->valuename;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- NT_PRINTER_PARAM param;
- int snum=0;
- WERROR status = WERR_OK;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ int snum=0;
+ WERROR status = WERR_OK;
+ Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+ pstring valuename;
DEBUG(5,("spoolss_deleteprinterdata\n"));
@@ -7408,15 +7182,14 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
if (!W_ERROR_IS_OK(status))
return status;
- ZERO_STRUCTP(&param);
- unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
+ unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
- if(!unlink_specific_param_if_exist(printer->info_2, &param))
- status = WERR_INVALID_PARAM;
- else
+ status = delete_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename );
+ if ( NT_STATUS_IS_OK(status) )
status = mod_a_printer(*printer, 2);
free_a_printer(&printer, 2);
+
return status;
}
@@ -7426,7 +7199,6 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
{
POLICY_HND *handle = &q_u->handle;
-/* uint32 level = q_u->level; - notused. */
FORM *form = &q_u->form;
nt_forms_struct tmpForm;
int snum;
@@ -8045,9 +7817,10 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u,
* (a) DsDriver
* (b) DsSpooler
* (c) PnPData
+ * (d) DsUser
*/
- if (strcmp(key, "PrinterDriverData") != 0)
+ if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
return WERR_BADFILE;
DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
@@ -8093,7 +7866,7 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
- if (strcmp(key, "PrinterDriverData") != 0)
+ if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
return WERR_INVALID_PARAM;
ZERO_STRUCT(q_u_local);
@@ -8128,7 +7901,7 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
- if (strcmp(key, "PrinterDriverData") != 0)
+ if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
return WERR_INVALID_PARAM;
memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND));
@@ -8153,7 +7926,7 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO
uint16 enumkeys[ENUMERATED_KEY_SIZE+1];
char* ptr = NULL;
int i;
- char *PrinterKey = "PrinterDriverData";
+ char *PrinterKey = SPOOL_PRINTERDATA_KEY;
DEBUG(4,("_spoolss_enumprinterkey\n"));
@@ -8222,7 +7995,7 @@ WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u,
unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
- if (strcmp(key, "PrinterDriverData") != 0)
+ if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
return WERR_INVALID_PARAM;
/*
@@ -8246,14 +8019,16 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
needed;
NT_PRINTER_INFO_LEVEL *printer = NULL;
PRINTER_ENUM_VALUES *enum_values = NULL;
- fstring key, value;
+ NT_PRINTER_DATA *p_data;
+ fstring key;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
int snum;
- uint32 param_index,
- data_len,
- type;
WERROR result;
- uint8 *data=NULL;
+ int key_index;
+ int i;
+ REGISTRY_VALUE *val;
+ char *value_name;
+ int data_len;
DEBUG(4,("_spoolss_enumprinterdataex\n"));
@@ -8264,20 +8039,8 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
}
- /*
- * The only key we support is "PrinterDriverData". This should return
- > an array of all the key/value pairs returned by EnumPrinterDataSee
- * _spoolss_getprinterdataex() for details --jerry
- */
-
- unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
- if (strcmp(key, "PrinterDriverData") != 0)
- {
- DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
- return WERR_INVALID_PARAM;
- }
-
-
+ /* first get the printer off of disk */
+
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
@@ -8285,61 +8048,76 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
result = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(result))
return result;
-
- /*
- * loop through all params and build the array to pass
- * back to the client
- */
+ /* now look for a match on the key name */
+
+ p_data = &printer->info_2->data;
+
+ unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
+ if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
+ {
+ DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
+ result = WERR_INVALID_PARAM;
+ goto done;
+ }
+
result = WERR_OK;
- param_index = 0;
- needed = 0;
- num_entries = 0;
+ needed = 0;
- while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len))
+ /* allocate the memory for the array of pointers -- if necessary */
+
+ num_entries = regval_ctr_numvals( &p_data->keys[key_index].values );
+ if ( num_entries )
{
- PRINTER_ENUM_VALUES *ptr;
-
- DEBUG(10,("retrieved value number [%d] [%s]\n", num_entries, value));
-
- if ((ptr=talloc_realloc(p->mem_ctx, enum_values, (num_entries+1) * sizeof(PRINTER_ENUM_VALUES))) == NULL)
+ if ( (enum_values=talloc(p->mem_ctx, num_entries*sizeof(PRINTER_ENUM_VALUES))) == NULL )
{
- DEBUG(0,("talloc_realloc failed to allocate more memory!\n"));
+ DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%d] bytes!\n",
+ num_entries*sizeof(PRINTER_ENUM_VALUES)));
result = WERR_NOMEM;
goto done;
}
- enum_values = ptr;
+
+ memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
+ }
+
+ /*
+ * loop through all params and build the array to pass
+ * back to the client
+ */
+
+ for ( i=0; i<num_entries; i++ )
+ {
+ /* lookup the registry value */
- ZERO_STRUCTP( &enum_values[num_entries] );
+ val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
+ DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
/* copy the data */
- init_unistr(&enum_values[num_entries].valuename, value);
- enum_values[num_entries].value_len = (strlen(value)+1) * 2;
- enum_values[num_entries].type = type;
+ value_name = regval_name( val );
+ init_unistr( &enum_values[i].valuename, value_name );
+ enum_values[i].value_len = (strlen(value_name)+1) * 2;
+ enum_values[i].type = regval_type( val );
- if ( data_len )
- {
- if ( !(enum_values[num_entries].data = talloc_zero(p->mem_ctx, data_len)) ) {
- DEBUG(0,("talloc_realloc failed to allocate more memory [data_len=%d] for data!\n", data_len ));
+ data_len = regval_size( val );
+ if ( data_len ) {
+ if ( !(enum_values[i].data = talloc_memdup(p->mem_ctx, regval_data_p(val), data_len)) )
+ {
+ DEBUG(0,("talloc_memdup failed to allocate memory [data_len=%d] for data!\n",
+ data_len ));
result = WERR_NOMEM;
goto done;
}
- memcpy(enum_values[num_entries].data, data, data_len);
}
-
- enum_values[num_entries].data_len = data_len;
+ enum_values[i].data_len = data_len;
/* keep track of the size of the array in bytes */
needed += spoolss_size_printer_enum_values(&enum_values[num_entries]);
-
- num_entries++;
- param_index++;
}
- r_u->needed = needed;
- r_u->returned = num_entries;
+ r_u->needed = needed;
+ r_u->returned = num_entries;
if (needed > in_size) {
result = WERR_MORE_DATA;