📄 srv_spoolss_nt.c
字号:
WERROR result; DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename))); aprinter = handlename; if ( *handlename == '\\' ) { servername = handlename + 2; if ( (aprinter = strchr_m( handlename+2, '\\' )) != NULL ) { *aprinter = '\0'; aprinter++; } } else { servername = ""; } /* save the servername to fill in replies on this handle */ if ( !is_myname_or_ipaddr( servername ) ) return False; fstrcpy( Printer->servername, servername ); if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) return True; if ( Printer->printer_type != PRINTER_HANDLE_IS_PRINTER ) return False; DEBUGADD(5, ("searching for [%s]\n", aprinter )); /* Search all sharenames first as this is easier than pulling the printer_info_2 off of disk. Don't use find_service() since that calls out to map_username() */ /* do another loop to look for printernames */ for (snum=0; !found && snum<n_services; snum++) { /* no point going on if this is not a printer */ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) continue; fstrcpy(sname, lp_servicename(snum)); if ( strequal( aprinter, sname ) ) { found = True; break; } /* no point looking up the printer object if we aren't allowing printername != sharename */ if ( lp_force_printername(snum) ) continue; fstrcpy(sname, lp_servicename(snum)); printer = NULL; result = get_a_printer( NULL, &printer, 2, sname ); if ( !W_ERROR_IS_OK(result) ) { DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n", sname, dos_errstr(result))); continue; } /* printername is always returned as \\server\printername */ if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) { DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n", printer->info_2->printername)); free_a_printer( &printer, 2); continue; } printername++; if ( strequal(printername, aprinter) ) { found = True; break; } DEBUGADD(10, ("printername: %s\n", printername)); free_a_printer( &printer, 2); } if ( !found ) { DEBUGADD(4,("Printer not found\n")); return False; } DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname)); fstrcpy(Printer->sharename, sname); return True;}/**************************************************************************** Find first available printer slot. creates a printer handle for you. ****************************************************************************/static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted){ Printer_entry *new_printer; DEBUG(10,("open_printer_hnd: name [%s]\n", name)); if((new_printer=SMB_MALLOC_P(Printer_entry)) == NULL) return False; ZERO_STRUCTP(new_printer); if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) { SAFE_FREE(new_printer); return False; } /* Add to the internal list. */ DLIST_ADD(printers_list, new_printer); new_printer->notify.option=NULL; if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) { DEBUG(0,("open_printer_hnd: talloc_init() failed!\n")); close_printer_handle(p, hnd); return False; } if (!set_printer_hnd_printertype(new_printer, name)) { close_printer_handle(p, hnd); return False; } if (!set_printer_hnd_name(new_printer, name)) { close_printer_handle(p, hnd); return False; } new_printer->access_granted = access_granted; DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count )); return True;}/*************************************************************************** check to see if the client motify handle is monitoring the notification given by (notify_type, notify_field). **************************************************************************/static BOOL is_monitoring_event_flags(uint32 flags, uint16 notify_type, uint16 notify_field){ return True;}static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type, uint16 notify_field){ SPOOL_NOTIFY_OPTION *option = p->notify.option; uint32 i, j; /* * Flags should always be zero when the change notify * is registered by the client's spooler. A user Win32 app * might use the flags though instead of the NOTIFY_OPTION_INFO * --jerry */ if (!option) { return False; } 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, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n", p->servername, p->sharename, 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;}static void notify_string(struct spoolss_notify_msg *msg, SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx){ UNISTR2 unistr; /* The length of the message includes the trailing \0 */ init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE); data->notify_data.data.length = msg->len * 2; data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len); if (!data->notify_data.data.string) { data->notify_data.data.length = 0; return; } memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);}static void notify_system_time(struct spoolss_notify_msg *msg, SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx){ 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; } if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) { DEBUG(5, ("notify_system_time: prs_init() failed\n")); return; } if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) { DEBUG(5, ("notify_system_time: unable to make systemtime\n")); return; } 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)); prs_copy_all_data_out((char *)data->notify_data.data.string, &ps); prs_mem_free(&ps);}struct notify2_message_table { const 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", notify_string }, /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string }, /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string }, /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string }, /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string }, /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string }, /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string }, /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL }, /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string }, /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string }, /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL }, /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string }, /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL }, /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value }, /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value }, /* 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 },};/*********************************************************************** Allocate talloc context for container object **********************************************************************/ static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr ){ if ( !ctr ) return; ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr); return;}/*********************************************************************** release all allocated memory and zero out structure **********************************************************************/ static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr ){ if ( !ctr ) return; if ( ctr->ctx ) talloc_destroy(ctr->ctx); ZERO_STRUCTP(ctr); return;}/*********************************************************************** **********************************************************************/ static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr ){ if ( !ctr ) return NULL; return ctr->ctx;}/*********************************************************************** **********************************************************************/ static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ){ if ( !ctr || !ctr->msg_groups ) return NULL; if ( idx >= ctr->num_groups ) return NULL; return &ctr->msg_groups[idx];}/*********************************************************************** How many groups of change messages do we have ? **********************************************************************/ static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr ){ if ( !ctr ) return 0; return ctr->num_groups;}/*********************************************************************** Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group **********************************************************************/ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg ){ SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL; SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL; SPOOLSS_NOTIFY_MSG *msg_list = NULL; int i, new_slot; if ( !ctr || !msg ) return 0; /* loop over all groups looking for a matching printer name */ for ( i=0; i<ctr->num_groups; i++ ) { if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 ) break; } /* add a new group? */ if ( i == ctr->num_groups ) { ctr->num_groups++; if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) { DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n")); return 0; } ctr->msg_groups = groups; /* clear the new entry and set the printer name */ ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] ); fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer ); } /* add the change messages; 'i' is the correct index now regardless */ msg_grp = &ctr->msg_groups[i]; msg_grp->num_msgs++; if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) { DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs)); return 0; } msg_grp->msgs = msg_list; new_slot = msg_grp->num_msgs-1; memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) ); /* need to allocate own copy of data */ if ( msg->len != 0 ) msg_grp->msgs[new_slot].notify.data = TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len ); return ctr->num_groups;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -