summaryrefslogtreecommitdiffstats
path: root/source/rpc_server/srv_spoolss_nt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/rpc_server/srv_spoolss_nt.c')
-rw-r--r--source/rpc_server/srv_spoolss_nt.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 613d516971f..582c74942a1 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -559,6 +559,144 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
return True;
}
+/**********************************************************************
+ Release the memory held by a SPOOL_NOTIFY_INFO_DATA
+ *********************************************************************/
+
+static void free_notify_data(SPOOL_NOTIFY_INFO_DATA *data, uint32 len)
+{
+ uint32 i;
+
+ if (!data)
+ return;
+
+ for (i=0; i<len; i++) {
+ if (data[i].size == POINTER)
+ SAFE_FREE(data[i].notify_data.data.string);
+ }
+
+ SAFE_FREE(data);
+}
+
+/***************************************************************************
+ Send a notify to the client.
+****************************************************************************/
+
+static BOOL cli_spoolss_reply_rrpcn(struct cli_state *pcli, POLICY_HND *handle,
+ char* printername, uint32 change_low, uint32 change_high,
+ WERROR *status)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+
+ SPOOL_NOTIFY_INFO notify_info;
+ SPOOL_NOTIFY_INFO_DATA *notify_data = NULL, *data;
+ uint32 idx = 0;
+
+ WERROR result;
+
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+
+ SPOOL_Q_REPLY_RRPCN q_s;
+ SPOOL_R_REPLY_RRPCN r_s;
+
+ prs_init(&buf, 1024, pcli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, pcli->mem_ctx, UNMARSHALL );
+
+ ZERO_STRUCT(notify_info);
+
+ /* lookup the printer if we have a name */
+
+ if (*printername) {
+ result = get_a_printer(&printer, 2, printername);
+ if (! W_ERROR_IS_OK(result)) {
+ *status = result;
+ goto done;
+ }
+ }
+
+ /*
+ * See comments in _spoolss_setprinter() about PRINTER_CHANGE_XXX
+ * events. --jerry
+ */
+
+ /* Did the driver change? */
+
+ if (change_low & PRINTER_CHANGE_SET_PRINTER_DRIVER) {
+ change_low &= ~PRINTER_CHANGE_SET_PRINTER_DRIVER;
+ DEBUG(10,("cli_spoolss_reply_rrpcn: PRINTER_CHANGE_SET_PRINTER_DRIVER set on [%s][%d]\n",
+ printername, idx));
+ if ((data=Realloc(notify_data, (idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+ DEBUG(0,("cli_spoolss_reply_rrpcn: Realloc() failed with size [%d]!\n",
+ (idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA)));
+ *status = WERR_NOMEM;
+ goto done;
+ }
+ notify_data = data;
+
+ memset(notify_data+idx, 0x0, sizeof(SPOOL_NOTIFY_INFO_DATA));
+
+ /*
+ * 'id' (last param here) is undefined when type == PRINTER_NOTIFY_TYPE
+ * See PRINTER_NOTIFY_INFO_DATA entries in MSDN
+ * --jerry
+ */
+ construct_info_data(notify_data+idx, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, 0x00);
+
+ spoolss_notify_driver_name(-1, notify_data+idx, NULL, printer, pcli->mem_ctx);
+ idx++;
+ }
+
+
+#if 0 /* JERRY -- do not delete */
+ DEBUG(4,("cli_spoolss_reply_open_printer: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
+ pcli->srv_name_slash, pcli->mach_acct, sec_chan_type, global_myname,
+ credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
+#endif
+
+ /* create and send a MSRPC command with api */
+
+ /* store the parameters */
+
+ notify_info.flags = 0x00000200;
+ notify_info.count = idx;
+ notify_info.data = notify_data;
+
+ make_spoolss_q_reply_rrpcn(&q_s, handle, change_low, change_high, &notify_info);
+
+ /* turn parameters into data stream */
+ if(!spoolss_io_q_reply_rrpcn("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to marshall SPOOL_Q_REPLY_RRPCN struct.\n"));
+ *status = WERR_BADFUNC;
+ goto done;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(pcli, SPOOLSS_RRPCN, &buf, &rbuf)) {
+ DEBUG(0,("cli_spoolss_reply_rrpcn: SPOOLSS_RRPCN failed!\n"));
+ *status = WERR_BADFUNC;
+ goto done;
+ }
+
+
+ /* turn data stream into parameters*/
+ if(!spoolss_io_r_reply_rrpcn("", &r_s, &rbuf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to unmarshall SPOOL_R_REPLY_RRPCN struct.\n"));
+ *status = WERR_BADFUNC;
+ goto done;
+ }
+
+ *status = r_s.status;
+
+done:
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ free_a_printer(&printer, 2);
+ free_notify_data(notify_data, idx);
+
+ return W_ERROR_IS_OK(*status);
+}
+
/***************************************************************************
Receive the notify message.
****************************************************************************/