2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
26 up, all the errors returned are DOS errors, not NT status codes. */
30 extern userdom_struct current_user_info
;
33 #define DBGC_CLASS DBGC_RPC_SRV
35 #ifndef MAX_OPEN_PRINTER_EXS
36 #define MAX_OPEN_PRINTER_EXS 50
39 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
40 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
43 const char *long_archi
;
44 const char *short_archi
;
48 static Printer_entry
*printers_list
;
50 typedef struct _counter_printer_0
{
51 struct _counter_printer_0
*next
;
52 struct _counter_printer_0
*prev
;
58 static counter_printer_0
*counter_list
;
60 static struct rpc_pipe_client
*notify_cli_pipe
; /* print notify back-channel pipe handle*/
61 static uint32 smb_connections
=0;
64 /* in printing/nt_printing.c */
66 extern struct standard_mapping printer_std_mapping
, printserver_std_mapping
;
68 /* API table for Xcv Monitor functions */
70 struct xcv_api_table
{
72 WERROR(*fn
) (NT_USER_TOKEN
*token
, RPC_BUFFER
*in
, RPC_BUFFER
*out
, uint32
*needed
);
75 /********************************************************************
76 * Canonicalize servername.
77 ********************************************************************/
79 static const char *canon_servername(const char *servername
)
81 const char *pservername
= servername
;
82 while (*pservername
== '\\') {
88 /* translate between internal status numbers and NT status numbers */
89 static int nt_printj_status(int v
)
95 return JOB_STATUS_PAUSED
;
97 return JOB_STATUS_SPOOLING
;
99 return JOB_STATUS_PRINTING
;
101 return JOB_STATUS_ERROR
;
103 return JOB_STATUS_DELETING
;
105 return JOB_STATUS_OFFLINE
;
107 return JOB_STATUS_PAPEROUT
;
109 return JOB_STATUS_PRINTED
;
111 return JOB_STATUS_DELETED
;
113 return JOB_STATUS_BLOCKED
;
114 case LPQ_USER_INTERVENTION
:
115 return JOB_STATUS_USER_INTERVENTION
;
120 static int nt_printq_status(int v
)
124 return PRINTER_STATUS_PAUSED
;
133 /****************************************************************************
134 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
135 ****************************************************************************/
137 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION
**pp
)
142 SAFE_FREE((*pp
)->ctr
.type
);
146 /***************************************************************************
147 Disconnect from the client
148 ****************************************************************************/
150 static void srv_spoolss_replycloseprinter(int snum
, POLICY_HND
*handle
)
156 * Tell the specific printing tdb we no longer want messages for this printer
157 * by deregistering our PID.
160 if (!print_notify_deregister_pid(snum
))
161 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum
) ));
163 /* weird if the test succeds !!! */
164 if (smb_connections
==0) {
165 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
169 status
= rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe
, talloc_tos(),
172 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
173 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
174 win_errstr(result
)));
176 /* if it's the last connection, deconnect the IPC$ share */
177 if (smb_connections
==1) {
179 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe
) );
180 notify_cli_pipe
= NULL
; /* The above call shuts downn the pipe also. */
182 messaging_deregister(smbd_messaging_context(),
183 MSG_PRINTER_NOTIFY2
, NULL
);
185 /* Tell the connections db we're no longer interested in
186 * printer notify messages. */
188 register_message_flags( False
, FLAG_MSG_PRINT_NOTIFY
);
194 /****************************************************************************
195 Functions to free a printer entry datastruct.
196 ****************************************************************************/
198 static int printer_entry_destructor(Printer_entry
*Printer
)
200 if (Printer
->notify
.client_connected
==True
) {
203 if ( Printer
->printer_type
== SPLHND_SERVER
) {
205 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
206 } else if (Printer
->printer_type
== SPLHND_PRINTER
) {
207 snum
= print_queue_snum(Printer
->sharename
);
209 srv_spoolss_replycloseprinter(snum
,
210 &Printer
->notify
.client_hnd
);
214 Printer
->notify
.flags
=0;
215 Printer
->notify
.options
=0;
216 Printer
->notify
.localmachine
[0]='\0';
217 Printer
->notify
.printerlocal
=0;
218 free_spool_notify_option(&Printer
->notify
.option
);
219 Printer
->notify
.option
=NULL
;
220 Printer
->notify
.client_connected
=False
;
222 free_nt_devicemode( &Printer
->nt_devmode
);
223 free_a_printer( &Printer
->printer_info
, 2 );
225 /* Remove from the internal list. */
226 DLIST_REMOVE(printers_list
, Printer
);
230 /****************************************************************************
231 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
232 ****************************************************************************/
234 static SPOOL_NOTIFY_OPTION
*dup_spool_notify_option(SPOOL_NOTIFY_OPTION
*sp
)
236 SPOOL_NOTIFY_OPTION
*new_sp
= NULL
;
241 new_sp
= SMB_MALLOC_P(SPOOL_NOTIFY_OPTION
);
248 new_sp
->ctr
.type
= (SPOOL_NOTIFY_OPTION_TYPE
*)memdup(sp
->ctr
.type
, sizeof(SPOOL_NOTIFY_OPTION_TYPE
) * sp
->ctr
.count
);
250 if (!new_sp
->ctr
.type
) {
259 /****************************************************************************
260 find printer index by handle
261 ****************************************************************************/
263 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
265 Printer_entry
*find_printer
= NULL
;
267 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)&find_printer
)) {
268 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
275 /****************************************************************************
276 Close printer index by handle.
277 ****************************************************************************/
279 static bool close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
281 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
284 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
288 close_policy_hnd(p
, hnd
);
293 /****************************************************************************
294 Delete a printer given a handle.
295 ****************************************************************************/
297 WERROR
delete_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *sharename
)
299 char *cmd
= lp_deleteprinter_cmd();
300 char *command
= NULL
;
302 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
303 bool is_print_op
= False
;
305 /* can't fail if we don't try */
310 command
= talloc_asprintf(ctx
,
317 is_print_op
= user_has_privileges( token
, &se_printop
);
319 DEBUG(10,("Running [%s]\n", command
));
321 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
326 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
327 /* Tell everyone we updated smb.conf. */
328 message_send_all(smbd_messaging_context(),
329 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
335 /********** END SePrintOperatorPrivlege BLOCK **********/
337 DEBUGADD(10,("returned [%d]\n", ret
));
339 TALLOC_FREE(command
);
342 return WERR_BADFID
; /* What to return here? */
344 /* go ahead and re-read the services immediately */
345 reload_services( False
);
347 if ( lp_servicenumber( sharename
) < 0 )
348 return WERR_ACCESS_DENIED
;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
359 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
362 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
367 * It turns out that Windows allows delete printer on a handle
368 * opened by an admin user, then used on a pipe handle created
369 * by an anonymous user..... but they're working on security.... riiight !
373 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
374 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
375 return WERR_ACCESS_DENIED
;
378 /* this does not need a become root since the access check has been
379 done on the handle already */
381 if (del_a_printer( Printer
->sharename
) != 0) {
382 DEBUG(3,("Error deleting printer %s\n", Printer
->sharename
));
386 return delete_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
387 Printer
->sharename
);
390 /****************************************************************************
391 Return the snum of a printer corresponding to an handle.
392 ****************************************************************************/
394 static bool get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
,
395 struct share_params
**params
)
397 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
400 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
404 switch (Printer
->printer_type
) {
406 DEBUG(4,("short name:%s\n", Printer
->sharename
));
407 *number
= print_queue_snum(Printer
->sharename
);
408 return (*number
!= -1);
416 /****************************************************************************
417 Set printer handle type.
418 Check if it's \\server or \\server\printer
419 ****************************************************************************/
421 static bool set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
423 DEBUG(3,("Setting printer type=%s\n", handlename
));
425 if ( strlen(handlename
) < 3 ) {
426 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
430 /* it's a print server */
431 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
432 DEBUGADD(4,("Printer is a print server\n"));
433 Printer
->printer_type
= SPLHND_SERVER
;
435 /* it's a printer (set_printer_hnd_name() will handle port monitors */
437 DEBUGADD(4,("Printer is a printer\n"));
438 Printer
->printer_type
= SPLHND_PRINTER
;
444 /****************************************************************************
445 Set printer handle name.. Accept names like \\server, \\server\printer,
446 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
447 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
448 XcvDataPort() interface.
449 ****************************************************************************/
451 static bool set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
454 int n_services
=lp_numservices();
455 char *aprinter
, *printername
;
456 const char *servername
;
459 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
462 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename
, (unsigned long)strlen(handlename
)));
464 aprinter
= handlename
;
465 if ( *handlename
== '\\' ) {
466 servername
= canon_servername(handlename
);
467 if ( (aprinter
= strchr_m( servername
, '\\' )) != NULL
) {
475 /* save the servername to fill in replies on this handle */
477 if ( !is_myname_or_ipaddr( servername
) )
480 fstrcpy( Printer
->servername
, servername
);
482 if ( Printer
->printer_type
== SPLHND_SERVER
)
485 if ( Printer
->printer_type
!= SPLHND_PRINTER
)
488 DEBUGADD(5, ("searching for [%s]\n", aprinter
));
490 /* check for the Port Monitor Interface */
492 if ( strequal( aprinter
, SPL_XCV_MONITOR_TCPMON
) ) {
493 Printer
->printer_type
= SPLHND_PORTMON_TCP
;
494 fstrcpy(sname
, SPL_XCV_MONITOR_TCPMON
);
497 else if ( strequal( aprinter
, SPL_XCV_MONITOR_LOCALMON
) ) {
498 Printer
->printer_type
= SPLHND_PORTMON_LOCAL
;
499 fstrcpy(sname
, SPL_XCV_MONITOR_LOCALMON
);
503 /* Search all sharenames first as this is easier than pulling
504 the printer_info_2 off of disk. Don't use find_service() since
505 that calls out to map_username() */
507 /* do another loop to look for printernames */
509 for (snum
=0; !found
&& snum
<n_services
; snum
++) {
511 /* no point going on if this is not a printer */
513 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
)) )
516 fstrcpy(sname
, lp_servicename(snum
));
517 if ( strequal( aprinter
, sname
) ) {
522 /* no point looking up the printer object if
523 we aren't allowing printername != sharename */
525 if ( lp_force_printername(snum
) )
528 fstrcpy(sname
, lp_servicename(snum
));
532 /* This call doesn't fill in the location or comment from
533 * a CUPS server for efficiency with large numbers of printers.
537 result
= get_a_printer_search( NULL
, &printer
, 2, sname
);
538 if ( !W_ERROR_IS_OK(result
) ) {
539 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
540 sname
, win_errstr(result
)));
544 /* printername is always returned as \\server\printername */
545 if ( !(printername
= strchr_m(&printer
->info_2
->printername
[2], '\\')) ) {
546 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
547 printer
->info_2
->printername
));
548 free_a_printer( &printer
, 2);
554 if ( strequal(printername
, aprinter
) ) {
555 free_a_printer( &printer
, 2);
560 DEBUGADD(10, ("printername: %s\n", printername
));
562 free_a_printer( &printer
, 2);
565 free_a_printer( &printer
, 2);
568 DEBUGADD(4,("Printer not found\n"));
572 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
574 fstrcpy(Printer
->sharename
, sname
);
579 /****************************************************************************
580 Find first available printer slot. creates a printer handle for you.
581 ****************************************************************************/
583 static bool open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
, uint32 access_granted
)
585 Printer_entry
*new_printer
;
587 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
589 new_printer
= TALLOC_ZERO_P(NULL
, Printer_entry
);
590 if (new_printer
== NULL
) {
593 talloc_set_destructor(new_printer
, printer_entry_destructor
);
595 if (!create_policy_hnd(p
, hnd
, new_printer
)) {
596 TALLOC_FREE(new_printer
);
600 /* Add to the internal list. */
601 DLIST_ADD(printers_list
, new_printer
);
603 new_printer
->notify
.option
=NULL
;
605 if (!set_printer_hnd_printertype(new_printer
, name
)) {
606 close_printer_handle(p
, hnd
);
610 if (!set_printer_hnd_name(new_printer
, name
)) {
611 close_printer_handle(p
, hnd
);
615 new_printer
->access_granted
= access_granted
;
617 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
622 /***************************************************************************
623 check to see if the client motify handle is monitoring the notification
624 given by (notify_type, notify_field).
625 **************************************************************************/
627 static bool is_monitoring_event_flags(uint32 flags
, uint16 notify_type
,
633 static bool is_monitoring_event(Printer_entry
*p
, uint16 notify_type
,
636 SPOOL_NOTIFY_OPTION
*option
= p
->notify
.option
;
640 * Flags should always be zero when the change notify
641 * is registered by the client's spooler. A user Win32 app
642 * might use the flags though instead of the NOTIFY_OPTION_INFO
651 return is_monitoring_event_flags(
652 p
->notify
.flags
, notify_type
, notify_field
);
654 for (i
= 0; i
< option
->count
; i
++) {
656 /* Check match for notify_type */
658 if (option
->ctr
.type
[i
].type
!= notify_type
)
661 /* Check match for field */
663 for (j
= 0; j
< option
->ctr
.type
[i
].count
; j
++) {
664 if (option
->ctr
.type
[i
].fields
[j
] == notify_field
) {
670 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
671 p
->servername
, p
->sharename
, notify_type
, notify_field
));
676 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
678 static void notify_one_value(struct spoolss_notify_msg
*msg
,
679 SPOOL_NOTIFY_INFO_DATA
*data
,
682 data
->notify_data
.value
[0] = msg
->notify
.value
[0];
683 data
->notify_data
.value
[1] = 0;
686 static void notify_string(struct spoolss_notify_msg
*msg
,
687 SPOOL_NOTIFY_INFO_DATA
*data
,
692 /* The length of the message includes the trailing \0 */
694 init_unistr2(&unistr
, msg
->notify
.data
, UNI_STR_TERMINATE
);
696 data
->notify_data
.data
.length
= msg
->len
* 2;
697 data
->notify_data
.data
.string
= TALLOC_ARRAY(mem_ctx
, uint16
, msg
->len
);
699 if (!data
->notify_data
.data
.string
) {
700 data
->notify_data
.data
.length
= 0;
704 memcpy(data
->notify_data
.data
.string
, unistr
.buffer
, msg
->len
* 2);
707 static void notify_system_time(struct spoolss_notify_msg
*msg
,
708 SPOOL_NOTIFY_INFO_DATA
*data
,
714 if (msg
->len
!= sizeof(time_t)) {
715 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
720 if (!prs_init(&ps
, RPC_MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
)) {
721 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
725 if (!make_systemtime(&systime
, gmtime((time_t *)msg
->notify
.data
))) {
726 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
731 if (!spoolss_io_system_time("", &ps
, 0, &systime
)) {
736 data
->notify_data
.data
.length
= prs_offset(&ps
);
737 if (prs_offset(&ps
)) {
738 data
->notify_data
.data
.string
= (uint16
*)
739 TALLOC(mem_ctx
, prs_offset(&ps
));
740 if (!data
->notify_data
.data
.string
) {
744 prs_copy_all_data_out((char *)data
->notify_data
.data
.string
, &ps
);
746 data
->notify_data
.data
.string
= NULL
;
752 struct notify2_message_table
{
754 void (*fn
)(struct spoolss_notify_msg
*msg
,
755 SPOOL_NOTIFY_INFO_DATA
*data
, TALLOC_CTX
*mem_ctx
);
758 static struct notify2_message_table printer_notify_table
[] = {
759 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string
},
760 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string
},
761 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string
},
762 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string
},
763 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string
},
764 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string
},
765 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string
},
766 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL
},
767 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string
},
768 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string
},
769 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL
},
770 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string
},
771 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
772 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value
},
773 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value
},
774 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL
},
775 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL
},
776 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL
},
777 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value
},
780 static struct notify2_message_table job_notify_table
[] = {
781 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL
},
782 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL
},
783 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL
},
784 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string
},
785 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL
},
786 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL
},
787 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL
},
788 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL
},
789 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL
},
790 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL
},
791 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value
},
792 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL
},
793 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
794 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string
},
795 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL
},
796 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL
},
797 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time
},
798 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL
},
799 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL
},
800 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL
},
801 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value
},
802 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL
},
803 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value
},
804 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL
},
808 /***********************************************************************
809 Allocate talloc context for container object
810 **********************************************************************/
812 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
817 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
822 /***********************************************************************
823 release all allocated memory and zero out structure
824 **********************************************************************/
826 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
832 talloc_destroy(ctr
->ctx
);
839 /***********************************************************************
840 **********************************************************************/
842 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
850 /***********************************************************************
851 **********************************************************************/
853 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
855 if ( !ctr
|| !ctr
->msg_groups
)
858 if ( idx
>= ctr
->num_groups
)
861 return &ctr
->msg_groups
[idx
];
865 /***********************************************************************
866 How many groups of change messages do we have ?
867 **********************************************************************/
869 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
874 return ctr
->num_groups
;
877 /***********************************************************************
878 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
879 **********************************************************************/
881 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
883 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
884 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
885 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
891 /* loop over all groups looking for a matching printer name */
893 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
894 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
898 /* add a new group? */
900 if ( i
== ctr
->num_groups
) {
903 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
904 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
907 ctr
->msg_groups
= groups
;
909 /* clear the new entry and set the printer name */
911 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
912 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
915 /* add the change messages; 'i' is the correct index now regardless */
917 msg_grp
= &ctr
->msg_groups
[i
];
921 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
922 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
925 msg_grp
->msgs
= msg_list
;
927 new_slot
= msg_grp
->num_msgs
-1;
928 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
930 /* need to allocate own copy of data */
933 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
934 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
936 return ctr
->num_groups
;
939 /***********************************************************************
940 Send a change notication message on all handles which have a call
942 **********************************************************************/
944 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
947 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
948 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
949 SPOOLSS_NOTIFY_MSG
*messages
;
950 int sending_msg_count
;
953 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
957 messages
= msg_group
->msgs
;
960 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
964 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
966 /* loop over all printers */
968 for (p
= printers_list
; p
; p
= p
->next
) {
969 SPOOL_NOTIFY_INFO_DATA
*data
;
974 /* Is there notification on this handle? */
976 if ( !p
->notify
.client_connected
)
979 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
981 /* For this printer? Print servers always receive
984 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
985 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
988 DEBUG(10,("Our printer\n"));
990 /* allocate the max entries possible */
992 data
= TALLOC_ARRAY( mem_ctx
, SPOOL_NOTIFY_INFO_DATA
, msg_group
->num_msgs
);
999 /* build the array of change notifications */
1001 sending_msg_count
= 0;
1003 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
1004 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
1006 /* Are we monitoring this event? */
1008 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
1011 sending_msg_count
++;
1014 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1015 msg
->type
, msg
->field
, p
->sharename
));
1018 * if the is a printer notification handle and not a job notification
1019 * type, then set the id to 0. Other wise just use what was specified
1022 * When registering change notification on a print server handle
1023 * we always need to send back the id (snum) matching the printer
1024 * for which the change took place. For change notify registered
1025 * on a printer handle, this does not matter and the id should be 0.
1030 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1036 /* Convert unix jobid to smb jobid */
1038 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1039 id
= sysjob_to_jobid(msg
->id
);
1042 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1047 construct_info_data( &data
[data_len
], msg
->type
, msg
->field
, id
);
1050 case PRINTER_NOTIFY_TYPE
:
1051 if ( printer_notify_table
[msg
->field
].fn
)
1052 printer_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1055 case JOB_NOTIFY_TYPE
:
1056 if ( job_notify_table
[msg
->field
].fn
)
1057 job_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1061 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1068 if ( sending_msg_count
) {
1069 rpccli_spoolss_rrpcn( notify_cli_pipe
, mem_ctx
, &p
->notify
.client_hnd
,
1070 data_len
, data
, p
->notify
.change
, 0 );
1075 DEBUG(8,("send_notify2_changes: Exit...\n"));
1079 /***********************************************************************
1080 **********************************************************************/
1082 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1085 uint32 tv_sec
, tv_usec
;
1088 /* Unpack message */
1090 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "f",
1093 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "ddddddd",
1095 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1098 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "dd",
1099 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1101 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "B",
1102 &msg
->len
, &msg
->notify
.data
);
1104 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1105 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1107 tv
->tv_sec
= tv_sec
;
1108 tv
->tv_usec
= tv_usec
;
1111 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1112 msg
->notify
.value
[1]));
1114 dump_data(3, (uint8
*)msg
->notify
.data
, msg
->len
);
1119 /********************************************************************
1120 Receive a notify2 message list
1121 ********************************************************************/
1123 static void receive_notify2_message_list(struct messaging_context
*msg
,
1126 struct server_id server_id
,
1129 size_t msg_count
, i
;
1130 char *buf
= (char *)data
->data
;
1133 SPOOLSS_NOTIFY_MSG notify
;
1134 SPOOLSS_NOTIFY_MSG_CTR messages
;
1137 if (data
->length
< 4) {
1138 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1142 msg_count
= IVAL(buf
, 0);
1145 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1147 if (msg_count
== 0) {
1148 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1152 /* initialize the container */
1154 ZERO_STRUCT( messages
);
1155 notify_msg_ctr_init( &messages
);
1158 * build message groups for each printer identified
1159 * in a change_notify msg. Remember that a PCN message
1160 * includes the handle returned for the srv_spoolss_replyopenprinter()
1161 * call. Therefore messages are grouped according to printer handle.
1164 for ( i
=0; i
<msg_count
; i
++ ) {
1165 struct timeval msg_tv
;
1167 if (msg_ptr
+ 4 - buf
> data
->length
) {
1168 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1172 msg_len
= IVAL(msg_ptr
,0);
1175 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1176 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1180 /* unpack messages */
1182 ZERO_STRUCT( notify
);
1183 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1186 /* add to correct list in container */
1188 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1190 /* free memory that might have been allocated by notify2_unpack_msg() */
1192 if ( notify
.len
!= 0 )
1193 SAFE_FREE( notify
.notify
.data
);
1196 /* process each group of messages */
1198 num_groups
= notify_msg_ctr_numgroups( &messages
);
1199 for ( i
=0; i
<num_groups
; i
++ )
1200 send_notify2_changes( &messages
, i
);
1205 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32
)msg_count
));
1207 notify_msg_ctr_destroy( &messages
);
1212 /********************************************************************
1213 Send a message to ourself about new driver being installed
1214 so we can upgrade the information for each printer bound to this
1216 ********************************************************************/
1218 static bool srv_spoolss_drv_upgrade_printer(char* drivername
)
1220 int len
= strlen(drivername
);
1225 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1228 messaging_send_buf(smbd_messaging_context(), procid_self(),
1229 MSG_PRINTER_DRVUPGRADE
,
1230 (uint8
*)drivername
, len
+1);
1235 /**********************************************************************
1236 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1237 over all printers, upgrading ones as necessary
1238 **********************************************************************/
1240 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1243 struct server_id server_id
,
1248 int n_services
= lp_numservices();
1251 len
= MIN(data
->length
,sizeof(drivername
)-1);
1252 strncpy(drivername
, (const char *)data
->data
, len
);
1254 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1256 /* Iterate the printer list */
1258 for (snum
=0; snum
<n_services
; snum
++)
1260 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1263 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1265 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
1266 if (!W_ERROR_IS_OK(result
))
1269 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1271 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1273 /* all we care about currently is the change_id */
1275 result
= mod_a_printer(printer
, 2);
1276 if (!W_ERROR_IS_OK(result
)) {
1277 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1278 win_errstr(result
)));
1282 free_a_printer(&printer
, 2);
1289 /********************************************************************
1290 Update the cache for all printq's with a registered client
1292 ********************************************************************/
1294 void update_monitored_printq_cache( void )
1296 Printer_entry
*printer
= printers_list
;
1299 /* loop through all printers and update the cache where
1300 client_connected == True */
1303 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1304 && printer
->notify
.client_connected
)
1306 snum
= print_queue_snum(printer
->sharename
);
1307 print_queue_status( snum
, NULL
, NULL
);
1310 printer
= printer
->next
;
1315 /********************************************************************
1316 Send a message to ourself about new driver being installed
1317 so we can upgrade the information for each printer bound to this
1319 ********************************************************************/
1321 static bool srv_spoolss_reset_printerdata(char* drivername
)
1323 int len
= strlen(drivername
);
1328 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1331 messaging_send_buf(smbd_messaging_context(), procid_self(),
1332 MSG_PRINTERDATA_INIT_RESET
,
1333 (uint8
*)drivername
, len
+1);
1338 /**********************************************************************
1339 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1340 over all printers, resetting printer data as neessary
1341 **********************************************************************/
1343 void reset_all_printerdata(struct messaging_context
*msg
,
1346 struct server_id server_id
,
1351 int n_services
= lp_numservices();
1354 len
= MIN( data
->length
, sizeof(drivername
)-1 );
1355 strncpy( drivername
, (const char *)data
->data
, len
);
1357 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername
));
1359 /* Iterate the printer list */
1361 for ( snum
=0; snum
<n_services
; snum
++ )
1363 if ( lp_snum_ok(snum
) && lp_print_ok(snum
) )
1366 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1368 result
= get_a_printer( NULL
, &printer
, 2, lp_const_servicename(snum
) );
1369 if ( !W_ERROR_IS_OK(result
) )
1373 * if the printer is bound to the driver,
1374 * then reset to the new driver initdata
1377 if ( printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
) )
1379 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer
->info_2
->printername
));
1381 if ( !set_driver_init(printer
, 2) ) {
1382 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1383 printer
->info_2
->printername
, printer
->info_2
->drivername
));
1386 result
= mod_a_printer( printer
, 2 );
1387 if ( !W_ERROR_IS_OK(result
) ) {
1388 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1389 get_dos_error_msg(result
)));
1393 free_a_printer( &printer
, 2 );
1402 /****************************************************************
1403 _spoolss_OpenPrinter
1404 ****************************************************************/
1406 WERROR
_spoolss_OpenPrinter(pipes_struct
*p
,
1407 struct spoolss_OpenPrinter
*r
)
1409 struct spoolss_OpenPrinterEx e
;
1412 ZERO_STRUCT(e
.in
.userlevel
);
1414 e
.in
.printername
= r
->in
.printername
;
1415 e
.in
.datatype
= r
->in
.datatype
;
1416 e
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
1417 e
.in
.access_mask
= r
->in
.access_mask
;
1420 e
.out
.handle
= r
->out
.handle
;
1422 werr
= _spoolss_OpenPrinterEx(p
, &e
);
1424 if (W_ERROR_EQUAL(werr
, WERR_INVALID_PARAM
)) {
1425 /* OpenPrinterEx returns this for a bad
1426 * printer name. We must return WERR_INVALID_PRINTER_NAME
1429 werr
= WERR_INVALID_PRINTER_NAME
;
1435 /********************************************************************
1436 FIXME: temporary convert_devicemode_new function
1437 ********************************************************************/
1439 static bool convert_devicemode_new(const char *printername
,
1440 struct spoolss_DeviceMode
*devmode
,
1441 NT_DEVICEMODE
**pp_nt_devmode
)
1443 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1446 * Ensure nt_devmode is a valid pointer
1447 * as we will be overwriting it.
1450 if (nt_devmode
== NULL
) {
1451 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1452 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1456 rpcstr_push(nt_devmode
->devicename
, devmode
->devicename
, 31, 0);
1457 rpcstr_push(nt_devmode
->formname
, devmode
->formname
, 31, 0);
1459 nt_devmode
->specversion
= devmode
->specversion
;
1460 nt_devmode
->driverversion
= devmode
->driverversion
;
1461 nt_devmode
->size
= devmode
->size
;
1462 nt_devmode
->fields
= devmode
->fields
;
1463 nt_devmode
->orientation
= devmode
->orientation
;
1464 nt_devmode
->papersize
= devmode
->papersize
;
1465 nt_devmode
->paperlength
= devmode
->paperlength
;
1466 nt_devmode
->paperwidth
= devmode
->paperwidth
;
1467 nt_devmode
->scale
= devmode
->scale
;
1468 nt_devmode
->copies
= devmode
->copies
;
1469 nt_devmode
->defaultsource
= devmode
->defaultsource
;
1470 nt_devmode
->printquality
= devmode
->printquality
;
1471 nt_devmode
->color
= devmode
->color
;
1472 nt_devmode
->duplex
= devmode
->duplex
;
1473 nt_devmode
->yresolution
= devmode
->yresolution
;
1474 nt_devmode
->ttoption
= devmode
->ttoption
;
1475 nt_devmode
->collate
= devmode
->collate
;
1477 nt_devmode
->logpixels
= devmode
->logpixels
;
1478 nt_devmode
->bitsperpel
= devmode
->bitsperpel
;
1479 nt_devmode
->pelswidth
= devmode
->pelswidth
;
1480 nt_devmode
->pelsheight
= devmode
->pelsheight
;
1481 nt_devmode
->displayflags
= devmode
->displayflags
;
1482 nt_devmode
->displayfrequency
= devmode
->displayfrequency
;
1483 nt_devmode
->icmmethod
= devmode
->icmmethod
;
1484 nt_devmode
->icmintent
= devmode
->icmintent
;
1485 nt_devmode
->mediatype
= devmode
->mediatype
;
1486 nt_devmode
->dithertype
= devmode
->dithertype
;
1487 nt_devmode
->reserved1
= devmode
->reserved1
;
1488 nt_devmode
->reserved2
= devmode
->reserved2
;
1489 nt_devmode
->panningwidth
= devmode
->panningwidth
;
1490 nt_devmode
->panningheight
= devmode
->panningheight
;
1493 * Only change private and driverextra if the incoming devmode
1494 * has a new one. JRA.
1497 if ((devmode
->__driverextra_length
!= 0) && (devmode
->driverextra_data
.data
!= NULL
)) {
1498 SAFE_FREE(nt_devmode
->nt_dev_private
);
1499 nt_devmode
->driverextra
= devmode
->__driverextra_length
;
1500 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
1502 memcpy(nt_devmode
->nt_dev_private
, devmode
->driverextra_data
.data
, nt_devmode
->driverextra
);
1505 *pp_nt_devmode
= nt_devmode
;
1510 /****************************************************************
1511 _spoolss_OpenPrinterEx
1512 ****************************************************************/
1514 WERROR
_spoolss_OpenPrinterEx(pipes_struct
*p
,
1515 struct spoolss_OpenPrinterEx
*r
)
1517 POLICY_HND
*handle
= r
->out
.handle
;
1518 char *name
= CONST_DISCARD(char *, r
->in
.printername
);
1520 Printer_entry
*Printer
=NULL
;
1523 return WERR_INVALID_PARAM
;
1526 /* some sanity check because you can open a printer or a print server */
1527 /* aka: \\server\printer or \\server */
1529 DEBUGADD(3,("checking name: %s\n",name
));
1531 if (!open_printer_hnd(p
, handle
, name
, 0)) {
1532 return WERR_INVALID_PARAM
;
1535 Printer
=find_printer_index_by_hnd(p
, handle
);
1537 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1538 "handle we created for printer %s\n", name
));
1539 close_printer_handle(p
,handle
);
1540 return WERR_INVALID_PARAM
;
1544 * First case: the user is opening the print server:
1546 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1547 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1549 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1550 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1551 * or if the user is listed in the smb.conf printer admin parameter.
1553 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1554 * client view printer folder, but does not show the MSAPW.
1556 * Note: this test needs code to check access rights here too. Jeremy
1557 * could you look at this?
1559 * Second case: the user is opening a printer:
1560 * NT doesn't let us connect to a printer if the connecting user
1561 * doesn't have print permission.
1563 * Third case: user is opening a Port Monitor
1564 * access checks same as opening a handle to the print server.
1567 switch (Printer
->printer_type
)
1570 case SPLHND_PORTMON_TCP
:
1571 case SPLHND_PORTMON_LOCAL
:
1572 /* Printserver handles use global struct... */
1576 /* Map standard access rights to object specific access rights */
1578 se_map_standard(&r
->in
.access_mask
,
1579 &printserver_std_mapping
);
1581 /* Deny any object specific bits that don't apply to print
1582 servers (i.e printer and job specific bits) */
1584 r
->in
.access_mask
&= SPECIFIC_RIGHTS_MASK
;
1586 if (r
->in
.access_mask
&
1587 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1588 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1589 close_printer_handle(p
, handle
);
1590 return WERR_ACCESS_DENIED
;
1593 /* Allow admin access */
1595 if ( r
->in
.access_mask
& SERVER_ACCESS_ADMINISTER
)
1597 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1599 if (!lp_ms_add_printer_wizard()) {
1600 close_printer_handle(p
, handle
);
1601 return WERR_ACCESS_DENIED
;
1604 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1605 and not a printer admin, then fail */
1607 if ((p
->server_info
->utok
.uid
!= 0) &&
1608 !user_has_privileges(p
->server_info
->ptok
,
1610 !token_contains_name_in_list(
1611 uidtoname(p
->server_info
->utok
.uid
),
1613 p
->server_info
->ptok
,
1614 lp_printer_admin(snum
))) {
1615 close_printer_handle(p
, handle
);
1616 return WERR_ACCESS_DENIED
;
1619 r
->in
.access_mask
= SERVER_ACCESS_ADMINISTER
;
1623 r
->in
.access_mask
= SERVER_ACCESS_ENUMERATE
;
1626 DEBUG(4,("Setting print server access = %s\n", (r
->in
.access_mask
== SERVER_ACCESS_ADMINISTER
)
1627 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1629 /* We fall through to return WERR_OK */
1632 case SPLHND_PRINTER
:
1633 /* NT doesn't let us connect to a printer if the connecting user
1634 doesn't have print permission. */
1636 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
1637 close_printer_handle(p
, handle
);
1641 se_map_standard(&r
->in
.access_mask
, &printer_std_mapping
);
1643 /* map an empty access mask to the minimum access mask */
1644 if (r
->in
.access_mask
== 0x0)
1645 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1648 * If we are not serving the printer driver for this printer,
1649 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1650 * will keep NT clients happy --jerry
1653 if (lp_use_client_driver(snum
)
1654 && (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
))
1656 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1659 /* check smb.conf parameters and the the sec_desc */
1661 if ( !check_access(get_client_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1662 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1663 return WERR_ACCESS_DENIED
;
1666 if (!user_ok_token(uidtoname(p
->server_info
->utok
.uid
), NULL
,
1667 p
->server_info
->ptok
, snum
) ||
1668 !print_access_check(p
->server_info
, snum
,
1669 r
->in
.access_mask
)) {
1670 DEBUG(3, ("access DENIED for printer open\n"));
1671 close_printer_handle(p
, handle
);
1672 return WERR_ACCESS_DENIED
;
1675 if ((r
->in
.access_mask
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1676 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1677 close_printer_handle(p
, handle
);
1678 return WERR_ACCESS_DENIED
;
1681 if (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
)
1682 r
->in
.access_mask
= PRINTER_ACCESS_ADMINISTER
;
1684 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1686 DEBUG(4,("Setting printer access = %s\n", (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1687 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1692 /* sanity check to prevent programmer error */
1696 Printer
->access_granted
= r
->in
.access_mask
;
1699 * If the client sent a devmode in the OpenPrinter() call, then
1700 * save it here in case we get a job submission on this handle
1703 if ( (Printer
->printer_type
!= SPLHND_SERVER
)
1704 && r
->in
.devmode_ctr
.devmode
)
1706 convert_devicemode_new(Printer
->sharename
,
1707 r
->in
.devmode_ctr
.devmode
,
1708 &Printer
->nt_devmode
);
1711 #if 0 /* JERRY -- I'm doubtful this is really effective */
1712 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1713 optimization in Windows 2000 clients --jerry */
1715 if ( (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1716 && (RA_WIN2K
== get_remote_arch()) )
1718 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1719 sys_usleep( 500000 );
1726 /****************************************************************************
1727 ****************************************************************************/
1729 static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
1730 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
1736 /* allocate memory if needed. Messy because
1737 convert_printer_info is used to update an existing
1738 printer or build a new one */
1740 if ( !printer
->info_2
) {
1741 printer
->info_2
= TALLOC_ZERO_P( printer
, NT_PRINTER_INFO_LEVEL_2
);
1742 if ( !printer
->info_2
) {
1743 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
1748 ret
= uni_2_asc_printer_info_2(uni
->info_2
, printer
->info_2
);
1749 printer
->info_2
->setuptime
= time(NULL
);
1757 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
1758 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
1764 printer
->info_3
=NULL
;
1765 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
1769 printer
->info_6
=NULL
;
1770 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
1780 bool convert_devicemode(const char *printername
, const DEVICEMODE
*devmode
,
1781 NT_DEVICEMODE
**pp_nt_devmode
)
1783 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1786 * Ensure nt_devmode is a valid pointer
1787 * as we will be overwriting it.
1790 if (nt_devmode
== NULL
) {
1791 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1792 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1796 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
1797 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
1799 nt_devmode
->specversion
=devmode
->specversion
;
1800 nt_devmode
->driverversion
=devmode
->driverversion
;
1801 nt_devmode
->size
=devmode
->size
;
1802 nt_devmode
->fields
=devmode
->fields
;
1803 nt_devmode
->orientation
=devmode
->orientation
;
1804 nt_devmode
->papersize
=devmode
->papersize
;
1805 nt_devmode
->paperlength
=devmode
->paperlength
;
1806 nt_devmode
->paperwidth
=devmode
->paperwidth
;
1807 nt_devmode
->scale
=devmode
->scale
;
1808 nt_devmode
->copies
=devmode
->copies
;
1809 nt_devmode
->defaultsource
=devmode
->defaultsource
;
1810 nt_devmode
->printquality
=devmode
->printquality
;
1811 nt_devmode
->color
=devmode
->color
;
1812 nt_devmode
->duplex
=devmode
->duplex
;
1813 nt_devmode
->yresolution
=devmode
->yresolution
;
1814 nt_devmode
->ttoption
=devmode
->ttoption
;
1815 nt_devmode
->collate
=devmode
->collate
;
1817 nt_devmode
->logpixels
=devmode
->logpixels
;
1818 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
1819 nt_devmode
->pelswidth
=devmode
->pelswidth
;
1820 nt_devmode
->pelsheight
=devmode
->pelsheight
;
1821 nt_devmode
->displayflags
=devmode
->displayflags
;
1822 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
1823 nt_devmode
->icmmethod
=devmode
->icmmethod
;
1824 nt_devmode
->icmintent
=devmode
->icmintent
;
1825 nt_devmode
->mediatype
=devmode
->mediatype
;
1826 nt_devmode
->dithertype
=devmode
->dithertype
;
1827 nt_devmode
->reserved1
=devmode
->reserved1
;
1828 nt_devmode
->reserved2
=devmode
->reserved2
;
1829 nt_devmode
->panningwidth
=devmode
->panningwidth
;
1830 nt_devmode
->panningheight
=devmode
->panningheight
;
1833 * Only change private and driverextra if the incoming devmode
1834 * has a new one. JRA.
1837 if ((devmode
->driverextra
!= 0) && (devmode
->dev_private
!= NULL
)) {
1838 SAFE_FREE(nt_devmode
->nt_dev_private
);
1839 nt_devmode
->driverextra
=devmode
->driverextra
;
1840 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
1842 memcpy(nt_devmode
->nt_dev_private
, devmode
->dev_private
, nt_devmode
->driverextra
);
1845 *pp_nt_devmode
= nt_devmode
;
1850 /********************************************************************
1851 * _spoolss_enddocprinter_internal.
1852 ********************************************************************/
1854 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1856 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1860 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
1864 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
1867 Printer
->document_started
=False
;
1868 print_job_end(snum
, Printer
->jobid
,NORMAL_CLOSE
);
1869 /* error codes unhandled so far ... */
1874 /****************************************************************
1875 _spoolss_ClosePrinter
1876 ****************************************************************/
1878 WERROR
_spoolss_ClosePrinter(pipes_struct
*p
,
1879 struct spoolss_ClosePrinter
*r
)
1881 POLICY_HND
*handle
= r
->in
.handle
;
1883 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1885 if (Printer
&& Printer
->document_started
)
1886 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1888 if (!close_printer_handle(p
, handle
))
1891 /* clear the returned printer handle. Observed behavior
1892 from Win2k server. Don't think this really matters.
1893 Previous code just copied the value of the closed
1896 ZERO_STRUCTP(r
->out
.handle
);
1901 /****************************************************************
1902 _spoolss_DeletePrinter
1903 ****************************************************************/
1905 WERROR
_spoolss_DeletePrinter(pipes_struct
*p
,
1906 struct spoolss_DeletePrinter
*r
)
1908 POLICY_HND
*handle
= r
->in
.handle
;
1909 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1912 if (Printer
&& Printer
->document_started
)
1913 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1915 result
= delete_printer_handle(p
, handle
);
1917 update_c_setprinter(False
);
1922 /*******************************************************************
1923 * static function to lookup the version id corresponding to an
1924 * long architecture string
1925 ******************************************************************/
1927 static int get_version_id (char * arch
)
1930 struct table_node archi_table
[]= {
1932 {"Windows 4.0", "WIN40", 0 },
1933 {"Windows NT x86", "W32X86", 2 },
1934 {"Windows NT R4000", "W32MIPS", 2 },
1935 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1936 {"Windows NT PowerPC", "W32PPC", 2 },
1937 {"Windows IA64", "IA64", 3 },
1938 {"Windows x64", "x64", 3 },
1942 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1944 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1945 return (archi_table
[i
].version
);
1951 /****************************************************************
1952 _spoolss_DeletePrinterDriver
1953 ****************************************************************/
1955 WERROR
_spoolss_DeletePrinterDriver(pipes_struct
*p
,
1956 struct spoolss_DeletePrinterDriver
*r
)
1960 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1961 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
1964 WERROR status_win2k
= WERR_ACCESS_DENIED
;
1965 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1967 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1968 and not a printer admin, then fail */
1970 if ( (p
->server_info
->utok
.uid
!= 0)
1971 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
1972 && !token_contains_name_in_list(
1973 uidtoname(p
->server_info
->utok
.uid
), NULL
,
1974 NULL
, p
->server_info
->ptok
,
1975 lp_printer_admin(-1)) )
1977 return WERR_ACCESS_DENIED
;
1980 driver
= CONST_DISCARD(char *, r
->in
.driver
);
1981 arch
= CONST_DISCARD(char *, r
->in
.architecture
);
1983 /* check that we have a valid driver name first */
1985 if ((version
=get_version_id(arch
)) == -1)
1986 return WERR_INVALID_ENVIRONMENT
;
1989 ZERO_STRUCT(info_win2k
);
1991 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
)))
1993 /* try for Win2k driver if "Windows NT x86" */
1995 if ( version
== 2 ) {
1997 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
1998 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2002 /* otherwise it was a failure */
2004 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2010 if (printer_driver_in_use(info
.info_3
)) {
2011 status
= WERR_PRINTER_DRIVER_IN_USE
;
2017 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2019 /* if we get to here, we now have 2 driver info structures to remove */
2020 /* remove the Win2k driver first*/
2022 status_win2k
= delete_printer_driver(
2023 p
, info_win2k
.info_3
, 3, False
);
2024 free_a_printer_driver( info_win2k
, 3 );
2026 /* this should not have failed---if it did, report to client */
2027 if ( !W_ERROR_IS_OK(status_win2k
) )
2029 status
= status_win2k
;
2035 status
= delete_printer_driver(p
, info
.info_3
, version
, False
);
2037 /* if at least one of the deletes succeeded return OK */
2039 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2043 free_a_printer_driver( info
, 3 );
2048 /****************************************************************
2049 _spoolss_DeletePrinterDriverEx
2050 ****************************************************************/
2052 WERROR
_spoolss_DeletePrinterDriverEx(pipes_struct
*p
,
2053 struct spoolss_DeletePrinterDriverEx
*r
)
2057 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2058 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2060 uint32_t flags
= r
->in
.delete_flags
;
2063 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2064 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2066 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2067 and not a printer admin, then fail */
2069 if ( (p
->server_info
->utok
.uid
!= 0)
2070 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
2071 && !token_contains_name_in_list(
2072 uidtoname(p
->server_info
->utok
.uid
), NULL
, NULL
,
2073 p
->server_info
->ptok
, lp_printer_admin(-1)) )
2075 return WERR_ACCESS_DENIED
;
2078 driver
= CONST_DISCARD(char *, r
->in
.driver
);
2079 arch
= CONST_DISCARD(char *, r
->in
.architecture
);
2081 /* check that we have a valid driver name first */
2082 if ((version
=get_version_id(arch
)) == -1) {
2083 /* this is what NT returns */
2084 return WERR_INVALID_ENVIRONMENT
;
2087 if ( flags
& DPD_DELETE_SPECIFIC_VERSION
)
2088 version
= r
->in
.version
;
2091 ZERO_STRUCT(info_win2k
);
2093 status
= get_a_printer_driver(&info
, 3, driver
, arch
, version
);
2095 if ( !W_ERROR_IS_OK(status
) )
2098 * if the client asked for a specific version,
2099 * or this is something other than Windows NT x86,
2103 if ( (flags
&DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
2106 /* try for Win2k driver if "Windows NT x86" */
2109 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2110 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2115 if ( printer_driver_in_use(info
.info_3
) ) {
2116 status
= WERR_PRINTER_DRIVER_IN_USE
;
2121 * we have a couple of cases to consider.
2122 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2123 * then the delete should fail if **any** files overlap with
2125 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2126 * non-overlapping files
2127 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2128 * is set, the do not delete any files
2129 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2132 delete_files
= flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2134 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2136 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2137 /* no idea of the correct error here */
2138 status
= WERR_ACCESS_DENIED
;
2143 /* also check for W32X86/3 if necessary; maybe we already have? */
2145 if ( (version
== 2) && ((flags
&DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2146 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2149 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2150 /* no idea of the correct error here */
2151 free_a_printer_driver( info_win2k
, 3 );
2152 status
= WERR_ACCESS_DENIED
;
2156 /* if we get to here, we now have 2 driver info structures to remove */
2157 /* remove the Win2k driver first*/
2159 status_win2k
= delete_printer_driver(
2160 p
, info_win2k
.info_3
, 3, delete_files
);
2161 free_a_printer_driver( info_win2k
, 3 );
2163 /* this should not have failed---if it did, report to client */
2165 if ( !W_ERROR_IS_OK(status_win2k
) )
2170 status
= delete_printer_driver(p
, info
.info_3
, version
, delete_files
);
2172 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2175 free_a_printer_driver( info
, 3 );
2181 /****************************************************************************
2182 Internal routine for retreiving printerdata
2183 ***************************************************************************/
2185 static WERROR
get_printer_dataex( TALLOC_CTX
*ctx
, NT_PRINTER_INFO_LEVEL
*printer
,
2186 const char *key
, const char *value
, uint32
*type
, uint8
**data
,
2187 uint32
*needed
, uint32 in_size
)
2189 REGISTRY_VALUE
*val
;
2193 if ( !(val
= get_printer_data( printer
->info_2
, key
, value
)) )
2194 return WERR_BADFILE
;
2196 *type
= regval_type( val
);
2198 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size
));
2200 size
= regval_size( val
);
2202 /* copy the min(in_size, len) */
2205 data_len
= (size
> in_size
) ? in_size
: size
*sizeof(uint8
);
2207 /* special case for 0 length values */
2209 if ( (*data
= (uint8
*)TALLOC_MEMDUP(ctx
, regval_data_p(val
), data_len
)) == NULL
)
2213 if ( (*data
= (uint8
*)TALLOC_ZERO(ctx
, in_size
)) == NULL
)
2222 DEBUG(5,("get_printer_dataex: copy done\n"));
2227 /****************************************************************************
2228 Internal routine for removing printerdata
2229 ***************************************************************************/
2231 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
)
2233 return delete_printer_data( printer
->info_2
, key
, value
);
2236 /****************************************************************************
2237 Internal routine for storing printerdata
2238 ***************************************************************************/
2240 WERROR
set_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
,
2241 uint32 type
, uint8
*data
, int real_len
)
2243 /* the registry objects enforce uniqueness based on value name */
2245 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2248 /********************************************************************
2249 GetPrinterData on a printer server Handle.
2250 ********************************************************************/
2252 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
2256 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2258 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2260 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2262 SIVAL(*data
, 0, 0x00);
2267 if (!StrCaseCmp(value
, "BeepEnabled")) {
2269 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2271 SIVAL(*data
, 0, 0x00);
2276 if (!StrCaseCmp(value
, "EventLog")) {
2278 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2280 /* formally was 0x1b */
2281 SIVAL(*data
, 0, 0x0);
2286 if (!StrCaseCmp(value
, "NetPopup")) {
2288 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2290 SIVAL(*data
, 0, 0x00);
2295 if (!StrCaseCmp(value
, "MajorVersion")) {
2297 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2300 /* Windows NT 4.0 seems to not allow uploading of drivers
2301 to a server that reports 0x3 as the MajorVersion.
2302 need to investigate more how Win2k gets around this .
2305 if ( RA_WINNT
== get_remote_arch() )
2314 if (!StrCaseCmp(value
, "MinorVersion")) {
2316 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2324 * uint32 size = 0x114
2326 * uint32 minor = [0|1]
2327 * uint32 build = [2195|2600]
2328 * extra unicode string = e.g. "Service Pack 3"
2330 if (!StrCaseCmp(value
, "OSVersion")) {
2334 if ( !(*data
= TALLOC_ZERO_ARRAY(ctx
, uint8
, (*needed
> in_size
) ? *needed
:in_size
)) )
2337 SIVAL(*data
, 0, *needed
); /* size */
2338 SIVAL(*data
, 4, 5); /* Windows 2000 == 5.0 */
2340 SIVAL(*data
, 12, 2195); /* build */
2342 /* leave extra string empty */
2348 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2349 const char *string
="C:\\PRINTERS";
2351 *needed
= 2*(strlen(string
)+1);
2352 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2354 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2356 /* it's done by hand ready to go on the wire */
2357 for (i
=0; i
<strlen(string
); i
++) {
2358 (*data
)[2*i
]=string
[i
];
2359 (*data
)[2*i
+1]='\0';
2364 if (!StrCaseCmp(value
, "Architecture")) {
2365 const char *string
="Windows NT x86";
2367 *needed
= 2*(strlen(string
)+1);
2368 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2370 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2371 for (i
=0; i
<strlen(string
); i
++) {
2372 (*data
)[2*i
]=string
[i
];
2373 (*data
)[2*i
+1]='\0';
2378 if (!StrCaseCmp(value
, "DsPresent")) {
2380 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2383 /* only show the publish check box if we are a
2384 memeber of a AD domain */
2386 if ( lp_security() == SEC_ADS
)
2387 SIVAL(*data
, 0, 0x01);
2389 SIVAL(*data
, 0, 0x00);
2395 if (!StrCaseCmp(value
, "DNSMachineName")) {
2396 const char *hostname
= get_mydnsfullname();
2399 return WERR_BADFILE
;
2401 *needed
= 2*(strlen(hostname
)+1);
2402 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2404 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2405 for (i
=0; i
<strlen(hostname
); i
++) {
2406 (*data
)[2*i
]=hostname
[i
];
2407 (*data
)[2*i
+1]='\0';
2413 return WERR_BADFILE
;
2416 /********************************************************************
2417 * spoolss_getprinterdata
2418 ********************************************************************/
2420 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
2422 POLICY_HND
*handle
= &q_u
->handle
;
2423 UNISTR2
*valuename
= &q_u
->valuename
;
2424 uint32 in_size
= q_u
->size
;
2425 uint32
*type
= &r_u
->type
;
2426 uint32
*out_size
= &r_u
->size
;
2427 uint8
**data
= &r_u
->data
;
2428 uint32
*needed
= &r_u
->needed
;
2431 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
2432 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2436 * Reminder: when it's a string, the length is in BYTES
2437 * even if UNICODE is negociated.
2442 *out_size
= in_size
;
2444 /* in case of problem, return some default values */
2449 DEBUG(4,("_spoolss_getprinterdata\n"));
2452 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2453 status
= WERR_BADFID
;
2457 unistr2_to_ascii(value
, valuename
, sizeof(value
));
2459 if ( Printer
->printer_type
== SPLHND_SERVER
)
2460 status
= getprinterdata_printer_server( p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
2463 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) ) {
2464 status
= WERR_BADFID
;
2468 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
2469 if ( !W_ERROR_IS_OK(status
) )
2472 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2474 if ( strequal(value
, "ChangeId") ) {
2476 *needed
= sizeof(uint32
);
2477 if ( (*data
= (uint8
*)TALLOC(p
->mem_ctx
, sizeof(uint32
))) == NULL
) {
2478 status
= WERR_NOMEM
;
2481 SIVAL( *data
, 0, printer
->info_2
->changeid
);
2485 status
= get_printer_dataex( p
->mem_ctx
, printer
, SPOOL_PRINTERDATA_KEY
, value
, type
, data
, needed
, *out_size
);
2488 if (*needed
> *out_size
)
2489 status
= WERR_MORE_DATA
;
2492 if ( !W_ERROR_IS_OK(status
) )
2494 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status
),*out_size
));
2496 /* reply this param doesn't exist */
2499 if((*data
=(uint8
*)TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint8
, *out_size
)) == NULL
) {
2501 free_a_printer( &printer
, 2 );
2509 /* cleanup & exit */
2512 free_a_printer( &printer
, 2 );
2517 /*********************************************************
2518 Connect to the client machine.
2519 **********************************************************/
2521 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2522 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2525 struct cli_state
*the_cli
;
2526 struct sockaddr_storage rm_addr
;
2528 if ( is_zero_addr((struct sockaddr
*)client_ss
) ) {
2529 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20) ) {
2530 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2534 if (ismyaddr((struct sockaddr
*)&rm_addr
)) {
2535 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2539 char addr
[INET6_ADDRSTRLEN
];
2540 rm_addr
= *client_ss
;
2541 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2542 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2546 /* setup the connection */
2548 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2549 &rm_addr
, 0, "IPC$", "IPC",
2553 0, lp_client_signing(), NULL
);
2555 if ( !NT_STATUS_IS_OK( ret
) ) {
2556 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2561 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2562 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2563 cli_shutdown(the_cli
);
2568 * Ok - we have an anonymous connection to the IPC$ share.
2569 * Now start the NT Domain stuff :-).
2572 ret
= cli_rpc_pipe_open_noauth(the_cli
, &syntax_spoolss
, pp_pipe
);
2573 if (!NT_STATUS_IS_OK(ret
)) {
2574 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2575 remote_machine
, nt_errstr(ret
)));
2576 cli_shutdown(the_cli
);
2583 /***************************************************************************
2584 Connect to the client.
2585 ****************************************************************************/
2587 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2588 uint32 localprinter
, uint32 type
,
2589 POLICY_HND
*handle
, struct sockaddr_storage
*client_ss
)
2595 * If it's the first connection, contact the client
2596 * and connect to the IPC$ share anonymously
2598 if (smb_connections
==0) {
2599 fstring unix_printer
;
2601 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2603 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2606 messaging_register(smbd_messaging_context(), NULL
,
2607 MSG_PRINTER_NOTIFY2
,
2608 receive_notify2_message_list
);
2609 /* Tell the connections db we're now interested in printer
2610 * notify messages. */
2611 register_message_flags( True
, FLAG_MSG_PRINT_NOTIFY
);
2615 * Tell the specific printing tdb we want messages for this printer
2616 * by registering our PID.
2619 if (!print_notify_register_pid(snum
))
2620 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2624 status
= rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe
, talloc_tos(),
2632 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
2633 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2634 win_errstr(result
)));
2636 return (W_ERROR_IS_OK(result
));
2639 /********************************************************************
2641 * ReplyFindFirstPrinterChangeNotifyEx
2643 * before replying OK: status=0 a rpc call is made to the workstation
2644 * asking ReplyOpenPrinter
2646 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2647 * called from api_spoolss_rffpcnex
2648 ********************************************************************/
2650 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
2652 POLICY_HND
*handle
= &q_u
->handle
;
2653 uint32 flags
= q_u
->flags
;
2654 uint32 options
= q_u
->options
;
2655 UNISTR2
*localmachine
= &q_u
->localmachine
;
2656 uint32 printerlocal
= q_u
->printerlocal
;
2658 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
2659 struct sockaddr_storage client_ss
;
2661 /* store the notify value in the printer struct */
2663 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2666 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2670 Printer
->notify
.flags
=flags
;
2671 Printer
->notify
.options
=options
;
2672 Printer
->notify
.printerlocal
=printerlocal
;
2674 if (Printer
->notify
.option
)
2675 free_spool_notify_option(&Printer
->notify
.option
);
2677 Printer
->notify
.option
=dup_spool_notify_option(option
);
2679 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
,
2680 sizeof(Printer
->notify
.localmachine
));
2682 /* Connect to the client machine and send a ReplyOpenPrinter */
2684 if ( Printer
->printer_type
== SPLHND_SERVER
)
2686 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2687 !get_printer_snum(p
, handle
, &snum
, NULL
) )
2690 if (!interpret_string_addr(&client_ss
, p
->client_address
,
2692 return WERR_SERVER_UNAVAILABLE
;
2695 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2696 Printer
->notify
.printerlocal
, 1,
2697 &Printer
->notify
.client_hnd
, &client_ss
))
2698 return WERR_SERVER_UNAVAILABLE
;
2700 Printer
->notify
.client_connected
=True
;
2705 /*******************************************************************
2706 * fill a notify_info_data with the servername
2707 ********************************************************************/
2709 void spoolss_notify_server_name(int snum
,
2710 SPOOL_NOTIFY_INFO_DATA
*data
,
2711 print_queue_struct
*queue
,
2712 NT_PRINTER_INFO_LEVEL
*printer
,
2713 TALLOC_CTX
*mem_ctx
)
2715 smb_ucs2_t
*temp
= NULL
;
2718 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->servername
);
2719 if (len
== (uint32
)-1) {
2723 data
->notify_data
.data
.length
= len
;
2725 data
->notify_data
.data
.string
= (uint16
*)temp
;
2727 data
->notify_data
.data
.string
= NULL
;
2731 /*******************************************************************
2732 * fill a notify_info_data with the printername (not including the servername).
2733 ********************************************************************/
2735 void spoolss_notify_printer_name(int snum
,
2736 SPOOL_NOTIFY_INFO_DATA
*data
,
2737 print_queue_struct
*queue
,
2738 NT_PRINTER_INFO_LEVEL
*printer
,
2739 TALLOC_CTX
*mem_ctx
)
2741 smb_ucs2_t
*temp
= NULL
;
2744 /* the notify name should not contain the \\server\ part */
2745 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2748 p
= printer
->info_2
->printername
;
2753 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
2754 if (len
== (uint32
)-1) {
2758 data
->notify_data
.data
.length
= len
;
2760 data
->notify_data
.data
.string
= (uint16
*)temp
;
2762 data
->notify_data
.data
.string
= NULL
;
2766 /*******************************************************************
2767 * fill a notify_info_data with the servicename
2768 ********************************************************************/
2770 void spoolss_notify_share_name(int snum
,
2771 SPOOL_NOTIFY_INFO_DATA
*data
,
2772 print_queue_struct
*queue
,
2773 NT_PRINTER_INFO_LEVEL
*printer
,
2774 TALLOC_CTX
*mem_ctx
)
2776 smb_ucs2_t
*temp
= NULL
;
2779 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_servicename(snum
));
2780 if (len
== (uint32
)-1) {
2784 data
->notify_data
.data
.length
= len
;
2786 data
->notify_data
.data
.string
= (uint16
*)temp
;
2788 data
->notify_data
.data
.string
= NULL
;
2793 /*******************************************************************
2794 * fill a notify_info_data with the port name
2795 ********************************************************************/
2797 void spoolss_notify_port_name(int snum
,
2798 SPOOL_NOTIFY_INFO_DATA
*data
,
2799 print_queue_struct
*queue
,
2800 NT_PRINTER_INFO_LEVEL
*printer
,
2801 TALLOC_CTX
*mem_ctx
)
2803 smb_ucs2_t
*temp
= NULL
;
2806 /* even if it's strange, that's consistant in all the code */
2808 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->portname
);
2809 if (len
== (uint32
)-1) {
2813 data
->notify_data
.data
.length
= len
;
2815 data
->notify_data
.data
.string
= (uint16
*)temp
;
2817 data
->notify_data
.data
.string
= NULL
;
2821 /*******************************************************************
2822 * fill a notify_info_data with the printername
2823 * but it doesn't exist, have to see what to do
2824 ********************************************************************/
2826 void spoolss_notify_driver_name(int snum
,
2827 SPOOL_NOTIFY_INFO_DATA
*data
,
2828 print_queue_struct
*queue
,
2829 NT_PRINTER_INFO_LEVEL
*printer
,
2830 TALLOC_CTX
*mem_ctx
)
2832 smb_ucs2_t
*temp
= NULL
;
2835 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->drivername
);
2836 if (len
== (uint32
)-1) {
2840 data
->notify_data
.data
.length
= len
;
2842 data
->notify_data
.data
.string
= (uint16
*)temp
;
2844 data
->notify_data
.data
.string
= NULL
;
2848 /*******************************************************************
2849 * fill a notify_info_data with the comment
2850 ********************************************************************/
2852 void spoolss_notify_comment(int snum
,
2853 SPOOL_NOTIFY_INFO_DATA
*data
,
2854 print_queue_struct
*queue
,
2855 NT_PRINTER_INFO_LEVEL
*printer
,
2856 TALLOC_CTX
*mem_ctx
)
2858 smb_ucs2_t
*temp
= NULL
;
2861 if (*printer
->info_2
->comment
== '\0')
2862 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_comment(snum
));
2864 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->comment
);
2866 if (len
== (uint32
)-1) {
2869 data
->notify_data
.data
.length
= len
;
2871 data
->notify_data
.data
.string
= (uint16
*)temp
;
2873 data
->notify_data
.data
.string
= NULL
;
2877 /*******************************************************************
2878 * fill a notify_info_data with the comment
2879 * location = "Room 1, floor 2, building 3"
2880 ********************************************************************/
2882 void spoolss_notify_location(int snum
,
2883 SPOOL_NOTIFY_INFO_DATA
*data
,
2884 print_queue_struct
*queue
,
2885 NT_PRINTER_INFO_LEVEL
*printer
,
2886 TALLOC_CTX
*mem_ctx
)
2888 smb_ucs2_t
*temp
= NULL
;
2891 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->location
);
2892 if (len
== (uint32
)-1) {
2896 data
->notify_data
.data
.length
= len
;
2898 data
->notify_data
.data
.string
= (uint16
*)temp
;
2900 data
->notify_data
.data
.string
= NULL
;
2904 /*******************************************************************
2905 * fill a notify_info_data with the device mode
2906 * jfm:xxxx don't to it for know but that's a real problem !!!
2907 ********************************************************************/
2909 static void spoolss_notify_devmode(int snum
,
2910 SPOOL_NOTIFY_INFO_DATA
*data
,
2911 print_queue_struct
*queue
,
2912 NT_PRINTER_INFO_LEVEL
*printer
,
2913 TALLOC_CTX
*mem_ctx
)
2915 /* for a dummy implementation we have to zero the fields */
2916 data
->notify_data
.data
.length
= 0;
2917 data
->notify_data
.data
.string
= NULL
;
2920 /*******************************************************************
2921 * fill a notify_info_data with the separator file name
2922 ********************************************************************/
2924 void spoolss_notify_sepfile(int snum
,
2925 SPOOL_NOTIFY_INFO_DATA
*data
,
2926 print_queue_struct
*queue
,
2927 NT_PRINTER_INFO_LEVEL
*printer
,
2928 TALLOC_CTX
*mem_ctx
)
2930 smb_ucs2_t
*temp
= NULL
;
2933 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->sepfile
);
2934 if (len
== (uint32
)-1) {
2938 data
->notify_data
.data
.length
= len
;
2940 data
->notify_data
.data
.string
= (uint16
*)temp
;
2942 data
->notify_data
.data
.string
= NULL
;
2946 /*******************************************************************
2947 * fill a notify_info_data with the print processor
2948 * jfm:xxxx return always winprint to indicate we don't do anything to it
2949 ********************************************************************/
2951 void spoolss_notify_print_processor(int snum
,
2952 SPOOL_NOTIFY_INFO_DATA
*data
,
2953 print_queue_struct
*queue
,
2954 NT_PRINTER_INFO_LEVEL
*printer
,
2955 TALLOC_CTX
*mem_ctx
)
2957 smb_ucs2_t
*temp
= NULL
;
2960 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->printprocessor
);
2961 if (len
== (uint32
)-1) {
2965 data
->notify_data
.data
.length
= len
;
2967 data
->notify_data
.data
.string
= (uint16
*)temp
;
2969 data
->notify_data
.data
.string
= NULL
;
2973 /*******************************************************************
2974 * fill a notify_info_data with the print processor options
2975 * jfm:xxxx send an empty string
2976 ********************************************************************/
2978 void spoolss_notify_parameters(int snum
,
2979 SPOOL_NOTIFY_INFO_DATA
*data
,
2980 print_queue_struct
*queue
,
2981 NT_PRINTER_INFO_LEVEL
*printer
,
2982 TALLOC_CTX
*mem_ctx
)
2984 smb_ucs2_t
*temp
= NULL
;
2987 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->parameters
);
2988 if (len
== (uint32
)-1) {
2992 data
->notify_data
.data
.length
= len
;
2994 data
->notify_data
.data
.string
= (uint16
*)temp
;
2996 data
->notify_data
.data
.string
= NULL
;
3000 /*******************************************************************
3001 * fill a notify_info_data with the data type
3002 * jfm:xxxx always send RAW as data type
3003 ********************************************************************/
3005 void spoolss_notify_datatype(int snum
,
3006 SPOOL_NOTIFY_INFO_DATA
*data
,
3007 print_queue_struct
*queue
,
3008 NT_PRINTER_INFO_LEVEL
*printer
,
3009 TALLOC_CTX
*mem_ctx
)
3011 smb_ucs2_t
*temp
= NULL
;
3014 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->datatype
);
3015 if (len
== (uint32
)-1) {
3019 data
->notify_data
.data
.length
= len
;
3021 data
->notify_data
.data
.string
= (uint16
*)temp
;
3023 data
->notify_data
.data
.string
= NULL
;
3027 /*******************************************************************
3028 * fill a notify_info_data with the security descriptor
3029 * jfm:xxxx send an null pointer to say no security desc
3030 * have to implement security before !
3031 ********************************************************************/
3033 static void spoolss_notify_security_desc(int snum
,
3034 SPOOL_NOTIFY_INFO_DATA
*data
,
3035 print_queue_struct
*queue
,
3036 NT_PRINTER_INFO_LEVEL
*printer
,
3037 TALLOC_CTX
*mem_ctx
)
3039 data
->notify_data
.sd
.size
= printer
->info_2
->secdesc_buf
->sd_size
;
3040 data
->notify_data
.sd
.desc
= dup_sec_desc( mem_ctx
, printer
->info_2
->secdesc_buf
->sd
) ;
3043 /*******************************************************************
3044 * fill a notify_info_data with the attributes
3045 * jfm:xxxx a samba printer is always shared
3046 ********************************************************************/
3048 void spoolss_notify_attributes(int snum
,
3049 SPOOL_NOTIFY_INFO_DATA
*data
,
3050 print_queue_struct
*queue
,
3051 NT_PRINTER_INFO_LEVEL
*printer
,
3052 TALLOC_CTX
*mem_ctx
)
3054 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
3055 data
->notify_data
.value
[1] = 0;
3058 /*******************************************************************
3059 * fill a notify_info_data with the priority
3060 ********************************************************************/
3062 static void spoolss_notify_priority(int snum
,
3063 SPOOL_NOTIFY_INFO_DATA
*data
,
3064 print_queue_struct
*queue
,
3065 NT_PRINTER_INFO_LEVEL
*printer
,
3066 TALLOC_CTX
*mem_ctx
)
3068 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
3069 data
->notify_data
.value
[1] = 0;
3072 /*******************************************************************
3073 * fill a notify_info_data with the default priority
3074 ********************************************************************/
3076 static void spoolss_notify_default_priority(int snum
,
3077 SPOOL_NOTIFY_INFO_DATA
*data
,
3078 print_queue_struct
*queue
,
3079 NT_PRINTER_INFO_LEVEL
*printer
,
3080 TALLOC_CTX
*mem_ctx
)
3082 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
3083 data
->notify_data
.value
[1] = 0;
3086 /*******************************************************************
3087 * fill a notify_info_data with the start time
3088 ********************************************************************/
3090 static void spoolss_notify_start_time(int snum
,
3091 SPOOL_NOTIFY_INFO_DATA
*data
,
3092 print_queue_struct
*queue
,
3093 NT_PRINTER_INFO_LEVEL
*printer
,
3094 TALLOC_CTX
*mem_ctx
)
3096 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
3097 data
->notify_data
.value
[1] = 0;
3100 /*******************************************************************
3101 * fill a notify_info_data with the until time
3102 ********************************************************************/
3104 static void spoolss_notify_until_time(int snum
,
3105 SPOOL_NOTIFY_INFO_DATA
*data
,
3106 print_queue_struct
*queue
,
3107 NT_PRINTER_INFO_LEVEL
*printer
,
3108 TALLOC_CTX
*mem_ctx
)
3110 data
->notify_data
.value
[0] = printer
->info_2
->untiltime
;
3111 data
->notify_data
.value
[1] = 0;
3114 /*******************************************************************
3115 * fill a notify_info_data with the status
3116 ********************************************************************/
3118 static void spoolss_notify_status(int snum
,
3119 SPOOL_NOTIFY_INFO_DATA
*data
,
3120 print_queue_struct
*queue
,
3121 NT_PRINTER_INFO_LEVEL
*printer
,
3122 TALLOC_CTX
*mem_ctx
)
3124 print_status_struct status
;
3126 print_queue_length(snum
, &status
);
3127 data
->notify_data
.value
[0]=(uint32
) status
.status
;
3128 data
->notify_data
.value
[1] = 0;
3131 /*******************************************************************
3132 * fill a notify_info_data with the number of jobs queued
3133 ********************************************************************/
3135 void spoolss_notify_cjobs(int snum
,
3136 SPOOL_NOTIFY_INFO_DATA
*data
,
3137 print_queue_struct
*queue
,
3138 NT_PRINTER_INFO_LEVEL
*printer
,
3139 TALLOC_CTX
*mem_ctx
)
3141 data
->notify_data
.value
[0] = print_queue_length(snum
, NULL
);
3142 data
->notify_data
.value
[1] = 0;
3145 /*******************************************************************
3146 * fill a notify_info_data with the average ppm
3147 ********************************************************************/
3149 static void spoolss_notify_average_ppm(int snum
,
3150 SPOOL_NOTIFY_INFO_DATA
*data
,
3151 print_queue_struct
*queue
,
3152 NT_PRINTER_INFO_LEVEL
*printer
,
3153 TALLOC_CTX
*mem_ctx
)
3155 /* always respond 8 pages per minutes */
3156 /* a little hard ! */
3157 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
3158 data
->notify_data
.value
[1] = 0;
3161 /*******************************************************************
3162 * fill a notify_info_data with username
3163 ********************************************************************/
3165 static void spoolss_notify_username(int snum
,
3166 SPOOL_NOTIFY_INFO_DATA
*data
,
3167 print_queue_struct
*queue
,
3168 NT_PRINTER_INFO_LEVEL
*printer
,
3169 TALLOC_CTX
*mem_ctx
)
3171 smb_ucs2_t
*temp
= NULL
;
3174 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_user
);
3175 if (len
== (uint32
)-1) {
3179 data
->notify_data
.data
.length
= len
;
3181 data
->notify_data
.data
.string
= (uint16
*)temp
;
3183 data
->notify_data
.data
.string
= NULL
;
3187 /*******************************************************************
3188 * fill a notify_info_data with job status
3189 ********************************************************************/
3191 static void spoolss_notify_job_status(int snum
,
3192 SPOOL_NOTIFY_INFO_DATA
*data
,
3193 print_queue_struct
*queue
,
3194 NT_PRINTER_INFO_LEVEL
*printer
,
3195 TALLOC_CTX
*mem_ctx
)
3197 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
3198 data
->notify_data
.value
[1] = 0;
3201 /*******************************************************************
3202 * fill a notify_info_data with job name
3203 ********************************************************************/
3205 static void spoolss_notify_job_name(int snum
,
3206 SPOOL_NOTIFY_INFO_DATA
*data
,
3207 print_queue_struct
*queue
,
3208 NT_PRINTER_INFO_LEVEL
*printer
,
3209 TALLOC_CTX
*mem_ctx
)
3211 smb_ucs2_t
*temp
= NULL
;
3214 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_file
);
3215 if (len
== (uint32
)-1) {
3219 data
->notify_data
.data
.length
= len
;
3221 data
->notify_data
.data
.string
= (uint16
*)temp
;
3223 data
->notify_data
.data
.string
= NULL
;
3227 /*******************************************************************
3228 * fill a notify_info_data with job status
3229 ********************************************************************/
3231 static void spoolss_notify_job_status_string(int snum
,
3232 SPOOL_NOTIFY_INFO_DATA
*data
,
3233 print_queue_struct
*queue
,
3234 NT_PRINTER_INFO_LEVEL
*printer
,
3235 TALLOC_CTX
*mem_ctx
)
3238 * Now we're returning job status codes we just return a "" here. JRA.
3242 smb_ucs2_t
*temp
= NULL
;
3245 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3248 switch (queue
->status
) {
3253 p
= ""; /* NT provides the paused string */
3262 #endif /* NO LONGER NEEDED. */
3264 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
3265 if (len
== (uint32
)-1) {
3269 data
->notify_data
.data
.length
= len
;
3271 data
->notify_data
.data
.string
= (uint16
*)temp
;
3273 data
->notify_data
.data
.string
= NULL
;
3277 /*******************************************************************
3278 * fill a notify_info_data with job time
3279 ********************************************************************/
3281 static void spoolss_notify_job_time(int snum
,
3282 SPOOL_NOTIFY_INFO_DATA
*data
,
3283 print_queue_struct
*queue
,
3284 NT_PRINTER_INFO_LEVEL
*printer
,
3285 TALLOC_CTX
*mem_ctx
)
3287 data
->notify_data
.value
[0]=0x0;
3288 data
->notify_data
.value
[1]=0;
3291 /*******************************************************************
3292 * fill a notify_info_data with job size
3293 ********************************************************************/
3295 static void spoolss_notify_job_size(int snum
,
3296 SPOOL_NOTIFY_INFO_DATA
*data
,
3297 print_queue_struct
*queue
,
3298 NT_PRINTER_INFO_LEVEL
*printer
,
3299 TALLOC_CTX
*mem_ctx
)
3301 data
->notify_data
.value
[0]=queue
->size
;
3302 data
->notify_data
.value
[1]=0;
3305 /*******************************************************************
3306 * fill a notify_info_data with page info
3307 ********************************************************************/
3308 static void spoolss_notify_total_pages(int snum
,
3309 SPOOL_NOTIFY_INFO_DATA
*data
,
3310 print_queue_struct
*queue
,
3311 NT_PRINTER_INFO_LEVEL
*printer
,
3312 TALLOC_CTX
*mem_ctx
)
3314 data
->notify_data
.value
[0]=queue
->page_count
;
3315 data
->notify_data
.value
[1]=0;
3318 /*******************************************************************
3319 * fill a notify_info_data with pages printed info.
3320 ********************************************************************/
3321 static void spoolss_notify_pages_printed(int snum
,
3322 SPOOL_NOTIFY_INFO_DATA
*data
,
3323 print_queue_struct
*queue
,
3324 NT_PRINTER_INFO_LEVEL
*printer
,
3325 TALLOC_CTX
*mem_ctx
)
3327 data
->notify_data
.value
[0]=0; /* Add code when back-end tracks this */
3328 data
->notify_data
.value
[1]=0;
3331 /*******************************************************************
3332 Fill a notify_info_data with job position.
3333 ********************************************************************/
3335 static void spoolss_notify_job_position(int snum
,
3336 SPOOL_NOTIFY_INFO_DATA
*data
,
3337 print_queue_struct
*queue
,
3338 NT_PRINTER_INFO_LEVEL
*printer
,
3339 TALLOC_CTX
*mem_ctx
)
3341 data
->notify_data
.value
[0]=queue
->job
;
3342 data
->notify_data
.value
[1]=0;
3345 /*******************************************************************
3346 Fill a notify_info_data with submitted time.
3347 ********************************************************************/
3349 static void spoolss_notify_submitted_time(int snum
,
3350 SPOOL_NOTIFY_INFO_DATA
*data
,
3351 print_queue_struct
*queue
,
3352 NT_PRINTER_INFO_LEVEL
*printer
,
3353 TALLOC_CTX
*mem_ctx
)
3360 t
=gmtime(&queue
->time
);
3362 len
= sizeof(SYSTEMTIME
);
3364 data
->notify_data
.data
.length
= len
;
3365 data
->notify_data
.data
.string
= (uint16
*)TALLOC(mem_ctx
, len
);
3367 if (!data
->notify_data
.data
.string
) {
3368 data
->notify_data
.data
.length
= 0;
3372 make_systemtime(&st
, t
);
3375 * Systemtime must be linearized as a set of UINT16's.
3376 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3379 p
= (char *)data
->notify_data
.data
.string
;
3380 SSVAL(p
, 0, st
.year
);
3381 SSVAL(p
, 2, st
.month
);
3382 SSVAL(p
, 4, st
.dayofweek
);
3383 SSVAL(p
, 6, st
.day
);
3384 SSVAL(p
, 8, st
.hour
);
3385 SSVAL(p
, 10, st
.minute
);
3386 SSVAL(p
, 12, st
.second
);
3387 SSVAL(p
, 14, st
.milliseconds
);
3390 struct s_notify_info_data_table
3396 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
3397 print_queue_struct
*queue
,
3398 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
3401 /* A table describing the various print notification constants and
3402 whether the notification data is a pointer to a variable sized
3403 buffer, a one value uint32 or a two value uint32. */
3405 static const struct s_notify_info_data_table notify_info_data_table
[] =
3407 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3408 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3409 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING
, spoolss_notify_share_name
},
3410 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3411 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3412 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING
, spoolss_notify_comment
},
3413 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING
, spoolss_notify_location
},
3414 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3415 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING
, spoolss_notify_sepfile
},
3416 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3417 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3418 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3419 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC
, spoolss_notify_security_desc
},
3420 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE
, spoolss_notify_attributes
},
3421 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3422 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_default_priority
},
3423 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3424 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3425 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_status
},
3426 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER
, NULL
},
3427 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE
, spoolss_notify_cjobs
},
3428 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE
, spoolss_notify_average_ppm
},
3429 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER
, NULL
},
3430 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER
, NULL
},
3431 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER
, NULL
},
3432 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER
, NULL
},
3433 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3434 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3435 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3436 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3437 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3438 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3439 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3440 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3441 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3442 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3443 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_job_status
},
3444 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING
, spoolss_notify_job_status_string
},
3445 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER
, NULL
},
3446 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING
, spoolss_notify_job_name
},
3447 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3448 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE
, spoolss_notify_job_position
},
3449 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER
, spoolss_notify_submitted_time
},
3450 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3451 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3452 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_job_time
},
3453 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE
, spoolss_notify_total_pages
},
3454 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE
, spoolss_notify_pages_printed
},
3455 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE
, spoolss_notify_job_size
},
3456 { PRINT_TABLE_END
, 0x0, NULL
, 0x0, NULL
},
3459 /*******************************************************************
3460 Return the size of info_data structure.
3461 ********************************************************************/
3463 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
3467 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3468 if ( (notify_info_data_table
[i
].type
== type
)
3469 && (notify_info_data_table
[i
].field
== field
) ) {
3470 switch(notify_info_data_table
[i
].size
) {
3471 case NOTIFY_ONE_VALUE
:
3472 case NOTIFY_TWO_VALUE
:
3477 /* The only pointer notify data I have seen on
3478 the wire is the submitted time and this has
3479 the notify size set to 4. -tpot */
3481 case NOTIFY_POINTER
:
3484 case NOTIFY_SECDESC
:
3490 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3495 /*******************************************************************
3496 Return the type of notify_info_data.
3497 ********************************************************************/
3499 static uint32
type_of_notify_info_data(uint16 type
, uint16 field
)
3503 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3504 if (notify_info_data_table
[i
].type
== type
&&
3505 notify_info_data_table
[i
].field
== field
)
3506 return notify_info_data_table
[i
].size
;
3512 /****************************************************************************
3513 ****************************************************************************/
3515 static bool search_notify(uint16 type
, uint16 field
, int *value
)
3519 for (i
= 0; notify_info_data_table
[i
].type
!= PRINT_TABLE_END
; i
++) {
3520 if (notify_info_data_table
[i
].type
== type
&&
3521 notify_info_data_table
[i
].field
== field
&&
3522 notify_info_data_table
[i
].fn
!= NULL
) {
3531 /****************************************************************************
3532 ****************************************************************************/
3534 void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
3536 info_data
->type
= type
;
3537 info_data
->field
= field
;
3538 info_data
->reserved
= 0;
3540 info_data
->size
= size_of_notify_info_data(type
, field
);
3541 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
3546 /*******************************************************************
3548 * fill a notify_info struct with info asked
3550 ********************************************************************/
3552 static bool construct_notify_printer_info(Printer_entry
*print_hnd
, SPOOL_NOTIFY_INFO
*info
, int
3553 snum
, SPOOL_NOTIFY_OPTION_TYPE
3554 *option_type
, uint32 id
,
3555 TALLOC_CTX
*mem_ctx
)
3561 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3562 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3563 print_queue_struct
*queue
=NULL
;
3565 type
=option_type
->type
;
3567 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3568 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3569 option_type
->count
, lp_servicename(snum
)));
3571 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &printer
, 2, lp_const_servicename(snum
))))
3574 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3575 field
= option_type
->fields
[field_num
];
3577 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3579 if (!search_notify(type
, field
, &j
) )
3582 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3583 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3584 free_a_printer(&printer
, 2);
3588 current_data
= &info
->data
[info
->count
];
3590 construct_info_data(current_data
, type
, field
, id
);
3592 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3593 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3595 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3601 free_a_printer(&printer
, 2);
3605 /*******************************************************************
3607 * fill a notify_info struct with info asked
3609 ********************************************************************/
3611 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3612 SPOOL_NOTIFY_INFO
*info
,
3613 NT_PRINTER_INFO_LEVEL
*printer
,
3614 int snum
, SPOOL_NOTIFY_OPTION_TYPE
3615 *option_type
, uint32 id
,
3616 TALLOC_CTX
*mem_ctx
)
3622 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3624 DEBUG(4,("construct_notify_jobs_info\n"));
3626 type
= option_type
->type
;
3628 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3629 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3630 option_type
->count
));
3632 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3633 field
= option_type
->fields
[field_num
];
3635 if (!search_notify(type
, field
, &j
) )
3638 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3639 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3643 current_data
=&(info
->data
[info
->count
]);
3645 construct_info_data(current_data
, type
, field
, id
);
3646 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3655 * JFM: The enumeration is not that simple, it's even non obvious.
3657 * let's take an example: I want to monitor the PRINTER SERVER for
3658 * the printer's name and the number of jobs currently queued.
3659 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3660 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3662 * I have 3 printers on the back of my server.
3664 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3667 * 1 printer 1 name 1
3668 * 2 printer 1 cjob 1
3669 * 3 printer 2 name 2
3670 * 4 printer 2 cjob 2
3671 * 5 printer 3 name 3
3672 * 6 printer 3 name 3
3674 * that's the print server case, the printer case is even worse.
3677 /*******************************************************************
3679 * enumerate all printers on the printserver
3680 * fill a notify_info struct with info asked
3682 ********************************************************************/
3684 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
3685 SPOOL_NOTIFY_INFO
*info
,
3686 TALLOC_CTX
*mem_ctx
)
3689 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3690 int n_services
=lp_numservices();
3692 SPOOL_NOTIFY_OPTION
*option
;
3693 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3695 DEBUG(4,("printserver_notify_info\n"));
3700 option
=Printer
->notify
.option
;
3705 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3706 sending a ffpcn() request first */
3711 for (i
=0; i
<option
->count
; i
++) {
3712 option_type
=&(option
->ctr
.type
[i
]);
3714 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
3717 for (snum
=0; snum
<n_services
; snum
++)
3719 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3720 construct_notify_printer_info ( Printer
, info
, snum
, option_type
, snum
, mem_ctx
);
3726 * Debugging information, don't delete.
3729 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3730 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3731 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3733 for (i
=0; i
<info
->count
; i
++) {
3734 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3735 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3736 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3743 /*******************************************************************
3745 * fill a notify_info struct with info asked
3747 ********************************************************************/
3749 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
3750 TALLOC_CTX
*mem_ctx
)
3753 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3756 SPOOL_NOTIFY_OPTION
*option
;
3757 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3759 print_queue_struct
*queue
=NULL
;
3760 print_status_struct status
;
3762 DEBUG(4,("printer_notify_info\n"));
3767 option
=Printer
->notify
.option
;
3773 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3774 sending a ffpcn() request first */
3779 get_printer_snum(p
, hnd
, &snum
, NULL
);
3781 for (i
=0; i
<option
->count
; i
++) {
3782 option_type
=&option
->ctr
.type
[i
];
3784 switch ( option_type
->type
) {
3785 case PRINTER_NOTIFY_TYPE
:
3786 if(construct_notify_printer_info(Printer
, info
, snum
,
3792 case JOB_NOTIFY_TYPE
: {
3793 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3795 count
= print_queue_status(snum
, &queue
, &status
);
3797 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))))
3800 for (j
=0; j
<count
; j
++) {
3801 construct_notify_jobs_info(&queue
[j
], info
,
3808 free_a_printer(&printer
, 2);
3818 * Debugging information, don't delete.
3821 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3822 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3823 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3825 for (i=0; i<info->count; i++) {
3826 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3827 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3828 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3834 /********************************************************************
3836 ********************************************************************/
3838 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
3840 POLICY_HND
*handle
= &q_u
->handle
;
3841 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
3843 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
3844 WERROR result
= WERR_BADFID
;
3846 /* we always have a NOTIFY_INFO struct */
3850 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3851 OUR_HANDLE(handle
)));
3855 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3858 * We are now using the change value, and
3859 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3860 * I don't have a global notification system, I'm sending back all the
3861 * informations even when _NOTHING_ has changed.
3864 /* We need to keep track of the change value to send back in
3865 RRPCN replies otherwise our updates are ignored. */
3867 Printer
->notify
.fnpcn
= True
;
3869 if (Printer
->notify
.client_connected
) {
3870 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u
->change
));
3871 Printer
->notify
.change
= q_u
->change
;
3874 /* just ignore the SPOOL_NOTIFY_OPTION */
3876 switch (Printer
->printer_type
) {
3878 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
3881 case SPLHND_PRINTER
:
3882 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
3886 Printer
->notify
.fnpcn
= False
;
3892 /********************************************************************
3893 * construct_printer_info_0
3894 * fill a printer_info_0 struct
3895 ********************************************************************/
3897 static bool construct_printer_info_0(Printer_entry
*print_hnd
, PRINTER_INFO_0
*printer
, int snum
)
3899 char *chaine
= NULL
;
3901 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3902 counter_printer_0
*session_counter
;
3903 uint32 global_counter
;
3906 print_status_struct status
;
3907 TALLOC_CTX
*ctx
= talloc_tos();
3909 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
3912 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
3914 chaine
= talloc_asprintf(ctx
, "\\\\%s", get_server_name(print_hnd
));
3916 free_a_printer(&ntprinter
,2);
3920 count
= print_queue_length(snum
, &status
);
3922 /* check if we already have a counter for this printer */
3923 for(session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3924 if (session_counter
->snum
== snum
)
3928 init_unistr(&printer
->servername
, chaine
);
3930 /* it's the first time, add it to the list */
3931 if (session_counter
==NULL
) {
3932 if((session_counter
=SMB_MALLOC_P(counter_printer_0
)) == NULL
) {
3933 free_a_printer(&ntprinter
, 2);
3936 ZERO_STRUCTP(session_counter
);
3937 session_counter
->snum
=snum
;
3938 session_counter
->counter
=0;
3939 DLIST_ADD(counter_list
, session_counter
);
3943 session_counter
->counter
++;
3946 * the global_counter should be stored in a TDB as it's common to all the clients
3947 * and should be zeroed on samba startup
3949 global_counter
=session_counter
->counter
;
3950 printer
->cjobs
= count
;
3951 printer
->total_jobs
= 0;
3952 printer
->total_bytes
= 0;
3954 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
3955 t
=gmtime(&setuptime
);
3957 printer
->year
= t
->tm_year
+1900;
3958 printer
->month
= t
->tm_mon
+1;
3959 printer
->dayofweek
= t
->tm_wday
;
3960 printer
->day
= t
->tm_mday
;
3961 printer
->hour
= t
->tm_hour
;
3962 printer
->minute
= t
->tm_min
;
3963 printer
->second
= t
->tm_sec
;
3964 printer
->milliseconds
= 0;
3966 printer
->global_counter
= global_counter
;
3967 printer
->total_pages
= 0;
3969 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3970 printer
->major_version
= 0x0005; /* NT 5 */
3971 printer
->build_version
= 0x0893; /* build 2195 */
3973 printer
->unknown7
= 0x1;
3974 printer
->unknown8
= 0x0;
3975 printer
->unknown9
= 0x0;
3976 printer
->session_counter
= session_counter
->counter
;
3977 printer
->unknown11
= 0x0;
3978 printer
->printer_errors
= 0x0; /* number of print failure */
3979 printer
->unknown13
= 0x0;
3980 printer
->unknown14
= 0x1;
3981 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
3982 printer
->unknown16
= 0x0;
3983 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
3984 printer
->unknown18
= 0x0;
3985 printer
->status
= nt_printq_status(status
.status
);
3986 printer
->unknown20
= 0x0;
3987 printer
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3988 printer
->unknown22
= 0x0;
3989 printer
->unknown23
= 0x6; /* 6 ???*/
3990 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
3991 printer
->unknown25
= 0;
3992 printer
->unknown26
= 0;
3993 printer
->unknown27
= 0;
3994 printer
->unknown28
= 0;
3995 printer
->unknown29
= 0;
3997 free_a_printer(&ntprinter
,2);
4001 /********************************************************************
4002 * construct_printer_info_1
4003 * fill a printer_info_1 struct
4004 ********************************************************************/
4005 static bool construct_printer_info_1(Printer_entry
*print_hnd
, uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
4007 char *chaine
= NULL
;
4008 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4009 TALLOC_CTX
*ctx
= talloc_tos();
4011 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4014 printer
->flags
=flags
;
4016 if (*ntprinter
->info_2
->comment
== '\0') {
4017 init_unistr(&printer
->comment
, lp_comment(snum
));
4018 chaine
= talloc_asprintf(ctx
,
4019 "%s,%s,%s", ntprinter
->info_2
->printername
,
4020 ntprinter
->info_2
->drivername
, lp_comment(snum
));
4023 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4024 chaine
= talloc_asprintf(ctx
,
4025 "%s,%s,%s", ntprinter
->info_2
->printername
,
4026 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
4030 free_a_printer(&ntprinter
,2);
4034 init_unistr(&printer
->description
, chaine
);
4035 init_unistr(&printer
->name
, ntprinter
->info_2
->printername
);
4037 free_a_printer(&ntprinter
,2);
4042 /****************************************************************************
4043 Free a DEVMODE struct.
4044 ****************************************************************************/
4046 static void free_dev_mode(DEVICEMODE
*dev
)
4051 SAFE_FREE(dev
->dev_private
);
4056 /****************************************************************************
4057 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4058 should be valid upon entry
4059 ****************************************************************************/
4061 static bool convert_nt_devicemode( DEVICEMODE
*devmode
, NT_DEVICEMODE
*ntdevmode
)
4063 if ( !devmode
|| !ntdevmode
)
4066 init_unistr(&devmode
->devicename
, ntdevmode
->devicename
);
4068 init_unistr(&devmode
->formname
, ntdevmode
->formname
);
4070 devmode
->specversion
= ntdevmode
->specversion
;
4071 devmode
->driverversion
= ntdevmode
->driverversion
;
4072 devmode
->size
= ntdevmode
->size
;
4073 devmode
->driverextra
= ntdevmode
->driverextra
;
4074 devmode
->fields
= ntdevmode
->fields
;
4076 devmode
->orientation
= ntdevmode
->orientation
;
4077 devmode
->papersize
= ntdevmode
->papersize
;
4078 devmode
->paperlength
= ntdevmode
->paperlength
;
4079 devmode
->paperwidth
= ntdevmode
->paperwidth
;
4080 devmode
->scale
= ntdevmode
->scale
;
4081 devmode
->copies
= ntdevmode
->copies
;
4082 devmode
->defaultsource
= ntdevmode
->defaultsource
;
4083 devmode
->printquality
= ntdevmode
->printquality
;
4084 devmode
->color
= ntdevmode
->color
;
4085 devmode
->duplex
= ntdevmode
->duplex
;
4086 devmode
->yresolution
= ntdevmode
->yresolution
;
4087 devmode
->ttoption
= ntdevmode
->ttoption
;
4088 devmode
->collate
= ntdevmode
->collate
;
4089 devmode
->icmmethod
= ntdevmode
->icmmethod
;
4090 devmode
->icmintent
= ntdevmode
->icmintent
;
4091 devmode
->mediatype
= ntdevmode
->mediatype
;
4092 devmode
->dithertype
= ntdevmode
->dithertype
;
4094 if (ntdevmode
->nt_dev_private
!= NULL
) {
4095 if ((devmode
->dev_private
=(uint8
*)memdup(ntdevmode
->nt_dev_private
, ntdevmode
->driverextra
)) == NULL
)
4102 /****************************************************************************
4103 Create a DEVMODE struct. Returns malloced memory.
4104 ****************************************************************************/
4106 DEVICEMODE
*construct_dev_mode(const char *servicename
)
4108 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4109 DEVICEMODE
*devmode
= NULL
;
4111 DEBUG(7,("construct_dev_mode\n"));
4113 DEBUGADD(8,("getting printer characteristics\n"));
4115 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, servicename
)))
4118 if ( !printer
->info_2
->devmode
) {
4119 DEBUG(5, ("BONG! There was no device mode!\n"));
4123 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) == NULL
) {
4124 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4128 ZERO_STRUCTP(devmode
);
4130 DEBUGADD(8,("loading DEVICEMODE\n"));
4132 if ( !convert_nt_devicemode( devmode
, printer
->info_2
->devmode
) ) {
4133 free_dev_mode( devmode
);
4138 free_a_printer(&printer
,2);
4143 /********************************************************************
4144 * construct_printer_info_2
4145 * fill a printer_info_2 struct
4146 ********************************************************************/
4148 static bool construct_printer_info_2(Printer_entry
*print_hnd
, PRINTER_INFO_2
*printer
, int snum
)
4151 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4153 print_status_struct status
;
4155 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4158 count
= print_queue_length(snum
, &status
);
4160 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4161 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4162 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
4163 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
4164 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
4166 if (*ntprinter
->info_2
->comment
== '\0')
4167 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
4169 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4171 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
4172 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
4173 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
4174 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
4175 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
4177 printer
->attributes
= ntprinter
->info_2
->attributes
;
4179 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
4180 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
4181 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
4182 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
4183 printer
->status
= nt_printq_status(status
.status
); /* status */
4184 printer
->cjobs
= count
; /* jobs */
4185 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
4187 if ( !(printer
->devmode
= construct_dev_mode(
4188 lp_const_servicename(snum
))) )
4189 DEBUG(8, ("Returning NULL Devicemode!\n"));
4191 printer
->secdesc
= NULL
;
4193 if ( ntprinter
->info_2
->secdesc_buf
4194 && ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0 )
4196 /* don't use talloc_steal() here unless you do a deep steal of all
4197 the SEC_DESC members */
4199 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4200 ntprinter
->info_2
->secdesc_buf
->sd
);
4203 free_a_printer(&ntprinter
, 2);
4208 /********************************************************************
4209 * construct_printer_info_3
4210 * fill a printer_info_3 struct
4211 ********************************************************************/
4213 static bool construct_printer_info_3(Printer_entry
*print_hnd
, PRINTER_INFO_3
**pp_printer
, int snum
)
4215 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4216 PRINTER_INFO_3
*printer
= NULL
;
4218 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4222 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_3
)) == NULL
) {
4223 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4224 free_a_printer(&ntprinter
, 2);
4228 ZERO_STRUCTP(printer
);
4230 /* These are the components of the SD we are returning. */
4232 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0) {
4233 /* don't use talloc_steal() here unless you do a deep steal of all
4234 the SEC_DESC members */
4236 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4237 ntprinter
->info_2
->secdesc_buf
->sd
);
4240 free_a_printer(&ntprinter
, 2);
4242 *pp_printer
= printer
;
4246 /********************************************************************
4247 * construct_printer_info_4
4248 * fill a printer_info_4 struct
4249 ********************************************************************/
4251 static bool construct_printer_info_4(Printer_entry
*print_hnd
, PRINTER_INFO_4
*printer
, int snum
)
4253 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4255 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4258 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4259 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4260 printer
->attributes
= ntprinter
->info_2
->attributes
;
4262 free_a_printer(&ntprinter
, 2);
4266 /********************************************************************
4267 * construct_printer_info_5
4268 * fill a printer_info_5 struct
4269 ********************************************************************/
4271 static bool construct_printer_info_5(Printer_entry
*print_hnd
, PRINTER_INFO_5
*printer
, int snum
)
4273 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4275 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4278 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
4279 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
);
4280 printer
->attributes
= ntprinter
->info_2
->attributes
;
4282 /* these two are not used by NT+ according to MSDN */
4284 printer
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
4285 printer
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
4287 free_a_printer(&ntprinter
, 2);
4292 /********************************************************************
4293 * construct_printer_info_6
4294 * fill a printer_info_6 struct
4295 ********************************************************************/
4297 static bool construct_printer_info_6(Printer_entry
*print_hnd
,
4298 PRINTER_INFO_6
*printer
,
4301 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4303 print_status_struct status
;
4305 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2,
4306 lp_const_servicename(snum
))))
4309 count
= print_queue_length(snum
, &status
);
4311 printer
->status
= nt_printq_status(status
.status
);
4313 free_a_printer(&ntprinter
, 2);
4318 /********************************************************************
4319 * construct_printer_info_7
4320 * fill a printer_info_7 struct
4321 ********************************************************************/
4323 static bool construct_printer_info_7(Printer_entry
*print_hnd
, PRINTER_INFO_7
*printer
, int snum
)
4325 char *guid_str
= NULL
;
4328 if (is_printer_published(print_hnd
, snum
, &guid
)) {
4329 if (asprintf(&guid_str
, "{%s}",
4330 GUID_string(talloc_tos(), &guid
)) == -1) {
4333 strupper_m(guid_str
);
4334 init_unistr(&printer
->guid
, guid_str
);
4335 SAFE_FREE(guid_str
);
4336 printer
->action
= SPOOL_DS_PUBLISH
;
4338 init_unistr(&printer
->guid
, "");
4339 printer
->action
= SPOOL_DS_UNPUBLISH
;
4345 /********************************************************************
4346 Spoolss_enumprinters.
4347 ********************************************************************/
4349 static WERROR
enum_all_printers_info_1(uint32 flags
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4353 int n_services
=lp_numservices();
4354 PRINTER_INFO_1
*printers
=NULL
;
4355 PRINTER_INFO_1 current_prt
;
4356 WERROR result
= WERR_OK
;
4358 DEBUG(4,("enum_all_printers_info_1\n"));
4360 for (snum
=0; snum
<n_services
; snum
++) {
4361 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4362 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4364 if (construct_printer_info_1(NULL
, flags
, ¤t_prt
, snum
)) {
4365 if((printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_1
, *returned
+1)) == NULL
) {
4366 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4370 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
4372 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
4378 /* check the required size. */
4379 for (i
=0; i
<*returned
; i
++)
4380 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
4382 if (*needed
> offered
) {
4383 result
= WERR_INSUFFICIENT_BUFFER
;
4387 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4388 result
= WERR_NOMEM
;
4392 /* fill the buffer with the structures */
4393 for (i
=0; i
<*returned
; i
++)
4394 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
4399 SAFE_FREE(printers
);
4401 if ( !W_ERROR_IS_OK(result
) )
4407 /********************************************************************
4408 enum_all_printers_info_1_local.
4409 *********************************************************************/
4411 static WERROR
enum_all_printers_info_1_local(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4413 DEBUG(4,("enum_all_printers_info_1_local\n"));
4415 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4418 /********************************************************************
4419 enum_all_printers_info_1_name.
4420 *********************************************************************/
4422 static WERROR
enum_all_printers_info_1_name(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4426 DEBUG(4,("enum_all_printers_info_1_name\n"));
4428 if ((name
[0] == '\\') && (name
[1] == '\\'))
4431 if (is_myname_or_ipaddr(s
)) {
4432 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4435 return WERR_INVALID_NAME
;
4438 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4439 /********************************************************************
4440 enum_all_printers_info_1_remote.
4441 *********************************************************************/
4443 static WERROR
enum_all_printers_info_1_remote(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4445 PRINTER_INFO_1
*printer
;
4446 fstring printername
;
4449 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4450 WERROR result
= WERR_OK
;
4452 /* JFM: currently it's more a place holder than anything else.
4453 * In the spooler world there is a notion of server registration.
4454 * the print servers are registered on the PDC (in the same domain)
4456 * We should have a TDB here. The registration is done thru an
4457 * undocumented RPC call.
4460 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4465 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", name
);
4466 slprintf(desc
, sizeof(desc
)-1,"%s", name
);
4467 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
4469 init_unistr(&printer
->description
, desc
);
4470 init_unistr(&printer
->name
, printername
);
4471 init_unistr(&printer
->comment
, comment
);
4472 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
4474 /* check the required size. */
4475 *needed
+= spoolss_size_printer_info_1(printer
);
4477 if (*needed
> offered
) {
4478 result
= WERR_INSUFFICIENT_BUFFER
;
4482 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4483 result
= WERR_NOMEM
;
4487 /* fill the buffer with the structures */
4488 smb_io_printer_info_1("", buffer
, printer
, 0);
4494 if ( !W_ERROR_IS_OK(result
) )
4502 /********************************************************************
4503 enum_all_printers_info_1_network.
4504 *********************************************************************/
4506 static WERROR
enum_all_printers_info_1_network(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4510 DEBUG(4,("enum_all_printers_info_1_network\n"));
4512 /* If we respond to a enum_printers level 1 on our name with flags
4513 set to PRINTER_ENUM_REMOTE with a list of printers then these
4514 printers incorrectly appear in the APW browse list.
4515 Specifically the printers for the server appear at the workgroup
4516 level where all the other servers in the domain are
4517 listed. Windows responds to this call with a
4518 WERR_CAN_NOT_COMPLETE so we should do the same. */
4520 if (name
[0] == '\\' && name
[1] == '\\')
4523 if (is_myname_or_ipaddr(s
))
4524 return WERR_CAN_NOT_COMPLETE
;
4526 return enum_all_printers_info_1(PRINTER_ENUM_NAME
, buffer
, offered
, needed
, returned
);
4529 /********************************************************************
4530 * api_spoolss_enumprinters
4532 * called from api_spoolss_enumprinters (see this to understand)
4533 ********************************************************************/
4535 static WERROR
enum_all_printers_info_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4539 int n_services
=lp_numservices();
4540 PRINTER_INFO_2
*printers
=NULL
;
4541 PRINTER_INFO_2 current_prt
;
4542 WERROR result
= WERR_OK
;
4546 for (snum
=0; snum
<n_services
; snum
++) {
4547 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4548 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4550 if (construct_printer_info_2(NULL
, ¤t_prt
, snum
)) {
4551 if ( !(printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_2
, *returned
+1)) ) {
4552 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4557 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
+ 1));
4559 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
4566 /* check the required size. */
4567 for (i
=0; i
<*returned
; i
++)
4568 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
4570 if (*needed
> offered
) {
4571 result
= WERR_INSUFFICIENT_BUFFER
;
4575 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4576 result
= WERR_NOMEM
;
4580 /* fill the buffer with the structures */
4581 for (i
=0; i
<*returned
; i
++)
4582 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
4587 for (i
=0; i
<*returned
; i
++)
4588 free_devmode(printers
[i
].devmode
);
4590 SAFE_FREE(printers
);
4592 if ( !W_ERROR_IS_OK(result
) )
4598 /********************************************************************
4599 * handle enumeration of printers at level 1
4600 ********************************************************************/
4602 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
4603 RPC_BUFFER
*buffer
, uint32 offered
,
4604 uint32
*needed
, uint32
*returned
)
4606 /* Not all the flags are equals */
4608 if (flags
& PRINTER_ENUM_LOCAL
)
4609 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
4611 if (flags
& PRINTER_ENUM_NAME
)
4612 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
4614 #if 0 /* JERRY - disabled for now */
4615 if (flags
& PRINTER_ENUM_REMOTE
)
4616 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
4619 if (flags
& PRINTER_ENUM_NETWORK
)
4620 return enum_all_printers_info_1_network(name
, buffer
, offered
, needed
, returned
);
4622 return WERR_OK
; /* NT4sp5 does that */
4625 /********************************************************************
4626 * handle enumeration of printers at level 2
4627 ********************************************************************/
4629 static WERROR
enumprinters_level2( uint32 flags
, const char *servername
,
4630 RPC_BUFFER
*buffer
, uint32 offered
,
4631 uint32
*needed
, uint32
*returned
)
4633 if (flags
& PRINTER_ENUM_LOCAL
) {
4634 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4637 if (flags
& PRINTER_ENUM_NAME
) {
4638 if (is_myname_or_ipaddr(canon_servername(servername
)))
4639 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4641 return WERR_INVALID_NAME
;
4644 if (flags
& PRINTER_ENUM_REMOTE
)
4645 return WERR_UNKNOWN_LEVEL
;
4650 /********************************************************************
4651 * handle enumeration of printers at level 5
4652 ********************************************************************/
4654 static WERROR
enumprinters_level5( uint32 flags
, const char *servername
,
4655 RPC_BUFFER
*buffer
, uint32 offered
,
4656 uint32
*needed
, uint32
*returned
)
4658 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4662 /********************************************************************
4663 * api_spoolss_enumprinters
4665 * called from api_spoolss_enumprinters (see this to understand)
4666 ********************************************************************/
4668 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
4670 uint32 flags
= q_u
->flags
;
4671 UNISTR2
*servername
= &q_u
->servername
;
4672 uint32 level
= q_u
->level
;
4673 RPC_BUFFER
*buffer
= NULL
;
4674 uint32 offered
= q_u
->offered
;
4675 uint32
*needed
= &r_u
->needed
;
4676 uint32
*returned
= &r_u
->returned
;
4680 /* that's an [in out] buffer */
4682 if (!q_u
->buffer
&& (offered
!=0)) {
4683 return WERR_INVALID_PARAM
;
4686 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
4687 buffer
= r_u
->buffer
;
4689 DEBUG(4,("_spoolss_enumprinters\n"));
4696 * flags==PRINTER_ENUM_NAME
4697 * if name=="" then enumerates all printers
4698 * if name!="" then enumerate the printer
4699 * flags==PRINTER_ENUM_REMOTE
4700 * name is NULL, enumerate printers
4701 * Level 2: name!="" enumerates printers, name can't be NULL
4702 * Level 3: doesn't exist
4703 * Level 4: does a local registry lookup
4704 * Level 5: same as Level 2
4707 unistr2_to_ascii(name
, servername
, sizeof(name
));
4712 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
4714 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
4716 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
4721 return WERR_UNKNOWN_LEVEL
;
4724 /****************************************************************************
4725 ****************************************************************************/
4727 static WERROR
getprinter_level_0(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4729 PRINTER_INFO_0
*printer
=NULL
;
4730 WERROR result
= WERR_OK
;
4732 if((printer
=SMB_MALLOC_P(PRINTER_INFO_0
)) == NULL
)
4735 construct_printer_info_0(print_hnd
, printer
, snum
);
4737 /* check the required size. */
4738 *needed
+= spoolss_size_printer_info_0(printer
);
4740 if (*needed
> offered
) {
4741 result
= WERR_INSUFFICIENT_BUFFER
;
4745 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4746 result
= WERR_NOMEM
;
4750 /* fill the buffer with the structures */
4751 smb_io_printer_info_0("", buffer
, printer
, 0);
4761 /****************************************************************************
4762 ****************************************************************************/
4764 static WERROR
getprinter_level_1(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4766 PRINTER_INFO_1
*printer
=NULL
;
4767 WERROR result
= WERR_OK
;
4769 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4772 construct_printer_info_1(print_hnd
, PRINTER_ENUM_ICON8
, printer
, snum
);
4774 /* check the required size. */
4775 *needed
+= spoolss_size_printer_info_1(printer
);
4777 if (*needed
> offered
) {
4778 result
= WERR_INSUFFICIENT_BUFFER
;
4782 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4783 result
= WERR_NOMEM
;
4787 /* fill the buffer with the structures */
4788 smb_io_printer_info_1("", buffer
, printer
, 0);
4797 /****************************************************************************
4798 ****************************************************************************/
4800 static WERROR
getprinter_level_2(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4802 PRINTER_INFO_2
*printer
=NULL
;
4803 WERROR result
= WERR_OK
;
4805 if((printer
=SMB_MALLOC_P(PRINTER_INFO_2
))==NULL
)
4808 construct_printer_info_2(print_hnd
, printer
, snum
);
4810 /* check the required size. */
4811 *needed
+= spoolss_size_printer_info_2(printer
);
4813 if (*needed
> offered
) {
4814 result
= WERR_INSUFFICIENT_BUFFER
;
4818 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4819 result
= WERR_NOMEM
;
4823 /* fill the buffer with the structures */
4824 if (!smb_io_printer_info_2("", buffer
, printer
, 0))
4825 result
= WERR_NOMEM
;
4829 free_printer_info_2(printer
);
4834 /****************************************************************************
4835 ****************************************************************************/
4837 static WERROR
getprinter_level_3(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4839 PRINTER_INFO_3
*printer
=NULL
;
4840 WERROR result
= WERR_OK
;
4842 if (!construct_printer_info_3(print_hnd
, &printer
, snum
))
4845 /* check the required size. */
4846 *needed
+= spoolss_size_printer_info_3(printer
);
4848 if (*needed
> offered
) {
4849 result
= WERR_INSUFFICIENT_BUFFER
;
4853 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4854 result
= WERR_NOMEM
;
4858 /* fill the buffer with the structures */
4859 smb_io_printer_info_3("", buffer
, printer
, 0);
4863 free_printer_info_3(printer
);
4868 /****************************************************************************
4869 ****************************************************************************/
4871 static WERROR
getprinter_level_4(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4873 PRINTER_INFO_4
*printer
=NULL
;
4874 WERROR result
= WERR_OK
;
4876 if((printer
=SMB_MALLOC_P(PRINTER_INFO_4
))==NULL
)
4879 if (!construct_printer_info_4(print_hnd
, printer
, snum
)) {
4884 /* check the required size. */
4885 *needed
+= spoolss_size_printer_info_4(printer
);
4887 if (*needed
> offered
) {
4888 result
= WERR_INSUFFICIENT_BUFFER
;
4892 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4893 result
= WERR_NOMEM
;
4897 /* fill the buffer with the structures */
4898 smb_io_printer_info_4("", buffer
, printer
, 0);
4902 free_printer_info_4(printer
);
4907 /****************************************************************************
4908 ****************************************************************************/
4910 static WERROR
getprinter_level_5(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4912 PRINTER_INFO_5
*printer
=NULL
;
4913 WERROR result
= WERR_OK
;
4915 if((printer
=SMB_MALLOC_P(PRINTER_INFO_5
))==NULL
)
4918 if (!construct_printer_info_5(print_hnd
, printer
, snum
)) {
4919 free_printer_info_5(printer
);
4923 /* check the required size. */
4924 *needed
+= spoolss_size_printer_info_5(printer
);
4926 if (*needed
> offered
) {
4927 result
= WERR_INSUFFICIENT_BUFFER
;
4931 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4932 result
= WERR_NOMEM
;
4936 /* fill the buffer with the structures */
4937 smb_io_printer_info_5("", buffer
, printer
, 0);
4941 free_printer_info_5(printer
);
4946 static WERROR
getprinter_level_6(Printer_entry
*print_hnd
,
4948 RPC_BUFFER
*buffer
, uint32 offered
,
4951 PRINTER_INFO_6
*printer
;
4952 WERROR result
= WERR_OK
;
4954 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_6
)) == NULL
) {
4958 if (!construct_printer_info_6(print_hnd
, printer
, snum
)) {
4959 free_printer_info_6(printer
);
4963 /* check the required size. */
4964 *needed
+= spoolss_size_printer_info_6(printer
);
4966 if (*needed
> offered
) {
4967 result
= WERR_INSUFFICIENT_BUFFER
;
4971 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4972 result
= WERR_NOMEM
;
4976 /* fill the buffer with the structures */
4977 smb_io_printer_info_6("", buffer
, printer
, 0);
4981 free_printer_info_6(printer
);
4986 static WERROR
getprinter_level_7(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4988 PRINTER_INFO_7
*printer
=NULL
;
4989 WERROR result
= WERR_OK
;
4991 if((printer
=SMB_MALLOC_P(PRINTER_INFO_7
))==NULL
)
4994 if (!construct_printer_info_7(print_hnd
, printer
, snum
)) {
4995 result
= WERR_NOMEM
;
4999 /* check the required size. */
5000 *needed
+= spoolss_size_printer_info_7(printer
);
5002 if (*needed
> offered
) {
5003 result
= WERR_INSUFFICIENT_BUFFER
;
5007 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5008 result
= WERR_NOMEM
;
5013 /* fill the buffer with the structures */
5014 smb_io_printer_info_7("", buffer
, printer
, 0);
5018 free_printer_info_7(printer
);
5023 /****************************************************************************
5024 ****************************************************************************/
5026 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
5028 POLICY_HND
*handle
= &q_u
->handle
;
5029 uint32 level
= q_u
->level
;
5030 RPC_BUFFER
*buffer
= NULL
;
5031 uint32 offered
= q_u
->offered
;
5032 uint32
*needed
= &r_u
->needed
;
5033 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
5037 /* that's an [in out] buffer */
5039 if (!q_u
->buffer
&& (offered
!=0)) {
5040 return WERR_INVALID_PARAM
;
5043 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5044 buffer
= r_u
->buffer
;
5048 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5053 return getprinter_level_0(Printer
, snum
, buffer
, offered
, needed
);
5055 return getprinter_level_1(Printer
, snum
, buffer
, offered
, needed
);
5057 return getprinter_level_2(Printer
, snum
, buffer
, offered
, needed
);
5059 return getprinter_level_3(Printer
, snum
, buffer
, offered
, needed
);
5061 return getprinter_level_4(Printer
, snum
, buffer
, offered
, needed
);
5063 return getprinter_level_5(Printer
, snum
, buffer
, offered
, needed
);
5065 return getprinter_level_6(Printer
, snum
, buffer
, offered
, needed
);
5067 return getprinter_level_7(Printer
, snum
, buffer
, offered
, needed
);
5069 return WERR_UNKNOWN_LEVEL
;
5072 /********************************************************************
5073 * fill a DRIVER_INFO_1 struct
5074 ********************************************************************/
5076 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
, fstring architecture
)
5078 init_unistr( &info
->name
, driver
.info_3
->name
);
5081 /********************************************************************
5082 * construct_printer_driver_info_1
5083 ********************************************************************/
5085 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5087 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5088 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5090 ZERO_STRUCT(driver
);
5092 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5093 return WERR_INVALID_PRINTER_NAME
;
5095 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5096 free_a_printer(&printer
, 2);
5097 return WERR_UNKNOWN_PRINTER_DRIVER
;
5100 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
5102 free_a_printer(&printer
,2);
5107 /********************************************************************
5108 * construct_printer_driver_info_2
5109 * fill a printer_info_2 struct
5110 ********************************************************************/
5112 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5114 TALLOC_CTX
*ctx
= talloc_tos();
5116 const char *cservername
= canon_servername(servername
);
5118 info
->version
=driver
.info_3
->cversion
;
5120 init_unistr( &info
->name
, driver
.info_3
->name
);
5121 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5123 if (strlen(driver
.info_3
->driverpath
)) {
5124 temp
= talloc_asprintf(ctx
,
5127 driver
.info_3
->driverpath
);
5128 init_unistr( &info
->driverpath
, temp
);
5130 init_unistr( &info
->driverpath
, "" );
5134 if (strlen(driver
.info_3
->datafile
)) {
5135 temp
= talloc_asprintf(ctx
,
5138 driver
.info_3
->datafile
);
5139 init_unistr( &info
->datafile
, temp
);
5141 init_unistr( &info
->datafile
, "" );
5144 if (strlen(driver
.info_3
->configfile
)) {
5145 temp
= talloc_asprintf(ctx
,
5148 driver
.info_3
->configfile
);
5149 init_unistr( &info
->configfile
, temp
);
5151 init_unistr( &info
->configfile
, "" );
5154 /********************************************************************
5155 * construct_printer_driver_info_2
5156 * fill a printer_info_2 struct
5157 ********************************************************************/
5159 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5161 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5162 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5164 ZERO_STRUCT(printer
);
5165 ZERO_STRUCT(driver
);
5167 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5168 return WERR_INVALID_PRINTER_NAME
;
5170 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5171 free_a_printer(&printer
, 2);
5172 return WERR_UNKNOWN_PRINTER_DRIVER
;
5175 fill_printer_driver_info_2(info
, driver
, servername
);
5177 free_a_printer(&printer
,2);
5182 /********************************************************************
5183 * copy a strings array and convert to UNICODE
5185 * convert an array of ascii string to a UNICODE string
5186 ********************************************************************/
5188 static uint32
init_unistr_array(uint16
**uni_array
, fstring
*char_array
, const char *servername
)
5194 TALLOC_CTX
*ctx
= talloc_tos();
5196 DEBUG(6,("init_unistr_array\n"));
5200 if ( !char_array
) {
5205 v
= ""; /* hack to handle null lists */
5208 /* hack to allow this to be used in places other than when generating
5209 the list of dependent files */
5213 line
= talloc_asprintf(ctx
,
5215 canon_servername(servername
),
5218 line
= talloc_strdup(ctx
, v
);
5222 SAFE_FREE(*uni_array
);
5225 DEBUGADD(6,("%d:%s:%lu\n", i
, line
, (unsigned long)strlen(line
)));
5227 /* add one extra unit16 for the second terminating NULL */
5229 if ( (*uni_array
=SMB_REALLOC_ARRAY(*uni_array
, uint16
, j
+1+strlen(line
)+2)) == NULL
) {
5230 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5237 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, STR_TERMINATE
) / sizeof(uint16
));
5242 /* special case for ""; we need to add both NULL's here */
5244 (*uni_array
)[j
++]=0x0000;
5245 (*uni_array
)[j
]=0x0000;
5248 DEBUGADD(6,("last one:done\n"));
5250 /* return size of array in uint16's */
5255 /********************************************************************
5256 * construct_printer_info_3
5257 * fill a printer_info_3 struct
5258 ********************************************************************/
5260 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5263 TALLOC_CTX
*ctx
= talloc_tos();
5264 const char *cservername
= canon_servername(servername
);
5268 info
->version
=driver
.info_3
->cversion
;
5270 init_unistr( &info
->name
, driver
.info_3
->name
);
5271 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5273 if (strlen(driver
.info_3
->driverpath
)) {
5274 temp
= talloc_asprintf(ctx
,
5277 driver
.info_3
->driverpath
);
5278 init_unistr( &info
->driverpath
, temp
);
5280 init_unistr( &info
->driverpath
, "" );
5283 if (strlen(driver
.info_3
->datafile
)) {
5284 temp
= talloc_asprintf(ctx
,
5287 driver
.info_3
->datafile
);
5288 init_unistr( &info
->datafile
, temp
);
5290 init_unistr( &info
->datafile
, "" );
5293 if (strlen(driver
.info_3
->configfile
)) {
5294 temp
= talloc_asprintf(ctx
,
5297 driver
.info_3
->configfile
);
5298 init_unistr( &info
->configfile
, temp
);
5300 init_unistr( &info
->configfile
, "" );
5303 if (strlen(driver
.info_3
->helpfile
)) {
5304 temp
= talloc_asprintf(ctx
,
5307 driver
.info_3
->helpfile
);
5308 init_unistr( &info
->helpfile
, temp
);
5310 init_unistr( &info
->helpfile
, "" );
5313 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5314 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5316 info
->dependentfiles
=NULL
;
5317 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, cservername
);
5320 /********************************************************************
5321 * construct_printer_info_3
5322 * fill a printer_info_3 struct
5323 ********************************************************************/
5325 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5327 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5328 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5330 ZERO_STRUCT(driver
);
5332 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5333 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5334 if (!W_ERROR_IS_OK(status
))
5335 return WERR_INVALID_PRINTER_NAME
;
5337 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5338 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5343 * I put this code in during testing. Helpful when commenting out the
5344 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5345 * as win2k always queries the driver using an infor level of 6.
5346 * I've left it in (but ifdef'd out) because I'll probably
5347 * use it in experimentation again in the future. --jerry 22/01/2002
5350 if (!W_ERROR_IS_OK(status
)) {
5352 * Is this a W2k client ?
5355 /* Yes - try again with a WinNT driver. */
5357 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5358 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5362 if (!W_ERROR_IS_OK(status
)) {
5363 free_a_printer(&printer
,2);
5364 return WERR_UNKNOWN_PRINTER_DRIVER
;
5372 fill_printer_driver_info_3(info
, driver
, servername
);
5374 free_a_printer(&printer
,2);
5379 /********************************************************************
5380 * construct_printer_info_6
5381 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5382 ********************************************************************/
5384 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5388 TALLOC_CTX
*ctx
= talloc_tos();
5389 const char *cservername
= canon_servername(servername
);
5392 memset(&nullstr
, '\0', sizeof(fstring
));
5394 info
->version
=driver
.info_3
->cversion
;
5396 init_unistr( &info
->name
, driver
.info_3
->name
);
5397 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5399 if (strlen(driver
.info_3
->driverpath
)) {
5400 temp
= talloc_asprintf(ctx
,
5403 driver
.info_3
->driverpath
);
5404 init_unistr( &info
->driverpath
, temp
);
5406 init_unistr( &info
->driverpath
, "" );
5409 if (strlen(driver
.info_3
->datafile
)) {
5410 temp
= talloc_asprintf(ctx
,
5413 driver
.info_3
->datafile
);
5414 init_unistr( &info
->datafile
, temp
);
5416 init_unistr( &info
->datafile
, "" );
5419 if (strlen(driver
.info_3
->configfile
)) {
5420 temp
= talloc_asprintf(ctx
,
5423 driver
.info_3
->configfile
);
5424 init_unistr( &info
->configfile
, temp
);
5426 init_unistr( &info
->configfile
, "" );
5429 if (strlen(driver
.info_3
->helpfile
)) {
5430 temp
= talloc_asprintf(ctx
,
5433 driver
.info_3
->helpfile
);
5434 init_unistr( &info
->helpfile
, temp
);
5436 init_unistr( &info
->helpfile
, "" );
5439 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5440 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5442 info
->dependentfiles
= NULL
;
5443 init_unistr_array( &info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5445 info
->previousdrivernames
=NULL
;
5446 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
5448 info
->driver_date
=0;
5451 info
->driver_version_low
=0;
5452 info
->driver_version_high
=0;
5454 init_unistr( &info
->mfgname
, "");
5455 init_unistr( &info
->oem_url
, "");
5456 init_unistr( &info
->hardware_id
, "");
5457 init_unistr( &info
->provider
, "");
5460 /********************************************************************
5461 * construct_printer_info_6
5462 * fill a printer_info_6 struct
5463 ********************************************************************/
5465 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
,
5466 const char *servername
, fstring architecture
, uint32 version
)
5468 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5469 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5472 ZERO_STRUCT(driver
);
5474 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5476 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5478 if (!W_ERROR_IS_OK(status
))
5479 return WERR_INVALID_PRINTER_NAME
;
5481 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5483 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5485 if (!W_ERROR_IS_OK(status
))
5488 * Is this a W2k client ?
5492 free_a_printer(&printer
,2);
5493 return WERR_UNKNOWN_PRINTER_DRIVER
;
5496 /* Yes - try again with a WinNT driver. */
5498 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5499 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5500 if (!W_ERROR_IS_OK(status
)) {
5501 free_a_printer(&printer
,2);
5502 return WERR_UNKNOWN_PRINTER_DRIVER
;
5506 fill_printer_driver_info_6(info
, driver
, servername
);
5508 free_a_printer(&printer
,2);
5509 free_a_printer_driver(driver
, 3);
5514 /****************************************************************************
5515 ****************************************************************************/
5517 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
5519 SAFE_FREE(info
->dependentfiles
);
5522 /****************************************************************************
5523 ****************************************************************************/
5525 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
5527 SAFE_FREE(info
->dependentfiles
);
5530 /****************************************************************************
5531 ****************************************************************************/
5533 static WERROR
getprinterdriver2_level1(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5535 DRIVER_INFO_1
*info
=NULL
;
5538 if((info
=SMB_MALLOC_P(DRIVER_INFO_1
)) == NULL
)
5541 result
= construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
5542 if (!W_ERROR_IS_OK(result
))
5545 /* check the required size. */
5546 *needed
+= spoolss_size_printer_driver_info_1(info
);
5548 if (*needed
> offered
) {
5549 result
= WERR_INSUFFICIENT_BUFFER
;
5553 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5554 result
= WERR_NOMEM
;
5558 /* fill the buffer with the structures */
5559 smb_io_printer_driver_info_1("", buffer
, info
, 0);
5568 /****************************************************************************
5569 ****************************************************************************/
5571 static WERROR
getprinterdriver2_level2(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5573 DRIVER_INFO_2
*info
=NULL
;
5576 if((info
=SMB_MALLOC_P(DRIVER_INFO_2
)) == NULL
)
5579 result
= construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
5580 if (!W_ERROR_IS_OK(result
))
5583 /* check the required size. */
5584 *needed
+= spoolss_size_printer_driver_info_2(info
);
5586 if (*needed
> offered
) {
5587 result
= WERR_INSUFFICIENT_BUFFER
;
5591 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5592 result
= WERR_NOMEM
;
5596 /* fill the buffer with the structures */
5597 smb_io_printer_driver_info_2("", buffer
, info
, 0);
5606 /****************************************************************************
5607 ****************************************************************************/
5609 static WERROR
getprinterdriver2_level3(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5616 result
= construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
5617 if (!W_ERROR_IS_OK(result
))
5620 /* check the required size. */
5621 *needed
+= spoolss_size_printer_driver_info_3(&info
);
5623 if (*needed
> offered
) {
5624 result
= WERR_INSUFFICIENT_BUFFER
;
5628 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5629 result
= WERR_NOMEM
;
5633 /* fill the buffer with the structures */
5634 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
5637 free_printer_driver_info_3(&info
);
5642 /****************************************************************************
5643 ****************************************************************************/
5645 static WERROR
getprinterdriver2_level6(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5652 result
= construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
5653 if (!W_ERROR_IS_OK(result
))
5656 /* check the required size. */
5657 *needed
+= spoolss_size_printer_driver_info_6(&info
);
5659 if (*needed
> offered
) {
5660 result
= WERR_INSUFFICIENT_BUFFER
;
5664 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5665 result
= WERR_NOMEM
;
5669 /* fill the buffer with the structures */
5670 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
5673 free_printer_driver_info_6(&info
);
5678 /****************************************************************************
5679 ****************************************************************************/
5681 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
5683 POLICY_HND
*handle
= &q_u
->handle
;
5684 UNISTR2
*uni_arch
= &q_u
->architecture
;
5685 uint32 level
= q_u
->level
;
5686 uint32 clientmajorversion
= q_u
->clientmajorversion
;
5687 RPC_BUFFER
*buffer
= NULL
;
5688 uint32 offered
= q_u
->offered
;
5689 uint32
*needed
= &r_u
->needed
;
5690 uint32
*servermajorversion
= &r_u
->servermajorversion
;
5691 uint32
*serverminorversion
= &r_u
->serverminorversion
;
5692 Printer_entry
*printer
;
5695 fstring architecture
;
5698 /* that's an [in out] buffer */
5700 if (!q_u
->buffer
&& (offered
!=0)) {
5701 return WERR_INVALID_PARAM
;
5704 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5705 buffer
= r_u
->buffer
;
5707 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5709 if ( !(printer
= find_printer_index_by_hnd( p
, handle
)) ) {
5710 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5711 return WERR_INVALID_PRINTER_NAME
;
5715 *servermajorversion
= 0;
5716 *serverminorversion
= 0;
5718 fstrcpy(servername
, get_server_name( printer
));
5719 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
));
5721 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5726 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5728 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5730 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5732 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5735 /* apparently this call is the equivalent of
5736 EnumPrinterDataEx() for the DsDriver key */
5741 return WERR_UNKNOWN_LEVEL
;
5745 /****************************************************************
5746 _spoolss_StartPagePrinter
5747 ****************************************************************/
5749 WERROR
_spoolss_StartPagePrinter(pipes_struct
*p
,
5750 struct spoolss_StartPagePrinter
*r
)
5752 POLICY_HND
*handle
= r
->in
.handle
;
5754 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5757 DEBUG(3,("_spoolss_StartPagePrinter: "
5758 "Error in startpageprinter printer handle\n"));
5762 Printer
->page_started
=True
;
5766 /****************************************************************
5767 _spoolss_EndPagePrinter
5768 ****************************************************************/
5770 WERROR
_spoolss_EndPagePrinter(pipes_struct
*p
,
5771 struct spoolss_EndPagePrinter
*r
)
5773 POLICY_HND
*handle
= r
->in
.handle
;
5776 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5779 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5780 OUR_HANDLE(handle
)));
5784 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5787 Printer
->page_started
=False
;
5788 print_job_endpage(snum
, Printer
->jobid
);
5793 /****************************************************************
5794 _spoolss_StartDocPrinter
5795 ****************************************************************/
5797 WERROR
_spoolss_StartDocPrinter(pipes_struct
*p
,
5798 struct spoolss_StartDocPrinter
*r
)
5800 POLICY_HND
*handle
= r
->in
.handle
;
5801 uint32_t *jobid
= r
->out
.job_id
;
5802 struct spoolss_DocumentInfo1
*info_1
;
5804 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5807 DEBUG(2,("_spoolss_StartDocPrinter: "
5808 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5812 if (r
->in
.level
!= 1) {
5813 return WERR_UNKNOWN_LEVEL
;
5816 info_1
= r
->in
.info
.info1
;
5819 * a nice thing with NT is it doesn't listen to what you tell it.
5820 * when asked to send _only_ RAW datas, it tries to send datas
5823 * So I add checks like in NT Server ...
5826 if (info_1
->datatype
) {
5827 if (strcmp(info_1
->datatype
, "RAW") != 0) {
5829 return WERR_INVALID_DATATYPE
;
5833 /* get the share number of the printer */
5834 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5838 Printer
->jobid
= print_job_start(p
->server_info
, snum
,
5839 CONST_DISCARD(char *,info_1
->document_name
),
5840 Printer
->nt_devmode
);
5842 /* An error occured in print_job_start() so return an appropriate
5845 if (Printer
->jobid
== -1) {
5846 return map_werror_from_unix(errno
);
5849 Printer
->document_started
=True
;
5850 (*jobid
) = Printer
->jobid
;
5855 /****************************************************************
5856 _spoolss_EndDocPrinter
5857 ****************************************************************/
5859 WERROR
_spoolss_EndDocPrinter(pipes_struct
*p
,
5860 struct spoolss_EndDocPrinter
*r
)
5862 POLICY_HND
*handle
= r
->in
.handle
;
5864 return _spoolss_enddocprinter_internal(p
, handle
);
5867 /****************************************************************
5868 _spoolss_WritePrinter
5869 ****************************************************************/
5871 WERROR
_spoolss_WritePrinter(pipes_struct
*p
,
5872 struct spoolss_WritePrinter
*r
)
5874 POLICY_HND
*handle
= r
->in
.handle
;
5875 uint32 buffer_size
= r
->in
._data_size
;
5876 uint8
*buffer
= r
->in
.data
.data
;
5877 uint32
*buffer_written
= &r
->in
._data_size
;
5879 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5882 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5883 OUR_HANDLE(handle
)));
5884 *r
->out
.num_written
= r
->in
._data_size
;
5888 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5891 (*buffer_written
) = (uint32
)print_job_write(snum
, Printer
->jobid
, (const char *)buffer
,
5892 (SMB_OFF_T
)-1, (size_t)buffer_size
);
5893 if (*buffer_written
== (uint32
)-1) {
5894 *r
->out
.num_written
= 0;
5895 if (errno
== ENOSPC
)
5896 return WERR_NO_SPOOL_SPACE
;
5898 return WERR_ACCESS_DENIED
;
5901 *r
->out
.num_written
= r
->in
._data_size
;
5906 /********************************************************************
5907 * api_spoolss_getprinter
5908 * called from the spoolss dispatcher
5910 ********************************************************************/
5912 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
5916 WERROR errcode
= WERR_BADFUNC
;
5917 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5920 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5924 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5928 case SPOOLSS_PRINTER_CONTROL_PAUSE
:
5929 if (print_queue_pause(p
->server_info
, snum
, &errcode
)) {
5933 case SPOOLSS_PRINTER_CONTROL_RESUME
:
5934 case SPOOLSS_PRINTER_CONTROL_UNPAUSE
:
5935 if (print_queue_resume(p
->server_info
, snum
, &errcode
)) {
5939 case SPOOLSS_PRINTER_CONTROL_PURGE
:
5940 if (print_queue_purge(p
->server_info
, snum
, &errcode
)) {
5945 return WERR_UNKNOWN_LEVEL
;
5952 /****************************************************************
5953 _spoolss_AbortPrinter
5954 * From MSDN: "Deletes printer's spool file if printer is configured
5956 ****************************************************************/
5958 WERROR
_spoolss_AbortPrinter(pipes_struct
*p
,
5959 struct spoolss_AbortPrinter
*r
)
5961 POLICY_HND
*handle
= r
->in
.handle
;
5962 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5964 WERROR errcode
= WERR_OK
;
5967 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5968 OUR_HANDLE(handle
)));
5972 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5975 print_job_delete(p
->server_info
, snum
, Printer
->jobid
, &errcode
);
5980 /********************************************************************
5981 * called by spoolss_api_setprinter
5982 * when updating a printer description
5983 ********************************************************************/
5985 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
5986 const SPOOL_PRINTER_INFO_LEVEL
*info
,
5987 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
5989 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
5993 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5995 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
5996 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5997 OUR_HANDLE(handle
)));
5999 result
= WERR_BADFID
;
6004 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6005 result
= WERR_INVALID_PARAM
;
6009 /* Check the user has permissions to change the security
6010 descriptor. By experimentation with two NT machines, the user
6011 requires Full Access to the printer to change security
6014 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6015 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6016 result
= WERR_ACCESS_DENIED
;
6020 /* NT seems to like setting the security descriptor even though
6021 nothing may have actually changed. */
6023 if ( !nt_printing_getsec(p
->mem_ctx
, Printer
->sharename
, &old_secdesc_ctr
)) {
6024 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6025 result
= WERR_BADFID
;
6029 if (DEBUGLEVEL
>= 10) {
6033 the_acl
= old_secdesc_ctr
->sd
->dacl
;
6034 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6035 PRINTERNAME(snum
), the_acl
->num_aces
));
6037 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6038 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6039 &the_acl
->aces
[i
].trustee
),
6040 the_acl
->aces
[i
].access_mask
));
6043 the_acl
= secdesc_ctr
->sd
->dacl
;
6046 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6047 PRINTERNAME(snum
), the_acl
->num_aces
));
6049 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6050 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6051 &the_acl
->aces
[i
].trustee
),
6052 the_acl
->aces
[i
].access_mask
));
6055 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6059 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
6060 if (!new_secdesc_ctr
) {
6061 result
= WERR_NOMEM
;
6065 if (sec_desc_equal(new_secdesc_ctr
->sd
, old_secdesc_ctr
->sd
)) {
6070 result
= nt_printing_setsec(Printer
->sharename
, new_secdesc_ctr
);
6077 /********************************************************************
6078 Canonicalize printer info from a client
6080 ATTN: It does not matter what we set the servername to hear
6081 since we do the necessary work in get_a_printer() to set it to
6082 the correct value based on what the client sent in the
6083 _spoolss_open_printer_ex().
6084 ********************************************************************/
6086 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
6088 fstring printername
;
6091 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6092 "portname=%s drivername=%s comment=%s location=%s\n",
6093 info
->servername
, info
->printername
, info
->sharename
,
6094 info
->portname
, info
->drivername
, info
->comment
, info
->location
));
6096 /* we force some elements to "correct" values */
6097 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname());
6098 fstrcpy(info
->sharename
, lp_servicename(snum
));
6100 /* check to see if we allow printername != sharename */
6102 if ( lp_force_printername(snum
) ) {
6103 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6104 global_myname(), info
->sharename
);
6107 /* make sure printername is in \\server\printername format */
6109 fstrcpy( printername
, info
->printername
);
6111 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
6112 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
6116 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6117 global_myname(), p
);
6120 info
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
6121 info
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
6128 /****************************************************************************
6129 ****************************************************************************/
6131 WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
6133 char *cmd
= lp_addport_cmd();
6134 char *command
= NULL
;
6136 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6137 bool is_print_op
= False
;
6140 return WERR_ACCESS_DENIED
;
6143 command
= talloc_asprintf(ctx
,
6144 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
6150 is_print_op
= user_has_privileges( token
, &se_printop
);
6152 DEBUG(10,("Running [%s]\n", command
));
6154 /********* BEGIN SePrintOperatorPrivilege **********/
6159 ret
= smbrun(command
, NULL
);
6164 /********* END SePrintOperatorPrivilege **********/
6166 DEBUGADD(10,("returned [%d]\n", ret
));
6168 TALLOC_FREE(command
);
6171 return WERR_ACCESS_DENIED
;
6177 /****************************************************************************
6178 ****************************************************************************/
6180 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, NT_PRINTER_INFO_LEVEL
*printer
)
6182 char *cmd
= lp_addprinter_cmd();
6184 char *command
= NULL
;
6188 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6189 bool is_print_op
= False
;
6190 char *remote_machine
= talloc_strdup(ctx
, "%m");
6192 if (!remote_machine
) {
6195 remote_machine
= talloc_sub_basic(ctx
,
6196 current_user_info
.smb_name
,
6197 current_user_info
.domain
,
6199 if (!remote_machine
) {
6203 command
= talloc_asprintf(ctx
,
6204 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6205 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
6206 printer
->info_2
->portname
, printer
->info_2
->drivername
,
6207 printer
->info_2
->location
, printer
->info_2
->comment
, remote_machine
);
6213 is_print_op
= user_has_privileges( token
, &se_printop
);
6215 DEBUG(10,("Running [%s]\n", command
));
6217 /********* BEGIN SePrintOperatorPrivilege **********/
6222 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
6223 /* Tell everyone we updated smb.conf. */
6224 message_send_all(smbd_messaging_context(),
6225 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
6231 /********* END SePrintOperatorPrivilege **********/
6233 DEBUGADD(10,("returned [%d]\n", ret
));
6235 TALLOC_FREE(command
);
6236 TALLOC_FREE(remote_machine
);
6244 /* reload our services immediately */
6245 reload_services( False
);
6248 /* Get lines and convert them back to dos-codepage */
6249 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
6250 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6253 /* Set the portname to what the script says the portname should be. */
6254 /* but don't require anything to be return from the script exit a good error code */
6257 /* Set the portname to what the script says the portname should be. */
6258 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
6259 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
6262 TALLOC_FREE(qlines
);
6267 /********************************************************************
6268 * Called by spoolss_api_setprinter
6269 * when updating a printer description.
6270 ********************************************************************/
6272 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
6273 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6274 DEVICEMODE
*devmode
)
6277 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
6278 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6283 DEBUG(8,("update_printer\n"));
6288 result
= WERR_BADFID
;
6292 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6293 result
= WERR_BADFID
;
6297 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))) ||
6298 (!W_ERROR_IS_OK(get_a_printer(Printer
, &old_printer
, 2, lp_const_servicename(snum
))))) {
6299 result
= WERR_BADFID
;
6303 DEBUGADD(8,("Converting info_2 struct\n"));
6306 * convert_printer_info converts the incoming
6307 * info from the client and overwrites the info
6308 * just read from the tdb in the pointer 'printer'.
6311 if (!convert_printer_info(info
, printer
, level
)) {
6312 result
= WERR_NOMEM
;
6317 /* we have a valid devmode
6318 convert it and link it*/
6320 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6321 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
6322 &printer
->info_2
->devmode
)) {
6323 result
= WERR_NOMEM
;
6328 /* Do sanity check on the requested changes for Samba */
6330 if (!check_printer_ok(printer
->info_2
, snum
)) {
6331 result
= WERR_INVALID_PARAM
;
6335 /* FIXME!!! If the driver has changed we really should verify that
6336 it is installed before doing much else --jerry */
6338 /* Check calling user has permission to update printer description */
6340 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6341 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6342 result
= WERR_ACCESS_DENIED
;
6346 /* Call addprinter hook */
6347 /* Check changes to see if this is really needed */
6349 if ( *lp_addprinter_cmd()
6350 && (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
)
6351 || !strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)
6352 || !strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)
6353 || !strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) )
6355 /* add_printer_hook() will call reload_services() */
6357 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
6359 result
= WERR_ACCESS_DENIED
;
6365 * When a *new* driver is bound to a printer, the drivername is used to
6366 * lookup previously saved driver initialization info, which is then
6367 * bound to the printer, simulating what happens in the Windows arch.
6369 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
6371 if (!set_driver_init(printer
, 2))
6373 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6374 printer
->info_2
->drivername
));
6377 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6378 printer
->info_2
->drivername
));
6380 notify_printer_driver(snum
, printer
->info_2
->drivername
);
6384 * flag which changes actually occured. This is a small subset of
6385 * all the possible changes. We also have to update things in the
6389 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)) {
6390 init_unistr2( &buffer
, printer
->info_2
->comment
, UNI_STR_TERMINATE
);
6391 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "description",
6392 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6394 notify_printer_comment(snum
, printer
->info_2
->comment
);
6397 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
)) {
6398 init_unistr2( &buffer
, printer
->info_2
->sharename
, UNI_STR_TERMINATE
);
6399 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shareName",
6400 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6402 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
6405 if (!strequal(printer
->info_2
->printername
, old_printer
->info_2
->printername
)) {
6408 if ( (pname
= strchr_m( printer
->info_2
->printername
+2, '\\' )) != NULL
)
6411 pname
= printer
->info_2
->printername
;
6414 init_unistr2( &buffer
, pname
, UNI_STR_TERMINATE
);
6415 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "printerName",
6416 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6418 notify_printer_printername( snum
, pname
);
6421 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)) {
6422 init_unistr2( &buffer
, printer
->info_2
->portname
, UNI_STR_TERMINATE
);
6423 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "portName",
6424 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6426 notify_printer_port(snum
, printer
->info_2
->portname
);
6429 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) {
6430 init_unistr2( &buffer
, printer
->info_2
->location
, UNI_STR_TERMINATE
);
6431 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "location",
6432 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6434 notify_printer_location(snum
, printer
->info_2
->location
);
6437 /* here we need to update some more DsSpooler keys */
6438 /* uNCName, serverName, shortServerName */
6440 init_unistr2( &buffer
, global_myname(), UNI_STR_TERMINATE
);
6441 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "serverName",
6442 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6443 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shortServerName",
6444 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6446 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
6447 global_myname(), printer
->info_2
->sharename
);
6448 init_unistr2( &buffer
, asc_buffer
, UNI_STR_TERMINATE
);
6449 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "uNCName",
6450 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6452 /* Update printer info */
6453 result
= mod_a_printer(printer
, 2);
6456 free_a_printer(&printer
, 2);
6457 free_a_printer(&old_printer
, 2);
6463 /****************************************************************************
6464 ****************************************************************************/
6465 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
, POLICY_HND
*handle
,
6466 const SPOOL_PRINTER_INFO_LEVEL
*info
)
6469 SPOOL_PRINTER_INFO_LEVEL_7
*info7
= info
->info_7
;
6471 Printer_entry
*Printer
;
6473 if ( lp_security() != SEC_ADS
) {
6474 return WERR_UNKNOWN_LEVEL
;
6477 Printer
= find_printer_index_by_hnd(p
, handle
);
6479 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6484 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6487 nt_printer_publish(Printer
, snum
, info7
->action
);
6491 return WERR_UNKNOWN_LEVEL
;
6494 /****************************************************************************
6495 ****************************************************************************/
6497 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
6499 POLICY_HND
*handle
= &q_u
->handle
;
6500 uint32 level
= q_u
->level
;
6501 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
6502 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
6503 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
6504 uint32 command
= q_u
->command
;
6507 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6510 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6514 /* check the level */
6517 return control_printer(handle
, command
, p
);
6519 result
= update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
6520 if (!W_ERROR_IS_OK(result
))
6523 result
= update_printer_sec(handle
, level
, info
, p
, secdesc_ctr
);
6526 return update_printer_sec(handle
, level
, info
, p
,
6529 return publish_or_unpublish_printer(p
, handle
, info
);
6531 return WERR_UNKNOWN_LEVEL
;
6535 /****************************************************************
6536 _spoolss_FindClosePrinterNotify
6537 ****************************************************************/
6539 WERROR
_spoolss_FindClosePrinterNotify(pipes_struct
*p
,
6540 struct spoolss_FindClosePrinterNotify
*r
)
6542 POLICY_HND
*handle
= r
->in
.handle
;
6543 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6546 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6547 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6551 if (Printer
->notify
.client_connected
==True
) {
6554 if ( Printer
->printer_type
== SPLHND_SERVER
)
6556 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6557 !get_printer_snum(p
, handle
, &snum
, NULL
) )
6560 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6563 Printer
->notify
.flags
=0;
6564 Printer
->notify
.options
=0;
6565 Printer
->notify
.localmachine
[0]='\0';
6566 Printer
->notify
.printerlocal
=0;
6567 if (Printer
->notify
.option
)
6568 free_spool_notify_option(&Printer
->notify
.option
);
6569 Printer
->notify
.client_connected
=False
;
6574 /****************************************************************
6576 ****************************************************************/
6578 WERROR
_spoolss_AddJob(pipes_struct
*p
,
6579 struct spoolss_AddJob
*r
)
6581 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6582 return WERR_INVALID_PARAM
;
6585 /* this is what a NT server returns for AddJob. AddJob must fail on
6586 * non-local printers */
6588 return WERR_INVALID_PARAM
;
6591 /****************************************************************************
6592 ****************************************************************************/
6594 static void fill_job_info_1(JOB_INFO_1
*job_info
, const print_queue_struct
*queue
,
6595 int position
, int snum
,
6596 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
6600 t
=gmtime(&queue
->time
);
6602 job_info
->jobid
=queue
->job
;
6603 init_unistr(&job_info
->printername
, lp_servicename(snum
));
6604 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6605 init_unistr(&job_info
->username
, queue
->fs_user
);
6606 init_unistr(&job_info
->document
, queue
->fs_file
);
6607 init_unistr(&job_info
->datatype
, "RAW");
6608 init_unistr(&job_info
->text_status
, "");
6609 job_info
->status
=nt_printj_status(queue
->status
);
6610 job_info
->priority
=queue
->priority
;
6611 job_info
->position
=position
;
6612 job_info
->totalpages
=queue
->page_count
;
6613 job_info
->pagesprinted
=0;
6615 make_systemtime(&job_info
->submitted
, t
);
6618 /****************************************************************************
6619 ****************************************************************************/
6621 static bool fill_job_info_2(JOB_INFO_2
*job_info
, const print_queue_struct
*queue
,
6622 int position
, int snum
,
6623 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6624 DEVICEMODE
*devmode
)
6628 t
=gmtime(&queue
->time
);
6630 job_info
->jobid
=queue
->job
;
6632 init_unistr(&job_info
->printername
, ntprinter
->info_2
->printername
);
6634 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6635 init_unistr(&job_info
->username
, queue
->fs_user
);
6636 init_unistr(&job_info
->document
, queue
->fs_file
);
6637 init_unistr(&job_info
->notifyname
, queue
->fs_user
);
6638 init_unistr(&job_info
->datatype
, "RAW");
6639 init_unistr(&job_info
->printprocessor
, "winprint");
6640 init_unistr(&job_info
->parameters
, "");
6641 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
6642 init_unistr(&job_info
->text_status
, "");
6644 /* and here the security descriptor */
6646 job_info
->status
=nt_printj_status(queue
->status
);
6647 job_info
->priority
=queue
->priority
;
6648 job_info
->position
=position
;
6649 job_info
->starttime
=0;
6650 job_info
->untiltime
=0;
6651 job_info
->totalpages
=queue
->page_count
;
6652 job_info
->size
=queue
->size
;
6653 make_systemtime(&(job_info
->submitted
), t
);
6654 job_info
->timeelapsed
=0;
6655 job_info
->pagesprinted
=0;
6657 job_info
->devmode
= devmode
;
6662 /****************************************************************************
6663 Enumjobs at level 1.
6664 ****************************************************************************/
6666 static WERROR
enumjobs_level1(const print_queue_struct
*queue
, int snum
,
6667 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6668 RPC_BUFFER
*buffer
, uint32 offered
,
6669 uint32
*needed
, uint32
*returned
)
6673 WERROR result
= WERR_OK
;
6675 info
=SMB_MALLOC_ARRAY(JOB_INFO_1
,*returned
);
6681 for (i
=0; i
<*returned
; i
++)
6682 fill_job_info_1( &info
[i
], &queue
[i
], i
, snum
, ntprinter
);
6684 /* check the required size. */
6685 for (i
=0; i
<*returned
; i
++)
6686 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
6688 if (*needed
> offered
) {
6689 result
= WERR_INSUFFICIENT_BUFFER
;
6693 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6694 result
= WERR_NOMEM
;
6698 /* fill the buffer with the structures */
6699 for (i
=0; i
<*returned
; i
++)
6700 smb_io_job_info_1("", buffer
, &info
[i
], 0);
6706 if ( !W_ERROR_IS_OK(result
) )
6712 /****************************************************************************
6713 Enumjobs at level 2.
6714 ****************************************************************************/
6716 static WERROR
enumjobs_level2(const print_queue_struct
*queue
, int snum
,
6717 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6718 RPC_BUFFER
*buffer
, uint32 offered
,
6719 uint32
*needed
, uint32
*returned
)
6721 JOB_INFO_2
*info
= NULL
;
6723 WERROR result
= WERR_OK
;
6724 DEVICEMODE
*devmode
= NULL
;
6726 if ( !(info
= SMB_MALLOC_ARRAY(JOB_INFO_2
,*returned
)) ) {
6731 /* this should not be a failure condition if the devmode is NULL */
6733 devmode
= construct_dev_mode(lp_const_servicename(snum
));
6735 for (i
=0; i
<*returned
; i
++)
6736 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
, devmode
);
6738 /* check the required size. */
6739 for (i
=0; i
<*returned
; i
++)
6740 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
6742 if (*needed
> offered
) {
6743 result
= WERR_INSUFFICIENT_BUFFER
;
6747 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6748 result
= WERR_NOMEM
;
6752 /* fill the buffer with the structures */
6753 for (i
=0; i
<*returned
; i
++)
6754 smb_io_job_info_2("", buffer
, &info
[i
], 0);
6757 free_devmode(devmode
);
6760 if ( !W_ERROR_IS_OK(result
) )
6767 /****************************************************************************
6769 ****************************************************************************/
6771 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
6773 POLICY_HND
*handle
= &q_u
->handle
;
6774 uint32 level
= q_u
->level
;
6775 RPC_BUFFER
*buffer
= NULL
;
6776 uint32 offered
= q_u
->offered
;
6777 uint32
*needed
= &r_u
->needed
;
6778 uint32
*returned
= &r_u
->returned
;
6780 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6782 print_status_struct prt_status
;
6783 print_queue_struct
*queue
=NULL
;
6785 /* that's an [in out] buffer */
6787 if (!q_u
->buffer
&& (offered
!=0)) {
6788 return WERR_INVALID_PARAM
;
6791 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6792 buffer
= r_u
->buffer
;
6794 DEBUG(4,("_spoolss_enumjobs\n"));
6799 /* lookup the printer snum and tdb entry */
6801 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6804 wret
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6805 if ( !W_ERROR_IS_OK(wret
) )
6808 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
6809 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
6811 if (*returned
== 0) {
6813 free_a_printer(&ntprinter
, 2);
6819 wret
= enumjobs_level1(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6822 wret
= enumjobs_level2(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6826 wret
= WERR_UNKNOWN_LEVEL
;
6831 free_a_printer( &ntprinter
, 2 );
6835 /****************************************************************
6836 _spoolss_ScheduleJob
6837 ****************************************************************/
6839 WERROR
_spoolss_ScheduleJob(pipes_struct
*p
,
6840 struct spoolss_ScheduleJob
*r
)
6845 /****************************************************************
6847 ****************************************************************/
6849 WERROR
_spoolss_SetJob(pipes_struct
*p
,
6850 struct spoolss_SetJob
*r
)
6852 POLICY_HND
*handle
= r
->in
.handle
;
6853 uint32 jobid
= r
->in
.job_id
;
6854 uint32 command
= r
->in
.command
;
6857 WERROR errcode
= WERR_BADFUNC
;
6859 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6863 if (!print_job_exists(lp_const_servicename(snum
), jobid
)) {
6864 return WERR_INVALID_PRINTER_NAME
;
6868 case SPOOLSS_JOB_CONTROL_CANCEL
:
6869 case SPOOLSS_JOB_CONTROL_DELETE
:
6870 if (print_job_delete(p
->server_info
, snum
, jobid
, &errcode
)) {
6874 case SPOOLSS_JOB_CONTROL_PAUSE
:
6875 if (print_job_pause(p
->server_info
, snum
, jobid
, &errcode
)) {
6879 case SPOOLSS_JOB_CONTROL_RESTART
:
6880 case SPOOLSS_JOB_CONTROL_RESUME
:
6881 if (print_job_resume(p
->server_info
, snum
, jobid
, &errcode
)) {
6886 return WERR_UNKNOWN_LEVEL
;
6892 /****************************************************************************
6893 Enumerates all printer drivers at level 1.
6894 ****************************************************************************/
6896 static WERROR
enumprinterdrivers_level1(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6901 fstring
*list
= NULL
;
6902 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6903 DRIVER_INFO_1
*driver_info_1
=NULL
;
6904 WERROR result
= WERR_OK
;
6908 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6910 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6911 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6913 if(ndrivers
== -1) {
6914 SAFE_FREE(driver_info_1
);
6919 if((driver_info_1
=SMB_REALLOC_ARRAY(driver_info_1
, DRIVER_INFO_1
, *returned
+ndrivers
)) == NULL
) {
6920 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6926 for (i
=0; i
<ndrivers
; i
++) {
6928 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6929 ZERO_STRUCT(driver
);
6930 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6931 architecture
, version
);
6932 if (!W_ERROR_IS_OK(status
)) {
6934 SAFE_FREE(driver_info_1
);
6937 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
6938 free_a_printer_driver(driver
, 3);
6941 *returned
+=ndrivers
;
6945 /* check the required size. */
6946 for (i
=0; i
<*returned
; i
++) {
6947 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6948 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
6951 if (*needed
> offered
) {
6952 result
= WERR_INSUFFICIENT_BUFFER
;
6956 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6957 result
= WERR_NOMEM
;
6961 /* fill the buffer with the driver structures */
6962 for (i
=0; i
<*returned
; i
++) {
6963 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6964 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
6968 SAFE_FREE(driver_info_1
);
6970 if ( !W_ERROR_IS_OK(result
) )
6976 /****************************************************************************
6977 Enumerates all printer drivers at level 2.
6978 ****************************************************************************/
6980 static WERROR
enumprinterdrivers_level2(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6985 fstring
*list
= NULL
;
6986 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6987 DRIVER_INFO_2
*driver_info_2
=NULL
;
6988 WERROR result
= WERR_OK
;
6992 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6994 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6995 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6997 if(ndrivers
== -1) {
6998 SAFE_FREE(driver_info_2
);
7003 if((driver_info_2
=SMB_REALLOC_ARRAY(driver_info_2
, DRIVER_INFO_2
, *returned
+ndrivers
)) == NULL
) {
7004 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7010 for (i
=0; i
<ndrivers
; i
++) {
7013 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7014 ZERO_STRUCT(driver
);
7015 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7016 architecture
, version
);
7017 if (!W_ERROR_IS_OK(status
)) {
7019 SAFE_FREE(driver_info_2
);
7022 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
7023 free_a_printer_driver(driver
, 3);
7026 *returned
+=ndrivers
;
7030 /* check the required size. */
7031 for (i
=0; i
<*returned
; i
++) {
7032 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7033 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
7036 if (*needed
> offered
) {
7037 result
= WERR_INSUFFICIENT_BUFFER
;
7041 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7042 result
= WERR_NOMEM
;
7046 /* fill the buffer with the form structures */
7047 for (i
=0; i
<*returned
; i
++) {
7048 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7049 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
7053 SAFE_FREE(driver_info_2
);
7055 if ( !W_ERROR_IS_OK(result
) )
7061 /****************************************************************************
7062 Enumerates all printer drivers at level 3.
7063 ****************************************************************************/
7065 static WERROR
enumprinterdrivers_level3(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7070 fstring
*list
= NULL
;
7071 DRIVER_INFO_3
*driver_info_3
=NULL
;
7072 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7073 WERROR result
= WERR_OK
;
7077 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7079 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7080 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7082 if(ndrivers
== -1) {
7083 SAFE_FREE(driver_info_3
);
7088 if((driver_info_3
=SMB_REALLOC_ARRAY(driver_info_3
, DRIVER_INFO_3
, *returned
+ndrivers
)) == NULL
) {
7089 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7095 for (i
=0; i
<ndrivers
; i
++) {
7098 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7099 ZERO_STRUCT(driver
);
7100 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7101 architecture
, version
);
7102 if (!W_ERROR_IS_OK(status
)) {
7104 SAFE_FREE(driver_info_3
);
7107 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
7108 free_a_printer_driver(driver
, 3);
7111 *returned
+=ndrivers
;
7115 /* check the required size. */
7116 for (i
=0; i
<*returned
; i
++) {
7117 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7118 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
7121 if (*needed
> offered
) {
7122 result
= WERR_INSUFFICIENT_BUFFER
;
7126 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7127 result
= WERR_NOMEM
;
7131 /* fill the buffer with the driver structures */
7132 for (i
=0; i
<*returned
; i
++) {
7133 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7134 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
7138 for (i
=0; i
<*returned
; i
++) {
7139 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
7142 SAFE_FREE(driver_info_3
);
7144 if ( !W_ERROR_IS_OK(result
) )
7150 /****************************************************************************
7151 Enumerates all printer drivers.
7152 ****************************************************************************/
7154 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
7156 uint32 level
= q_u
->level
;
7157 RPC_BUFFER
*buffer
= NULL
;
7158 uint32 offered
= q_u
->offered
;
7159 uint32
*needed
= &r_u
->needed
;
7160 uint32
*returned
= &r_u
->returned
;
7161 const char *cservername
;
7163 fstring architecture
;
7165 /* that's an [in out] buffer */
7167 if (!q_u
->buffer
&& (offered
!=0)) {
7168 return WERR_INVALID_PARAM
;
7171 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7172 buffer
= r_u
->buffer
;
7174 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7179 unistr2_to_ascii(architecture
, &q_u
->environment
, sizeof(architecture
));
7180 unistr2_to_ascii(servername
, &q_u
->name
, sizeof(servername
));
7182 cservername
= canon_servername(servername
);
7184 if (!is_myname_or_ipaddr(cservername
))
7185 return WERR_UNKNOWN_PRINTER_DRIVER
;
7189 return enumprinterdrivers_level1(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7191 return enumprinterdrivers_level2(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7193 return enumprinterdrivers_level3(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7195 return WERR_UNKNOWN_LEVEL
;
7199 /****************************************************************************
7200 ****************************************************************************/
7202 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
7204 form
->flag
=list
->flag
;
7205 init_unistr(&form
->name
, list
->name
);
7206 form
->width
=list
->width
;
7207 form
->length
=list
->length
;
7208 form
->left
=list
->left
;
7209 form
->top
=list
->top
;
7210 form
->right
=list
->right
;
7211 form
->bottom
=list
->bottom
;
7214 /****************************************************************************
7215 ****************************************************************************/
7217 static WERROR
fill_form_info_1(TALLOC_CTX
*mem_ctx
,
7218 struct spoolss_FormInfo1
*form
,
7219 nt_forms_struct
*list
)
7221 form
->form_name
= talloc_strdup(mem_ctx
, list
->name
);
7222 W_ERROR_HAVE_NO_MEMORY(form
->form_name
);
7224 form
->flags
= list
->flag
;
7225 form
->size
.width
= list
->width
;
7226 form
->size
.height
= list
->length
;
7227 form
->area
.left
= list
->left
;
7228 form
->area
.top
= list
->top
;
7229 form
->area
.right
= list
->right
;
7230 form
->area
.bottom
= list
->bottom
;
7235 /****************************************************************************
7236 ****************************************************************************/
7238 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
7240 uint32 level
= q_u
->level
;
7241 RPC_BUFFER
*buffer
= NULL
;
7242 uint32 offered
= q_u
->offered
;
7243 uint32
*needed
= &r_u
->needed
;
7244 uint32
*numofforms
= &r_u
->numofforms
;
7245 uint32 numbuiltinforms
;
7247 nt_forms_struct
*list
=NULL
;
7248 nt_forms_struct
*builtinlist
=NULL
;
7253 /* that's an [in out] buffer */
7255 if (!q_u
->buffer
&& (offered
!=0) ) {
7256 return WERR_INVALID_PARAM
;
7259 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7260 buffer
= r_u
->buffer
;
7262 DEBUG(4,("_spoolss_enumforms\n"));
7263 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7264 DEBUGADD(5,("Info level [%d]\n", level
));
7266 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
7267 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
7268 *numofforms
= get_ntforms(&list
);
7269 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
7270 *numofforms
+= numbuiltinforms
;
7272 if (*numofforms
== 0) {
7273 SAFE_FREE(builtinlist
);
7275 return WERR_NO_MORE_ITEMS
;
7280 if ((forms_1
=SMB_MALLOC_ARRAY(FORM_1
, *numofforms
)) == NULL
) {
7281 SAFE_FREE(builtinlist
);
7287 /* construct the list of form structures */
7288 for (i
=0; i
<numbuiltinforms
; i
++) {
7289 DEBUGADD(6,("Filling form number [%d]\n",i
));
7290 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
7293 SAFE_FREE(builtinlist
);
7295 for (; i
<*numofforms
; i
++) {
7296 DEBUGADD(6,("Filling form number [%d]\n",i
));
7297 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
7302 /* check the required size. */
7303 for (i
=0; i
<numbuiltinforms
; i
++) {
7304 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7305 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7307 for (; i
<*numofforms
; i
++) {
7308 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7309 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7312 *needed
=buffer_size
;
7314 if (*needed
> offered
) {
7317 return WERR_INSUFFICIENT_BUFFER
;
7320 if (!rpcbuf_alloc_size(buffer
, buffer_size
)){
7326 /* fill the buffer with the form structures */
7327 for (i
=0; i
<numbuiltinforms
; i
++) {
7328 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7329 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7331 for (; i
<*numofforms
; i
++) {
7332 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7333 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7342 SAFE_FREE(builtinlist
);
7343 return WERR_UNKNOWN_LEVEL
;
7347 /****************************************************************
7349 ****************************************************************/
7351 WERROR
_spoolss_GetForm(pipes_struct
*p
,
7352 struct spoolss_GetForm
*r
)
7354 uint32 level
= r
->in
.level
;
7355 uint32 offered
= r
->in
.offered
;
7356 uint32
*needed
= r
->out
.needed
;
7358 nt_forms_struct
*list
=NULL
;
7359 nt_forms_struct builtin_form
;
7361 union spoolss_FormInfo info
;
7362 struct spoolss_FormInfo1 form_1
;
7363 int numofforms
=0, i
=0;
7365 /* that's an [in out] buffer */
7367 if (!r
->in
.buffer
&& (offered
!=0)) {
7368 return WERR_INVALID_PARAM
;
7371 DEBUG(4,("_spoolss_GetForm\n"));
7372 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7373 DEBUGADD(5,("Info level [%d]\n", level
));
7375 foundBuiltin
= get_a_builtin_ntform_by_string(r
->in
.form_name
, &builtin_form
);
7376 if (!foundBuiltin
) {
7377 numofforms
= get_ntforms(&list
);
7378 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
7380 if (numofforms
== 0)
7384 ZERO_STRUCT(form_1
);
7389 fill_form_info_1(p
->mem_ctx
, &form_1
, &builtin_form
);
7392 /* Check if the requested name is in the list of form structures */
7393 for (i
=0; i
<numofforms
; i
++) {
7395 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7396 list
[i
].name
, r
->in
.form_name
));
7398 if (strequal(r
->in
.form_name
, list
[i
].name
)) {
7399 DEBUGADD(6,("Found form %s number [%d]\n",
7400 r
->in
.form_name
, i
));
7401 fill_form_info_1(p
->mem_ctx
, &form_1
, &list
[i
]);
7407 if (i
== numofforms
) {
7411 /* check the required size. */
7413 info
.info1
= form_1
;
7415 *needed
= ndr_size_spoolss_FormInfo(&info
, 1, NULL
, 0);
7417 if (*needed
> offered
) {
7419 return WERR_INSUFFICIENT_BUFFER
;
7422 r
->out
.info
->info1
= form_1
;
7424 /* fill the buffer with the form structures */
7425 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7426 r
->in
.form_name
, i
));
7432 return WERR_UNKNOWN_LEVEL
;
7436 /****************************************************************************
7437 ****************************************************************************/
7439 static void fill_port_1(PORT_INFO_1
*port
, const char *name
)
7441 init_unistr(&port
->port_name
, name
);
7444 /****************************************************************************
7445 TODO: This probably needs distinguish between TCP/IP and Local ports
7447 ****************************************************************************/
7449 static void fill_port_2(PORT_INFO_2
*port
, const char *name
)
7451 init_unistr(&port
->port_name
, name
);
7452 init_unistr(&port
->monitor_name
, "Local Monitor");
7453 init_unistr(&port
->description
, SPL_LOCAL_PORT
);
7454 port
->port_type
=PORT_TYPE_WRITE
;
7459 /****************************************************************************
7460 wrapper around the enumer ports command
7461 ****************************************************************************/
7463 WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7465 char *cmd
= lp_enumports_cmd();
7466 char **qlines
= NULL
;
7467 char *command
= NULL
;
7475 /* if no hook then just fill in the default port */
7478 if (!(qlines
= TALLOC_ARRAY( NULL
, char*, 2 ))) {
7481 if (!(qlines
[0] = talloc_strdup(qlines
, SAMBA_PRINTER_PORT_NAME
))) {
7482 TALLOC_FREE(qlines
);
7489 /* we have a valid enumport command */
7491 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7496 DEBUG(10,("Running [%s]\n", command
));
7497 ret
= smbrun(command
, &fd
);
7498 DEBUG(10,("Returned [%d]\n", ret
));
7499 TALLOC_FREE(command
);
7504 return WERR_ACCESS_DENIED
;
7508 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
7509 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7519 /****************************************************************************
7521 ****************************************************************************/
7523 static WERROR
enumports_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7525 PORT_INFO_1
*ports
=NULL
;
7527 WERROR result
= WERR_OK
;
7528 char **qlines
= NULL
;
7531 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7532 if (!W_ERROR_IS_OK(result
)) {
7533 TALLOC_FREE(qlines
);
7538 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_1
, numlines
)) == NULL
) {
7539 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7540 win_errstr(WERR_NOMEM
)));
7541 TALLOC_FREE(qlines
);
7545 for (i
=0; i
<numlines
; i
++) {
7546 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7547 fill_port_1(&ports
[i
], qlines
[i
]);
7550 TALLOC_FREE(qlines
);
7552 *returned
= numlines
;
7554 /* check the required size. */
7555 for (i
=0; i
<*returned
; i
++) {
7556 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7557 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
7560 if (*needed
> offered
) {
7561 result
= WERR_INSUFFICIENT_BUFFER
;
7565 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7566 result
= WERR_NOMEM
;
7570 /* fill the buffer with the ports structures */
7571 for (i
=0; i
<*returned
; i
++) {
7572 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7573 smb_io_port_1("", buffer
, &ports
[i
], 0);
7579 if ( !W_ERROR_IS_OK(result
) )
7585 /****************************************************************************
7587 ****************************************************************************/
7589 static WERROR
enumports_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7591 PORT_INFO_2
*ports
=NULL
;
7593 WERROR result
= WERR_OK
;
7594 char **qlines
= NULL
;
7597 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7598 if ( !W_ERROR_IS_OK(result
)) {
7599 TALLOC_FREE(qlines
);
7604 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_2
, numlines
)) == NULL
) {
7605 TALLOC_FREE(qlines
);
7609 for (i
=0; i
<numlines
; i
++) {
7610 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7611 fill_port_2(&(ports
[i
]), qlines
[i
]);
7615 TALLOC_FREE(qlines
);
7617 *returned
= numlines
;
7619 /* check the required size. */
7620 for (i
=0; i
<*returned
; i
++) {
7621 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7622 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
7625 if (*needed
> offered
) {
7626 result
= WERR_INSUFFICIENT_BUFFER
;
7630 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7631 result
= WERR_NOMEM
;
7635 /* fill the buffer with the ports structures */
7636 for (i
=0; i
<*returned
; i
++) {
7637 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7638 smb_io_port_2("", buffer
, &ports
[i
], 0);
7644 if ( !W_ERROR_IS_OK(result
) )
7650 /****************************************************************************
7652 ****************************************************************************/
7654 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
7656 uint32 level
= q_u
->level
;
7657 RPC_BUFFER
*buffer
= NULL
;
7658 uint32 offered
= q_u
->offered
;
7659 uint32
*needed
= &r_u
->needed
;
7660 uint32
*returned
= &r_u
->returned
;
7662 /* that's an [in out] buffer */
7664 if (!q_u
->buffer
&& (offered
!=0)) {
7665 return WERR_INVALID_PARAM
;
7668 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7669 buffer
= r_u
->buffer
;
7671 DEBUG(4,("_spoolss_enumports\n"));
7678 return enumports_level_1(buffer
, offered
, needed
, returned
);
7680 return enumports_level_2(buffer
, offered
, needed
, returned
);
7682 return WERR_UNKNOWN_LEVEL
;
7686 /****************************************************************************
7687 ****************************************************************************/
7689 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
7690 const SPOOL_PRINTER_INFO_LEVEL
*info
,
7691 DEVICEMODE
*devmode
, SEC_DESC_BUF
*sec_desc_buf
,
7692 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
7695 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7698 WERROR err
= WERR_OK
;
7700 if ( !(printer
= TALLOC_ZERO_P(NULL
, NT_PRINTER_INFO_LEVEL
)) ) {
7701 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7705 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7706 if (!convert_printer_info(info
, printer
, 2)) {
7707 free_a_printer(&printer
, 2);
7711 /* check to see if the printer already exists */
7713 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
7714 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7715 printer
->info_2
->sharename
));
7716 free_a_printer(&printer
, 2);
7717 return WERR_PRINTER_ALREADY_EXISTS
;
7720 /* FIXME!!! smbd should check to see if the driver is installed before
7721 trying to add a printer like this --jerry */
7723 if (*lp_addprinter_cmd() ) {
7724 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
7726 free_a_printer(&printer
,2);
7727 return WERR_ACCESS_DENIED
;
7730 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7731 "smb.conf parameter \"addprinter command\" is defined. This"
7732 "parameter must exist for this call to succeed\n",
7733 printer
->info_2
->sharename
));
7736 /* use our primary netbios name since get_a_printer() will convert
7737 it to what the client expects on a case by case basis */
7739 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname(),
7740 printer
->info_2
->sharename
);
7743 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
7744 free_a_printer(&printer
,2);
7745 return WERR_ACCESS_DENIED
;
7748 /* you must be a printer admin to add a new printer */
7749 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7750 free_a_printer(&printer
,2);
7751 return WERR_ACCESS_DENIED
;
7755 * Do sanity check on the requested changes for Samba.
7758 if (!check_printer_ok(printer
->info_2
, snum
)) {
7759 free_a_printer(&printer
,2);
7760 return WERR_INVALID_PARAM
;
7764 * When a printer is created, the drivername bound to the printer is used
7765 * to lookup previously saved driver initialization info, which is then
7766 * bound to the new printer, simulating what happens in the Windows arch.
7771 set_driver_init(printer
, 2);
7775 /* A valid devmode was included, convert and link it
7777 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7779 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
7780 &printer
->info_2
->devmode
))
7784 /* write the ASCII on disk */
7785 err
= mod_a_printer(printer
, 2);
7786 if (!W_ERROR_IS_OK(err
)) {
7787 free_a_printer(&printer
,2);
7791 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
7792 /* Handle open failed - remove addition. */
7793 del_a_printer(printer
->info_2
->sharename
);
7794 free_a_printer(&printer
,2);
7795 return WERR_ACCESS_DENIED
;
7798 update_c_setprinter(False
);
7799 free_a_printer(&printer
,2);
7804 /****************************************************************************
7805 ****************************************************************************/
7807 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
7809 UNISTR2
*uni_srv_name
= q_u
->server_name
;
7810 uint32 level
= q_u
->level
;
7811 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
7812 DEVICEMODE
*devmode
= q_u
->devmode_ctr
.devmode
;
7813 SEC_DESC_BUF
*sdb
= q_u
->secdesc_ctr
;
7814 uint32 user_switch
= q_u
->user_switch
;
7815 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
7816 POLICY_HND
*handle
= &r_u
->handle
;
7820 /* we don't handle yet */
7821 /* but I know what to do ... */
7822 return WERR_UNKNOWN_LEVEL
;
7824 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
7826 user_switch
, user
, handle
);
7828 return WERR_UNKNOWN_LEVEL
;
7832 /****************************************************************************
7833 ****************************************************************************/
7835 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
7837 uint32 level
= q_u
->level
;
7838 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
7839 WERROR err
= WERR_OK
;
7840 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7841 fstring driver_name
;
7844 ZERO_STRUCT(driver
);
7846 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7851 DEBUG(5,("Cleaning driver's information\n"));
7852 err
= clean_up_driver_struct(p
, driver
, level
);
7853 if (!W_ERROR_IS_OK(err
))
7856 DEBUG(5,("Moving driver to final destination\n"));
7857 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(p
, driver
, level
,
7862 if (add_a_printer_driver(driver
, level
)!=0) {
7863 err
= WERR_ACCESS_DENIED
;
7869 fstrcpy(driver_name
,
7870 driver
.info_3
->name
? driver
.info_3
->name
: "");
7873 fstrcpy(driver_name
,
7874 driver
.info_6
->name
? driver
.info_6
->name
: "");
7879 * I think this is where he DrvUpgradePrinter() hook would be
7880 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7881 * server. Right now, we just need to send ourselves a message
7882 * to update each printer bound to this driver. --jerry
7885 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7886 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7891 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7892 * decide if the driver init data should be deleted. The rules are:
7893 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7894 * 2) delete init data only if there is no 2k/Xp driver
7895 * 3) always delete init data
7896 * The generalized rule is always use init data from the highest order driver.
7897 * It is necessary to follow the driver install by an initialization step to
7898 * finish off this process.
7901 version
= driver
.info_3
->cversion
;
7902 else if (level
== 6)
7903 version
= driver
.info_6
->version
;
7908 * 9x printer driver - never delete init data
7911 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7916 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7917 * there is no 2k/Xp driver init data for this driver name.
7921 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7923 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7925 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7927 if (!del_driver_init(driver_name
))
7928 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name
));
7931 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7933 free_a_printer_driver(driver1
,3);
7934 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7941 * 2k or Xp printer driver - always delete init data
7944 if (!del_driver_init(driver_name
))
7945 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name
));
7949 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level
));
7955 free_a_printer_driver(driver
, level
);
7959 /********************************************************************
7960 * spoolss_addprinterdriverex
7961 ********************************************************************/
7963 WERROR
_spoolss_addprinterdriverex(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVEREX
*q_u
, SPOOL_R_ADDPRINTERDRIVEREX
*r_u
)
7965 SPOOL_Q_ADDPRINTERDRIVER q_u_local
;
7966 SPOOL_R_ADDPRINTERDRIVER r_u_local
;
7969 * we only support the semantics of AddPrinterDriver()
7970 * i.e. only copy files that are newer than existing ones
7973 if ( q_u
->copy_flags
!= APD_COPY_NEW_FILES
)
7974 return WERR_ACCESS_DENIED
;
7976 ZERO_STRUCT(q_u_local
);
7977 ZERO_STRUCT(r_u_local
);
7979 /* just pass the information off to _spoolss_addprinterdriver() */
7980 q_u_local
.server_name_ptr
= q_u
->server_name_ptr
;
7981 copy_unistr2(&q_u_local
.server_name
, &q_u
->server_name
);
7982 q_u_local
.level
= q_u
->level
;
7983 memcpy( &q_u_local
.info
, &q_u
->info
, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL
) );
7985 return _spoolss_addprinterdriver( p
, &q_u_local
, &r_u_local
);
7988 /****************************************************************************
7989 ****************************************************************************/
7991 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
7993 init_unistr(&info
->name
, name
);
7996 /****************************************************************************
7997 ****************************************************************************/
7999 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
8002 char *long_archi
= NULL
;
8003 char *servername
= NULL
;
8004 const char *pservername
= NULL
;
8005 const char *short_archi
;
8006 DRIVER_DIRECTORY_1
*info
=NULL
;
8007 WERROR result
= WERR_OK
;
8008 TALLOC_CTX
*ctx
= talloc_tos();
8010 servername
= unistr2_to_ascii_talloc(ctx
, name
);
8014 long_archi
= unistr2_to_ascii_talloc(ctx
, uni_environment
);
8019 pservername
= canon_servername(servername
);
8021 if ( !is_myname_or_ipaddr(pservername
))
8022 return WERR_INVALID_PARAM
;
8024 if (!(short_archi
= get_short_archi(long_archi
)))
8025 return WERR_INVALID_ENVIRONMENT
;
8027 if((info
=SMB_MALLOC_P(DRIVER_DIRECTORY_1
)) == NULL
)
8030 path
= talloc_asprintf(ctx
,
8031 "\\\\%s\\print$\\%s", pservername
, short_archi
);
8033 result
= WERR_NOMEM
;
8037 DEBUG(4,("printer driver directory: [%s]\n", path
));
8039 fill_driverdir_1(info
, path
);
8041 *needed
+= spoolss_size_driverdir_info_1(info
);
8043 if (*needed
> offered
) {
8044 result
= WERR_INSUFFICIENT_BUFFER
;
8048 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8049 result
= WERR_NOMEM
;
8053 smb_io_driverdir_1("", buffer
, info
, 0);
8061 /****************************************************************************
8062 ****************************************************************************/
8064 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
8066 UNISTR2
*name
= &q_u
->name
;
8067 UNISTR2
*uni_environment
= &q_u
->environment
;
8068 uint32 level
= q_u
->level
;
8069 RPC_BUFFER
*buffer
= NULL
;
8070 uint32 offered
= q_u
->offered
;
8071 uint32
*needed
= &r_u
->needed
;
8073 /* that's an [in out] buffer */
8075 if (!q_u
->buffer
&& (offered
!=0)) {
8076 return WERR_INVALID_PARAM
;
8079 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8080 buffer
= r_u
->buffer
;
8082 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8088 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
8090 return WERR_UNKNOWN_LEVEL
;
8094 /****************************************************************************
8095 ****************************************************************************/
8097 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
8099 POLICY_HND
*handle
= &q_u
->handle
;
8100 uint32 idx
= q_u
->index
;
8101 uint32 in_value_len
= q_u
->valuesize
;
8102 uint32 in_data_len
= q_u
->datasize
;
8103 uint32
*out_max_value_len
= &r_u
->valuesize
;
8104 uint16
**out_value
= &r_u
->value
;
8105 uint32
*out_value_len
= &r_u
->realvaluesize
;
8106 uint32
*out_type
= &r_u
->type
;
8107 uint32
*out_max_data_len
= &r_u
->datasize
;
8108 uint8
**data_out
= &r_u
->data
;
8109 uint32
*out_data_len
= &r_u
->realdatasize
;
8111 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8113 uint32 biggest_valuesize
;
8114 uint32 biggest_datasize
;
8116 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8119 REGISTRY_VALUE
*val
= NULL
;
8120 NT_PRINTER_DATA
*p_data
;
8121 int i
, key_index
, num_values
;
8126 *out_max_data_len
= 0;
8130 DEBUG(5,("spoolss_enumprinterdata\n"));
8133 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8137 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8140 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8141 if (!W_ERROR_IS_OK(result
))
8144 p_data
= printer
->info_2
->data
;
8145 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
8150 * The NT machine wants to know the biggest size of value and data
8152 * cf: MSDN EnumPrinterData remark section
8155 if ( !in_value_len
&& !in_data_len
&& (key_index
!= -1) )
8157 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8159 biggest_valuesize
= 0;
8160 biggest_datasize
= 0;
8162 num_values
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
8164 for ( i
=0; i
<num_values
; i
++ )
8166 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
8168 name_length
= strlen(val
->valuename
);
8169 if ( strlen(val
->valuename
) > biggest_valuesize
)
8170 biggest_valuesize
= name_length
;
8172 if ( val
->size
> biggest_datasize
)
8173 biggest_datasize
= val
->size
;
8175 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
8179 /* the value is an UNICODE string but real_value_size is the length
8180 in bytes including the trailing 0 */
8182 *out_value_len
= 2 * (1+biggest_valuesize
);
8183 *out_data_len
= biggest_datasize
;
8185 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
8191 * the value len is wrong in NT sp3
8192 * that's the number of bytes not the number of unicode chars
8195 if ( key_index
!= -1 )
8196 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, idx
);
8201 /* out_value should default to "" or else NT4 has
8202 problems unmarshalling the response */
8204 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8207 if((*out_value
=(uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8209 result
= WERR_NOMEM
;
8212 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
8218 /* the data is counted in bytes */
8220 *out_max_data_len
= in_data_len
;
8221 *out_data_len
= in_data_len
;
8223 /* only allocate when given a non-zero data_len */
8225 if ( in_data_len
&& ((*data_out
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) )
8227 result
= WERR_NOMEM
;
8231 result
= WERR_NO_MORE_ITEMS
;
8237 * - counted in bytes in the request
8238 * - counted in UNICODE chars in the max reply
8239 * - counted in bytes in the real size
8241 * take a pause *before* coding not *during* coding
8245 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8247 if ( (*out_value
= (uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8249 result
= WERR_NOMEM
;
8253 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, regval_name(val
), (size_t)in_value_len
, 0);
8261 *out_type
= regval_type( val
);
8263 /* data - counted in bytes */
8265 *out_max_data_len
= in_data_len
;
8266 if ( in_data_len
&& (*data_out
= (uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
8268 result
= WERR_NOMEM
;
8271 data_len
= regval_size(val
);
8272 if ( *data_out
&& data_len
)
8273 memcpy( *data_out
, regval_data_p(val
), data_len
);
8274 *out_data_len
= data_len
;
8278 free_a_printer(&printer
, 2);
8282 /****************************************************************************
8283 ****************************************************************************/
8285 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
8287 POLICY_HND
*handle
= &q_u
->handle
;
8288 UNISTR2
*value
= &q_u
->value
;
8289 uint32 type
= q_u
->type
;
8290 uint8
*data
= q_u
->data
;
8291 uint32 real_len
= q_u
->real_len
;
8293 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8295 WERROR status
= WERR_OK
;
8296 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8299 DEBUG(5,("spoolss_setprinterdata\n"));
8302 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8306 if ( Printer
->printer_type
== SPLHND_SERVER
) {
8307 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8308 return WERR_INVALID_PARAM
;
8311 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8315 * Access check : NT returns "access denied" if you make a
8316 * SetPrinterData call without the necessary privildge.
8317 * we were originally returning OK if nothing changed
8318 * which made Win2k issue **a lot** of SetPrinterData
8319 * when connecting to a printer --jerry
8322 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
8324 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8325 status
= WERR_ACCESS_DENIED
;
8329 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8330 if (!W_ERROR_IS_OK(status
))
8333 unistr2_to_ascii(valuename
, value
, sizeof(valuename
));
8336 * When client side code sets a magic printer data key, detect it and save
8337 * the current printer data and the magic key's data (its the DEVMODE) for
8338 * future printer/driver initializations.
8340 if ( (type
== REG_BINARY
) && strequal( valuename
, PHANTOM_DEVMODE_KEY
))
8342 /* Set devmode and printer initialization info */
8343 status
= save_driver_init( printer
, 2, data
, real_len
);
8345 srv_spoolss_reset_printerdata( printer
->info_2
->drivername
);
8349 status
= set_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
,
8350 type
, data
, real_len
);
8351 if ( W_ERROR_IS_OK(status
) )
8352 status
= mod_a_printer(printer
, 2);
8356 free_a_printer(&printer
, 2);
8361 /****************************************************************************
8362 ****************************************************************************/
8364 WERROR
_spoolss_resetprinter(pipes_struct
*p
, SPOOL_Q_RESETPRINTER
*q_u
, SPOOL_R_RESETPRINTER
*r_u
)
8366 POLICY_HND
*handle
= &q_u
->handle
;
8367 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8370 DEBUG(5,("_spoolss_resetprinter\n"));
8373 * All we do is to check to see if the handle and queue is valid.
8374 * This call really doesn't mean anything to us because we only
8375 * support RAW printing. --jerry
8379 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8383 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8387 /* blindly return success */
8391 /****************************************************************
8392 _spoolss_DeletePrinterData
8393 ****************************************************************/
8395 WERROR
_spoolss_DeletePrinterData(pipes_struct
*p
,
8396 struct spoolss_DeletePrinterData
*r
)
8398 POLICY_HND
*handle
= r
->in
.handle
;
8399 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8401 WERROR status
= WERR_OK
;
8402 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8404 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8407 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8408 OUR_HANDLE(handle
)));
8412 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
8415 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8416 DEBUG(3, ("_spoolss_DeletePrinterData: "
8417 "printer properties change denied by handle\n"));
8418 return WERR_ACCESS_DENIED
;
8421 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8422 if (!W_ERROR_IS_OK(status
))
8425 if (!r
->in
.value_name
) {
8426 free_a_printer(&printer
, 2);
8430 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
,
8433 if ( W_ERROR_IS_OK(status
) )
8434 mod_a_printer( printer
, 2 );
8436 free_a_printer(&printer
, 2);
8441 /****************************************************************
8443 ****************************************************************/
8445 WERROR
_spoolss_AddForm(pipes_struct
*p
,
8446 struct spoolss_AddForm
*r
)
8448 POLICY_HND
*handle
= r
->in
.handle
;
8449 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
8450 nt_forms_struct tmpForm
;
8452 WERROR status
= WERR_OK
;
8453 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8456 nt_forms_struct
*list
=NULL
;
8457 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8459 DEBUG(5,("_spoolss_AddForm\n"));
8462 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8463 OUR_HANDLE(handle
)));
8468 /* forms can be added on printer of on the print server handle */
8470 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8472 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8475 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8476 if (!W_ERROR_IS_OK(status
))
8480 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8481 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8482 status
= WERR_ACCESS_DENIED
;
8486 /* can't add if builtin */
8488 if (get_a_builtin_ntform_by_string(form
->form_name
, &tmpForm
)) {
8489 status
= WERR_FILE_EXISTS
;
8493 count
= get_ntforms(&list
);
8495 if(!add_a_form(&list
, form
, &count
)) {
8496 status
= WERR_NOMEM
;
8500 write_ntforms(&list
, count
);
8503 * ChangeID must always be set if this is a printer
8506 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8507 status
= mod_a_printer(printer
, 2);
8511 free_a_printer(&printer
, 2);
8517 /****************************************************************
8519 ****************************************************************/
8521 WERROR
_spoolss_DeleteForm(pipes_struct
*p
,
8522 struct spoolss_DeleteForm
*r
)
8524 POLICY_HND
*handle
= r
->in
.handle
;
8525 const char *form_name
= r
->in
.form_name
;
8526 nt_forms_struct tmpForm
;
8528 nt_forms_struct
*list
=NULL
;
8529 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8531 WERROR status
= WERR_OK
;
8532 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8534 DEBUG(5,("_spoolss_DeleteForm\n"));
8537 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8538 OUR_HANDLE(handle
)));
8542 /* forms can be deleted on printer of on the print server handle */
8544 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8546 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8549 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8550 if (!W_ERROR_IS_OK(status
))
8554 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8555 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8556 status
= WERR_ACCESS_DENIED
;
8560 /* can't delete if builtin */
8562 if (get_a_builtin_ntform_by_string(form_name
,&tmpForm
)) {
8563 status
= WERR_INVALID_PARAM
;
8567 count
= get_ntforms(&list
);
8569 if ( !delete_a_form(&list
, form_name
, &count
, &status
))
8573 * ChangeID must always be set if this is a printer
8576 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8577 status
= mod_a_printer(printer
, 2);
8581 free_a_printer(&printer
, 2);
8587 /****************************************************************
8589 ****************************************************************/
8591 WERROR
_spoolss_SetForm(pipes_struct
*p
,
8592 struct spoolss_SetForm
*r
)
8594 POLICY_HND
*handle
= r
->in
.handle
;
8595 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
8596 nt_forms_struct tmpForm
;
8598 WERROR status
= WERR_OK
;
8599 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8602 nt_forms_struct
*list
=NULL
;
8603 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8605 DEBUG(5,("_spoolss_SetForm\n"));
8608 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8609 OUR_HANDLE(handle
)));
8613 /* forms can be modified on printer of on the print server handle */
8615 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8617 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8620 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8621 if (!W_ERROR_IS_OK(status
))
8625 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8626 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8627 status
= WERR_ACCESS_DENIED
;
8631 /* can't set if builtin */
8632 if (get_a_builtin_ntform_by_string(form
->form_name
, &tmpForm
)) {
8633 status
= WERR_INVALID_PARAM
;
8637 count
= get_ntforms(&list
);
8638 update_a_form(&list
, form
, count
);
8639 write_ntforms(&list
, count
);
8642 * ChangeID must always be set if this is a printer
8645 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8646 status
= mod_a_printer(printer
, 2);
8651 free_a_printer(&printer
, 2);
8657 /****************************************************************************
8658 enumprintprocessors level 1.
8659 ****************************************************************************/
8661 static WERROR
enumprintprocessors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8663 PRINTPROCESSOR_1
*info_1
=NULL
;
8664 WERROR result
= WERR_OK
;
8666 if((info_1
= SMB_MALLOC_P(PRINTPROCESSOR_1
)) == NULL
)
8671 init_unistr(&info_1
->name
, "winprint");
8673 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
8675 if (*needed
> offered
) {
8676 result
= WERR_INSUFFICIENT_BUFFER
;
8680 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8681 result
= WERR_NOMEM
;
8685 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
8690 if ( !W_ERROR_IS_OK(result
) )
8696 /****************************************************************************
8697 ****************************************************************************/
8699 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
8701 uint32 level
= q_u
->level
;
8702 RPC_BUFFER
*buffer
= NULL
;
8703 uint32 offered
= q_u
->offered
;
8704 uint32
*needed
= &r_u
->needed
;
8705 uint32
*returned
= &r_u
->returned
;
8707 /* that's an [in out] buffer */
8709 if (!q_u
->buffer
&& (offered
!=0)) {
8710 return WERR_INVALID_PARAM
;
8713 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8714 buffer
= r_u
->buffer
;
8716 DEBUG(5,("spoolss_enumprintprocessors\n"));
8719 * Enumerate the print processors ...
8721 * Just reply with "winprint", to keep NT happy
8722 * and I can use my nice printer checker.
8730 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
8732 return WERR_UNKNOWN_LEVEL
;
8736 /****************************************************************************
8737 enumprintprocdatatypes level 1.
8738 ****************************************************************************/
8740 static WERROR
enumprintprocdatatypes_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8742 PRINTPROCDATATYPE_1
*info_1
=NULL
;
8743 WERROR result
= WERR_OK
;
8745 if((info_1
= SMB_MALLOC_P(PRINTPROCDATATYPE_1
)) == NULL
)
8750 init_unistr(&info_1
->name
, "RAW");
8752 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
8754 if (*needed
> offered
) {
8755 result
= WERR_INSUFFICIENT_BUFFER
;
8759 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8760 result
= WERR_NOMEM
;
8764 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
8769 if ( !W_ERROR_IS_OK(result
) )
8775 /****************************************************************************
8776 ****************************************************************************/
8778 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
8780 uint32 level
= q_u
->level
;
8781 RPC_BUFFER
*buffer
= NULL
;
8782 uint32 offered
= q_u
->offered
;
8783 uint32
*needed
= &r_u
->needed
;
8784 uint32
*returned
= &r_u
->returned
;
8786 /* that's an [in out] buffer */
8788 if (!q_u
->buffer
&& (offered
!=0)) {
8789 return WERR_INVALID_PARAM
;
8792 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8793 buffer
= r_u
->buffer
;
8795 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8802 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
8804 return WERR_UNKNOWN_LEVEL
;
8808 /****************************************************************************
8809 enumprintmonitors level 1.
8810 ****************************************************************************/
8812 static WERROR
enumprintmonitors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8814 PRINTMONITOR_1
*info_1
;
8815 WERROR result
= WERR_OK
;
8818 if((info_1
= SMB_MALLOC_ARRAY(PRINTMONITOR_1
, 2)) == NULL
)
8823 init_unistr(&(info_1
[0].name
), SPL_LOCAL_PORT
);
8824 init_unistr(&(info_1
[1].name
), SPL_TCPIP_PORT
);
8826 for ( i
=0; i
<*returned
; i
++ ) {
8827 *needed
+= spoolss_size_printmonitor_info_1(&info_1
[i
]);
8830 if (*needed
> offered
) {
8831 result
= WERR_INSUFFICIENT_BUFFER
;
8835 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8836 result
= WERR_NOMEM
;
8840 for ( i
=0; i
<*returned
; i
++ ) {
8841 smb_io_printmonitor_info_1("", buffer
, &info_1
[i
], 0);
8847 if ( !W_ERROR_IS_OK(result
) )
8853 /****************************************************************************
8854 enumprintmonitors level 2.
8855 ****************************************************************************/
8857 static WERROR
enumprintmonitors_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8859 PRINTMONITOR_2
*info_2
;
8860 WERROR result
= WERR_OK
;
8863 if((info_2
= SMB_MALLOC_ARRAY(PRINTMONITOR_2
, 2)) == NULL
)
8868 init_unistr( &(info_2
[0].name
), SPL_LOCAL_PORT
);
8869 init_unistr( &(info_2
[0].environment
), "Windows NT X86" );
8870 init_unistr( &(info_2
[0].dll_name
), "localmon.dll" );
8872 init_unistr( &(info_2
[1].name
), SPL_TCPIP_PORT
);
8873 init_unistr( &(info_2
[1].environment
), "Windows NT X86" );
8874 init_unistr( &(info_2
[1].dll_name
), "tcpmon.dll" );
8876 for ( i
=0; i
<*returned
; i
++ ) {
8877 *needed
+= spoolss_size_printmonitor_info_2(&info_2
[i
]);
8880 if (*needed
> offered
) {
8881 result
= WERR_INSUFFICIENT_BUFFER
;
8885 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8886 result
= WERR_NOMEM
;
8890 for ( i
=0; i
<*returned
; i
++ ) {
8891 smb_io_printmonitor_info_2("", buffer
, &info_2
[i
], 0);
8897 if ( !W_ERROR_IS_OK(result
) )
8903 /****************************************************************************
8904 ****************************************************************************/
8906 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
8908 uint32 level
= q_u
->level
;
8909 RPC_BUFFER
*buffer
= NULL
;
8910 uint32 offered
= q_u
->offered
;
8911 uint32
*needed
= &r_u
->needed
;
8912 uint32
*returned
= &r_u
->returned
;
8914 /* that's an [in out] buffer */
8916 if (!q_u
->buffer
&& (offered
!=0)) {
8917 return WERR_INVALID_PARAM
;
8920 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8921 buffer
= r_u
->buffer
;
8923 DEBUG(5,("spoolss_enumprintmonitors\n"));
8926 * Enumerate the print monitors ...
8928 * Just reply with "Local Port", to keep NT happy
8929 * and I can use my nice printer checker.
8937 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
8939 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
8941 return WERR_UNKNOWN_LEVEL
;
8945 /****************************************************************************
8946 ****************************************************************************/
8948 static WERROR
getjob_level_1(print_queue_struct
**queue
, int count
, int snum
,
8949 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8950 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8955 JOB_INFO_1
*info_1
=NULL
;
8956 WERROR result
= WERR_OK
;
8958 info_1
=SMB_MALLOC_P(JOB_INFO_1
);
8960 if (info_1
== NULL
) {
8964 for (i
=0; i
<count
&& found
==False
; i
++) {
8965 if ((*queue
)[i
].job
==(int)jobid
)
8971 /* NT treats not found as bad param... yet another bad choice */
8972 return WERR_INVALID_PARAM
;
8975 fill_job_info_1( info_1
, &((*queue
)[i
-1]), i
, snum
, ntprinter
);
8977 *needed
+= spoolss_size_job_info_1(info_1
);
8979 if (*needed
> offered
) {
8980 result
= WERR_INSUFFICIENT_BUFFER
;
8984 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8985 result
= WERR_NOMEM
;
8989 smb_io_job_info_1("", buffer
, info_1
, 0);
8997 /****************************************************************************
8998 ****************************************************************************/
9000 static WERROR
getjob_level_2(print_queue_struct
**queue
, int count
, int snum
,
9001 NT_PRINTER_INFO_LEVEL
*ntprinter
,
9002 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
9009 DEVICEMODE
*devmode
= NULL
;
9010 NT_DEVICEMODE
*nt_devmode
= NULL
;
9012 if ( !(info_2
=SMB_MALLOC_P(JOB_INFO_2
)) )
9015 ZERO_STRUCTP(info_2
);
9017 for ( i
=0; i
<count
&& found
==False
; i
++ )
9019 if ((*queue
)[i
].job
== (int)jobid
)
9024 /* NT treats not found as bad param... yet another bad
9026 result
= WERR_INVALID_PARAM
;
9031 * if the print job does not have a DEVMODE associated with it,
9032 * just use the one for the printer. A NULL devicemode is not
9033 * a failure condition
9036 if ( !(nt_devmode
=print_job_devmode( lp_const_servicename(snum
), jobid
)) )
9037 devmode
= construct_dev_mode(lp_const_servicename(snum
));
9039 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) != NULL
) {
9040 ZERO_STRUCTP( devmode
);
9041 convert_nt_devicemode( devmode
, nt_devmode
);
9045 fill_job_info_2(info_2
, &((*queue
)[i
-1]), i
, snum
, ntprinter
, devmode
);
9047 *needed
+= spoolss_size_job_info_2(info_2
);
9049 if (*needed
> offered
) {
9050 result
= WERR_INSUFFICIENT_BUFFER
;
9054 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9055 result
= WERR_NOMEM
;
9059 smb_io_job_info_2("", buffer
, info_2
, 0);
9064 /* Cleanup allocated memory */
9066 free_job_info_2(info_2
); /* Also frees devmode */
9072 /****************************************************************************
9073 ****************************************************************************/
9075 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
9077 POLICY_HND
*handle
= &q_u
->handle
;
9078 uint32 jobid
= q_u
->jobid
;
9079 uint32 level
= q_u
->level
;
9080 RPC_BUFFER
*buffer
= NULL
;
9081 uint32 offered
= q_u
->offered
;
9082 uint32
*needed
= &r_u
->needed
;
9083 WERROR wstatus
= WERR_OK
;
9084 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
9087 print_queue_struct
*queue
= NULL
;
9088 print_status_struct prt_status
;
9090 /* that's an [in out] buffer */
9092 if (!q_u
->buffer
&& (offered
!=0)) {
9093 return WERR_INVALID_PARAM
;
9096 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9097 buffer
= r_u
->buffer
;
9099 DEBUG(5,("spoolss_getjob\n"));
9103 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9106 wstatus
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
9107 if ( !W_ERROR_IS_OK(wstatus
) )
9110 count
= print_queue_status(snum
, &queue
, &prt_status
);
9112 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9113 count
, prt_status
.status
, prt_status
.message
));
9117 wstatus
= getjob_level_1(&queue
, count
, snum
, ntprinter
, jobid
,
9118 buffer
, offered
, needed
);
9121 wstatus
= getjob_level_2(&queue
, count
, snum
, ntprinter
, jobid
,
9122 buffer
, offered
, needed
);
9125 wstatus
= WERR_UNKNOWN_LEVEL
;
9130 free_a_printer( &ntprinter
, 2 );
9135 /****************************************************************
9136 _spoolss_GetPrinterDataEx
9138 From MSDN documentation of GetPrinterDataEx: pass request
9139 to GetPrinterData if key is "PrinterDriverData".
9140 ****************************************************************/
9142 WERROR
_spoolss_GetPrinterDataEx(pipes_struct
*p
,
9143 struct spoolss_GetPrinterDataEx
*r
)
9145 POLICY_HND
*handle
= r
->in
.handle
;
9147 const char *keyname
= r
->in
.key_name
;
9148 const char *valuename
= r
->in
.value_name
;
9150 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9152 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9154 WERROR status
= WERR_OK
;
9156 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9158 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9159 keyname
, valuename
));
9161 /* in case of problem, return some default values */
9167 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9168 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9169 status
= WERR_BADFID
;
9173 /* Is the handle to a printer or to the server? */
9175 if (Printer
->printer_type
== SPLHND_SERVER
) {
9176 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9177 "Not implemented for server handles yet\n"));
9178 status
= WERR_INVALID_PARAM
;
9182 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9185 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9186 if ( !W_ERROR_IS_OK(status
) )
9189 /* check to see if the keyname is valid */
9190 if ( !strlen(keyname
) ) {
9191 status
= WERR_INVALID_PARAM
;
9195 if ( lookup_printerkey( printer
->info_2
->data
, keyname
) == -1 ) {
9196 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9197 "Invalid keyname [%s]\n", keyname
));
9198 free_a_printer( &printer
, 2 );
9199 status
= WERR_BADFILE
;
9203 /* When given a new keyname, we should just create it */
9205 status
= get_printer_dataex( p
->mem_ctx
, printer
, keyname
, valuename
,
9206 r
->out
.type
, &data
, r
->out
.needed
,
9209 if (*r
->out
.needed
> r
->in
.offered
) {
9210 status
= WERR_MORE_DATA
;
9213 if (W_ERROR_IS_OK(status
)) {
9214 memcpy(r
->out
.buffer
, data
, r
->in
.offered
);
9219 free_a_printer( &printer
, 2 );
9224 /****************************************************************
9225 _spoolss_SetPrinterDataEx
9226 ****************************************************************/
9228 WERROR
_spoolss_SetPrinterDataEx(pipes_struct
*p
,
9229 struct spoolss_SetPrinterDataEx
*r
)
9231 POLICY_HND
*handle
= r
->in
.handle
;
9232 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9234 WERROR status
= WERR_OK
;
9235 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9238 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9240 /* From MSDN documentation of SetPrinterDataEx: pass request to
9241 SetPrinterData if key is "PrinterDriverData" */
9244 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9245 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9249 if ( Printer
->printer_type
== SPLHND_SERVER
) {
9250 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9251 "Not implemented for server handles yet\n"));
9252 return WERR_INVALID_PARAM
;
9255 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9259 * Access check : NT returns "access denied" if you make a
9260 * SetPrinterData call without the necessary privildge.
9261 * we were originally returning OK if nothing changed
9262 * which made Win2k issue **a lot** of SetPrinterData
9263 * when connecting to a printer --jerry
9266 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
9268 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9269 "change denied by handle access permissions\n"));
9270 return WERR_ACCESS_DENIED
;
9273 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9274 if (!W_ERROR_IS_OK(status
))
9277 /* check for OID in valuename */
9279 if ( (oid_string
= strchr( r
->in
.value_name
, ',' )) != NULL
)
9285 /* save the registry data */
9287 status
= set_printer_dataex( printer
, r
->in
.key_name
, r
->in
.value_name
,
9288 r
->in
.type
, r
->in
.buffer
, r
->in
.offered
);
9290 if ( W_ERROR_IS_OK(status
) )
9292 /* save the OID if one was specified */
9294 char *str
= talloc_asprintf(p
->mem_ctx
, "%s\\%s",
9295 r
->in
.key_name
, SPOOL_OID_KEY
);
9301 * I'm not checking the status here on purpose. Don't know
9302 * if this is right, but I'm returning the status from the
9303 * previous set_printer_dataex() call. I have no idea if
9304 * this is right. --jerry
9307 set_printer_dataex( printer
, str
, r
->in
.value_name
,
9308 REG_SZ
, (uint8
*)oid_string
,
9309 strlen(oid_string
)+1 );
9312 status
= mod_a_printer(printer
, 2);
9315 free_a_printer(&printer
, 2);
9320 /****************************************************************
9321 _spoolss_DeletePrinterDataEx
9322 ****************************************************************/
9324 WERROR
_spoolss_DeletePrinterDataEx(pipes_struct
*p
,
9325 struct spoolss_DeletePrinterDataEx
*r
)
9327 POLICY_HND
*handle
= r
->in
.handle
;
9328 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9330 WERROR status
= WERR_OK
;
9331 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
9333 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9336 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9337 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9341 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9344 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9345 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9346 "printer properties change denied by handle\n"));
9347 return WERR_ACCESS_DENIED
;
9350 if (!r
->in
.value_name
|| !r
->in
.key_name
) {
9354 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9355 if (!W_ERROR_IS_OK(status
))
9358 status
= delete_printer_dataex( printer
, r
->in
.key_name
, r
->in
.value_name
);
9360 if ( W_ERROR_IS_OK(status
) )
9361 mod_a_printer( printer
, 2 );
9363 free_a_printer(&printer
, 2);
9368 /********************************************************************
9369 * spoolss_enumprinterkey
9370 ********************************************************************/
9373 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
9376 fstring
*keynames
= NULL
;
9377 uint16
*enumkeys
= NULL
;
9380 POLICY_HND
*handle
= &q_u
->handle
;
9381 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9382 NT_PRINTER_DATA
*data
;
9383 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9385 WERROR status
= WERR_BADFILE
;
9388 DEBUG(4,("_spoolss_enumprinterkey\n"));
9391 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9395 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9398 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9399 if (!W_ERROR_IS_OK(status
))
9402 /* get the list of subkey names */
9404 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9405 data
= printer
->info_2
->data
;
9407 num_keys
= get_printer_subkeys( data
, key
, &keynames
);
9409 if ( num_keys
== -1 ) {
9410 status
= WERR_BADFILE
;
9414 printerkey_len
= init_unistr_array( &enumkeys
, keynames
, NULL
);
9416 r_u
->needed
= printerkey_len
*2;
9418 if ( q_u
->size
< r_u
->needed
) {
9419 status
= WERR_MORE_DATA
;
9423 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, printerkey_len
, enumkeys
)) {
9424 status
= WERR_NOMEM
;
9430 if ( q_u
->size
< r_u
->needed
)
9431 status
= WERR_MORE_DATA
;
9434 free_a_printer( &printer
, 2 );
9435 SAFE_FREE( keynames
);
9440 /****************************************************************
9441 _spoolss_DeletePrinterKey
9442 ****************************************************************/
9444 WERROR
_spoolss_DeletePrinterKey(pipes_struct
*p
,
9445 struct spoolss_DeletePrinterKey
*r
)
9447 POLICY_HND
*handle
= r
->in
.handle
;
9448 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9449 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9453 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9456 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9457 OUR_HANDLE(handle
)));
9461 /* if keyname == NULL, return error */
9463 if ( !r
->in
.key_name
)
9464 return WERR_INVALID_PARAM
;
9466 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9469 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9470 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9471 "printer properties change denied by handle\n"));
9472 return WERR_ACCESS_DENIED
;
9475 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9476 if (!W_ERROR_IS_OK(status
))
9479 /* delete the key and all subneys */
9481 status
= delete_all_printer_data( printer
->info_2
, r
->in
.key_name
);
9483 if ( W_ERROR_IS_OK(status
) )
9484 status
= mod_a_printer(printer
, 2);
9486 free_a_printer( &printer
, 2 );
9492 /********************************************************************
9493 * spoolss_enumprinterdataex
9494 ********************************************************************/
9496 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
9498 POLICY_HND
*handle
= &q_u
->handle
;
9499 uint32 in_size
= q_u
->size
;
9502 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9503 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
9504 NT_PRINTER_DATA
*p_data
;
9506 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9511 REGISTRY_VALUE
*val
;
9516 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9519 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
9524 * first check for a keyname of NULL or "". Win2k seems to send
9525 * this a lot and we should send back WERR_INVALID_PARAM
9526 * no need to spend time looking up the printer in this case.
9530 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9531 if ( !strlen(key
) ) {
9532 result
= WERR_INVALID_PARAM
;
9536 /* get the printer off of disk */
9538 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
9541 ZERO_STRUCT(printer
);
9542 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9543 if (!W_ERROR_IS_OK(result
))
9546 /* now look for a match on the key name */
9548 p_data
= printer
->info_2
->data
;
9550 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9551 if ( (key_index
= lookup_printerkey( p_data
, key
)) == -1 )
9553 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
9554 result
= WERR_INVALID_PARAM
;
9561 /* allocate the memory for the array of pointers -- if necessary */
9563 num_entries
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
9566 if ( (enum_values
=TALLOC_ARRAY(p
->mem_ctx
, PRINTER_ENUM_VALUES
, num_entries
)) == NULL
)
9568 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9569 (unsigned long)num_entries
*sizeof(PRINTER_ENUM_VALUES
)));
9570 result
= WERR_NOMEM
;
9574 memset( enum_values
, 0x0, num_entries
*sizeof(PRINTER_ENUM_VALUES
) );
9578 * loop through all params and build the array to pass
9579 * back to the client
9582 for ( i
=0; i
<num_entries
; i
++ )
9584 /* lookup the registry value */
9586 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
9587 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
) ));
9591 value_name
= regval_name( val
);
9592 init_unistr( &enum_values
[i
].valuename
, value_name
);
9593 enum_values
[i
].value_len
= (strlen(value_name
)+1) * 2;
9594 enum_values
[i
].type
= regval_type( val
);
9596 data_len
= regval_size( val
);
9598 if ( !(enum_values
[i
].data
= (uint8
*)TALLOC_MEMDUP(p
->mem_ctx
, regval_data_p(val
), data_len
)) )
9600 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9602 result
= WERR_NOMEM
;
9606 enum_values
[i
].data_len
= data_len
;
9608 /* keep track of the size of the array in bytes */
9610 needed
+= spoolss_size_printer_enum_values(&enum_values
[i
]);
9613 /* housekeeping information in the reply */
9615 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9616 * the hand marshalled container size is a multiple
9617 * of 4 bytes for RPC alignment.
9621 needed
+= 4-(needed
% 4);
9624 r_u
->needed
= needed
;
9625 r_u
->returned
= num_entries
;
9627 if (needed
> in_size
) {
9628 result
= WERR_MORE_DATA
;
9632 /* copy data into the reply */
9634 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9635 response buffer size is != the offered buffer size
9637 r_u->ctr.size = r_u->needed;
9639 r_u
->ctr
.size
= in_size
;
9641 r_u
->ctr
.size_of_array
= r_u
->returned
;
9642 r_u
->ctr
.values
= enum_values
;
9646 free_a_printer(&printer
, 2);
9651 /****************************************************************************
9652 ****************************************************************************/
9654 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1
*info
, const char *name
)
9656 init_unistr(&info
->name
, name
);
9659 static WERROR
getprintprocessordirectory_level_1(UNISTR2
*name
,
9660 UNISTR2
*environment
,
9665 char *long_archi
= NULL
;
9666 PRINTPROCESSOR_DIRECTORY_1
*info
=NULL
;
9667 WERROR result
= WERR_OK
;
9668 TALLOC_CTX
*ctx
= talloc_tos();
9670 long_archi
= unistr2_to_ascii_talloc(ctx
, environment
);
9675 if (!get_short_archi(long_archi
))
9676 return WERR_INVALID_ENVIRONMENT
;
9678 if((info
=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1
)) == NULL
)
9681 fill_printprocessordirectory_1(info
, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9683 *needed
+= spoolss_size_printprocessordirectory_info_1(info
);
9685 if (*needed
> offered
) {
9686 result
= WERR_INSUFFICIENT_BUFFER
;
9690 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9691 result
= WERR_INSUFFICIENT_BUFFER
;
9695 smb_io_printprocessordirectory_1("", buffer
, info
, 0);
9703 WERROR
_spoolss_getprintprocessordirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTPROCESSORDIRECTORY
*q_u
, SPOOL_R_GETPRINTPROCESSORDIRECTORY
*r_u
)
9705 uint32 level
= q_u
->level
;
9706 RPC_BUFFER
*buffer
= NULL
;
9707 uint32 offered
= q_u
->offered
;
9708 uint32
*needed
= &r_u
->needed
;
9711 /* that's an [in out] buffer */
9713 if (!q_u
->buffer
&& (offered
!=0)) {
9714 return WERR_INVALID_PARAM
;
9717 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9718 buffer
= r_u
->buffer
;
9720 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9726 result
= getprintprocessordirectory_level_1
9727 (&q_u
->name
, &q_u
->environment
, buffer
, offered
, needed
);
9730 result
= WERR_UNKNOWN_LEVEL
;
9736 /*******************************************************************
9737 Streams the monitor UI DLL name in UNICODE
9738 *******************************************************************/
9740 static WERROR
xcvtcp_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9741 RPC_BUFFER
*out
, uint32
*needed
)
9743 const char *dllname
= "tcpmonui.dll";
9745 *needed
= (strlen(dllname
)+1) * 2;
9747 if ( rpcbuf_get_size(out
) < *needed
) {
9748 return WERR_INSUFFICIENT_BUFFER
;
9751 if ( !make_monitorui_buf( out
, dllname
) ) {
9758 /*******************************************************************
9759 Create a new TCP/IP port
9760 *******************************************************************/
9762 static WERROR
xcvtcp_addport( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9763 RPC_BUFFER
*out
, uint32
*needed
)
9765 NT_PORT_DATA_1 port1
;
9766 TALLOC_CTX
*ctx
= talloc_tos();
9767 char *device_uri
= NULL
;
9769 ZERO_STRUCT( port1
);
9771 /* convert to our internal port data structure */
9773 if ( !convert_port_data_1( &port1
, in
) ) {
9777 /* create the device URI and call the add_port_hook() */
9779 switch ( port1
.protocol
) {
9780 case PORT_PROTOCOL_DIRECT
:
9781 device_uri
= talloc_asprintf(ctx
,
9782 "socket://%s:%d/", port1
.hostaddr
, port1
.port
);
9785 case PORT_PROTOCOL_LPR
:
9786 device_uri
= talloc_asprintf(ctx
,
9787 "lpr://%s/%s", port1
.hostaddr
, port1
.queue
);
9791 return WERR_UNKNOWN_PORT
;
9798 return add_port_hook(ctx
, token
, port1
.name
, device_uri
);
9801 /*******************************************************************
9802 *******************************************************************/
9804 struct xcv_api_table xcvtcp_cmds
[] = {
9805 { "MonitorUI", xcvtcp_monitorui
},
9806 { "AddPort", xcvtcp_addport
},
9810 static WERROR
process_xcvtcp_command( NT_USER_TOKEN
*token
, const char *command
,
9811 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9816 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
9818 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
9819 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
9820 return xcvtcp_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9823 return WERR_BADFUNC
;
9826 /*******************************************************************
9827 *******************************************************************/
9828 #if 0 /* don't support management using the "Local Port" monitor */
9830 static WERROR
xcvlocal_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9831 RPC_BUFFER
*out
, uint32
*needed
)
9833 const char *dllname
= "localui.dll";
9835 *needed
= (strlen(dllname
)+1) * 2;
9837 if ( rpcbuf_get_size(out
) < *needed
) {
9838 return WERR_INSUFFICIENT_BUFFER
;
9841 if ( !make_monitorui_buf( out
, dllname
)) {
9848 /*******************************************************************
9849 *******************************************************************/
9851 struct xcv_api_table xcvlocal_cmds
[] = {
9852 { "MonitorUI", xcvlocal_monitorui
},
9856 struct xcv_api_table xcvlocal_cmds
[] = {
9863 /*******************************************************************
9864 *******************************************************************/
9866 static WERROR
process_xcvlocal_command( NT_USER_TOKEN
*token
, const char *command
,
9867 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9872 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
9874 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
9875 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
9876 return xcvlocal_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9878 return WERR_BADFUNC
;
9881 /*******************************************************************
9882 *******************************************************************/
9884 WERROR
_spoolss_xcvdataport(pipes_struct
*p
, SPOOL_Q_XCVDATAPORT
*q_u
, SPOOL_R_XCVDATAPORT
*r_u
)
9886 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9890 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u
->handle
)));
9894 /* Has to be a handle to the TCP/IP port monitor */
9896 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
9897 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
9901 /* requires administrative access to the server */
9903 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9904 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
9905 return WERR_ACCESS_DENIED
;
9908 /* Get the command name. There's numerous commands supported by the
9909 TCPMON interface. */
9911 rpcstr_pull(command
, q_u
->dataname
.buffer
, sizeof(command
),
9912 q_u
->dataname
.uni_str_len
*2, 0);
9914 /* Allocate the outgoing buffer */
9916 if (!rpcbuf_init( &r_u
->outdata
, q_u
->offered
, p
->mem_ctx
))
9919 switch ( Printer
->printer_type
) {
9920 case SPLHND_PORTMON_TCP
:
9921 return process_xcvtcp_command( p
->server_info
->ptok
, command
,
9922 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9923 case SPLHND_PORTMON_LOCAL
:
9924 return process_xcvlocal_command( p
->server_info
->ptok
, command
,
9925 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9928 return WERR_INVALID_PRINT_MONITOR
;
9931 /****************************************************************
9932 _spoolss_AddPrintProcessor
9933 ****************************************************************/
9935 WERROR
_spoolss_AddPrintProcessor(pipes_struct
*p
,
9936 struct spoolss_AddPrintProcessor
*r
)
9938 /* for now, just indicate success and ignore the add. We'll
9939 automatically set the winprint processor for printer
9940 entries later. Used to debug the LexMark Optra S 1855 PCL
9946 /****************************************************************
9947 _spoolss_EnumPrinters
9948 ****************************************************************/
9950 WERROR
_spoolss_EnumPrinters(pipes_struct
*p
,
9951 struct spoolss_EnumPrinters
*r
)
9953 p
->rng_fault_state
= true;
9954 return WERR_NOT_SUPPORTED
;
9957 /****************************************************************
9959 ****************************************************************/
9961 WERROR
_spoolss_GetJob(pipes_struct
*p
,
9962 struct spoolss_GetJob
*r
)
9964 p
->rng_fault_state
= true;
9965 return WERR_NOT_SUPPORTED
;
9968 /****************************************************************
9970 ****************************************************************/
9972 WERROR
_spoolss_EnumJobs(pipes_struct
*p
,
9973 struct spoolss_EnumJobs
*r
)
9975 p
->rng_fault_state
= true;
9976 return WERR_NOT_SUPPORTED
;
9979 /****************************************************************
9981 ****************************************************************/
9983 WERROR
_spoolss_AddPrinter(pipes_struct
*p
,
9984 struct spoolss_AddPrinter
*r
)
9986 p
->rng_fault_state
= true;
9987 return WERR_NOT_SUPPORTED
;
9990 /****************************************************************
9992 ****************************************************************/
9994 WERROR
_spoolss_SetPrinter(pipes_struct
*p
,
9995 struct spoolss_SetPrinter
*r
)
9997 p
->rng_fault_state
= true;
9998 return WERR_NOT_SUPPORTED
;
10001 /****************************************************************
10002 _spoolss_GetPrinter
10003 ****************************************************************/
10005 WERROR
_spoolss_GetPrinter(pipes_struct
*p
,
10006 struct spoolss_GetPrinter
*r
)
10008 p
->rng_fault_state
= true;
10009 return WERR_NOT_SUPPORTED
;
10012 /****************************************************************
10013 _spoolss_AddPrinterDriver
10014 ****************************************************************/
10016 WERROR
_spoolss_AddPrinterDriver(pipes_struct
*p
,
10017 struct spoolss_AddPrinterDriver
*r
)
10019 p
->rng_fault_state
= true;
10020 return WERR_NOT_SUPPORTED
;
10023 /****************************************************************
10024 _spoolss_EnumPrinterDrivers
10025 ****************************************************************/
10027 WERROR
_spoolss_EnumPrinterDrivers(pipes_struct
*p
,
10028 struct spoolss_EnumPrinterDrivers
*r
)
10030 p
->rng_fault_state
= true;
10031 return WERR_NOT_SUPPORTED
;
10034 /****************************************************************
10035 _spoolss_GetPrinterDriver
10036 ****************************************************************/
10038 WERROR
_spoolss_GetPrinterDriver(pipes_struct
*p
,
10039 struct spoolss_GetPrinterDriver
*r
)
10041 p
->rng_fault_state
= true;
10042 return WERR_NOT_SUPPORTED
;
10045 /****************************************************************
10046 _spoolss_GetPrinterDriverDirectory
10047 ****************************************************************/
10049 WERROR
_spoolss_GetPrinterDriverDirectory(pipes_struct
*p
,
10050 struct spoolss_GetPrinterDriverDirectory
*r
)
10052 p
->rng_fault_state
= true;
10053 return WERR_NOT_SUPPORTED
;
10056 /****************************************************************
10057 _spoolss_EnumPrintProcessors
10058 ****************************************************************/
10060 WERROR
_spoolss_EnumPrintProcessors(pipes_struct
*p
,
10061 struct spoolss_EnumPrintProcessors
*r
)
10063 p
->rng_fault_state
= true;
10064 return WERR_NOT_SUPPORTED
;
10067 /****************************************************************
10068 _spoolss_GetPrintProcessorDirectory
10069 ****************************************************************/
10071 WERROR
_spoolss_GetPrintProcessorDirectory(pipes_struct
*p
,
10072 struct spoolss_GetPrintProcessorDirectory
*r
)
10074 p
->rng_fault_state
= true;
10075 return WERR_NOT_SUPPORTED
;
10078 /****************************************************************
10079 _spoolss_ReadPrinter
10080 ****************************************************************/
10082 WERROR
_spoolss_ReadPrinter(pipes_struct
*p
,
10083 struct spoolss_ReadPrinter
*r
)
10085 p
->rng_fault_state
= true;
10086 return WERR_NOT_SUPPORTED
;
10089 /****************************************************************
10090 _spoolss_GetPrinterData
10091 ****************************************************************/
10093 WERROR
_spoolss_GetPrinterData(pipes_struct
*p
,
10094 struct spoolss_GetPrinterData
*r
)
10096 p
->rng_fault_state
= true;
10097 return WERR_NOT_SUPPORTED
;
10100 /****************************************************************
10101 _spoolss_SetPrinterData
10102 ****************************************************************/
10104 WERROR
_spoolss_SetPrinterData(pipes_struct
*p
,
10105 struct spoolss_SetPrinterData
*r
)
10107 p
->rng_fault_state
= true;
10108 return WERR_NOT_SUPPORTED
;
10111 /****************************************************************
10112 _spoolss_WaitForPrinterChange
10113 ****************************************************************/
10115 WERROR
_spoolss_WaitForPrinterChange(pipes_struct
*p
,
10116 struct spoolss_WaitForPrinterChange
*r
)
10118 p
->rng_fault_state
= true;
10119 return WERR_NOT_SUPPORTED
;
10122 /****************************************************************
10124 ****************************************************************/
10126 WERROR
_spoolss_EnumForms(pipes_struct
*p
,
10127 struct spoolss_EnumForms
*r
)
10129 p
->rng_fault_state
= true;
10130 return WERR_NOT_SUPPORTED
;
10133 /****************************************************************
10135 ****************************************************************/
10137 WERROR
_spoolss_EnumPorts(pipes_struct
*p
,
10138 struct spoolss_EnumPorts
*r
)
10140 p
->rng_fault_state
= true;
10141 return WERR_NOT_SUPPORTED
;
10144 /****************************************************************
10145 _spoolss_EnumMonitors
10146 ****************************************************************/
10148 WERROR
_spoolss_EnumMonitors(pipes_struct
*p
,
10149 struct spoolss_EnumMonitors
*r
)
10151 p
->rng_fault_state
= true;
10152 return WERR_NOT_SUPPORTED
;
10155 /****************************************************************
10157 ****************************************************************/
10159 WERROR
_spoolss_AddPort(pipes_struct
*p
,
10160 struct spoolss_AddPort
*r
)
10162 p
->rng_fault_state
= true;
10163 return WERR_NOT_SUPPORTED
;
10166 /****************************************************************
10167 _spoolss_ConfigurePort
10168 ****************************************************************/
10170 WERROR
_spoolss_ConfigurePort(pipes_struct
*p
,
10171 struct spoolss_ConfigurePort
*r
)
10173 p
->rng_fault_state
= true;
10174 return WERR_NOT_SUPPORTED
;
10177 /****************************************************************
10178 _spoolss_DeletePort
10179 ****************************************************************/
10181 WERROR
_spoolss_DeletePort(pipes_struct
*p
,
10182 struct spoolss_DeletePort
*r
)
10184 p
->rng_fault_state
= true;
10185 return WERR_NOT_SUPPORTED
;
10188 /****************************************************************
10189 _spoolss_CreatePrinterIC
10190 ****************************************************************/
10192 WERROR
_spoolss_CreatePrinterIC(pipes_struct
*p
,
10193 struct spoolss_CreatePrinterIC
*r
)
10195 p
->rng_fault_state
= true;
10196 return WERR_NOT_SUPPORTED
;
10199 /****************************************************************
10200 _spoolss_PlayGDIScriptOnPrinterIC
10201 ****************************************************************/
10203 WERROR
_spoolss_PlayGDIScriptOnPrinterIC(pipes_struct
*p
,
10204 struct spoolss_PlayGDIScriptOnPrinterIC
*r
)
10206 p
->rng_fault_state
= true;
10207 return WERR_NOT_SUPPORTED
;
10210 /****************************************************************
10211 _spoolss_DeletePrinterIC
10212 ****************************************************************/
10214 WERROR
_spoolss_DeletePrinterIC(pipes_struct
*p
,
10215 struct spoolss_DeletePrinterIC
*r
)
10217 p
->rng_fault_state
= true;
10218 return WERR_NOT_SUPPORTED
;
10221 /****************************************************************
10222 _spoolss_AddPrinterConnection
10223 ****************************************************************/
10225 WERROR
_spoolss_AddPrinterConnection(pipes_struct
*p
,
10226 struct spoolss_AddPrinterConnection
*r
)
10228 p
->rng_fault_state
= true;
10229 return WERR_NOT_SUPPORTED
;
10232 /****************************************************************
10233 _spoolss_DeletePrinterConnection
10234 ****************************************************************/
10236 WERROR
_spoolss_DeletePrinterConnection(pipes_struct
*p
,
10237 struct spoolss_DeletePrinterConnection
*r
)
10239 p
->rng_fault_state
= true;
10240 return WERR_NOT_SUPPORTED
;
10243 /****************************************************************
10244 _spoolss_PrinterMessageBox
10245 ****************************************************************/
10247 WERROR
_spoolss_PrinterMessageBox(pipes_struct
*p
,
10248 struct spoolss_PrinterMessageBox
*r
)
10250 p
->rng_fault_state
= true;
10251 return WERR_NOT_SUPPORTED
;
10254 /****************************************************************
10255 _spoolss_AddMonitor
10256 ****************************************************************/
10258 WERROR
_spoolss_AddMonitor(pipes_struct
*p
,
10259 struct spoolss_AddMonitor
*r
)
10261 p
->rng_fault_state
= true;
10262 return WERR_NOT_SUPPORTED
;
10265 /****************************************************************
10266 _spoolss_DeleteMonitor
10267 ****************************************************************/
10269 WERROR
_spoolss_DeleteMonitor(pipes_struct
*p
,
10270 struct spoolss_DeleteMonitor
*r
)
10272 p
->rng_fault_state
= true;
10273 return WERR_NOT_SUPPORTED
;
10276 /****************************************************************
10277 _spoolss_DeletePrintProcessor
10278 ****************************************************************/
10280 WERROR
_spoolss_DeletePrintProcessor(pipes_struct
*p
,
10281 struct spoolss_DeletePrintProcessor
*r
)
10283 p
->rng_fault_state
= true;
10284 return WERR_NOT_SUPPORTED
;
10287 /****************************************************************
10288 _spoolss_AddPrintProvidor
10289 ****************************************************************/
10291 WERROR
_spoolss_AddPrintProvidor(pipes_struct
*p
,
10292 struct spoolss_AddPrintProvidor
*r
)
10294 p
->rng_fault_state
= true;
10295 return WERR_NOT_SUPPORTED
;
10298 /****************************************************************
10299 _spoolss_DeletePrintProvidor
10300 ****************************************************************/
10302 WERROR
_spoolss_DeletePrintProvidor(pipes_struct
*p
,
10303 struct spoolss_DeletePrintProvidor
*r
)
10305 p
->rng_fault_state
= true;
10306 return WERR_NOT_SUPPORTED
;
10309 /****************************************************************
10310 _spoolss_EnumPrintProcDataTypes
10311 ****************************************************************/
10313 WERROR
_spoolss_EnumPrintProcDataTypes(pipes_struct
*p
,
10314 struct spoolss_EnumPrintProcDataTypes
*r
)
10316 p
->rng_fault_state
= true;
10317 return WERR_NOT_SUPPORTED
;
10320 /****************************************************************
10321 _spoolss_ResetPrinter
10322 ****************************************************************/
10324 WERROR
_spoolss_ResetPrinter(pipes_struct
*p
,
10325 struct spoolss_ResetPrinter
*r
)
10327 p
->rng_fault_state
= true;
10328 return WERR_NOT_SUPPORTED
;
10331 /****************************************************************
10332 _spoolss_GetPrinterDriver2
10333 ****************************************************************/
10335 WERROR
_spoolss_GetPrinterDriver2(pipes_struct
*p
,
10336 struct spoolss_GetPrinterDriver2
*r
)
10338 p
->rng_fault_state
= true;
10339 return WERR_NOT_SUPPORTED
;
10342 /****************************************************************
10343 _spoolss_FindFirstPrinterChangeNotification
10344 ****************************************************************/
10346 WERROR
_spoolss_FindFirstPrinterChangeNotification(pipes_struct
*p
,
10347 struct spoolss_FindFirstPrinterChangeNotification
*r
)
10349 p
->rng_fault_state
= true;
10350 return WERR_NOT_SUPPORTED
;
10353 /****************************************************************
10354 _spoolss_FindNextPrinterChangeNotification
10355 ****************************************************************/
10357 WERROR
_spoolss_FindNextPrinterChangeNotification(pipes_struct
*p
,
10358 struct spoolss_FindNextPrinterChangeNotification
*r
)
10360 p
->rng_fault_state
= true;
10361 return WERR_NOT_SUPPORTED
;
10364 /****************************************************************
10365 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10366 ****************************************************************/
10368 WERROR
_spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct
*p
,
10369 struct spoolss_RouterFindFirstPrinterChangeNotificationOld
*r
)
10371 p
->rng_fault_state
= true;
10372 return WERR_NOT_SUPPORTED
;
10375 /****************************************************************
10376 _spoolss_ReplyOpenPrinter
10377 ****************************************************************/
10379 WERROR
_spoolss_ReplyOpenPrinter(pipes_struct
*p
,
10380 struct spoolss_ReplyOpenPrinter
*r
)
10382 p
->rng_fault_state
= true;
10383 return WERR_NOT_SUPPORTED
;
10386 /****************************************************************
10387 _spoolss_RouterReplyPrinter
10388 ****************************************************************/
10390 WERROR
_spoolss_RouterReplyPrinter(pipes_struct
*p
,
10391 struct spoolss_RouterReplyPrinter
*r
)
10393 p
->rng_fault_state
= true;
10394 return WERR_NOT_SUPPORTED
;
10397 /****************************************************************
10398 _spoolss_ReplyClosePrinter
10399 ****************************************************************/
10401 WERROR
_spoolss_ReplyClosePrinter(pipes_struct
*p
,
10402 struct spoolss_ReplyClosePrinter
*r
)
10404 p
->rng_fault_state
= true;
10405 return WERR_NOT_SUPPORTED
;
10408 /****************************************************************
10410 ****************************************************************/
10412 WERROR
_spoolss_AddPortEx(pipes_struct
*p
,
10413 struct spoolss_AddPortEx
*r
)
10415 p
->rng_fault_state
= true;
10416 return WERR_NOT_SUPPORTED
;
10419 /****************************************************************
10420 _spoolss_RouterFindFirstPrinterChangeNotification
10421 ****************************************************************/
10423 WERROR
_spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct
*p
,
10424 struct spoolss_RouterFindFirstPrinterChangeNotification
*r
)
10426 p
->rng_fault_state
= true;
10427 return WERR_NOT_SUPPORTED
;
10430 /****************************************************************
10431 _spoolss_SpoolerInit
10432 ****************************************************************/
10434 WERROR
_spoolss_SpoolerInit(pipes_struct
*p
,
10435 struct spoolss_SpoolerInit
*r
)
10437 p
->rng_fault_state
= true;
10438 return WERR_NOT_SUPPORTED
;
10441 /****************************************************************
10442 _spoolss_ResetPrinterEx
10443 ****************************************************************/
10445 WERROR
_spoolss_ResetPrinterEx(pipes_struct
*p
,
10446 struct spoolss_ResetPrinterEx
*r
)
10448 p
->rng_fault_state
= true;
10449 return WERR_NOT_SUPPORTED
;
10452 /****************************************************************
10453 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10454 ****************************************************************/
10456 WERROR
_spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct
*p
,
10457 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx
*r
)
10459 p
->rng_fault_state
= true;
10460 return WERR_NOT_SUPPORTED
;
10463 /****************************************************************
10464 _spoolss_RouterReplyPrinterEx
10465 ****************************************************************/
10467 WERROR
_spoolss_RouterReplyPrinterEx(pipes_struct
*p
,
10468 struct spoolss_RouterReplyPrinterEx
*r
)
10470 p
->rng_fault_state
= true;
10471 return WERR_NOT_SUPPORTED
;
10474 /****************************************************************
10475 _dcesrv_spoolss_RouterRefreshPrinterChangeNotify
10476 ****************************************************************/
10478 WERROR
_spoolss_RouterRefreshPrinterChangeNotify(pipes_struct
*p
,
10479 struct spoolss_RouterRefreshPrinterChangeNotify
*r
)
10481 p
->rng_fault_state
= true;
10482 return WERR_NOT_SUPPORTED
;
10485 /****************************************************************
10487 ****************************************************************/
10489 WERROR
_spoolss_44(pipes_struct
*p
,
10490 struct spoolss_44
*r
)
10492 p
->rng_fault_state
= true;
10493 return WERR_NOT_SUPPORTED
;
10496 /****************************************************************
10497 _spoolss_AddPrinterEx
10498 ****************************************************************/
10500 WERROR
_spoolss_AddPrinterEx(pipes_struct
*p
,
10501 struct spoolss_AddPrinterEx
*r
)
10503 p
->rng_fault_state
= true;
10504 return WERR_NOT_SUPPORTED
;
10507 /****************************************************************
10509 ****************************************************************/
10511 WERROR
_spoolss_47(pipes_struct
*p
,
10512 struct spoolss_47
*r
)
10514 p
->rng_fault_state
= true;
10515 return WERR_NOT_SUPPORTED
;
10518 /****************************************************************
10519 _spoolss_EnumPrinterData
10520 ****************************************************************/
10522 WERROR
_spoolss_EnumPrinterData(pipes_struct
*p
,
10523 struct spoolss_EnumPrinterData
*r
)
10525 p
->rng_fault_state
= true;
10526 return WERR_NOT_SUPPORTED
;
10529 /****************************************************************
10531 ****************************************************************/
10533 WERROR
_spoolss_4a(pipes_struct
*p
,
10534 struct spoolss_4a
*r
)
10536 p
->rng_fault_state
= true;
10537 return WERR_NOT_SUPPORTED
;
10540 /****************************************************************
10542 ****************************************************************/
10544 WERROR
_spoolss_4b(pipes_struct
*p
,
10545 struct spoolss_4b
*r
)
10547 p
->rng_fault_state
= true;
10548 return WERR_NOT_SUPPORTED
;
10551 /****************************************************************
10553 ****************************************************************/
10555 WERROR
_spoolss_4c(pipes_struct
*p
,
10556 struct spoolss_4c
*r
)
10558 p
->rng_fault_state
= true;
10559 return WERR_NOT_SUPPORTED
;
10562 /****************************************************************
10563 _spoolss_EnumPrinterDataEx
10564 ****************************************************************/
10566 WERROR
_spoolss_EnumPrinterDataEx(pipes_struct
*p
,
10567 struct spoolss_EnumPrinterDataEx
*r
)
10569 p
->rng_fault_state
= true;
10570 return WERR_NOT_SUPPORTED
;
10573 /****************************************************************
10574 _spoolss_EnumPrinterKey
10575 ****************************************************************/
10577 WERROR
_spoolss_EnumPrinterKey(pipes_struct
*p
,
10578 struct spoolss_EnumPrinterKey
*r
)
10580 p
->rng_fault_state
= true;
10581 return WERR_NOT_SUPPORTED
;
10584 /****************************************************************
10586 ****************************************************************/
10588 WERROR
_spoolss_53(pipes_struct
*p
,
10589 struct spoolss_53
*r
)
10591 p
->rng_fault_state
= true;
10592 return WERR_NOT_SUPPORTED
;
10595 /****************************************************************
10597 ****************************************************************/
10599 WERROR
_spoolss_55(pipes_struct
*p
,
10600 struct spoolss_55
*r
)
10602 p
->rng_fault_state
= true;
10603 return WERR_NOT_SUPPORTED
;
10606 /****************************************************************
10608 ****************************************************************/
10610 WERROR
_spoolss_56(pipes_struct
*p
,
10611 struct spoolss_56
*r
)
10613 p
->rng_fault_state
= true;
10614 return WERR_NOT_SUPPORTED
;
10617 /****************************************************************
10619 ****************************************************************/
10621 WERROR
_spoolss_57(pipes_struct
*p
,
10622 struct spoolss_57
*r
)
10624 p
->rng_fault_state
= true;
10625 return WERR_NOT_SUPPORTED
;
10628 /****************************************************************
10630 ****************************************************************/
10632 WERROR
_spoolss_XcvData(pipes_struct
*p
,
10633 struct spoolss_XcvData
*r
)
10635 p
->rng_fault_state
= true;
10636 return WERR_NOT_SUPPORTED
;
10639 /****************************************************************
10640 _spoolss_AddPrinterDriverEx
10641 ****************************************************************/
10643 WERROR
_spoolss_AddPrinterDriverEx(pipes_struct
*p
,
10644 struct spoolss_AddPrinterDriverEx
*r
)
10646 p
->rng_fault_state
= true;
10647 return WERR_NOT_SUPPORTED
;
10650 /****************************************************************
10652 ****************************************************************/
10654 WERROR
_spoolss_5a(pipes_struct
*p
,
10655 struct spoolss_5a
*r
)
10657 p
->rng_fault_state
= true;
10658 return WERR_NOT_SUPPORTED
;
10661 /****************************************************************
10663 ****************************************************************/
10665 WERROR
_spoolss_5b(pipes_struct
*p
,
10666 struct spoolss_5b
*r
)
10668 p
->rng_fault_state
= true;
10669 return WERR_NOT_SUPPORTED
;
10672 /****************************************************************
10674 ****************************************************************/
10676 WERROR
_spoolss_5c(pipes_struct
*p
,
10677 struct spoolss_5c
*r
)
10679 p
->rng_fault_state
= true;
10680 return WERR_NOT_SUPPORTED
;
10683 /****************************************************************
10685 ****************************************************************/
10687 WERROR
_spoolss_5d(pipes_struct
*p
,
10688 struct spoolss_5d
*r
)
10690 p
->rng_fault_state
= true;
10691 return WERR_NOT_SUPPORTED
;
10694 /****************************************************************
10696 ****************************************************************/
10698 WERROR
_spoolss_5e(pipes_struct
*p
,
10699 struct spoolss_5e
*r
)
10701 p
->rng_fault_state
= true;
10702 return WERR_NOT_SUPPORTED
;
10705 /****************************************************************
10707 ****************************************************************/
10709 WERROR
_spoolss_5f(pipes_struct
*p
,
10710 struct spoolss_5f
*r
)
10712 p
->rng_fault_state
= true;
10713 return WERR_NOT_SUPPORTED
;