⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srv_spoolss_nt.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}/*********************************************************************** Send a change notication message on all handles which have a call  back registered **********************************************************************/static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ){	Printer_entry 		 *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;		if ( !msg_group ) {		DEBUG(5,("send_notify2_changes() called with no msg group!\n"));		return;	}		messages = msg_group->msgs;		if ( !messages ) {		DEBUG(5,("send_notify2_changes() called with no messages!\n"));		return;	}		DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));		/* loop over all printers */		for (p = printers_list; p; p = p->next) {		SPOOL_NOTIFY_INFO_DATA *data;		uint32	data_len = 0;		uint32 	id;		int 	i;		/* Is there notification on this handle? */		if ( !p->notify.client_connected )			continue;		DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));		/* For this printer?  Print servers always receive                    notifications. */		if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER )  &&		    ( !strequal(msg_group->printername, p->sharename) ) )			continue;		DEBUG(10,("Our printer\n"));				/* allocate the max entries possible */				data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);		ZERO_STRUCTP(data);				/* build the array of change notifications */				sending_msg_count = 0;				for ( i=0; i<msg_group->num_msgs; i++ ) {			SPOOLSS_NOTIFY_MSG	*msg = &messages[i];						/* Are we monitoring this event? */			if (!is_monitoring_event(p, msg->type, msg->field))				continue;			sending_msg_count++;									DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",				msg->type, msg->field, p->sharename));			/* 			 * 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			 */			if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )				id = 0;			else				id = msg->id;			/* Convert unix jobid to smb jobid */			if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {				id = sysjob_to_jobid(msg->id);				if (id == -1) {					DEBUG(3, ("no such unix jobid %d\n", msg->id));					goto done;				}			}			construct_info_data( &data[data_len], 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[data_len], mem_ctx);				break;						case JOB_NOTIFY_TYPE:				if ( job_notify_table[msg->field].fn )					job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);				break;			default:				DEBUG(5, ("Unknown notification type %d\n", msg->type));				goto done;			}			data_len++;		}		if ( sending_msg_count ) {			rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd, 					data_len, data, p->notify.change, 0 );		}	}	done:	DEBUG(8,("send_notify2_changes: Exit...\n"));	return;}/*********************************************************************** **********************************************************************/static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len ){	uint32 tv_sec, tv_usec;	size_t offset = 0;	/* Unpack message */	offset += tdb_unpack((char *)buf + offset, len - offset, "f",			     msg->printer);		offset += tdb_unpack((char *)buf + offset, len - offset, "ddddddd",				&tv_sec, &tv_usec,				&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, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",		  msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));	tv->tv_sec = tv_sec;	tv->tv_usec = tv_usec;	if (msg->len == 0)		DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],			  msg->notify.value[1]));	else		dump_data(3, msg->notify.data, msg->len);	return True;}/******************************************************************** Receive a notify2 message list ********************************************************************/static void receive_notify2_message_list(int msg_type, struct process_id src,					 void *msg, size_t len){	size_t 			msg_count, i;	char 			*buf = (char *)msg;	char 			*msg_ptr;	size_t 			msg_len;	SPOOLSS_NOTIFY_MSG	notify;	SPOOLSS_NOTIFY_MSG_CTR	messages;	int			num_groups;	if (len < 4) {		DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));		return;	}		msg_count = IVAL(buf, 0);	msg_ptr = buf + 4;	DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));	if (msg_count == 0) {		DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));		return;	}	/* initialize the container */		ZERO_STRUCT( messages );	notify_msg_ctr_init( &messages );		/* 	 * build message groups for each printer identified	 * in a change_notify msg.  Remember that a PCN message	 * includes the handle returned for the srv_spoolss_replyopenprinter()	 * call.  Therefore messages are grouped according to printer handle.	 */	 	for ( i=0; i<msg_count; i++ ) {		struct timeval msg_tv;		if (msg_ptr + 4 - buf > len) {			DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));			return;		}		msg_len = IVAL(msg_ptr,0);		msg_ptr += 4;		if (msg_ptr + msg_len - buf > len) {			DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));			return;		}				/* unpack messages */				ZERO_STRUCT( notify );		notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );		msg_ptr += msg_len;		/* add to correct list in container */				notify_msg_ctr_addmsg( &messages, &notify );				/* free memory that might have been allocated by notify2_unpack_msg() */				if ( notify.len != 0 )			SAFE_FREE( notify.notify.data );	}		/* process each group of messages */		num_groups = notify_msg_ctr_numgroups( &messages );	for ( i=0; i<num_groups; i++ )		send_notify2_changes( &messages, i );			/* cleanup */			DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));			notify_msg_ctr_destroy( &messages );		return;}/******************************************************************** 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);		if (!len)		return False;	DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",		drivername));			message_send_pid(pid_to_procid(sys_getpid()),			 MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);	return True;}/********************************************************************** callback to receive a MSG_PRINTER_DRVUPGRADE message and interate over all printers, upgrading ones as necessary  **********************************************************************/ void do_drv_upgrade_printer(int msg_type, struct process_id 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(NULL, &printer, 2, lp_const_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 */	}/******************************************************************** Update the cache for all printq's with a registered client  connection ********************************************************************/void update_monitored_printq_cache( void ){	Printer_entry *printer = printers_list;	int snum;		/* loop through all printers and update the cache where 	   client_connected == True */	while ( printer ) 	{		if ( (printer->printer_type == PRINTER_HANDLE_IS_PRINTER) 			&& printer->notify.client_connected ) 		{			snum = print_queue_snum(printer->sharename);			print_queue_status( snum, NULL, NULL );		}				printer = printer->next;	}		return;}/******************************************************************** 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_reset_printerdata(char* drivername){	int len = strlen(drivername);		if (!len)		return False;	DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",		drivername));			message_send_pid(pid_to_procid(sys_getpid()),			 MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);	return True;}/********************************************************************** callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate over all printers, resetting printer data as neessary  **********************************************************************/ void reset_all_printerdata(int msg_type, struct process_id 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,("reset_all_printerdata: 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( NULL, &printer, 2, lp_const_servicename(snum) );			if ( !W_ERROR_IS_OK(result) )				continue;							/* 			 * if the printer is bound to the driver, 			 * then reset to the new driver initdata 			 */						if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) ) 			{				DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));								if ( !set_driver_init(printer, 2) ) {					DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",						printer->info_2->printername, printer->info_2->drivername));				}									result = mod_a_printer( printer, 2 );				if ( !W_ERROR_IS_OK(result) ) {					DEBUG(3,("reset_all_printerdata: mod_a_printer() failed!  (%s)\n", 						get_dos_error_msg(result)));				}			}						free_a_printer( &printer, 2 );		}	}		/* all done */			return;}/******************************************************************** Copy routines used by convert_to_openprinterex()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -