summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2002-03-15 08:14:10 +0000
committerGerald Carter <jerry@samba.org>2002-03-15 08:14:10 +0000
commit65c007b583e2107f5ad1ba6733d3e578a143863e (patch)
treea11e1da607580d291ce74926417126ce22f34852 /source3/rpc_server
parentd19e06c0c620046658621fcec7c2cda9a77ceac3 (diff)
downloadsamba-65c007b583e2107f5ad1ba6733d3e578a143863e.tar.gz
samba-65c007b583e2107f5ad1ba6733d3e578a143863e.tar.bz2
samba-65c007b583e2107f5ad1ba6733d3e578a143863e.zip
syncing up printing code with SAMBA_2_2 (already done some merges
in the reverse). * add in new printer change notify code from SAMBA_2_2 * add in se_map_standard() from 2.2 in _spoolss_open_printer_ex() * sync up the _print_queue_struct in smb.h (why did someone change the user/file names in fs_user/fs_file (or vice-versa) ? ) * sync up some cli_spoolss_XXX functions (This used to be commit 5760315c1de4033fdc22684c940f18010010924f)
Diffstat (limited to 'source3/rpc_server')
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c34
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c432
2 files changed, 317 insertions, 149 deletions
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index 3f3c6039c9..3838632021 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -975,7 +975,33 @@ static BOOL api_spoolss_setprinterdata(pipes_struct *p)
/****************************************************************************
****************************************************************************/
+static BOOL api_spoolss_reset_printer(pipes_struct *p)
+{
+ SPOOL_Q_RESETPRINTER q_u;
+ SPOOL_R_RESETPRINTER r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!spoolss_io_q_resetprinter("", &q_u, data, 0)) {
+ DEBUG(0,("spoolss_io_q_setprinterdata: unable to unmarshall SPOOL_Q_SETPRINTERDATA.\n"));
+ return False;
+ }
+
+ r_u.status = _spoolss_resetprinter(p, &q_u, &r_u);
+
+ if(!spoolss_io_r_resetprinter("", &r_u, rdata, 0)) {
+ DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_RESETPRINTER.\n"));
+ return False;
+ }
+
+ return True;
+}
+/****************************************************************************
+****************************************************************************/
static BOOL api_spoolss_addform(pipes_struct *p)
{
SPOOL_Q_ADDFORM q_u;
@@ -1318,11 +1344,6 @@ static BOOL api_spoolss_enumprinterdataex(pipes_struct *p)
/****************************************************************************
****************************************************************************/
-/* Disabled because it doesn't fix the bug I am looking at but it would be
- a shame to throw away the code. -tpot */
-
-#if 0
-
static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p)
{
SPOOL_Q_GETPRINTPROCESSORDIRECTORY q_u;
@@ -1348,8 +1369,6 @@ static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p)
return True;
}
-#endif
-
/*******************************************************************
\pipe\spoolss commands
********************************************************************/
@@ -1386,6 +1405,7 @@ struct api_struct api_spoolss_cmds[] =
{"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory },
{"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata },
{"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata },
+ {"SPOOLSS_RESETPRINTER", SPOOLSS_RESETPRINTER, api_spoolss_reset_printer },
{"SPOOLSS_DELETEPRINTERDATA", SPOOLSS_DELETEPRINTERDATA, api_spoolss_deleteprinterdata },
{"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform },
{"SPOOLSS_DELETEFORM", SPOOLSS_DELETEFORM, api_spoolss_deleteform },
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 3479e47f76..a6c0f9368c 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -91,6 +91,10 @@ static ubi_dlList counter_list;
static struct cli_state cli;
static uint32 smb_connections=0;
+
+/* in printing/nt_printing.c */
+extern STANDARD_MAPPING printer_std_mapping;
+
#define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
@@ -158,7 +162,7 @@ static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
{
- WERROR status;
+ NTSTATUS result;
/* weird if the test succeds !!! */
if (smb_connections==0) {
@@ -166,7 +170,9 @@ static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
return;
}
- if(!cli_spoolss_reply_close_printer(&cli, handle, &status))
+ result = cli_spoolss_reply_close_printer(&cli, cli.mem_ctx, handle);
+
+ if (!NT_STATUS_IS_OK(result))
DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n"));
/* if it's the last connection, deconnect the IPC$ share */
@@ -528,71 +534,233 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
return True;
}
+/***************************************************************************
+ 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 valid_notify_options(Printer_entry *printer)
+{
+ if (printer->notify.option == NULL)
+ return False;
+
+ return True;
+}
/***************************************************************************
- Receive the notify message.
-****************************************************************************/
+ 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)
+{
-static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
+ return True;
+}
+
+/***************************************************************************
+ 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 NTSTATUS srv_spoolss_routerreplyprinter (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, PRINTER_MESSAGE_INFO *info,
+ NT_PRINTER_INFO_LEVEL *printer)
{
- Printer_entry *find_printer;
- WERROR status;
- fstring printer_name;
- char msg[8];
- char *buf_ptr = (char *)buf;
- uint32 low, high;
+ NTSTATUS result;
+ uint32 condition = 0x0;
+
+ if (info->flags & PRINTER_MESSAGE_DRIVER)
+ condition = PRINTER_CHANGE_SET_PRINTER_DRIVER;
+
+ result = cli_spoolss_routerreplyprinter(cli, mem_ctx, pol, condition,
+ printer->info_2->changeid);
- if (len < sizeof(msg) + 2) {
- DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len));
- return;
+ return result;
+}
+
+/***********************************************************************
+ Wrapper around the decision of which RPC use to in the change
+ notification
+ **********************************************************************/
+
+static NTSTATUS srv_spoolss_send_event_to_client(Printer_entry* Printer,
+ struct cli_state *cli, PRINTER_MESSAGE_INFO *msg,
+ NT_PRINTER_INFO_LEVEL *info)
+{
+ NTSTATUS 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;
+ result = cli_spoolss_reply_rrpcn(cli, cli->mem_ctx, &Printer->notify.client_hnd,
+ msg, info);
}
+ else {
+ /* This requires that the server send an individual event notification for each change */
+ result = srv_spoolss_routerreplyprinter(cli, cli->mem_ctx, &Printer->notify.client_hnd,
+ msg, info);
+ }
+
+ return result;
+}
- memcpy(msg, buf_ptr, sizeof(msg));
- low = IVAL(msg,0);
- high = IVAL(msg,4);
- fstrcpy(printer_name, buf_ptr + sizeof(msg));
- DEBUG(10,("srv_spoolss_receive_message: Got message printer change name [%s] low=0x%x high=0x%x\n",
- printer_name, (unsigned int)low, (unsigned int)high ));
+/***********************************************************************
+ Send a change notication message on all handles which have a call
+ back registered
+ **********************************************************************/
+
+static void send_spoolss_event_notification(PRINTER_MESSAGE_INFO *msg)
+{
+ Printer_entry *find_printer;
+ NTSTATUS result;
+ WERROR wresult;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+
+ if (!msg) {
+ DEBUG(0,("send_spoolss_event_notification: NULL msg pointer!\n"));
+ return;
+ }
- /* Iterate the printer list */
for(find_printer = printers_list; find_printer; find_printer = find_printer->next) {
/*
- * If the entry has a connected client we send the message.
+ * 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
*/
if (find_printer->notify.client_connected==True) {
- DEBUG(10,("srv_spoolss_receive_message: printerserver [%s]\n", find_printer->dev.printerservername ));
- if (*printer_name && !strequal(printer_name, find_printer->dev.handlename)) {
- DEBUG(10,("srv_spoolss_receive_message: ignoring message sent to %s [%s]\n",
- printer_name, find_printer->dev.handlename ));
+
+ /* does the client care about what changed? */
+
+ 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;
}
- if (cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, low, high, &status))
- DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn status = 0x%x\n",
- (unsigned int)W_ERROR_V(status)));
+ if (find_printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ DEBUG(10,("send_spoolss_event_notification: printserver [%s]\n", find_printer->dev.printerservername ));
else
- DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn failed\n"));
+ DEBUG(10,("send_spoolss_event_notification: printer [%s]\n", find_printer->dev.handlename));
+
+ /*
+ * if handle is a printer, only send if the printer_name matches.
+ * ...else if handle is a printerserver, send to all
+ */
+
+ 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;
+ }
+
+
+ /* 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;
+ }
+
+ wresult = get_a_printer(&printer, 2, msg->printer_name);
+ if (! W_ERROR_IS_OK(wresult))
+ continue;
+ }
+
+ /* issue the client call */
+
+ result = srv_spoolss_send_event_to_client(find_printer, &cli, msg, printer);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("send_spoolss_event_notification: Event notification failed [%s]\n",
+ get_nt_error_msg(result)));
}
}
}
+ 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 srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
+{
+ PRINTER_MESSAGE_INFO msg;
+ pid_t my_pid = sys_getpid();
+
+ if (len < sizeof(msg)) {
+ DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len));
+ return;
+ }
+
+ memcpy(&msg, buf, sizeof(PRINTER_MESSAGE_INFO));
+
+ if (my_pid == src) {
+ DEBUG(10,("srv_spoolss_receive_message: Skipping message to myself\n"));
+ return;
+ }
+
+ 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 ));
+
+ /* Iterate the printer list */
+
+ send_spoolss_event_notification(&msg);
+
+}
+
/***************************************************************************
Send a notify event.
****************************************************************************/
-static BOOL srv_spoolss_sendnotify(uint32 high, uint32 low)
+static BOOL srv_spoolss_sendnotify(char* printer_name, uint32 high, uint32 low, uint32 flags)
{
- char msg[10];
+ char msg[sizeof(PRINTER_MESSAGE_INFO)];
+ PRINTER_MESSAGE_INFO info;
+
+ ZERO_STRUCT(info);
- ZERO_STRUCT(msg);
- SIVAL(msg,0,low);
- SIVAL(msg,4,high);
- DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x\n", low, high));
+ info.low = low;
+ info.high = high;
+ info.flags = flags;
+ fstrcpy(info.printer_name, printer_name);
+
+ memcpy(msg, &info, sizeof(PRINTER_MESSAGE_INFO));
+
+ 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_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(PRINTER_MESSAGE_INFO),
+ False, NULL);
- message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(msg), False, NULL);
return True;
}
@@ -707,6 +875,8 @@ Can't find printer handle we created for priunter %s\n", name ));
if (!get_printer_snum(p, handle, &snum))
return WERR_BADFID;
+ se_map_standard(&printer_default->access_required, &printer_std_mapping);
+
/* map an empty access mask to the minimum access mask */
if (printer_default->access_required == 0x0)
printer_default->access_required = PRINTER_ACCESS_USE;
@@ -993,10 +1163,10 @@ WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL
result = delete_printer_handle(p, handle);
- update_c_setprinter(FALSE);
+ update_c_setprinter(False);
if (W_ERROR_IS_OK(result)) {
- srv_spoolss_sendnotify(0, PRINTER_CHANGE_DELETE_PRINTER);
+ srv_spoolss_sendnotify(Printer->dev.handlename, 0, PRINTER_CHANGE_DELETE_PRINTER, 0x0);
}
return result;
@@ -1294,7 +1464,7 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle)
{
- WERROR status;
+ NTSTATUS result;
/*
* If it's the first connection, contact the client
@@ -1313,10 +1483,10 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin
smb_connections++;
- if(!cli_spoolss_reply_open_printer(&cli, printer, localprinter, type, &status, handle))
- return False;
+ result = cli_spoolss_reply_open_printer(&cli, cli.mem_ctx, printer, localprinter,
+ type, handle);
- return True;
+ return (NT_STATUS_IS_OK(result));
}
/********************************************************************
@@ -1364,7 +1534,9 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
if(srv_spoolss_replyopenprinter(Printer->notify.localmachine,
Printer->notify.printerlocal, 1,
&Printer->notify.client_hnd))
+ {
Printer->notify.client_connected=True;
+ }
return WERR_OK;
}
@@ -1373,7 +1545,7 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
* fill a notify_info_data with the servername
********************************************************************/
-static void spoolss_notify_server_name(int snum,
+void spoolss_notify_server_name(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1401,7 +1573,7 @@ static void spoolss_notify_server_name(int snum,
* fill a notify_info_data with the printername (not including the servername).
********************************************************************/
-static void spoolss_notify_printer_name(int snum,
+void spoolss_notify_printer_name(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1436,7 +1608,7 @@ static void spoolss_notify_printer_name(int snum,
* fill a notify_info_data with the servicename
********************************************************************/
-static void spoolss_notify_share_name(int snum,
+void spoolss_notify_share_name(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1462,7 +1634,7 @@ static void spoolss_notify_share_name(int snum,
* fill a notify_info_data with the port name
********************************************************************/
-static void spoolss_notify_port_name(int snum,
+void spoolss_notify_port_name(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1488,11 +1660,10 @@ static void spoolss_notify_port_name(int snum,
/*******************************************************************
* fill a notify_info_data with the printername
- * jfmxxxx: it's incorrect, should be lp_printerdrivername()
* but it doesn't exist, have to see what to do
********************************************************************/
-static void spoolss_notify_driver_name(int snum,
+void spoolss_notify_driver_name(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1517,7 +1688,7 @@ static void spoolss_notify_driver_name(int snum,
* fill a notify_info_data with the comment
********************************************************************/
-static void spoolss_notify_comment(int snum,
+void spoolss_notify_comment(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1544,11 +1715,10 @@ static void spoolss_notify_comment(int snum,
/*******************************************************************
* fill a notify_info_data with the comment
- * jfm:xxxx incorrect, have to create a new smb.conf option
* location = "Room 1, floor 2, building 3"
********************************************************************/
-static void spoolss_notify_location(int snum,
+void spoolss_notify_location(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1585,11 +1755,9 @@ static void spoolss_notify_devmode(int snum,
/*******************************************************************
* fill a notify_info_data with the separator file name
- * jfm:xxxx just return no file could add an option to smb.conf
- * separator file = "separator.txt"
********************************************************************/
-static void spoolss_notify_sepfile(int snum,
+void spoolss_notify_sepfile(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1616,7 +1784,7 @@ static void spoolss_notify_sepfile(int snum,
* jfm:xxxx return always winprint to indicate we don't do anything to it
********************************************************************/
-static void spoolss_notify_print_processor(int snum,
+void spoolss_notify_print_processor(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1643,7 +1811,7 @@ static void spoolss_notify_print_processor(int snum,
* jfm:xxxx send an empty string
********************************************************************/
-static void spoolss_notify_parameters(int snum,
+void spoolss_notify_parameters(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1670,7 +1838,7 @@ static void spoolss_notify_parameters(int snum,
* jfm:xxxx always send RAW as data type
********************************************************************/
-static void spoolss_notify_datatype(int snum,
+void spoolss_notify_datatype(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1713,7 +1881,7 @@ static void spoolss_notify_security_desc(int snum,
* jfm:xxxx a samba printer is always shared
********************************************************************/
-static void spoolss_notify_attributes(int snum,
+void spoolss_notify_attributes(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1800,7 +1968,7 @@ static void spoolss_notify_status(int snum,
* fill a notify_info_data with the number of jobs queued
********************************************************************/
-static void spoolss_notify_cjobs(int snum,
+void spoolss_notify_cjobs(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
@@ -1839,7 +2007,7 @@ static void spoolss_notify_username(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, queue->user, sizeof(temp)-2, STR_TERMINATE);
+ len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
@@ -1879,7 +2047,7 @@ static void spoolss_notify_job_name(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, queue->file, sizeof(temp)-2, STR_TERMINATE);
+ len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
@@ -2169,7 +2337,7 @@ static int search_notify(uint16 type, uint16 field, int *value)
/****************************************************************************
****************************************************************************/
-static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
+void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
{
info_data->type = type;
info_data->field = field;
@@ -2397,7 +2565,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
return WERR_BADFID;
option=Printer->notify.option;
- id=0xffffffff;
+ id = 0x0;
info->version=2;
info->data=NULL;
info->count=0;
@@ -2585,8 +2753,13 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
printer->global_counter = global_counter;
printer->total_pages = 0;
+#if 0 /* JERRY */
printer->major_version = 0x0004; /* NT 4 */
printer->build_version = 0x0565; /* build 1381 */
+#else
+ printer->major_version = 0x0005; /* NT 5 */
+ printer->build_version = 0x0893; /* build 2195 */
+#endif
printer->unknown7 = 0x1;
printer->unknown8 = 0x0;
printer->unknown9 = 0x0;
@@ -4362,9 +4535,9 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
/* we force some elements to "correct" values */
slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
- slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
- get_called_name(), lp_servicename(snum));
fstrcpy(info->sharename, lp_servicename(snum));
+ slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
+ get_called_name(), info->sharename);
info->attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK;
return True;
@@ -4686,10 +4859,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) {
@@ -4802,18 +4978,49 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
* lookup previously saved driver initialization info, which is then
* bound to the printer, simulating what happens in the Windows arch.
*/
- if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
+ if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){
set_driver_init(printer, 2);
+ msg.flags |= PRINTER_MESSAGE_DRIVER;
+ }
}
/* Update printer info */
result = mod_a_printer(*printer, 2);
+ /* flag which changes actually occured. This is a small subset of
+ all the possible changes */
+
+ if (!strequal(printer->info_2->comment, old_printer->info_2->comment))
+ msg.flags |= PRINTER_MESSAGE_COMMENT;
+
+ if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename))
+ msg.flags |= PRINTER_MESSAGE_SHARENAME;
+
+ if (!strequal(printer->info_2->portname, old_printer->info_2->portname))
+ msg.flags |= PRINTER_MESSAGE_PORT;
+
+ if (!strequal(printer->info_2->location, old_printer->info_2->location))
+ msg.flags |= PRINTER_MESSAGE_LOCATION;
+
+ 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)
+ {
+ /* send to myself before replying to SetPrinter() */
+ send_spoolss_event_notification(&msg);
+
+ /* send to other smbd's */
+ 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);
- srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER);
return result;
}
@@ -4910,8 +5117,8 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
job_info->jobid=queue->job;
init_unistr(&job_info->printername, lp_servicename(snum));
init_unistr(&job_info->machinename, temp_name);
- init_unistr(&job_info->username, queue->user);
- init_unistr(&job_info->document, queue->file);
+ init_unistr(&job_info->username, queue->fs_user);
+ init_unistr(&job_info->document, queue->fs_file);
init_unistr(&job_info->datatype, "RAW");
init_unistr(&job_info->text_status, "");
job_info->status=nt_printj_status(queue->status);
@@ -4945,9 +5152,9 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
init_unistr(&job_info->printername, chaine);
init_unistr(&job_info->machinename, temp_name);
- init_unistr(&job_info->username, queue->user);
- init_unistr(&job_info->document, queue->file);
- init_unistr(&job_info->notifyname, queue->user);
+ init_unistr(&job_info->username, queue->fs_user);
+ init_unistr(&job_info->document, queue->fs_file);
+ init_unistr(&job_info->notifyname, queue->fs_user);
init_unistr(&job_info->datatype, "RAW");
init_unistr(&job_info->printprocessor, "winprint");
init_unistr(&job_info->parameters, "");
@@ -5070,6 +5277,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
}
if (!alloc_buffer_size(buffer, *needed)) {
+ SAFE_FREE(info);
result = WERR_INSUFFICIENT_BUFFER;
goto done;
}
@@ -6031,11 +6239,12 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
return WERR_ACCESS_DENIED;
}
+ srv_spoolss_sendnotify(printer->info_2->printername, 0, PRINTER_CHANGE_ADD_PRINTER, 0x0);
+
free_a_printer(&printer,2);
update_c_setprinter(False);
- srv_spoolss_sendnotify(0, PRINTER_CHANGE_ADD_PRINTER);
return WERR_OK;
}
@@ -6128,9 +6337,7 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
pstring long_archi;
pstring short_archi;
DRIVER_DIRECTORY_1 *info=NULL;
-#if 0
- fstring asc_name, servername;
-#endif
+
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
if (get_short_archi(short_archi, long_archi)==False)
@@ -6139,20 +6346,6 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
return WERR_NOMEM;
-#if 0 /* JERRY */
- /* use the name the client sent us */
-
- unistr2_to_ascii(asc_name, name, sizeof(asc_name)-1);
- if (asc_name[0] == '\\' && asc_name[1] == '\\')
- fstrcpy(servername, asc_name);
- else {
- fstrcpy(servername, "\\\\");
- fstrcat(servername, asc_name);
- }
-
- slprintf(path, sizeof(path)-1, "%s\\print$\\%s", servername, short_archi);
-#endif
-
slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
DEBUG(4,("printer driver directory: [%s]\n", path));
@@ -6428,24 +6621,6 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
convert_specific_param(&param, value , type, data, real_len);
-#if 0
- /* JRA. W2K always changes changeid. */
-
- if (get_specific_param(*printer, 2, param->value, &old_param.data,
- &old_param.type, (uint32 *)&old_param.data_len)) {
-
- if (param->type == old_param.type &&
- param->data_len == old_param.data_len &&
- memcmp(param->data, old_param.data,
- old_param.data_len) == 0) {
-
- DEBUG(3, ("setprinterdata hasn't changed\n"));
- status = WERR_OK;
- goto done;
- }
- }
-#endif
-
unlink_specific_param_if_exist(printer->info_2, param);
/*
@@ -6470,17 +6645,18 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
free_nt_printer_param(&param);
SAFE_FREE(old_param.data);
-#if 0
- /* Is this correct. JRA ? */
- srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER);
-#endif
-
return status;
}
/****************************************************************************
****************************************************************************/
+WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
+{
+ return WERR_OK;
+}
+
+
WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
{
POLICY_HND *handle = &q_u->handle;
@@ -7025,7 +7201,6 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin
ret = get_a_printer(&ntprinter, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(ret))
goto done;
-
if (construct_dev_mode(snum) == NULL) {
ret = WERR_NOMEM;
goto done;
@@ -7371,27 +7546,6 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
enum_values[num_entries].value_len = (strlen(value)+1) * 2;
enum_values[num_entries].type = type;
-#if 0 /* JERRY - I think think was a bad assumption based on bad
- offset values when I first implemented it. Commented out.
- We should not be adding an extra NULL to the end of a string
- just send what the client set in the first place. */
- /*
- * NULL terminate REG_SZ
- * FIXME!!! We should not be correctly problems in the way
- * we store PrinterData here. Need to investogate
- * SetPrinterData[Ex] --jerry
- */
-
- if (type == REG_SZ) {
- /* fix alignment if the string was stored
- in a bizarre fashion */
- if ((data_len % 2) == 0)
- add_len = 2;
- else
- add_len = data_len % 2;
- }
-#endif
-
if (!(enum_values[num_entries].data=talloc_zero(p->mem_ctx, data_len+add_len))) {
DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n"));
result = WERR_NOMEM;
@@ -7433,11 +7587,6 @@ done:
/****************************************************************************
****************************************************************************/
-/* Disabled because it doesn't fix the bug I am looking at but it would be
- a shame to throw away the code. -tpot */
-
-#if 0
-
static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name)
{
init_unistr(&info->name, name);
@@ -7515,4 +7664,3 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
return WERR_ACCESS_DENIED;
}
-#endif