summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_spoolss_nt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server/srv_spoolss_nt.c')
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c1330
1 files changed, 414 insertions, 916 deletions
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 68c792f8b0..322efa22b5 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
* Copyright (C) Jean François Micouleau 1998-2000,
* Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Gerald Carter 2000-2002,
+ * Copyright (C) Gerald Carter 2000-2001,
* Copyright (C) Tim Potter 2001-2002.
*
* This program is free software; you can redistribute it and/or modify
@@ -28,10 +28,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-/* #define EMULATE_WIN2K_HACK 1 */
-
#ifndef MAX_OPEN_PRINTER_EXS
#define MAX_OPEN_PRINTER_EXS 50
#endif
@@ -41,15 +37,6 @@
#define PRINTER_HANDLE_IS_PRINTER 0
#define PRINTER_HANDLE_IS_PRINTSERVER 1
-/* Table to map the driver version */
-/* to OS */
-char * drv_ver_to_os[] = {
- "WIN9X", /* driver version/cversion 0 */
- "", /* unused ? */
- "WINNT", /* driver version/cversion 2 */
- "WIN2K", /* driver version/cversion 3 */
-};
-
struct table_node {
char *long_archi;
char *short_archi;
@@ -81,7 +68,6 @@ typedef struct _Printer{
SPOOL_NOTIFY_OPTION *option;
POLICY_HND client_hnd;
uint32 client_connected;
- uint32 change;
} notify;
struct {
fstring machine;
@@ -192,10 +178,10 @@ static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
/* if it's the last connection, deconnect the IPC$ share */
if (smb_connections==1) {
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- message_deregister(MSG_PRINTER_NOTIFY2);
+ if(!spoolss_disconnect_from_client(&cli))
+ return;
+
+ message_deregister(MSG_PRINTER_NOTIFY);
}
smb_connections--;
@@ -440,7 +426,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
* anymore, so I've simplified this loop greatly. Here
* we are just verifying that the printer name is a valid
* printer service defined in smb.conf
- * --jerry [Fri Feb 15 11:17:46 CST 2002]
+ * --jerry [Fri Feb 15 11:17:46 CST 2002]
*/
for (snum=0; snum<n_services; snum++) {
@@ -549,417 +535,229 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
return True;
}
-
/***************************************************************************
- check to see if the client motify handle is monitoring the notification
- given by (notify_type, notify_field).
+ Always give preference Printer_entry.notify.option over
+ Printer_entry.notify.flags. Return True if we should send notification
+ events using SPOOLSS_RRPCN. False means that we should use
+ SPOOLSS_ROUTERREPLYPRINTER.
**************************************************************************/
-
-static BOOL is_monitoring_event_flags(uint32 flags, uint16 notify_type,
- uint16 notify_field)
+static BOOL valid_notify_options(Printer_entry *printer)
{
+ if (printer->notify.option == NULL)
+ return False;
+
return True;
}
-static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type,
- uint16 notify_field)
+/***************************************************************************
+ Simple check to see if the client motify handle is set to watch for events
+ represented by 'flags'
+
+ FIXME!!!! only a stub right now --jerry
+ **************************************************************************/
+
+static BOOL is_client_monitoring_event(Printer_entry *p, uint32 flags)
{
- SPOOL_NOTIFY_OPTION *option = p->notify.option;
- uint32 i, j;
-
- if (p->notify.flags)
- return is_monitoring_event_flags(
- p->notify.flags, notify_type, notify_field);
- for (i = 0; i < option->count; i++) {
-
- /* Check match for notify_type */
-
- if (option->ctr.type[i].type != notify_type)
- continue;
-
- /* Check match for field */
-
- for (j = 0; j < option->ctr.type[i].count; j++) {
- if (option->ctr.type[i].fields[j] == notify_field) {
- return True;
- }
- }
- }
-
- DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n",
- (p->printer_type == PRINTER_HANDLE_IS_PRINTER) ?
- p->dev.handlename : p->dev.printerservername,
- notify_type, notify_field));
-
- return False;
-}
-
-/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
-
-static void notify_one_value(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
- TALLOC_CTX *mem_ctx)
-{
- data->notify_data.value[0] = msg->notify.value[0];
- data->notify_data.value[1] = 0;
+ return True;
}
-static void notify_string(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
- TALLOC_CTX *mem_ctx)
+/***************************************************************************
+ Server wrapper for cli_spoolss_routerreplyprinter() since the client
+ function can only send a single change notification at a time.
+
+ FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER)
+ --jerry
+ **************************************************************************/
+
+static WERROR srv_spoolss_routerreplyprinter (struct cli_state *reply_cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, PRINTER_MESSAGE_INFO *info,
+ NT_PRINTER_INFO_LEVEL *printer)
{
- UNISTR2 unistr;
+ WERROR result;
+ uint32 condition = 0x0;
- /* The length of the message includes the trailing \0 */
-
- init_unistr2(&unistr, msg->notify.data, msg->len);
-
- data->notify_data.data.length = msg->len * 2;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, msg->len * 2);
-
- if (!data->notify_data.data.string) {
- data->notify_data.data.length = 0;
- return;
- }
+ if (info->flags & PRINTER_MESSAGE_DRIVER)
+ condition = PRINTER_CHANGE_SET_PRINTER_DRIVER;
- memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
+ result = cli_spoolss_routerreplyprinter(reply_cli, mem_ctx, pol, condition,
+ printer->info_2->changeid);
+
+ return result;
}
-static void notify_system_time(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
- TALLOC_CTX *mem_ctx)
+/***********************************************************************
+ Wrapper around the decision of which RPC use to in the change
+ notification
+ **********************************************************************/
+
+static WERROR srv_spoolss_send_event_to_client(Printer_entry* Printer,
+ struct cli_state *send_cli, PRINTER_MESSAGE_INFO *msg,
+ NT_PRINTER_INFO_LEVEL *info)
{
- SYSTEMTIME systime;
- prs_struct ps;
-
- if (msg->len != sizeof(time_t)) {
- DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
- msg->len));
- return;
- }
+ WERROR result;
+
+ if (valid_notify_options(Printer)) {
+ /* This is a single call that can send information about multiple changes */
+ if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ msg->flags |= PRINTER_MESSAGE_ATTRIBUTES;
- if (!prs_init(&ps, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- DEBUG(5, ("notify_system_time: prs_init() failed\n"));
- return;
+ result = cli_spoolss_reply_rrpcn(send_cli, send_cli->mem_ctx, &Printer->notify.client_hnd,
+ msg, info);
}
-
- if (!make_systemtime(&systime, localtime((time_t *)msg->notify.data))) {
- DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
- return;
+ else {
+ /* This requires that the server send an individual event notification for each change */
+ result = srv_spoolss_routerreplyprinter(send_cli, send_cli->mem_ctx, &Printer->notify.client_hnd,
+ msg, info);
}
-
- if (!spoolss_io_system_time("", &ps, 0, &systime))
- return;
-
- data->notify_data.data.length = prs_offset(&ps);
- data->notify_data.data.string =
- talloc(mem_ctx, prs_offset(&ps));
-
- memcpy(data->notify_data.data.string, prs_data_p(&ps), prs_offset(&ps));
-
- prs_mem_free(&ps);
+
+ return result;
}
-struct notify2_message_table {
- char *name;
- void (*fn)(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
-};
-
-static struct notify2_message_table printer_notify_table[] = {
- /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", NULL },
- /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", NULL },
- /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", NULL },
- /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", NULL },
- /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", NULL },
- /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", NULL },
- /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", NULL },
- /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
- /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", NULL },
- /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", NULL },
- /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
- /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", NULL },
- /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
- /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", NULL },
- /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", NULL },
- /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
- /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
- /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
- /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
-};
-
-static struct notify2_message_table job_notify_table[] = {
- /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
- /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
- /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
- /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
- /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
- /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
- /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
- /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
- /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
- /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
- /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
- /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
- /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
- /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
- /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
- /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
- /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
- /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
- /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
- /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
- /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
- /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
- /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
- /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
-};
/***********************************************************************
Send a change notication message on all handles which have a call
back registered
**********************************************************************/
-static void process_notify2_message(struct spoolss_notify_msg *msg,
- TALLOC_CTX *mem_ctx)
+static void send_spoolss_event_notification(PRINTER_MESSAGE_INFO *msg)
{
- Printer_entry *p;
-
- for (p = printers_list; p; p = p->next) {
- SPOOL_NOTIFY_INFO_DATA *data;
- uint32 data_len = 1;
- uint32 id;
-
- /* Is there notification on this handle? */
-
- if (!p->notify.client_connected)
- continue;
-
- /* For this printer? Print servers always receive
- notifications. */
-
- if (p->printer_type == PRINTER_HANDLE_IS_PRINTER &&
- !strequal(msg->printer, p->dev.handlename))
- continue;
-
- /* Are we monitoring this event? */
-
- if (!is_monitoring_event(p, msg->type, msg->field))
- continue;
-
- /* OK - send the event to the client */
-
- data = talloc(mem_ctx, sizeof(SPOOL_NOTIFY_INFO_DATA));
-
- ZERO_STRUCTP(data);
+ Printer_entry *find_printer;
+ WERROR result;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
- /* Convert unix jobid to smb jobid */
+ if (!msg) {
+ DEBUG(0,("send_spoolss_event_notification: NULL msg pointer!\n"));
+ return;
+ }
- id = msg->id;
+ for(find_printer = printers_list; find_printer; find_printer = find_printer->next) {
- if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
+ /*
+ * If the entry has a connected client we send the message. There should
+ * only be one of these normally when dealing with the NT/2k spooler.
+ * However, iterate over all to make sure we deal with user applications
+ * in addition to spooler service.
+ *
+ * While we are only maintaining a single connection to the client,
+ * the FindFirstPrinterChangeNotification() call is made on a printer
+ * handle, so "client_connected" represents the whether or not the
+ * client asked for change notication on this handle.
+ *
+ * --jerry
+ */
- id = sysjob_to_jobid(msg->id);
+ if (find_printer->notify.client_connected==True) {
+
+ /* does the client care about what changed? */
- if (id == -1) {
- DEBUG(3, ("no such unix jobid %d\n", msg->id));
- goto done;
+ if (msg->flags && !is_client_monitoring_event(find_printer, msg->flags)) {
+ DEBUG(10,("send_spoolss_event_notification: Client [%s] not monitoring these events\n",
+ find_printer->client.machine));
+ continue;
}
- }
- construct_info_data(data, msg->type, msg->field, id);
-
- switch(msg->type) {
- case PRINTER_NOTIFY_TYPE:
- if (printer_notify_table[msg->field].fn)
- printer_notify_table[msg->field].fn(
- msg, data, mem_ctx);
- else
- goto done;
- break;
- case JOB_NOTIFY_TYPE:
- if (job_notify_table[msg->field].fn)
- job_notify_table[msg->field].fn(
- msg, data, mem_ctx);
+ if (find_printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ DEBUG(10,("send_spoolss_event_notification: printserver [%s]\n", find_printer->dev.printerservername ));
else
- goto done;
- break;
- default:
- DEBUG(5, ("Unknown notification type %d\n",
- msg->type));
- goto done;
- }
-
- if (!p->notify.flags)
- cli_spoolss_rrpcn(
- &cli, mem_ctx, &p->notify.client_hnd,
- data_len, data, p->notify.change, 0);
- else {
- NT_PRINTER_INFO_LEVEL *printer = NULL;
+ DEBUG(10,("send_spoolss_event_notification: printer [%s]\n", find_printer->dev.handlename));
- get_a_printer(&printer, 2, msg->printer);
+ /*
+ * if handle is a printer, only send if the printer_name matches.
+ * ...else if handle is a printerserver, send to all
+ */
- if (!printer) {
- DEBUG(5, ("unable to load info2 for %s\n",
- msg->printer));
- goto done;
+ if (*msg->printer_name && (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
+ && !strequal(msg->printer_name, find_printer->dev.handlename))
+ {
+ DEBUG(10,("send_spoolss_event_notification: ignoring message sent to %s [%s]\n",
+ msg->printer_name, find_printer->dev.handlename ));
+ continue;
}
- /* XXX: This needs to be updated for
- PRINTER_CHANGE_SET_PRINTER_DRIVER. */
- cli_spoolss_routerreplyprinter(
- &cli, mem_ctx, &p->notify.client_hnd,
- 0, printer->info_2->changeid);
+ /* lookup the printer if we have a name if we don't already have a
+ valid NT_PRINTER_INFO_LEVEL structure. And yes I'm assuming we
+ will always have a non-empty msg.printer_name */
+
+ if (!printer || !printer->info_2 || strcmp(msg->printer_name, printer->info_2->printername))
+ {
+
+ if (printer) {
+ free_a_printer(&printer, 2);
+ printer = NULL;
+ }
+
+ result = get_a_printer(&printer, 2, msg->printer_name);
+ if (!W_ERROR_IS_OK(result))
+ continue;
+ }
- free_a_printer(&printer, 2);
+ /* issue the client call */
+
+ result = srv_spoolss_send_event_to_client(find_printer, &cli, msg, printer);
+
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(5,("send_spoolss_event_notification: Event notification failed [%s]\n",
+ dos_errstr(result)));
}
}
-done:
- return;
}
-/* Receive a notify2 message */
+ return;
+}
+/***************************************************************************
+ Receive the notify message and decode the message. Do not send
+ notification if we sent this originally as that would result in
+ duplicates.
+****************************************************************************/
-static void receive_notify2_message(int msg_type, pid_t src, void *buf,
- size_t len)
+static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
{
- struct spoolss_notify_msg msg;
- int offset = 0;
- TALLOC_CTX *mem_ctx = talloc_init();
-
- /* Unpack message */
-
- ZERO_STRUCT(msg);
-
- offset += tdb_unpack((char *)buf + offset, len - offset, "f",
- msg.printer);
+ PRINTER_MESSAGE_INFO msg;
- offset += tdb_unpack((char *)buf + offset, len - offset, "ddddd",
- &msg.type, &msg.field, &msg.id, &msg.len, &msg.flags);
-
- if (msg.len == 0)
- tdb_unpack((char *)buf + offset, len - offset, "dd",
- &msg.notify.value[0], &msg.notify.value[1]);
- else
- tdb_unpack((char *)buf + offset, len - offset, "B",
- &msg.len, &msg.notify.data);
-
- DEBUG(3, ("got NOTIFY2 message, type %d, field 0x%02x, flags 0x%04x\n",
- msg.type, msg.field, msg.flags));
-
- if (msg.len == 0)
- DEBUG(3, ("value1 = %d, value2 = %d\n", msg.notify.value[0],
- msg.notify.value[1]));
- else
- dump_data(3, msg.notify.data, msg.len);
-
- /* Process message */
-
- process_notify2_message(&msg, mem_ctx);
-
- /* Free message */
+ if (len < sizeof(msg)) {
+ DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len));
+ return;
+ }
- if (msg.len > 0)
- free(msg.notify.data);
+ memcpy(&msg, buf, sizeof(PRINTER_MESSAGE_INFO));
+
+ DEBUG(10,("srv_spoolss_receive_message: Got message printer change [queue = %s] low=0x%x high=0x%x flags=0x%x\n",
+ msg.printer_name, (unsigned int)msg.low, (unsigned int)msg.high, msg.flags ));
- talloc_destroy(mem_ctx);
+ /* Iterate the printer list */
+
+ send_spoolss_event_notification(&msg);
+
}
/***************************************************************************
- Server wrapper for cli_spoolss_routerreplyprinter() since the client
- function can only send a single change notification at a time.
-
- FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER)
- --jerry
- **************************************************************************/
-
-static WERROR srv_spoolss_routerreplyprinter (struct cli_state *reply_cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, PRINTER_MESSAGE_INFO *info,
- NT_PRINTER_INFO_LEVEL *printer)
+ Send a notify event.
+****************************************************************************/
+
+static BOOL srv_spoolss_sendnotify(char* printer_name, uint32 high, uint32 low, uint32 flags)
{
- WERROR result;
- uint32 condition = 0x0;
+ char msg[sizeof(PRINTER_MESSAGE_INFO)];
+ PRINTER_MESSAGE_INFO info;
- if (info->flags & PRINTER_MESSAGE_DRIVER)
- condition = PRINTER_CHANGE_SET_PRINTER_DRIVER;
-
- result = cli_spoolss_routerreplyprinter(reply_cli, mem_ctx, pol, condition,
- printer->info_2->changeid);
-
- return result;
-}
+ ZERO_STRUCT(info);
-/********************************************************************
- Send a message to ourself about new driver being installed
- so we can upgrade the information for each printer bound to this
- driver
- ********************************************************************/
-
-static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
-{
- int len = strlen(drivername);
+ info.low = low;
+ info.high = high;
+ info.flags = flags;
+ fstrcpy(info.printer_name, printer_name);
- if (!len)
- return False;
+ memcpy(msg, &info, sizeof(PRINTER_MESSAGE_INFO));
- DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
- drivername));
+ DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x [%s], flags=0x%x\n",
+ low, high, printer_name, flags));
- message_send_pid(sys_getpid(), MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);
+ message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(PRINTER_MESSAGE_INFO),
+ False, NULL);
return True;
-}
-
-/**********************************************************************
- callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
- over all printers, upgrading ones as neessary
- **********************************************************************/
-
-void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
-{
- fstring drivername;
- int snum;
- int n_services = lp_numservices();
-
- len = MIN(len,sizeof(drivername)-1);
- strncpy(drivername, buf, len);
-
- DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
-
- /* Iterate the printer list */
-
- for (snum=0; snum<n_services; snum++)
- {
- if (lp_snum_ok(snum) && lp_print_ok(snum) )
- {
- WERROR result;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- result = get_a_printer(&printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(result))
- continue;
-
- if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
- {
- DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
-
- /* all we care about currently is the change_id */
-
- result = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(result)) {
- DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
- dos_errstr(result)));
- }
- }
-
- free_a_printer(&printer, 2);
- }
- }
-
- /* all done */
-}
+}
/********************************************************************
Copy routines used by convert_to_openprinterex()
@@ -1126,6 +924,16 @@ Can't find printer handle we created for printer %s\n", name ));
return WERR_INVALID_PRINTER_NAME;
}
+/*
+ if (printer_default->datatype_ptr != NULL)
+ {
+ unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
+ set_printer_hnd_datatype(handle, datatype);
+ }
+ else
+ set_printer_hnd_datatype(handle, "");
+*/
+
/*
First case: the user is opening the print server:
@@ -1189,7 +997,7 @@ Can't find printer handle we created for printer %s\n", name ));
user_in_list(uidtoname(user.uid),
lp_printer_admin(snum)))
return WERR_OK;
-
+
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
}
@@ -1223,9 +1031,7 @@ Can't find printer handle we created for printer %s\n", name ));
printer_default->access_required = PRINTER_ACCESS_USE;
}
- /* check smb.conf parameters and the the sec_desc */
-
- if (!user_ok(uidtoname(user.uid), snum) || !print_access_check(&user, snum, printer_default->access_required)) {
+ if (!print_access_check(&user, snum, printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -1502,6 +1308,10 @@ WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL
update_c_setprinter(False);
+ if (W_ERROR_IS_OK(result)) {
+ srv_spoolss_sendnotify(Printer->dev.handlename, 0, PRINTER_CHANGE_DELETE_PRINTER, 0x0);
+ }
+
return result;
}
@@ -1534,17 +1344,26 @@ static int get_version_id (char * arch)
/********************************************************************
* _spoolss_deleteprinterdriver
+ *
+ * We currently delete the driver for the architecture only.
+ * This can leave the driver for other archtectures. However,
+ * since every printer associates a "Windows NT x86" driver name
+ * and we cannot delete that one while it is in use, **and** since
+ * it is impossible to assign a driver to a Samba printer without
+ * having the "Windows NT x86" driver installed,...
+ *
+ * ....we should not get into trouble here.
+ *
+ * --jerry
********************************************************************/
-WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u)
+WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
+ SPOOL_R_DELETEPRINTERDRIVER *r_u)
{
fstring driver;
fstring arch;
NT_PRINTER_DRIVER_INFO_LEVEL info;
int version;
- struct current_user user;
-
- get_current_user(&user, p);
unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
@@ -1554,89 +1373,21 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* this is what NT returns */
return WERR_INVALID_ENVIRONMENT;
}
-
- /* if they said "Windows NT x86", then try for version 2 & 3 */
-
- if ( version == 2 )
- version = DRIVER_ANY_VERSION;
ZERO_STRUCT(info);
-
- if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
return WERR_UNKNOWN_PRINTER_DRIVER;
-
- if (printer_driver_in_use(info.info_3))
- return WERR_PRINTER_DRIVER_IN_USE;
-
- return delete_printer_driver(info.info_3, &user, DRIVER_ANY_VERSION, False);
-}
-
-/********************************************************************
- * spoolss_deleteprinterdriverex
- ********************************************************************/
-
-WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u)
-{
- fstring driver;
- fstring arch;
- NT_PRINTER_DRIVER_INFO_LEVEL info;
- int version;
- uint32 flags = q_u->delete_flags;
- BOOL delete_files;
- struct current_user user;
-
- get_current_user(&user, p);
-
- unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
- unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
-
- /* check that we have a valid driver name first */
- if ((version=get_version_id(arch)) == -1) {
- /* this is what NT returns */
- return WERR_INVALID_ENVIRONMENT;
}
- if ( flags & DPD_DELETE_SPECIFIC_VERSION )
- version = q_u->version;
- else if ( version == 2 )
- /* if they said "Windows NT x86", then try for version 2 & 3 */
- version = DRIVER_ANY_VERSION;
-
- ZERO_STRUCT(info);
-
- if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
- return WERR_UNKNOWN_PRINTER_DRIVER;
-
- if ( printer_driver_in_use(info.info_3) )
- return WERR_PRINTER_DRIVER_IN_USE;
-
- /*
- * we have a couple of cases to consider.
- * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
- * then the delete should fail if **any** files overlap with
- * other drivers
- * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
- * non-overlapping files
- * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
- * is set, the do not delete any files
- * Refer to MSDN docs on DeletePrinterDriverEx() for details.
- */
-
- delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
-
- if ( delete_files )
+
+ if (printer_driver_in_use(arch, driver))
{
- /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
-
- if ( printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) )
- /* no idea of the correct error here */
- return WERR_ACCESS_DENIED;
+ return WERR_PRINTER_DRIVER_IN_USE;
}
- return delete_printer_driver(info.info_3, &user, version, delete_files);
+ return delete_printer_driver(info.info_3);
}
-
/********************************************************************
GetPrinterData on a printer server Handle.
********************************************************************/
@@ -1687,11 +1438,7 @@ static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32
*type = 0x4;
if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
return False;
-#ifndef EMULATE_WIN2K_HACK /* JERRY */
SIVAL(*data, 0, 2);
-#else
- SIVAL(*data, 0, 3);
-#endif
*needed = 0x4;
return True;
}
@@ -1859,96 +1606,6 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
return WERR_OK;
}
-/*********************************************************
- Connect to the client machine.
-**********************************************************/
-
-static BOOL spoolss_connect_to_client(struct cli_state *the_cli, char *remote_machine)
-{
- extern pstring global_myname;
-
- ZERO_STRUCTP(the_cli);
- if(cli_initialise(the_cli) == NULL) {
- DEBUG(0,("connect_to_client: unable to initialize client connection.\n"));
- return False;
- }
-
- if(!resolve_name( remote_machine, &the_cli->dest_ip, 0x20)) {
- DEBUG(0,("connect_to_client: Can't resolve address for %s\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (ismyip(the_cli->dest_ip)) {
- DEBUG(0,("connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (!cli_connect(the_cli, remote_machine, &the_cli->dest_ip)) {
- DEBUG(0,("connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (!attempt_netbios_session_request(the_cli, global_myname, remote_machine, &the_cli->dest_ip)) {
- DEBUG(0,("connect_to_client: machine %s rejected the NetBIOS session request.\n",
- remote_machine));
- return False;
- }
-
- the_cli->protocol = PROTOCOL_NT1;
-
- if (!cli_negprot(the_cli)) {
- DEBUG(0,("connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (the_cli->protocol != PROTOCOL_NT1) {
- DEBUG(0,("connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- /*
- * Do an anonymous session setup.
- */
-
- if (!cli_session_setup(the_cli, "", "", 0, "", 0, "")) {
- DEBUG(0,("connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (!(the_cli->sec_mode & 1)) {
- DEBUG(0,("connect_to_client: machine %s isn't in user level security mode\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (!cli_send_tconX(the_cli, "IPC$", "IPC", "", 1)) {
- DEBUG(0,("connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- /*
- * Ok - we have an anonymous connection to the IPC$ share.
- * Now start the NT Domain stuff :-).
- */
-
- if(cli_nt_session_open(the_cli, PIPE_SPOOLSS) == False) {
- DEBUG(0,("connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli)));
- cli_nt_session_close(the_cli);
- cli_ulogoff(the_cli);
- cli_shutdown(the_cli);
- return False;
- }
-
- return True;
-}
-
/***************************************************************************
Connect to the client.
****************************************************************************/
@@ -1969,14 +1626,15 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin
if(!spoolss_connect_to_client(&cli, unix_printer))
return False;
- message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message);
+ message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message);
+
}
smb_connections++;
result = cli_spoolss_reply_open_printer(&cli, cli.mem_ctx, printer, localprinter,
type, handle);
-
+
if (!W_ERROR_IS_OK(result))
DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
dos_errstr(result)));
@@ -1988,8 +1646,9 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin
* _spoolss_rffpcnex
* ReplyFindFirstPrinterChangeNotifyEx
*
- * before replying OK: status=0 a rpc call is made to the workstation
- * asking ReplyOpenPrinter
+ * jfmxxxx: before replying OK: status=0
+ * should do a rpc call to the workstation asking ReplyOpenPrinter
+ * have to code it, later.
*
* in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
* called from api_spoolss_rffpcnex
@@ -2022,17 +1681,15 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
Printer->notify.option=dup_spool_notify_option(option);
- unistr2_to_ascii(Printer->notify.localmachine, localmachine,
- sizeof(Printer->notify.localmachine)-1);
-
- /* Connect to the client machine and send a ReplyOpenPrinter */
+ unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
- if(!srv_spoolss_replyopenprinter(Printer->notify.localmachine,
+ /* connect to the client machine and send a ReplyOpenPrinter */
+ if(srv_spoolss_replyopenprinter(Printer->notify.localmachine,
Printer->notify.printerlocal, 1,
&Printer->notify.client_hnd))
- return WERR_SERVER_UNAVAILABLE;
-
- Printer->notify.client_connected=True;
+ {
+ Printer->notify.client_connected=True;
+ }
return WERR_OK;
}
@@ -2054,7 +1711,7 @@ void spoolss_notify_server_name(int snum,
len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2089,7 +1746,7 @@ void spoolss_notify_printer_name(int snum,
len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2115,7 +1772,7 @@ void spoolss_notify_share_name(int snum,
len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2143,7 +1800,7 @@ void spoolss_notify_port_name(int snum,
len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2169,8 +1826,7 @@ void spoolss_notify_driver_name(int snum,
uint32 len;
len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
-
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2199,7 +1855,7 @@ void spoolss_notify_comment(int snum,
else
len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2226,7 +1882,7 @@ void spoolss_notify_location(int snum,
len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2265,7 +1921,7 @@ void spoolss_notify_sepfile(int snum,
len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2292,7 +1948,7 @@ void spoolss_notify_print_processor(int snum,
len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2319,7 +1975,7 @@ void spoolss_notify_parameters(int snum,
len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2346,7 +2002,7 @@ void spoolss_notify_datatype(int snum,
len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2506,7 +2162,7 @@ static void spoolss_notify_username(int snum,
len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2546,7 +2202,7 @@ static void spoolss_notify_job_name(int snum,
len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2596,7 +2252,7 @@ static void spoolss_notify_job_status_string(int snum,
len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2720,6 +2376,8 @@ static void spoolss_notify_submitted_time(int snum,
SSVAL(p, 14, st.milliseconds);
}
+#define END 65535
+
struct s_notify_info_data_table
{
uint16 type;
@@ -2731,61 +2389,59 @@ struct s_notify_info_data_table
NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
};
-/* A table describing the various print notification constants and
- whether the notification data is a pointer to a variable sized
- buffer, a one value uint32 or a two value uint32. */
-
struct s_notify_info_data_table notify_info_data_table[] =
{
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, spoolss_notify_security_desc },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, spoolss_notify_submitted_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, spoolss_notify_total_pages },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, spoolss_notify_pages_printed },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
+{ END, END, "", END, NULL }
};
/*******************************************************************
@@ -2796,46 +2452,43 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field)
{
int i=0;
- for (i = 0; i < sizeof(notify_info_data_table); i++) {
- if (notify_info_data_table[i].type == type &&
- notify_info_data_table[i].field == field) {
- switch(notify_info_data_table[i].size) {
- case NOTIFY_ONE_VALUE:
- case NOTIFY_TWO_VALUE:
- return 1;
- case NOTIFY_STRING:
- return 2;
-
- /* The only pointer notify data I have seen on
- the wire is the submitted time and this has
- the notify size set to 4. -tpot */
-
- case NOTIFY_POINTER:
- return 4;
- }
+ while (notify_info_data_table[i].type != END)
+ {
+ if ( (notify_info_data_table[i].type == type ) &&
+ (notify_info_data_table[i].field == field ) )
+ {
+ return (notify_info_data_table[i].size);
}
+ i++;
}
-
- DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
-
- return 0;
+ return (65535);
}
/*******************************************************************
Return the type of notify_info_data.
********************************************************************/
-static int type_of_notify_info_data(uint16 type, uint16 field)
+static BOOL type_of_notify_info_data(uint16 type, uint16 field)
{
int i=0;
- for (i = 0; i < sizeof(notify_info_data_table); i++) {
- if (notify_info_data_table[i].type == type &&
- notify_info_data_table[i].field == field)
- return notify_info_data_table[i].size;
+ while (notify_info_data_table[i].type != END)
+ {
+ if ( (notify_info_data_table[i].type == type ) &&
+ (notify_info_data_table[i].field == field ) )
+ {
+ if (notify_info_data_table[i].size == POINTER)
+ {
+ return (False);
+ }
+ else
+ {
+ return (True);
+ }
+ }
+ i++;
}
-
- return False;
+ return (False);
}
/****************************************************************************
@@ -2843,18 +2496,21 @@ static int type_of_notify_info_data(uint16 type, uint16 field)
static int search_notify(uint16 type, uint16 field, int *value)
{
- int i;
+ int j;
+ BOOL found;
- for (i = 0; i < sizeof(notify_info_data_table); i++) {
- if (notify_info_data_table[i].type == type &&
- notify_info_data_table[i].field == field &&
- notify_info_data_table[i].fn != NULL) {
- *value = i;
- return True;
- }
+ for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
+ {
+ if ( (notify_info_data_table[j].type == type ) &&
+ (notify_info_data_table[j].field == field ) )
+ found=True;
}
-
- return False;
+ *value=--j;
+
+ if ( found && (notify_info_data_table[j].fn != NULL) )
+ return True;
+ else
+ return False;
}
/****************************************************************************
@@ -2865,12 +2521,7 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16
info_data->type = type;
info_data->field = field;
info_data->reserved = 0;
-
- if (type == JOB_NOTIFY_TYPE)
- info_data->id = id;
- else
- info_data->id = 0;
-
+ info_data->id = id;
info_data->size = size_of_notify_info_data(type, field);
info_data->enc_type = type_of_notify_info_data(type, field);
}
@@ -2919,7 +2570,7 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
current_data=&info->data[info->count];
- construct_info_data(current_data, type, field, id);
+ construct_info_data(current_data, type, field, id);
DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
notify_info_data_table[j].name, snum, printer->info_2->printername ));
@@ -3161,6 +2812,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
{
POLICY_HND *handle = &q_u->handle;
+/* uint32 change = q_u->change; - notused. */
/* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
SPOOL_NOTIFY_INFO *info = &r_u->info;
@@ -3178,19 +2830,17 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
DEBUG(4,("Printer type %x\n",Printer->printer_type));
- /*
- * We are now using the change value, and
+ /* jfm: the change value isn't used right now.
+ * we will honour it when
+ * a) we'll be able to send notification to the client
+ * b) we'll have a way to communicate between the spoolss process.
+ *
+ * same thing for option->flags
* I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
* I don't have a global notification system, I'm sending back all the
* informations even when _NOTHING_ has changed.
*/
- /* We need to keep track of the change value to send back in
- RRPCN replies otherwise our updates are ignored. */
-
- if (Printer->notify.client_connected)
- Printer->notify.change = q_u->change;
-
/* just ignore the SPOOL_NOTIFY_OPTION */
switch (Printer->printer_type) {
@@ -3282,7 +2932,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
printer->global_counter = global_counter;
printer->total_pages = 0;
-#ifndef EMULATE_WIN2K_HACK /* JERRY */
+#if 0 /* JERRY */
printer->major_version = 0x0004; /* NT 4 */
printer->build_version = 0x0565; /* build 1381 */
#else
@@ -3321,6 +2971,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
* construct_printer_info_1
* fill a printer_info_1 struct
********************************************************************/
+
static BOOL construct_printer_info_1(uint32 flags, PRINTER_INFO_1 *printer, int snum)
{
pstring chaine;
@@ -3395,10 +3046,8 @@ static DEVICEMODE *construct_dev_mode(int snum)
if (printer->info_2->devmode)
ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
- if (ntdevmode == NULL) {
- DEBUG(5, ("BONG! There was no device mode!\n"));
+ if (ntdevmode == NULL)
goto fail;
- }
DEBUGADD(8,("loading DEVICEMODE\n"));
@@ -3759,26 +3408,10 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
enum_all_printers_info_1_network.
*********************************************************************/
-static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
- char *s = name;
-
DEBUG(4,("enum_all_printers_info_1_network\n"));
- /* If we respond to a enum_printers level 1 on our name with flags
- set to PRINTER_ENUM_REMOTE with a list of printers then these
- printers incorrectly appear in the APW browse list.
- Specifically the printers for the server appear at the workgroup
- level where all the other servers in the domain are
- listed. Windows responds to this call with a
- WERR_CAN_NOT_COMPLETE so we should do the same. */
-
- if (name[0] == '\\' && name[1] == '\\')
- s = name + 2;
-
- if (is_myname_or_ipaddr(s))
- return WERR_CAN_NOT_COMPLETE;
-
return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
}
@@ -3816,9 +3449,9 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
}
/* check the required size. */
- for (i=0; i<*returned; i++)
+ for (i=0; i<*returned; i++)
(*needed) += spoolss_size_printer_info_2(&printers[i]);
-
+
if (!alloc_buffer_size(buffer, *needed)) {
for (i=0; i<*returned; i++) {
free_devmode(printers[i].devmode);
@@ -3865,7 +3498,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
if (flags & PRINTER_ENUM_NETWORK)
- return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
+ return enum_all_printers_info_1_network(buffer, offered, needed, returned);
return WERR_OK; /* NT4sp5 does that */
}
@@ -4048,7 +3681,7 @@ static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, u
/* check the required size. */
*needed += spoolss_size_printer_info_2(printer);
-
+
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_info_2(printer);
return WERR_INSUFFICIENT_BUFFER;
@@ -5095,7 +4728,6 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
{
- extern userdom_struct current_user_info;
char *cmd = lp_addprinter_cmd();
char **qlines;
pstring command;
@@ -5110,13 +4742,13 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
get_called_name());
/* change \ to \\ for the shell */
all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
- standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
-
+
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
cmd, printer->info_2->printername, printer->info_2->sharename,
printer->info_2->portname, printer->info_2->drivername,
printer->info_2->location, driverlocation, remote_machine);
+ /* Convert script args to unix-codepage */
DEBUG(10,("Running [%s]\n", command));
ret = smbrun(command, &fd);
DEBUGADD(10,("returned [%d]\n", ret));
@@ -5407,10 +5039,13 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
int snum;
NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ PRINTER_MESSAGE_INFO msg;
WERROR result;
DEBUG(8,("update_printer\n"));
-
+
+ ZERO_STRUCT(msg);
+
result = WERR_OK;
if (level!=2) {
@@ -5524,11 +5159,8 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
* bound to the printer, simulating what happens in the Windows arch.
*/
if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){
- if (!set_driver_init(printer, 2)) {
- DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
- printer->info_2->drivername));
- }
- notify_printer_driver(snum, printer->info_2->drivername);
+ set_driver_init(printer, 2);
+ msg.flags |= PRINTER_MESSAGE_DRIVER;
}
}
@@ -5539,18 +5171,28 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
all the possible changes */
if (!strequal(printer->info_2->comment, old_printer->info_2->comment))
- notify_printer_comment(snum, printer->info_2->comment);
+ msg.flags |= PRINTER_MESSAGE_COMMENT;
if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename))
- notify_printer_sharename(snum, printer->info_2->sharename);
+ msg.flags |= PRINTER_MESSAGE_SHARENAME;
if (!strequal(printer->info_2->portname, old_printer->info_2->portname))
- notify_printer_port(snum, printer->info_2->portname);
+ msg.flags |= PRINTER_MESSAGE_PORT;
if (!strequal(printer->info_2->location, old_printer->info_2->location))
- notify_printer_location(snum, printer->info_2->location);
+ msg.flags |= PRINTER_MESSAGE_LOCATION;
-done:
+ ZERO_STRUCT(msg);
+
+ msg.low = PRINTER_CHANGE_ADD_PRINTER;
+ fstrcpy(msg.printer_name, printer->info_2->printername);
+
+ /* only send a notify if something changed */
+ if (msg.flags) {
+ srv_spoolss_sendnotify(msg.printer_name, 0, PRINTER_CHANGE_ADD_PRINTER, msg.flags);
+ }
+
+ done:
free_a_printer(&printer, 2);
free_a_printer(&old_printer, 2);
@@ -5668,7 +5310,7 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
int position, int snum,
- NT_PRINTER_INFO_LEVEL *ntprinter,
+ NT_PRINTER_INFO_LEVEL *ntprinter,
DEVICEMODE *devmode)
{
pstring temp_name;
@@ -5785,7 +5427,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
*returned = 0;
goto done;
}
-
+
if (!(devmode = construct_dev_mode(snum))) {
*returned = 0;
result = WERR_NOMEM;
@@ -5828,7 +5470,6 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
SAFE_FREE(info);
return result;
-
}
/****************************************************************************
@@ -5897,6 +5538,8 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
{
POLICY_HND *handle = &q_u->handle;
uint32 jobid = q_u->jobid;
+/* uint32 level = q_u->level; - notused. */
+/* JOB_INFO *ctr = &q_u->ctr; - notused. */
uint32 command = q_u->command;
struct current_user user;
@@ -5954,7 +5597,9 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
*returned=0;
- for (version=0; version<DRIVER_MAX_VERSION; version++) {
+#define MAX_VERSION 4
+
+ for (version=0; version<MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6033,7 +5678,9 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
*returned=0;
- for (version=0; version<DRIVER_MAX_VERSION; version++) {
+#define MAX_VERSION 4
+
+ for (version=0; version<MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6113,7 +5760,9 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
*returned=0;
- for (version=0; version<DRIVER_MAX_VERSION; version++) {
+#define MAX_VERSION 4
+
+ for (version=0; version<MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6766,6 +6415,9 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
}
update_c_setprinter(False);
+
+ srv_spoolss_sendnotify(printer->info_2->printername, 0, PRINTER_CHANGE_ADD_PRINTER, 0x0);
+
free_a_printer(&printer,2);
return WERR_OK;
@@ -6810,12 +6462,10 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
WERROR err = WERR_OK;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
struct current_user user;
- fstring driver_name;
- uint32 version;
-
+
ZERO_STRUCT(driver);
- get_current_user(&user, p);
+ get_current_user(&user, p);
if (!convert_printer_driver_info(info, &driver, level)) {
err = WERR_NOMEM;
@@ -6839,131 +6489,11 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
goto done;
}
- /* BEGIN_ADMIN_LOG */
- switch(level) {
- case 3:
- sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
- driver.info_3->name,drv_ver_to_os[driver.info_3->cversion],uidtoname(user.uid));
- fstrcpy(driver_name, driver.info_3->name);
- break;
- case 6:
- sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
- driver.info_6->name,drv_ver_to_os[driver.info_6->version],uidtoname(user.uid));
- fstrcpy(driver_name, driver.info_6->name);
- break;
- }
- /* END_ADMIN_LOG */
-
- /*
- * I think this is where he DrvUpgradePrinter() hook would be
- * be called in a driver's interface DLL on a Windows NT 4.0/2k
- * server. Right now, we just need to send ourselves a message
- * to update each printer bound to this driver. --jerry
- */
-
- if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
- DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
- driver_name));
- }
-
- /*
- * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
- * decide if the driver init data should be deleted. The rules are:
- * 1) never delete init data if it is a 9x driver, they don't use it anyway
- * 2) delete init data only if there is no 2k/Xp driver
- * 3) always delete init data
- * The generalized rule is always use init data from the highest order driver.
- * It is necessary to follow the driver install by an initialization step to
- * finish off this process.
- */
- if (level == 3)
- version = driver.info_3->cversion;
- else if (level == 6)
- version = driver.info_6->version;
- else
- version = -1;
- switch (version) {
- /*
- * 9x printer driver - never delete init data
- */
- case 0:
- DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
- driver_name));
- break;
-
- /*
- * Nt or 2k (compatiblity mode) printer driver - only delete init data if
- * there is no 2k/Xp driver init data for this driver name.
- */
- case 2:
- {
- NT_PRINTER_DRIVER_INFO_LEVEL driver1;
-
- if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
- /*
- * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
- */
- if (!del_driver_init(driver_name))
- DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
- } else {
- /*
- * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
- */
- free_a_printer_driver(driver1,3);
- DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
- driver_name));
- }
- }
- break;
-
- /*
- * 2k or Xp printer driver - always delete init data
- */
- case 3:
- if (!del_driver_init(driver_name))
- DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
- break;
-
- default:
- DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
- break;
- }
-
-
-done:
+ done:
free_a_printer_driver(driver, level);
return err;
}
-/********************************************************************
- * spoolss_addprinterdriverex
- ********************************************************************/
-
-WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
-{
- SPOOL_Q_ADDPRINTERDRIVER q_u_local;
- SPOOL_R_ADDPRINTERDRIVER r_u_local;
-
- /*
- * we only support the semantics of AddPrinterDriver()
- * i.e. only copy files that are newer than existing ones
- */
-
- if ( q_u->copy_flags != APD_COPY_NEW_FILES )
- return WERR_ACCESS_DENIED;
-
- /* just pass the information off to _spoolss_addprinterdriver() */
- ZERO_STRUCT(q_u_local);
- ZERO_STRUCT(r_u_local);
-
- q_u_local.server_name_ptr = q_u->server_name_ptr;
- copy_unistr2(&q_u_local.server_name, &q_u->server_name);
- q_u_local.level = q_u->level;
- memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
-
- return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
-}
-
/****************************************************************************
****************************************************************************/
@@ -7102,6 +6632,23 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if ( (in_value_len==0) && (in_data_len==0) ) {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
+#if 0
+ /*
+ * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
+ * if this parameter size doesn't exist.
+ * Ok - my opinion here is that the client is not asking for the greatest
+ * possible size of all the parameters, but is asking specifically for the size needed
+ * for this specific parameter. In that case we can remove the loop below and
+ * simplify this lookup code considerably. JF - comments welcome. JRA.
+ */
+
+ if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
+ SAFE_FREE(data);
+ free_a_printer(&printer, 2);
+ return WERR_NO_MORE_ITEMS;
+ }
+#endif
+
SAFE_FREE(data);
param_index=0;
@@ -7145,7 +6692,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
return WERR_NOMEM;
- *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
+ *out_value_len = rpcstr_push((char *)*out_value, "", in_value_len, 0);
/* the data is counted in bytes */
*out_max_data_len = in_data_len;
@@ -7173,7 +6720,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
return WERR_NOMEM;
}
- *out_value_len = (uint32)rpcstr_push((char *)*out_value,value, in_value_len, 0);
+ *out_value_len = rpcstr_push((char *)*out_value,value, in_value_len, 0);
*out_type=type;
@@ -7200,8 +6747,10 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
POLICY_HND *handle = &q_u->handle;
UNISTR2 *value = &q_u->value;
uint32 type = q_u->type;
+/* uint32 max_len = q_u->max_len; - notused. */
uint8 *data = q_u->data;
uint32 real_len = q_u->real_len;
+/* uint32 numeric_data = q_u->numeric_data; - notused. */
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_PARAM *param = NULL, old_param;
@@ -7473,6 +7022,8 @@ done:
WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
{
POLICY_HND *handle = &q_u->handle;
+/* UNISTR2 *uni_name = &q_u->name; - notused. */
+/* uint32 level = q_u->level; - notused. */
FORM *form = &q_u->form;
nt_forms_struct tmpForm;
int snum;
@@ -7563,10 +7114,12 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
+/* UNISTR2 *environment = &q_u->environment; - notused. */
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
+ uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
@@ -7630,6 +7183,8 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
+/* UNISTR2 *processor = &q_u->processor; - notused. */
uint32 level = q_u->level;
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
@@ -7724,10 +7279,11 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
+ uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
@@ -7871,7 +7427,7 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin
free_job_info_2(info_2); /* Also frees devmode */
SAFE_FREE(info_2);
free_a_printer(&ntprinter, 2);
-
+
return ret;
}
@@ -8038,34 +7594,6 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
return _spoolss_setprinterdata(p, &q_u_local, &r_u_local);
}
-
-/********************************************************************
- * spoolss_deleteprinterdataex
- ********************************************************************/
-
-WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX *q_u, SPOOL_R_DELETEPRINTERDATAEX *r_u)
-{
- SPOOL_Q_DELETEPRINTERDATA q_u_local;
- SPOOL_R_DELETEPRINTERDATA r_u_local;
- fstring key;
-
- /* From MSDN documentation of SetPrinterDataEx: pass request to
- SetPrinterData if key is "PrinterDriverData" */
-
- unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
-
- if (strcmp(key, "PrinterDriverData") != 0)
- return WERR_INVALID_PARAM;
-
- memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND));
- copy_unistr2(&q_u_local.valuename, &q_u->valuename);
-
- return _spoolss_deleteprinterdata( p, &q_u_local, &r_u_local );
-}
-
-
-
-
/********************************************************************
* spoolss_enumprinterkey
********************************************************************/
@@ -8133,34 +7661,6 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO
}
/********************************************************************
- * spoolss_deleteprinterkey
- ********************************************************************/
-
-WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u, SPOOL_R_DELETEPRINTERKEY *r_u)
-{
- Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
- fstring key;
-
- if (!Printer) {
- DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle)));
- return WERR_BADFID;
- }
-
- unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
-
- if (strcmp(key, "PrinterDriverData") != 0)
- return WERR_INVALID_PARAM;
-
- /*
- * this is what 2k returns when you try to delete the "PrinterDriverData"
- * key
- */
-
- return WERR_ACCESS_DENIED;
-}
-
-
-/********************************************************************
* spoolss_enumprinterdataex
********************************************************************/
@@ -8301,7 +7801,7 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
- if (get_short_archi(short_archi, long_archi)==False)
+ if (get_short_archi(short_archi, long_archi)==FALSE)
return WERR_INVALID_ENVIRONMENT;
if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
@@ -8334,7 +7834,6 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
- WERROR result;
/* that's an [in out] buffer */
spoolss_move_buffer(q_u->buffer, &r_u->buffer);
@@ -8346,13 +7845,12 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
switch(level) {
case 1:
- result = getprintprocessordirectory_level_1
+ return getprintprocessordirectory_level_1
(&q_u->name, &q_u->environment, buffer, offered, needed);
default:
- result = WERR_UNKNOWN_LEVEL;
+ return WERR_UNKNOWN_LEVEL;
}
- return result;
+ return WERR_ACCESS_DENIED;
}
-