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.c289
1 files changed, 162 insertions, 127 deletions
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 75d7ac7164..6bbd26b0a8 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -1082,168 +1082,203 @@ static void construct_info_data(struct spoolss_Notify *info_data,
back registered
**********************************************************************/
-static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
-{
- struct printer_handle *p;
- TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
- SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
- SPOOLSS_NOTIFY_MSG *messages;
- int sending_msg_count;
+static int build_notify2_messages(TALLOC_CTX *mem_ctx,
+ struct printer_handle *prn_hnd,
+ SPOOLSS_NOTIFY_MSG *messages,
+ uint32_t num_msgs,
+ struct spoolss_Notify **_notifies,
+ int *_count)
+{
+ struct spoolss_Notify *notifies;
+ SPOOLSS_NOTIFY_MSG *msg;
+ int count = 0;
+ uint32_t id;
+ int i;
- if ( !msg_group ) {
- DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
- return;
+ notifies = talloc_zero_array(mem_ctx,
+ struct spoolss_Notify, num_msgs);
+ if (!notifies) {
+ return ENOMEM;
}
- messages = msg_group->msgs;
+ for (i = 0; i < num_msgs; i++) {
- if ( !messages ) {
- DEBUG(5,("send_notify2_changes() called with no messages!\n"));
- return;
- }
+ msg = &messages[i];
- DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
+ /* Are we monitoring this event? */
- /* loop over all printers */
+ if (!is_monitoring_event(prn_hnd, msg->type, msg->field)) {
+ continue;
+ }
- for (p = printers_list; p; p = p->next) {
- struct spoolss_Notify *notifies;
- uint32_t count = 0;
- uint32_t id;
- int i;
+ DEBUG(10, ("Sending message type [0x%x] field [0x%2x] "
+ "for printer [%s]\n",
+ msg->type, msg->field, prn_hnd->sharename));
- /* Is there notification on this handle? */
+ /*
+ * if the is a printer notification handle and not a job
+ * notification type, then set the id to 0.
+ * Otherwise just use what was specified in the message.
+ *
+ * When registering change notification on a print server
+ * handle we always need to send back the id (snum) matching
+ * the printer for which the change took place.
+ * For change notify registered on a printer handle,
+ * this does not matter and the id should be 0.
+ *
+ * --jerry
+ */
- if ( !p->notify.client_connected )
- continue;
+ if ((msg->type == PRINTER_NOTIFY_TYPE) &&
+ (prn_hnd->printer_type == SPLHND_PRINTER)) {
+ id = 0;
+ } else {
+ id = msg->id;
+ }
- DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
+ /* Convert unix jobid to smb jobid */
- /* For this printer? Print servers always receive
- notifications. */
+ if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
+ id = sysjob_to_jobid(msg->id);
- if ( ( p->printer_type == SPLHND_PRINTER ) &&
- ( !strequal(msg_group->printername, p->sharename) ) )
- continue;
+ if (id == -1) {
+ DEBUG(3, ("no such unix jobid %d\n",
+ msg->id));
+ continue;
+ }
+ }
- DEBUG(10,("Our printer\n"));
+ construct_info_data(&notifies[count],
+ msg->type, msg->field, id);
- /* allocate the max entries possible */
+ switch(msg->type) {
+ case PRINTER_NOTIFY_TYPE:
+ if (printer_notify_table[msg->field].fn) {
+ printer_notify_table[msg->field].fn(msg,
+ &notifies[count], mem_ctx);
+ }
+ break;
- notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
- if (!notifies) {
- return;
- }
+ case JOB_NOTIFY_TYPE:
+ if (job_notify_table[msg->field].fn) {
+ job_notify_table[msg->field].fn(msg,
+ &notifies[count], mem_ctx);
+ }
+ break;
- /* build the array of change notifications */
+ default:
+ DEBUG(5, ("Unknown notification type %d\n",
+ msg->type));
+ continue;
+ }
- sending_msg_count = 0;
+ count++;
+ }
- for ( i=0; i<msg_group->num_msgs; i++ ) {
- SPOOLSS_NOTIFY_MSG *msg = &messages[i];
+ *_notifies = notifies;
+ *_count = count;
- /* Are we monitoring this event? */
+ return 0;
+}
- if (!is_monitoring_event(p, msg->type, msg->field))
- continue;
+static int send_notify2_printer(TALLOC_CTX *mem_ctx,
+ struct printer_handle *prn_hnd,
+ SPOOLSS_NOTIFY_MSG_GROUP *msg_group)
+{
+ struct spoolss_Notify *notifies;
+ int count = 0;
+ union spoolss_ReplyPrinterInfo info;
+ struct spoolss_NotifyInfo info0;
+ uint32_t reply_result;
+ NTSTATUS status;
+ WERROR werr;
+ int ret;
- sending_msg_count++;
+ /* Is there notification on this handle? */
+ if (!prn_hnd->notify.client_connected) {
+ return 0;
+ }
+ DEBUG(10, ("Client connected! [\\\\%s\\%s]\n",
+ prn_hnd->servername, prn_hnd->sharename));
- DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
- msg->type, msg->field, p->sharename));
+ /* For this printer? Print servers always receive notifications. */
+ if ((prn_hnd->printer_type == SPLHND_PRINTER) &&
+ (!strequal(msg_group->printername, prn_hnd->sharename))) {
+ return 0;
+ }
- /*
- * if the is a printer notification handle and not a job notification
- * type, then set the id to 0. Other wise just use what was specified
- * in the message.
- *
- * When registering change notification on a print server handle
- * we always need to send back the id (snum) matching the printer
- * for which the change took place. For change notify registered
- * on a printer handle, this does not matter and the id should be 0.
- *
- * --jerry
- */
+ DEBUG(10,("Our printer\n"));
- if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
- id = 0;
- else
- id = msg->id;
+ /* build the array of change notifications */
+ ret = build_notify2_messages(mem_ctx, prn_hnd,
+ msg_group->msgs,
+ msg_group->num_msgs,
+ &notifies, &count);
+ if (ret) {
+ return ret;
+ }
+ info0.version = 0x2;
+ info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
+ info0.count = count;
+ info0.notifies = notifies;
- /* Convert unix jobid to smb jobid */
+ info.info0 = &info0;
- if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
- id = sysjob_to_jobid(msg->id);
+ status = rpccli_spoolss_RouterReplyPrinterEx(
+ back_channel.cli_pipe, mem_ctx,
+ &prn_hnd->notify.client_hnd,
+ prn_hnd->notify.change, /* color */
+ prn_hnd->notify.flags,
+ &reply_result,
+ 0, /* reply_type, must be 0 */
+ info, &werr);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("RouterReplyPrinterEx to client: %s "
+ "failed: %s\n",
+ back_channel.cli_pipe->srv_name_slash,
+ win_errstr(werr)));
+ }
+ switch (reply_result) {
+ case 0:
+ break;
+ case PRINTER_NOTIFY_INFO_DISCARDED:
+ case PRINTER_NOTIFY_INFO_DISCARDNOTED:
+ case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
+ break;
+ default:
+ break;
+ }
- if (id == -1) {
- DEBUG(3, ("no such unix jobid %d\n", msg->id));
- goto done;
- }
- }
+ return 0;
+}
- construct_info_data(&notifies[count],
- (enum spoolss_NotifyType) msg->type,
- msg->field,
- id);
+static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
+{
+ struct printer_handle *p;
+ TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
+ SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
+ int ret;
- switch(msg->type) {
- case PRINTER_NOTIFY_TYPE:
- if ( printer_notify_table[msg->field].fn )
- printer_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
- break;
+ if ( !msg_group ) {
+ DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
+ return;
+ }
- case JOB_NOTIFY_TYPE:
- if ( job_notify_table[msg->field].fn )
- job_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
- break;
+ if (!msg_group->msgs) {
+ DEBUG(5, ("send_notify2_changes() called with no messages!\n"));
+ return;
+ }
- default:
- DEBUG(5, ("Unknown notification type %d\n", msg->type));
- goto done;
- }
+ DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
- count++;
- }
+ /* loop over all printers */
- if ( sending_msg_count ) {
- NTSTATUS status;
- WERROR werr;
- union spoolss_ReplyPrinterInfo info;
- struct spoolss_NotifyInfo info0;
- uint32_t reply_result;
-
- info0.version = 0x2;
- info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
- info0.count = count;
- info0.notifies = notifies;
-
- info.info0 = &info0;
-
- status = rpccli_spoolss_RouterReplyPrinterEx(back_channel.cli_pipe, mem_ctx,
- &p->notify.client_hnd,
- p->notify.change, /* color */
- p->notify.flags,
- &reply_result,
- 0, /* reply_type, must be 0 */
- info,
- &werr);
- if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
- DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
- back_channel.cli_pipe->srv_name_slash,
- win_errstr(werr)));
- }
- switch (reply_result) {
- case 0:
- break;
- case PRINTER_NOTIFY_INFO_DISCARDED:
- case PRINTER_NOTIFY_INFO_DISCARDNOTED:
- case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
- break;
- default:
- break;
- }
+ for (p = printers_list; p; p = p->next) {
+ ret = send_notify2_printer(mem_ctx, p, msg_group);
+ if (ret) {
+ goto done;
}
}