summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/printing/load.c8
-rw-r--r--source3/printing/notify.c65
-rw-r--r--source3/printing/nt_printing.c882
3 files changed, 432 insertions, 523 deletions
diff --git a/source3/printing/load.c b/source3/printing/load.c
index ed967fb0a7..cd90cbb6f3 100644
--- a/source3/printing/load.c
+++ b/source3/printing/load.c
@@ -38,7 +38,7 @@ auto-load some homes and printer services
***************************************************************************/
static void add_auto_printers(void)
{
- char *p;
+ const char *p;
int printers;
char *str = strdup(lp_auto_services());
@@ -47,9 +47,9 @@ static void add_auto_printers(void)
printers = lp_servicenumber(PRINTERS_NAME);
if (printers < 0) {
- SAFE_FREE(str);
- return;
- }
+ SAFE_FREE(str);
+ return;
+ }
for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
if (lp_servicenumber(p) >= 0) continue;
diff --git a/source3/printing/notify.c b/source3/printing/notify.c
index 21e28d0ca7..925d49a21d 100644
--- a/source3/printing/notify.c
+++ b/source3/printing/notify.c
@@ -3,6 +3,7 @@
Version 2.2
printing backend routines
Copyright (C) Tim Potter, 2002
+ Copyright (C) Gerald Carter, 2002
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
@@ -65,18 +66,17 @@ again:
/* Send message */
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
+ tdb = conn_tdb_ctx();
if (!tdb) {
DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n"));
- return;
+ goto done;
}
+
+ message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf, buflen, False, NULL);
- message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf,
- buflen, False, NULL);
-
+done:
SAFE_FREE(buf);
- tdb_close(tdb);
}
static void send_notify_field_values(const char *printer_name, uint32 type,
@@ -129,7 +129,7 @@ void notify_printer_status_byname(const char *printer_name, uint32 status)
void notify_printer_status(int snum, uint32 status)
{
- const char *printer_name = PRINTERNAME(snum);
+ const char *printer_name = SERVICE(snum);
if (printer_name)
notify_printer_status_byname(printer_name, status);
@@ -147,14 +147,14 @@ void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 sta
void notify_job_status(int snum, uint32 jobid, uint32 status)
{
- const char *printer_name = PRINTERNAME(snum);
+ const char *printer_name = SERVICE(snum);
notify_job_status_byname(printer_name, jobid, status, 0);
}
void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
{
- const char *printer_name = PRINTERNAME(snum);
+ const char *printer_name = SERVICE(snum);
/* Job id stored in id field, status in value1 */
@@ -165,7 +165,7 @@ void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
{
- const char *printer_name = PRINTERNAME(snum);
+ const char *printer_name = SERVICE(snum);
/* Job id stored in id field, status in value1 */
@@ -176,7 +176,7 @@ void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
void notify_job_username(int snum, uint32 jobid, char *name)
{
- const char *printer_name = PRINTERNAME(snum);
+ const char *printer_name = SERVICE(snum);
send_notify_field_buffer(
printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
@@ -185,7 +185,7 @@ void notify_job_username(int snum, uint32 jobid, char *name)
void notify_job_name(int snum, uint32 jobid, char *name)
{
- const char *printer_name = PRINTERNAME(snum);
+ const char *printer_name = SERVICE(snum);
send_notify_field_buffer(
printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
@@ -194,37 +194,54 @@ void notify_job_name(int snum, uint32 jobid, char *name)
void notify_job_submitted(int snum, uint32 jobid, time_t submitted)
{
- const char *printer_name = PRINTERNAME(snum);
+ const char *printer_name = SERVICE(snum);
send_notify_field_buffer(
printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED,
jobid, sizeof(submitted), (char *)&submitted);
}
-void notify_printer_delete(char *printer_name)
+void notify_printer_driver(int snum, char *driver_name)
{
-}
+ const char *printer_name = SERVICE(snum);
-void notify_printer_add(char *printer_name)
-{
+ send_notify_field_buffer(
+ printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,
+ snum, strlen(driver_name) + 1, driver_name);
}
-void notify_printer_driver(int num, char *driver_name)
+void notify_printer_comment(int snum, char *comment)
{
-}
+ const char *printer_name = SERVICE(snum);
-void notify_printer_comment(int num, char *comment)
-{
+ send_notify_field_buffer(
+ printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,
+ snum, strlen(comment) + 1, comment);
}
-void notify_printer_sharename(int num, char *share_name)
+void notify_printer_sharename(int snum, char *share_name)
{
+ const char *printer_name = SERVICE(snum);
+
+ send_notify_field_buffer(
+ printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
+ snum, strlen(share_name) + 1, share_name);
}
-void notify_printer_port(int num, char *port_name)
+void notify_printer_port(int snum, char *port_name)
{
+ const char *printer_name = SERVICE(snum);
+
+ send_notify_field_buffer(
+ printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,
+ snum, strlen(port_name) + 1, port_name);
}
-void notify_printer_location(int num, char *location)
+void notify_printer_location(int snum, char *location)
{
+ const char *printer_name = SERVICE(snum);
+
+ send_notify_field_buffer(
+ printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
+ snum, strlen(location) + 1, location);
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index ff08b99eb0..3b85fce020 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -319,7 +319,17 @@ BOOL nt_printing_init(void)
* register callback to handle updating printers as new
* drivers are installed
*/
- message_register(MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer);
+
+ message_register( MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer );
+
+ /*
+ * register callback to handle updating printer data
+ * when a driver is initialized
+ */
+
+ message_register( MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata );
+
+
return True;
}
@@ -435,25 +445,29 @@ int get_ntforms(nt_forms_struct **list)
for (kbuf = tdb_firstkey(tdb_forms);
kbuf.dptr;
- newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
- if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
+ newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
+ {
+ if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
+ continue;
dbuf = tdb_fetch(tdb_forms, kbuf);
- if (!dbuf.dptr) continue;
+ if (!dbuf.dptr)
+ continue;
fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
&i, &form.flag, &form.width, &form.length, &form.left,
&form.top, &form.right, &form.bottom);
SAFE_FREE(dbuf.dptr);
- if (ret != dbuf.dsize) continue;
+ if (ret != dbuf.dsize)
+ continue;
tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
if (!tl) {
DEBUG(0,("get_ntforms: Realloc fail.\n"));
return 0;
}
- *list = tl;
+ *list = tl;
(*list)[n] = form;
n++;
}
@@ -998,7 +1012,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file,
}
close_file(fsp, True);
- if (use_version) {
+ if (use_version && (new_major != old_major || new_minor != old_minor)) {
/* Compare versions and choose the larger version number */
if (new_major > old_major ||
(new_major == old_major && new_minor > old_minor)) {
@@ -1218,8 +1232,7 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
- struct current_user *user)
+static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
{
fstring architecture;
fstring new_name;
@@ -1274,8 +1287,7 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
* NT 4: cversion=2
* NT2K: cversion=3
*/
- if ((driver->version = get_correct_cversion(architecture,
- driver->driverpath, user, &err)) == -1)
+ if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
return err;
return WERR_OK;
@@ -1747,7 +1759,8 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
driver.defaultdatatype);
i=0;
- while (len < dbuf.dsize) {
+ while (len < dbuf.dsize)
+ {
fstring *tddfs;
tddfs = (fstring *)Realloc(driver.dependentfiles,
@@ -1762,13 +1775,15 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
&driver.dependentfiles[i]);
i++;
}
+
if (driver.dependentfiles != NULL)
fstrcpy(driver.dependentfiles[i], "");
SAFE_FREE(dbuf.dptr);
- if (len != dbuf.dsize) {
- SAFE_FREE(driver.dependentfiles);
+ if (len != dbuf.dsize)
+ {
+ SAFE_FREE(driver.dependentfiles);
return get_a_printer_driver_3_default(info_ptr, drivername, arch);
}
@@ -1950,22 +1965,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;
}
@@ -2059,7 +2104,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;
@@ -2099,89 +2144,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.
****************************************************************************/
@@ -2282,7 +2244,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);
}
@@ -2292,23 +2254,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 );
}
@@ -2388,32 +2356,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;
+}
- *list = NULL;
+/****************************************************************************
+ 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;
- while (1) {
- len += tdb_unpack(buf+len, buflen-len, "p", &p);
- if (!p) break;
+ DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
+ /* 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;
+
+ /* 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));
-
- DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
+ 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\\%s], len: %d\n", keyname, valuename, size));
}
return len;
}
+/****************************************************************************
+ ***************************************************************************/
+
static void map_to_os2_driver(fstring drivername)
{
static BOOL initialised=False;
@@ -2647,10 +2840,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);
@@ -2837,34 +3030,31 @@ 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;
+
+ ZERO_STRUCT(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);
- }
-
- ZERO_STRUCT(info);
-
+
+ delete_all_printer_data( info_ptr );
+
slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
kbuf.dptr = key;
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.
@@ -2872,16 +3062,18 @@ static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
free_nt_devicemode(&info_ptr->devmode);
return False;
}
-
+
/*
* Get the saved DEVMODE..
*/
+
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
/*
* The saved DEVMODE contains the devicename from the printer used during
* the initialization save. Change it to reflect the new printer.
*/
+
ZERO_STRUCT(info.devmode->devicename);
fstrcpy(info.devmode->devicename, info_ptr->printername);
@@ -2897,45 +3089,20 @@ static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
* --jerry
*/
-#if 1 /* JERRY */
- /*
- * Bind the saved DEVMODE to the new the printer.
- */
+ /* Bind the saved DEVMODE to the new the printer */
+
free_nt_devicemode(&info_ptr->devmode);
info_ptr->devmode = info.devmode;
-#else
- /* copy the entire devmode if we currently don't have one */
-
- if (!info_ptr->devmode) {
- DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n"));
- info_ptr->devmode = info.devmode;
- }
- else {
- /* only set the necessary fields */
- DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
- info.devmode->driverversion, info.devmode->driverextra));
-
- info_ptr->devmode->driverversion = info.devmode->driverversion;
-
- SAFE_FREE(info_ptr->devmode->private);
- info_ptr->devmode->private = NULL;
-
- if (info.devmode->driverversion)
- info_ptr->devmode->private = memdup(info.devmode->private, info.devmode->driverversion);
-
- free_nt_devicemode(&info.devmode);
- }
-#endif
DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
info_ptr->printername, info_ptr->drivername));
- /*
- * Add the printer data 'specifics' to the new printer
- */
- len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
+ /* Add the printer data 'values' to the new printer */
+
+ len += unpack_values( &info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
+
SAFE_FREE(dbuf.dptr);
@@ -2956,7 +3123,7 @@ BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
switch (level)
{
case 2:
- result=set_driver_init_2(printer->info_2);
+ result = set_driver_init_2(printer->info_2);
break;
default:
@@ -2993,7 +3160,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
@@ -3014,7 +3181,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;
@@ -3045,14 +3212,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)
@@ -3077,154 +3244,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.
****************************************************************************/
@@ -3752,7 +3771,7 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
{
pstring key;
fstring arch;
- TDB_DATA kbuf;
+ TDB_DATA kbuf, dbuf;
NT_PRINTER_DRIVER_INFO_LEVEL ctr;
/* delete the tdb data first */
@@ -3770,8 +3789,20 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
+ /* check if the driver actually exists for this environment */
+
+ dbuf = tdb_fetch( tdb_drivers, kbuf );
+ if ( !dbuf.dptr ) {
+ DEBUG(8,("delete_printer_driver_internal: Driver unknown [%s]\n", key));
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
+
+ SAFE_FREE( dbuf.dptr );
+
+ /* ok... the driver exists so the delete should return success */
+
if (tdb_delete(tdb_drivers, kbuf) == -1) {
- DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
+ DEBUG (0,("delete_printer_driver_internal: fail to delete %s!\n", key));
return WERR_ACCESS_DENIED;
}
@@ -3784,8 +3815,8 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
if ( delete_files )
delete_driver_files( i, user );
- DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
- i->name));
+
+ DEBUG(5,("delete_printer_driver_internal: driver delete successful [%s]\n", key));
return WERR_OK;
}
@@ -3798,99 +3829,33 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user,
uint32 version, BOOL delete_files )
{
- int ver;
WERROR err;
- /* see if we should delete all versions of this driver */
+ /*
+ * see if we should delete all versions of this driver
+ * (DRIVER_ANY_VERSION uis only set for "Windows NT x86")
+ */
- if ( version == DRIVER_ANY_VERSION ) {
- for ( ver=0; ver<DRIVER_MAX_VERSION; ver++ ) {
- err = delete_printer_driver_internal(i, user, ver, delete_files );
- if ( !W_ERROR_IS_OK(err) )
+ if ( version == DRIVER_ANY_VERSION )
+ {
+ /* Windows NT 4.0 */
+
+ err = delete_printer_driver_internal(i, user, 2, delete_files );
+ if ( !W_ERROR_IS_OK(err) && (W_ERROR_V(err) != ERRunknownprinterdriver ) )
+ return err;
+
+ /* Windows 2000/XP */
+
+ err = delete_printer_driver_internal(i, user, 3, delete_files );
+ if ( !W_ERROR_IS_OK(err) && (W_ERROR_V(err) != ERRunknownprinterdriver ) )
return err;
- }
- }
- else
- delete_printer_driver_internal(i, user, version, delete_files );
return WERR_OK;
-}
-
-
-/****************************************************************************
-****************************************************************************/
-
-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;
- }
+ /* just delete what they asked for */
- 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);
+ return delete_printer_driver_internal(i, user, version, delete_files );
}
/****************************************************************************
@@ -4328,76 +4293,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 */