2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 * Copyright (C) Jean François Micouleau 1998-2000.
8 * Copyright (C) Jeremy Allison 2001.
9 * Copyright (C) Gerald Carter 2000-2001.
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 2 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, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27 up, all the errors returned are DOS errors, not NT status codes. */
31 extern pstring global_myname
;
33 #ifndef MAX_OPEN_PRINTER_EXS
34 #define MAX_OPEN_PRINTER_EXS 50
37 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
38 #define PRINTER_HANDLE_IS_PRINTER 0
39 #define PRINTER_HANDLE_IS_PRINTSERVER 1
48 /* structure to store the printer handles */
49 /* and a reference to what it's pointing to */
50 /* and the notify info asked about */
51 /* that's the central struct */
52 typedef struct _Printer
{
53 BOOL document_started
;
55 int jobid
; /* jobid in printing backend */
59 fstring printerservername
;
68 SPOOL_NOTIFY_OPTION
*option
;
69 POLICY_HND client_hnd
;
70 uint32 client_connected
;
78 typedef struct _counter_printer_0
{
86 static ubi_dlList counter_list
;
88 static struct cli_state cli
;
89 static uint32 smb_connections
=0;
91 #define OUR_HANDLE(hnd) ((hnd==NULL)?"NULL":(IVAL(hnd->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER"))
93 /* translate between internal status numbers and NT status numbers */
94 static int nt_printj_status(int v
)
100 return JOB_STATUS_PAUSED
;
102 return JOB_STATUS_SPOOLING
;
104 return JOB_STATUS_PRINTING
;
106 return JOB_STATUS_ERROR
;
108 return JOB_STATUS_DELETING
;
110 return JOB_STATUS_OFFLINE
;
112 return JOB_STATUS_PAPEROUT
;
114 return JOB_STATUS_PRINTED
;
116 return JOB_STATUS_DELETED
;
118 return JOB_STATUS_BLOCKED
;
119 case LPQ_USER_INTERVENTION
:
120 return JOB_STATUS_USER_INTERVENTION
;
125 static int nt_printq_status(int v
)
129 return PRINTER_STATUS_PAUSED
;
138 /****************************************************************************
139 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
140 ****************************************************************************/
142 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION
**pp
)
147 SAFE_FREE((*pp
)->ctr
.type
);
151 /***************************************************************************
152 Disconnect from the client
153 ****************************************************************************/
155 static void srv_spoolss_replycloseprinter(POLICY_HND
*handle
)
159 /* weird if the test succeds !!! */
160 if (smb_connections
==0) {
161 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
165 if(!cli_spoolss_reply_close_printer(&cli
, handle
, &status
))
166 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n"));
168 /* if it's the last connection, deconnect the IPC$ share */
169 if (smb_connections
==1) {
170 if(!spoolss_disconnect_from_client(&cli
))
173 message_deregister(MSG_PRINTER_NOTIFY
);
179 /****************************************************************************
180 Functions to free a printer entry datastruct.
181 ****************************************************************************/
183 static void free_printer_entry(void *ptr
)
185 Printer_entry
*Printer
= (Printer_entry
*)ptr
;
187 if (Printer
->notify
.client_connected
==True
)
188 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
190 Printer
->notify
.flags
=0;
191 Printer
->notify
.options
=0;
192 Printer
->notify
.localmachine
[0]='\0';
193 Printer
->notify
.printerlocal
=0;
194 free_spool_notify_option(&Printer
->notify
.option
);
195 Printer
->notify
.option
=NULL
;
196 Printer
->notify
.client_connected
=False
;
201 /****************************************************************************
202 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
203 ****************************************************************************/
205 SPOOL_NOTIFY_OPTION
*dup_spool_notify_option(SPOOL_NOTIFY_OPTION
*sp
)
207 SPOOL_NOTIFY_OPTION
*new_sp
= NULL
;
212 new_sp
= (SPOOL_NOTIFY_OPTION
*)malloc(sizeof(SPOOL_NOTIFY_OPTION
));
219 new_sp
->ctr
.type
= (SPOOL_NOTIFY_OPTION_TYPE
*)memdup(sp
->ctr
.type
, sizeof(SPOOL_NOTIFY_OPTION_TYPE
) * sp
->ctr
.count
);
221 if (!new_sp
->ctr
.type
) {
230 /****************************************************************************
231 find printer index by handle
232 ****************************************************************************/
234 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
236 Printer_entry
*find_printer
= NULL
;
238 if(!find_policy_by_hnd(p
,hnd
,(void **)&find_printer
)) {
239 DEBUG(3,("find_printer_index_by_hnd: Printer handle not found: "));
246 /****************************************************************************
247 close printer index by handle
248 ****************************************************************************/
250 static BOOL
close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
252 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
255 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
259 close_policy_hnd(p
, hnd
);
264 /****************************************************************************
265 delete a printer given a handle
266 ****************************************************************************/
267 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
269 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
272 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
276 if (del_a_printer(Printer
->dev
.handlename
) != 0) {
277 DEBUG(3,("Error deleting printer %s\n", Printer
->dev
.handlename
));
281 /* Check calling user has permission to delete printer. Note that
282 since we set the snum parameter to -1 only administrators can
283 delete the printer. This stops people with the Full Control
284 permission from deleting the printer. */
286 if (!print_access_check(NULL
, -1, PRINTER_ACCESS_ADMINISTER
)) {
287 DEBUG(3, ("printer delete denied by security descriptor\n"));
288 return WERR_ACCESS_DENIED
;
291 if (*lp_deleteprinter_cmd()) {
293 char *cmd
= lp_deleteprinter_cmd();
298 /* Printer->dev.handlename equals portname equals sharename */
299 slprintf(command
, sizeof(command
)-1, "%s \"%s\"", cmd
,
300 Printer
->dev
.handlename
);
302 DEBUG(10,("Running [%s]\n", command
));
303 ret
= smbrun(command
, NULL
);
305 return WERR_BADFID
; /* What to return here? */
307 DEBUGADD(10,("returned [%d]\n", ret
));
309 /* Send SIGHUP to process group... is there a better way? */
312 if ( ( i
= lp_servicenumber( Printer
->dev
.handlename
) ) >= 0 ) {
316 return WERR_ACCESS_DENIED
;
322 /****************************************************************************
323 return the snum of a printer corresponding to an handle
324 ****************************************************************************/
325 static BOOL
get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
)
327 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
330 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
334 switch (Printer
->printer_type
) {
335 case PRINTER_HANDLE_IS_PRINTER
:
336 DEBUG(4,("short name:%s\n", Printer
->dev
.handlename
));
337 *number
= print_queue_snum(Printer
->dev
.handlename
);
338 return (*number
!= -1);
339 case PRINTER_HANDLE_IS_PRINTSERVER
:
346 /****************************************************************************
347 set printer handle type.
348 ****************************************************************************/
349 static BOOL
set_printer_hnd_accesstype(pipes_struct
*p
, POLICY_HND
*hnd
, uint32 access_required
)
351 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
354 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd
)));
358 DEBUG(4,("Setting printer access=%x\n", access_required
));
359 Printer
->access
= access_required
;
363 /****************************************************************************
364 Set printer handle type.
365 Check if it's \\server or \\server\printer
366 ****************************************************************************/
368 static BOOL
set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
370 DEBUG(3,("Setting printer type=%s\n", handlename
));
372 if ( strlen(handlename
) < 3 ) {
373 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
377 /* it's a print server */
378 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
379 DEBUGADD(4,("Printer is a print server\n"));
380 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTSERVER
;
384 DEBUGADD(4,("Printer is a printer\n"));
385 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTER
;
391 /****************************************************************************
392 Set printer handle name.
393 ****************************************************************************/
395 static BOOL
set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
397 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
399 int n_services
=lp_numservices();
403 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename
, strlen(handlename
)));
405 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTSERVER
) {
406 ZERO_STRUCT(Printer
->dev
.printerservername
);
407 strncpy(Printer
->dev
.printerservername
, handlename
, strlen(handlename
));
411 if (Printer
->printer_type
!=PRINTER_HANDLE_IS_PRINTER
)
414 if (*handlename
=='\\') {
415 aprinter
=strchr_m(handlename
+2, '\\');
422 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter
, strlen(aprinter
)));
425 * store the Samba share name in it
426 * in back we have the long printer name
427 * need to iterate all the snum and do a
428 * get_a_printer each time to find the printer
429 * faster to do it here than later.
432 for (snum
=0;snum
<n_services
&& found
==False
;snum
++) {
435 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
438 DEBUGADD(5,("share:%s\n",lp_servicename(snum
)));
440 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
443 printername
=strchr_m(printer
->info_2
->printername
+2, '\\');
446 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
447 printer
->info_2
->printername
, aprinter
));
449 if ( strlen(printername
) != strlen(aprinter
) ) {
450 free_a_printer(&printer
, 2);
454 if ( strncasecmp(printername
, aprinter
, strlen(aprinter
))) {
455 free_a_printer(&printer
, 2);
463 * if we haven't found a printer with the given handlename
464 * then it can be a share name as you can open both \\server\printer and
469 * we still check if the printer description file exists as NT won't be happy
470 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
474 DEBUGADD(5,("Printer not found, checking for share now\n"));
476 for (snum
=0;snum
<n_services
&& found
==False
;snum
++) {
478 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
481 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum
)));
483 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
486 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
487 printer
->info_2
->printername
, aprinter
));
489 if ( strlen(lp_servicename(snum
)) != strlen(aprinter
) ) {
490 free_a_printer(&printer
, 2);
494 if ( strncasecmp(lp_servicename(snum
), aprinter
, strlen(aprinter
))) {
495 free_a_printer(&printer
, 2);
504 DEBUGADD(4,("Printer not found\n"));
509 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
510 printer
->info_2
->printername
, lp_servicename(snum
),snum
));
512 ZERO_STRUCT(Printer
->dev
.handlename
);
513 strncpy(Printer
->dev
.handlename
, lp_servicename(snum
), strlen(lp_servicename(snum
)));
515 free_a_printer(&printer
, 2);
520 /****************************************************************************
521 find first available printer slot. creates a printer handle for you.
522 ****************************************************************************/
524 static BOOL
open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
)
526 Printer_entry
*new_printer
;
528 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
530 if((new_printer
=(Printer_entry
*)malloc(sizeof(Printer_entry
))) == NULL
)
533 ZERO_STRUCTP(new_printer
);
535 new_printer
->notify
.option
=NULL
;
537 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
538 SAFE_FREE(new_printer
);
542 if (!set_printer_hnd_printertype(new_printer
, name
)) {
543 close_printer_handle(p
, hnd
);
547 if (!set_printer_hnd_name(new_printer
, name
)) {
548 close_printer_handle(p
, hnd
);
552 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
557 /********************************************************************
558 Return True is the handle is a print server.
559 ********************************************************************/
561 static BOOL
handle_is_printserver(pipes_struct
*p
, POLICY_HND
*handle
)
563 Printer_entry
*Printer
=find_printer_index_by_hnd(p
,handle
);
568 if (Printer
->printer_type
!= PRINTER_HANDLE_IS_PRINTSERVER
)
574 /****************************************************************************
575 allocate more memory for a BUFFER.
576 ****************************************************************************/
577 static BOOL
alloc_buffer_size(NEW_BUFFER
*buffer
, uint32 buffer_size
)
585 /* damn, I'm doing the reverse operation of prs_grow() :) */
586 if (buffer_size
< prs_data_size(ps
))
589 extra_space
= buffer_size
- prs_data_size(ps
);
592 * save the offset and move to the end of the buffer
593 * prs_grow() checks the extra_space against the offset
595 old_offset
=prs_offset(ps
);
596 prs_set_offset(ps
, prs_data_size(ps
));
598 if (!prs_grow(ps
, extra_space
))
601 prs_set_offset(ps
, old_offset
);
603 buffer
->string_at_end
=prs_data_size(ps
);
608 /***************************************************************************
609 receive the notify message
610 ****************************************************************************/
612 static void srv_spoolss_receive_message(int msg_type
, pid_t src
, void *buf
, size_t len
)
616 struct pipes_struct
*p
;
618 struct handle_list
*hl
;
621 fstrcpy(printer
,buf
);
624 DEBUG(0,("srv_spoolss_receive_message: got null message !\n"));
628 DEBUG(10,("srv_spoolss_receive_message: Got message about printer %s\n", printer
));
631 * We need to enumerate all printers. The handle list is shared
632 * across pipes of the same name, so just find the first open
637 for ( p
= get_first_pipe(); p
; get_next_pipe(p
)) {
638 if (strequal(p
->name
, "spoolss")) {
639 hl
= p
->pipe_handles
;
645 DEBUG(0,("srv_spoolss_receive_message: no handle list on spoolss pipe !\n"));
649 /* Iterate the printer list on this pipe. */
650 for (pol
= hl
->Policy
; pol
; pol
= pol
->next
) {
651 Printer_entry
*find_printer
= (Printer_entry
*)pol
->data_ptr
;
657 * if the entry is the given printer or if it's a printerserver
658 * we send the message
661 if (find_printer
->printer_type
==PRINTER_HANDLE_IS_PRINTER
)
662 if (strcmp(find_printer
->dev
.handlename
, printer
))
665 if (find_printer
->notify
.client_connected
==True
)
666 cli_spoolss_reply_rrpcn(&cli
, &find_printer
->notify
.client_hnd
, PRINTER_CHANGE_ALL
, 0x0, &status
);
670 /***************************************************************************
672 ****************************************************************************/
673 static BOOL
srv_spoolss_sendnotify(pipes_struct
*p
, POLICY_HND
*handle
)
677 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
680 DEBUG(0,("srv_spoolss_sendnotify: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
684 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTER
)
685 fstrcpy(printer
, Printer
->dev
.handlename
);
687 fstrcpy(printer
, "");
689 /*srv_spoolss_receive_message(printer);*/
690 DEBUG(10,("srv_spoolss_sendnotify: Sending message about printer %s\n", printer
));
692 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY
, printer
, strlen(printer
) + 1, False
); /* Null terminate... */
697 /********************************************************************
698 * spoolss_open_printer
700 * called from the spoolss dispatcher
701 ********************************************************************/
703 WERROR
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
706 WERROR result
= WERR_OK
;
709 UNISTR2
*printername
= NULL
;
710 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
711 /* uint32 user_switch = q_u->user_switch; - notused */
712 /* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
713 POLICY_HND
*handle
= &r_u
->handle
;
717 struct current_user user
;
719 if (q_u
->printername_ptr
!= 0)
720 printername
= &q_u
->printername
;
722 if (printername
== NULL
)
723 return WERR_INVALID_PRINTER_NAME
;
725 /* some sanity check because you can open a printer or a print server */
726 /* aka: \\server\printer or \\server */
727 unistr2_to_ascii(name
, printername
, sizeof(name
)-1);
729 DEBUGADD(3,("checking name: %s\n",name
));
731 if (!open_printer_hnd(p
, handle
, name
))
732 return WERR_INVALID_PRINTER_NAME
;
735 if (printer_default->datatype_ptr != NULL)
737 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
738 set_printer_hnd_datatype(handle, datatype);
741 set_printer_hnd_datatype(handle, "");
744 if (!set_printer_hnd_accesstype(p
, handle
, printer_default
->access_required
)) {
745 close_printer_handle(p
, handle
);
746 return WERR_ACCESS_DENIED
;
750 First case: the user is opening the print server:
752 Disallow MS AddPrinterWizard if parameter disables it. A Win2k
753 client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
755 Then both Win2k and WinNT clients try an OpenPrinterEx with
756 SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
757 or if the user is listed in the smb.conf printer admin parameter.
759 Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
760 client view printer folder, but does not show the MSAPW.
762 Note: this test needs code to check access rights here too. Jeremy
763 could you look at this?
766 Second case: the user is opening a printer:
767 NT doesn't let us connect to a printer if the connecting user
768 doesn't have print permission.
772 get_current_user(&user
, p
);
774 if (handle_is_printserver(p
, handle
)) {
775 if (printer_default
->access_required
== 0) {
778 else if ((printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
) == SERVER_ACCESS_ADMINISTER
) {
780 /* Printserver handles use global struct... */
783 if (!lp_ms_add_printer_wizard()) {
784 close_printer_handle(p
, handle
);
785 return WERR_ACCESS_DENIED
;
787 else if (user
.uid
== 0 || user_in_list(uidtoname(user
.uid
), lp_printer_admin(snum
))) {
791 close_printer_handle(p
, handle
);
792 return WERR_ACCESS_DENIED
;
798 /* NT doesn't let us connect to a printer if the connecting user
799 doesn't have print permission. */
801 if (!get_printer_snum(p
, handle
, &snum
))
804 /* map an empty access mask to the minimum access mask */
805 if (printer_default
->access_required
== 0x0)
806 printer_default
->access_required
= PRINTER_ACCESS_USE
;
810 * If we are not serving the printer driver for this printer,
811 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
812 * will keep NT clients happy --jerry
815 if (lp_use_client_driver(snum
)
816 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
818 printer_default
->access_required
= PRINTER_ACCESS_USE
;
821 if (!print_access_check(&user
, snum
, printer_default
->access_required
)) {
822 DEBUG(3, ("access DENIED for printer open\n"));
823 close_printer_handle(p
, handle
);
824 return WERR_ACCESS_DENIED
;
828 * If we have a default device pointer in the
829 * printer_default struct, then we need to get
830 * the printer info from the tdb and if there is
831 * no default devicemode there then we do a *SET*
832 * here ! This is insanity.... JRA.
836 * If the openprinterex rpc call contains a devmode,
837 * it's a per-user one. This per-user devmode is derivated
838 * from the global devmode. Openprinterex() contains a per-user
839 * devmode for when you do EMF printing and spooling.
840 * In the EMF case, the NT workstation is only doing half the job
841 * of rendering the page. The other half is done by running the printer
842 * driver on the server.
843 * The EMF file doesn't contain the page description (paper size, orientation, ...).
844 * The EMF file only contains what is to be printed on the page.
845 * So in order for the server to know how to print, the NT client sends
846 * a devicemode attached to the openprinterex call.
847 * But this devicemode is short lived, it's only valid for the current print job.
849 * If Samba would have supported EMF spooling, this devicemode would
850 * have been attached to the handle, to sent it to the driver to correctly
851 * rasterize the EMF file.
853 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
854 * we just act as a pass-thru between windows and the printer.
856 * In order to know that Samba supports only RAW spooling, NT has to call
857 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
858 * and until NT sends a RAW job, we refuse it.
860 * But to call getprinter() or startdoc(), you first need a valid handle,
861 * and to get an handle you have to call openprintex(). Hence why you have
862 * a devicemode in the openprinterex() call.
865 * Differences between NT4 and NT 2000.
868 * On NT4, you only have a global devicemode. This global devicemode can be changed
869 * by the administrator (or by a user with enough privs). Everytime a user
870 * wants to print, the devicemode is resetted to the default. In Word, everytime
871 * you print, the printer's characteristics are always reset to the global devicemode.
875 * In W2K, there is the notion of per-user devicemode. The first time you use
876 * a printer, a per-user devicemode is build from the global devicemode.
877 * If you change your per-user devicemode, it is saved in the registry, under the
878 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
879 * printer preferences available.
881 * To change the per-user devicemode: it's the "Printing Preferences ..." button
882 * on the General Tab of the printer properties windows.
884 * To change the global devicemode: it's the "Printing Defaults..." button
885 * on the Advanced Tab of the printer properties window.
893 if (printer_default
->devmode_cont
.devmode
!= NULL
) {
894 result
= printer_write_default_dev( snum
, printer_default
);
896 close_printer_handle(p
, handle
);
906 /****************************************************************************
907 ****************************************************************************/
908 static BOOL
convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
909 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
915 ret
= uni_2_asc_printer_info_2(uni
->info_2
, &printer
->info_2
);
924 static BOOL
convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
925 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
931 printer
->info_3
=NULL
;
932 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
936 printer
->info_6
=NULL
;
937 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
947 BOOL
convert_devicemode(char *printername
, const DEVICEMODE
*devmode
,
948 NT_DEVICEMODE
**pp_nt_devmode
)
950 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
953 * Ensure nt_devmode is a valid pointer
954 * as we will be overwriting it.
957 if (nt_devmode
== NULL
) {
958 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
959 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
963 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
964 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
966 nt_devmode
->specversion
=devmode
->specversion
;
967 nt_devmode
->driverversion
=devmode
->driverversion
;
968 nt_devmode
->size
=devmode
->size
;
969 nt_devmode
->fields
=devmode
->fields
;
970 nt_devmode
->orientation
=devmode
->orientation
;
971 nt_devmode
->papersize
=devmode
->papersize
;
972 nt_devmode
->paperlength
=devmode
->paperlength
;
973 nt_devmode
->paperwidth
=devmode
->paperwidth
;
974 nt_devmode
->scale
=devmode
->scale
;
975 nt_devmode
->copies
=devmode
->copies
;
976 nt_devmode
->defaultsource
=devmode
->defaultsource
;
977 nt_devmode
->printquality
=devmode
->printquality
;
978 nt_devmode
->color
=devmode
->color
;
979 nt_devmode
->duplex
=devmode
->duplex
;
980 nt_devmode
->yresolution
=devmode
->yresolution
;
981 nt_devmode
->ttoption
=devmode
->ttoption
;
982 nt_devmode
->collate
=devmode
->collate
;
984 nt_devmode
->logpixels
=devmode
->logpixels
;
985 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
986 nt_devmode
->pelswidth
=devmode
->pelswidth
;
987 nt_devmode
->pelsheight
=devmode
->pelsheight
;
988 nt_devmode
->displayflags
=devmode
->displayflags
;
989 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
990 nt_devmode
->icmmethod
=devmode
->icmmethod
;
991 nt_devmode
->icmintent
=devmode
->icmintent
;
992 nt_devmode
->mediatype
=devmode
->mediatype
;
993 nt_devmode
->dithertype
=devmode
->dithertype
;
994 nt_devmode
->reserved1
=devmode
->reserved1
;
995 nt_devmode
->reserved2
=devmode
->reserved2
;
996 nt_devmode
->panningwidth
=devmode
->panningwidth
;
997 nt_devmode
->panningheight
=devmode
->panningheight
;
1000 * Only change private and driverextra if the incoming devmode
1001 * has a new one. JRA.
1004 if ((devmode
->driverextra
!= 0) && (devmode
->private != NULL
)) {
1005 SAFE_FREE(nt_devmode
->private);
1006 nt_devmode
->driverextra
=devmode
->driverextra
;
1007 if((nt_devmode
->private=(uint8
*)malloc(nt_devmode
->driverextra
* sizeof(uint8
))) == NULL
)
1009 memcpy(nt_devmode
->private, devmode
->private, nt_devmode
->driverextra
);
1012 *pp_nt_devmode
= nt_devmode
;
1017 /********************************************************************
1018 * _spoolss_enddocprinter_internal.
1019 ********************************************************************/
1021 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1023 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1026 DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
1030 Printer
->document_started
=False
;
1031 print_job_end(Printer
->jobid
,True
);
1032 /* error codes unhandled so far ... */
1037 /********************************************************************
1038 * api_spoolss_closeprinter
1039 ********************************************************************/
1041 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1043 POLICY_HND
*handle
= &q_u
->handle
;
1045 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1047 if (Printer
&& Printer
->document_started
)
1048 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1050 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1052 if (!close_printer_handle(p
, handle
))
1058 /********************************************************************
1059 * api_spoolss_deleteprinter
1061 ********************************************************************/
1063 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1065 POLICY_HND
*handle
= &q_u
->handle
;
1066 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1069 if (Printer
&& Printer
->document_started
)
1070 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1072 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1074 result
= delete_printer_handle(p
, handle
);
1076 if (W_ERROR_IS_OK(result
)) {
1077 srv_spoolss_sendnotify(p
, handle
);
1083 /*******************************************************************
1084 * static function to lookup the version id corresponding to an
1085 * long architecture string
1086 ******************************************************************/
1087 static int get_version_id (char * arch
)
1090 struct table_node archi_table
[]= {
1092 {"Windows 4.0", "WIN40", 0 },
1093 {"Windows NT x86", "W32X86", 2 },
1094 {"Windows NT R4000", "W32MIPS", 2 },
1095 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1096 {"Windows NT PowerPC", "W32PPC", 2 },
1100 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1102 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1103 return (archi_table
[i
].version
);
1109 /********************************************************************
1110 * _spoolss_deleteprinterdriver
1112 * We currently delete the driver for the architecture only.
1113 * This can leave the driver for other archtectures. However,
1114 * since every printer associates a "Windows NT x86" driver name
1115 * and we cannot delete that one while it is in use, **and** since
1116 * it is impossible to assign a driver to a Samba printer without
1117 * having the "Windows NT x86" driver installed,...
1119 * ....we should not get into trouble here.
1122 ********************************************************************/
1124 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
,
1125 SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
1129 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1132 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
)-1 );
1133 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
)-1 );
1135 /* check that we have a valid driver name first */
1136 if ((version
=get_version_id(arch
)) == -1) {
1137 /* this is what NT returns */
1138 return WERR_INVALID_ENVIRONMENT
;
1142 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
1143 return WERR_UNKNOWN_PRINTER_DRIVER
;
1147 if (printer_driver_in_use(arch
, driver
))
1149 return WERR_PRINTER_DRIVER_IN_USE
;
1152 return delete_printer_driver(info
.info_3
);
1156 /********************************************************************
1157 GetPrinterData on a printer server Handle.
1158 ********************************************************************/
1159 static BOOL
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
1163 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
1165 if (!strcmp(value
, "BeepEnabled")) {
1167 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1169 SIVAL(*data
, 0, 0x01);
1174 if (!strcmp(value
, "EventLog")) {
1176 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1178 SIVAL(*data
, 0, 0x1B);
1183 if (!strcmp(value
, "NetPopup")) {
1185 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1187 SIVAL(*data
, 0, 0x01);
1192 if (!strcmp(value
, "MajorVersion")) {
1194 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1196 SIVAL(*data
, 0, 0x02);
1201 if (!strcmp(value
, "DefaultSpoolDirectory")) {
1202 pstring string
="You are using a Samba server";
1204 *needed
= 2*(strlen(string
)+1);
1205 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1207 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1209 /* it's done by hand ready to go on the wire */
1210 for (i
=0; i
<strlen(string
); i
++) {
1211 (*data
)[2*i
]=string
[i
];
1212 (*data
)[2*i
+1]='\0';
1217 if (!strcmp(value
, "Architecture")) {
1218 pstring string
="Windows NT x86";
1220 *needed
= 2*(strlen(string
)+1);
1221 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1223 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1224 for (i
=0; i
<strlen(string
); i
++) {
1225 (*data
)[2*i
]=string
[i
];
1226 (*data
)[2*i
+1]='\0';
1234 /********************************************************************
1235 GetPrinterData on a printer Handle.
1236 ********************************************************************/
1237 static BOOL
getprinterdata_printer(pipes_struct
*p
, TALLOC_CTX
*ctx
, POLICY_HND
*handle
,
1238 fstring value
, uint32
*type
,
1239 uint8
**data
, uint32
*needed
, uint32 in_size
)
1241 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1245 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1247 DEBUG(5,("getprinterdata_printer\n"));
1250 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1254 if(!get_printer_snum(p
, handle
, &snum
))
1257 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
1260 if (!get_specific_param(*printer
, 2, value
, &idata
, type
, &len
)) {
1261 free_a_printer(&printer
, 2);
1265 free_a_printer(&printer
, 2);
1267 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size
));
1270 if((*data
= (uint8
*)talloc(ctx
, in_size
*sizeof(uint8
) )) == NULL
) {
1274 memset(*data
, 0, in_size
*sizeof(uint8
));
1275 /* copy the min(in_size, len) */
1276 memcpy(*data
, idata
, (len
>in_size
)?in_size
:len
*sizeof(uint8
));
1283 DEBUG(5,("getprinterdata_printer:copy done\n"));
1290 /********************************************************************
1291 * spoolss_getprinterdata
1292 ********************************************************************/
1294 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
1296 POLICY_HND
*handle
= &q_u
->handle
;
1297 UNISTR2
*valuename
= &q_u
->valuename
;
1298 uint32 in_size
= q_u
->size
;
1299 uint32
*type
= &r_u
->type
;
1300 uint32
*out_size
= &r_u
->size
;
1301 uint8
**data
= &r_u
->data
;
1302 uint32
*needed
= &r_u
->needed
;
1306 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1309 * Reminder: when it's a string, the length is in BYTES
1310 * even if UNICODE is negociated.
1317 /* in case of problem, return some default values */
1321 DEBUG(4,("_spoolss_getprinterdata\n"));
1324 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, 4*sizeof(uint8
))) == NULL
)
1326 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1330 unistr2_to_ascii(value
, valuename
, sizeof(value
)-1);
1332 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
1333 found
=getprinterdata_printer_server(p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
1335 found
= getprinterdata_printer(p
, p
->mem_ctx
, handle
, value
, type
, data
, needed
, *out_size
);
1338 DEBUG(5, ("value not found, allocating %d\n", *out_size
));
1339 /* reply this param doesn't exist */
1341 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
)
1347 return WERR_INVALID_PARAM
;
1350 if (*needed
> *out_size
)
1351 return WERR_STATUS_MORE_ENTRIES
;
1356 /***************************************************************************
1357 connect to the client
1358 ****************************************************************************/
1359 static BOOL
srv_spoolss_replyopenprinter(char *printer
, uint32 localprinter
, uint32 type
, POLICY_HND
*handle
)
1364 * If it's the first connection, contact the client
1365 * and connect to the IPC$ share anonumously
1367 if (smb_connections
==0) {
1368 fstring unix_printer
;
1370 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
1372 if(!spoolss_connect_to_client(&cli
, unix_printer
))
1374 message_register(MSG_PRINTER_NOTIFY
, srv_spoolss_receive_message
);
1380 if(!cli_spoolss_reply_open_printer(&cli
, printer
, localprinter
, type
, &status
, handle
))
1386 /********************************************************************
1388 * ReplyFindFirstPrinterChangeNotifyEx
1390 * jfmxxxx: before replying OK: status=0
1391 * should do a rpc call to the workstation asking ReplyOpenPrinter
1392 * have to code it, later.
1394 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
1395 * called from api_spoolss_rffpcnex
1396 ********************************************************************/
1398 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
1400 POLICY_HND
*handle
= &q_u
->handle
;
1401 uint32 flags
= q_u
->flags
;
1402 uint32 options
= q_u
->options
;
1403 UNISTR2
*localmachine
= &q_u
->localmachine
;
1404 uint32 printerlocal
= q_u
->printerlocal
;
1405 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
1407 /* store the notify value in the printer struct */
1409 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1412 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1416 Printer
->notify
.flags
=flags
;
1417 Printer
->notify
.options
=options
;
1418 Printer
->notify
.printerlocal
=printerlocal
;
1420 if (Printer
->notify
.option
)
1421 free_spool_notify_option(&Printer
->notify
.option
);
1423 Printer
->notify
.option
=dup_spool_notify_option(option
);
1425 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
, sizeof(Printer
->notify
.localmachine
)-1);
1427 /* connect to the client machine and send a ReplyOpenPrinter */
1428 if(srv_spoolss_replyopenprinter(Printer
->notify
.localmachine
,
1429 Printer
->notify
.printerlocal
, 1,
1430 &Printer
->notify
.client_hnd
))
1431 Printer
->notify
.client_connected
=True
;
1436 /*******************************************************************
1437 * fill a notify_info_data with the servername
1438 ********************************************************************/
1440 static void spoolss_notify_server_name(int snum
,
1441 SPOOL_NOTIFY_INFO_DATA
*data
,
1442 print_queue_struct
*queue
,
1443 NT_PRINTER_INFO_LEVEL
*printer
,
1444 TALLOC_CTX
*mem_ctx
)
1446 pstring temp_name
, temp
;
1449 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
1451 len
= rpcstr_push(temp
, temp_name
, sizeof(temp
)-2, STR_TERMINATE
);
1453 data
->notify_data
.data
.length
= len
/ 2;
1454 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1456 if (!data
->notify_data
.data
.string
) {
1457 data
->notify_data
.data
.length
= 0;
1461 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1464 /*******************************************************************
1465 * fill a notify_info_data with the printername (not including the servername).
1466 ********************************************************************/
1467 static void spoolss_notify_printer_name(int snum
,
1468 SPOOL_NOTIFY_INFO_DATA
*data
,
1469 print_queue_struct
*queue
,
1470 NT_PRINTER_INFO_LEVEL
*printer
,
1471 TALLOC_CTX
*mem_ctx
)
1476 /* the notify name should not contain the \\server\ part */
1477 char *p
= strrchr_m(printer
->info_2
->printername
, '\\');
1480 p
= printer
->info_2
->printername
;
1485 len
= rpcstr_push(temp
, p
, sizeof(temp
)-2, STR_TERMINATE
);
1486 data
->notify_data
.data
.length
= len
/ 2;
1487 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1489 if (!data
->notify_data
.data
.string
) {
1490 data
->notify_data
.data
.length
= 0;
1494 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1497 /*******************************************************************
1498 * fill a notify_info_data with the servicename
1499 ********************************************************************/
1500 static void spoolss_notify_share_name(int snum
,
1501 SPOOL_NOTIFY_INFO_DATA
*data
,
1502 print_queue_struct
*queue
,
1503 NT_PRINTER_INFO_LEVEL
*printer
,
1504 TALLOC_CTX
*mem_ctx
)
1509 len
= rpcstr_push(temp
, lp_servicename(snum
), sizeof(temp
)-2, STR_TERMINATE
);
1511 data
->notify_data
.data
.length
= len
/ 2;
1512 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1514 if (!data
->notify_data
.data
.string
) {
1515 data
->notify_data
.data
.length
= 0;
1519 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1522 /*******************************************************************
1523 * fill a notify_info_data with the port name
1524 ********************************************************************/
1525 static void spoolss_notify_port_name(int snum
,
1526 SPOOL_NOTIFY_INFO_DATA
*data
,
1527 print_queue_struct
*queue
,
1528 NT_PRINTER_INFO_LEVEL
*printer
,
1529 TALLOC_CTX
*mem_ctx
)
1534 /* even if it's strange, that's consistant in all the code */
1536 len
= rpcstr_push(temp
, printer
->info_2
->portname
, sizeof(temp
)-2, STR_TERMINATE
);
1538 data
->notify_data
.data
.length
= len
/ 2;
1539 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1541 if (!data
->notify_data
.data
.string
) {
1542 data
->notify_data
.data
.length
= 0;
1546 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1549 /*******************************************************************
1550 * fill a notify_info_data with the printername
1551 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
1552 * but it doesn't exist, have to see what to do
1553 ********************************************************************/
1554 static void spoolss_notify_driver_name(int snum
,
1555 SPOOL_NOTIFY_INFO_DATA
*data
,
1556 print_queue_struct
*queue
,
1557 NT_PRINTER_INFO_LEVEL
*printer
,
1558 TALLOC_CTX
*mem_ctx
)
1563 len
= rpcstr_push(temp
, printer
->info_2
->drivername
, sizeof(temp
)-2, STR_TERMINATE
);
1564 data
->notify_data
.data
.length
= len
/ 2;
1565 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1567 if (!data
->notify_data
.data
.string
) {
1568 data
->notify_data
.data
.length
= 0;
1572 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1575 /*******************************************************************
1576 * fill a notify_info_data with the comment
1577 ********************************************************************/
1578 static void spoolss_notify_comment(int snum
,
1579 SPOOL_NOTIFY_INFO_DATA
*data
,
1580 print_queue_struct
*queue
,
1581 NT_PRINTER_INFO_LEVEL
*printer
,
1582 TALLOC_CTX
*mem_ctx
)
1587 if (*printer
->info_2
->comment
== '\0')
1588 len
= rpcstr_push(temp
, lp_comment(snum
), sizeof(temp
)-2, STR_TERMINATE
);
1591 len
= rpcstr_push(temp
, printer
->info_2
->comment
, sizeof(temp
)-2, STR_TERMINATE
);
1593 data
->notify_data
.data
.length
= len
/ 2;
1594 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1596 if (!data
->notify_data
.data
.string
) {
1597 data
->notify_data
.data
.length
= 0;
1601 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1604 /*******************************************************************
1605 * fill a notify_info_data with the comment
1606 * jfm:xxxx incorrect, have to create a new smb.conf option
1607 * location = "Room 1, floor 2, building 3"
1608 ********************************************************************/
1609 static void spoolss_notify_location(int snum
,
1610 SPOOL_NOTIFY_INFO_DATA
*data
,
1611 print_queue_struct
*queue
,
1612 NT_PRINTER_INFO_LEVEL
*printer
,
1613 TALLOC_CTX
*mem_ctx
)
1618 len
= rpcstr_push(temp
, printer
->info_2
->location
,sizeof(temp
)-2, STR_TERMINATE
);
1620 data
->notify_data
.data
.length
= len
/ 2;
1621 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1623 if (!data
->notify_data
.data
.string
) {
1624 data
->notify_data
.data
.length
= 0;
1628 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1631 /*******************************************************************
1632 * fill a notify_info_data with the device mode
1633 * jfm:xxxx don't to it for know but that's a real problem !!!
1634 ********************************************************************/
1635 static void spoolss_notify_devmode(int snum
,
1636 SPOOL_NOTIFY_INFO_DATA
*data
,
1637 print_queue_struct
*queue
,
1638 NT_PRINTER_INFO_LEVEL
*printer
,
1639 TALLOC_CTX
*mem_ctx
)
1643 /*******************************************************************
1644 * fill a notify_info_data with the separator file name
1645 * jfm:xxxx just return no file could add an option to smb.conf
1646 * separator file = "separator.txt"
1647 ********************************************************************/
1648 static void spoolss_notify_sepfile(int snum
,
1649 SPOOL_NOTIFY_INFO_DATA
*data
,
1650 print_queue_struct
*queue
,
1651 NT_PRINTER_INFO_LEVEL
*printer
,
1652 TALLOC_CTX
*mem_ctx
)
1657 len
= rpcstr_push(temp
, printer
->info_2
->sepfile
, sizeof(temp
)-2, STR_TERMINATE
);
1659 data
->notify_data
.data
.length
= len
/ 2;
1660 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1662 if (!data
->notify_data
.data
.string
) {
1663 data
->notify_data
.data
.length
= 0;
1667 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1670 /*******************************************************************
1671 * fill a notify_info_data with the print processor
1672 * jfm:xxxx return always winprint to indicate we don't do anything to it
1673 ********************************************************************/
1674 static void spoolss_notify_print_processor(int snum
,
1675 SPOOL_NOTIFY_INFO_DATA
*data
,
1676 print_queue_struct
*queue
,
1677 NT_PRINTER_INFO_LEVEL
*printer
,
1678 TALLOC_CTX
*mem_ctx
)
1683 len
= rpcstr_push(temp
, printer
->info_2
->printprocessor
, sizeof(temp
)-2, STR_TERMINATE
);
1685 data
->notify_data
.data
.length
= len
/ 2;
1686 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1688 if (!data
->notify_data
.data
.string
) {
1689 data
->notify_data
.data
.length
= 0;
1693 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1696 /*******************************************************************
1697 * fill a notify_info_data with the print processor options
1698 * jfm:xxxx send an empty string
1699 ********************************************************************/
1700 static void spoolss_notify_parameters(int snum
,
1701 SPOOL_NOTIFY_INFO_DATA
*data
,
1702 print_queue_struct
*queue
,
1703 NT_PRINTER_INFO_LEVEL
*printer
,
1704 TALLOC_CTX
*mem_ctx
)
1709 len
= rpcstr_push(temp
, printer
->info_2
->parameters
, sizeof(temp
)-2, STR_TERMINATE
);
1711 data
->notify_data
.data
.length
= len
/ 2;
1712 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1714 if (!data
->notify_data
.data
.string
) {
1715 data
->notify_data
.data
.length
= 0;
1719 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1722 /*******************************************************************
1723 * fill a notify_info_data with the data type
1724 * jfm:xxxx always send RAW as data type
1725 ********************************************************************/
1726 static void spoolss_notify_datatype(int snum
,
1727 SPOOL_NOTIFY_INFO_DATA
*data
,
1728 print_queue_struct
*queue
,
1729 NT_PRINTER_INFO_LEVEL
*printer
,
1730 TALLOC_CTX
*mem_ctx
)
1735 len
= rpcstr_push(temp
, printer
->info_2
->datatype
, sizeof(pstring
)-2, STR_TERMINATE
);
1737 data
->notify_data
.data
.length
= len
/ 2;
1738 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1740 if (!data
->notify_data
.data
.string
) {
1741 data
->notify_data
.data
.length
= 0;
1745 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1748 /*******************************************************************
1749 * fill a notify_info_data with the security descriptor
1750 * jfm:xxxx send an null pointer to say no security desc
1751 * have to implement security before !
1752 ********************************************************************/
1753 static void spoolss_notify_security_desc(int snum
,
1754 SPOOL_NOTIFY_INFO_DATA
*data
,
1755 print_queue_struct
*queue
,
1756 NT_PRINTER_INFO_LEVEL
*printer
,
1757 TALLOC_CTX
*mem_ctx
)
1759 data
->notify_data
.data
.length
=0;
1760 data
->notify_data
.data
.string
= NULL
;
1763 /*******************************************************************
1764 * fill a notify_info_data with the attributes
1765 * jfm:xxxx a samba printer is always shared
1766 ********************************************************************/
1767 static void spoolss_notify_attributes(int snum
,
1768 SPOOL_NOTIFY_INFO_DATA
*data
,
1769 print_queue_struct
*queue
,
1770 NT_PRINTER_INFO_LEVEL
*printer
,
1771 TALLOC_CTX
*mem_ctx
)
1773 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
1774 data
->notify_data
.value
[1] = 0;
1777 /*******************************************************************
1778 * fill a notify_info_data with the priority
1779 ********************************************************************/
1780 static void spoolss_notify_priority(int snum
,
1781 SPOOL_NOTIFY_INFO_DATA
*data
,
1782 print_queue_struct
*queue
,
1783 NT_PRINTER_INFO_LEVEL
*printer
,
1784 TALLOC_CTX
*mem_ctx
)
1786 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
1787 data
->notify_data
.value
[1] = 0;
1790 /*******************************************************************
1791 * fill a notify_info_data with the default priority
1792 ********************************************************************/
1793 static void spoolss_notify_default_priority(int snum
,
1794 SPOOL_NOTIFY_INFO_DATA
*data
,
1795 print_queue_struct
*queue
,
1796 NT_PRINTER_INFO_LEVEL
*printer
,
1797 TALLOC_CTX
*mem_ctx
)
1799 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
1800 data
->notify_data
.value
[1] = 0;
1803 /*******************************************************************
1804 * fill a notify_info_data with the start time
1805 ********************************************************************/
1806 static void spoolss_notify_start_time(int snum
,
1807 SPOOL_NOTIFY_INFO_DATA
*data
,
1808 print_queue_struct
*queue
,
1809 NT_PRINTER_INFO_LEVEL
*printer
,
1810 TALLOC_CTX
*mem_ctx
)
1812 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
1813 data
->notify_data
.value
[1] = 0;
1816 /*******************************************************************
1817 * fill a notify_info_data with the until time
1818 ********************************************************************/
1819 static void spoolss_notify_until_time(int snum
,
1820 SPOOL_NOTIFY_INFO_DATA
*data
,
1821 print_queue_struct
*queue
,
1822 NT_PRINTER_INFO_LEVEL
*printer
,
1823 TALLOC_CTX
*mem_ctx
)
1825 data
->notify_data
.value
[0] = printer
->info_2
->untiltime
;
1826 data
->notify_data
.value
[1] = 0;
1829 /*******************************************************************
1830 * fill a notify_info_data with the status
1831 ********************************************************************/
1832 static void spoolss_notify_status(int snum
,
1833 SPOOL_NOTIFY_INFO_DATA
*data
,
1834 print_queue_struct
*queue
,
1835 NT_PRINTER_INFO_LEVEL
*printer
,
1836 TALLOC_CTX
*mem_ctx
)
1838 print_status_struct status
;
1840 memset(&status
, 0, sizeof(status
));
1841 print_queue_length(snum
, &status
);
1842 data
->notify_data
.value
[0]=(uint32
) status
.status
;
1843 data
->notify_data
.value
[1] = 0;
1846 /*******************************************************************
1847 * fill a notify_info_data with the number of jobs queued
1848 ********************************************************************/
1849 static void spoolss_notify_cjobs(int snum
,
1850 SPOOL_NOTIFY_INFO_DATA
*data
,
1851 print_queue_struct
*queue
,
1852 NT_PRINTER_INFO_LEVEL
*printer
,
1853 TALLOC_CTX
*mem_ctx
)
1855 data
->notify_data
.value
[0] = print_queue_length(snum
, NULL
);
1856 data
->notify_data
.value
[1] = 0;
1859 /*******************************************************************
1860 * fill a notify_info_data with the average ppm
1861 ********************************************************************/
1862 static void spoolss_notify_average_ppm(int snum
,
1863 SPOOL_NOTIFY_INFO_DATA
*data
,
1864 print_queue_struct
*queue
,
1865 NT_PRINTER_INFO_LEVEL
*printer
,
1866 TALLOC_CTX
*mem_ctx
)
1868 /* always respond 8 pages per minutes */
1869 /* a little hard ! */
1870 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
1871 data
->notify_data
.value
[1] = 0;
1874 /*******************************************************************
1875 * fill a notify_info_data with username
1876 ********************************************************************/
1877 static void spoolss_notify_username(int snum
,
1878 SPOOL_NOTIFY_INFO_DATA
*data
,
1879 print_queue_struct
*queue
,
1880 NT_PRINTER_INFO_LEVEL
*printer
,
1881 TALLOC_CTX
*mem_ctx
)
1886 len
= rpcstr_push(temp
, queue
->user
, sizeof(temp
)-2, STR_TERMINATE
);
1889 data
->notify_data
.data
.length
= len
/ 2;
1890 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1892 if (!data
->notify_data
.data
.string
) {
1893 data
->notify_data
.data
.length
= 0;
1897 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1900 /*******************************************************************
1901 * fill a notify_info_data with job status
1902 ********************************************************************/
1903 static void spoolss_notify_job_status(int snum
,
1904 SPOOL_NOTIFY_INFO_DATA
*data
,
1905 print_queue_struct
*queue
,
1906 NT_PRINTER_INFO_LEVEL
*printer
,
1907 TALLOC_CTX
*mem_ctx
)
1909 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
1910 data
->notify_data
.value
[1] = 0;
1913 /*******************************************************************
1914 * fill a notify_info_data with job name
1915 ********************************************************************/
1916 static void spoolss_notify_job_name(int snum
,
1917 SPOOL_NOTIFY_INFO_DATA
*data
,
1918 print_queue_struct
*queue
,
1919 NT_PRINTER_INFO_LEVEL
*printer
,
1920 TALLOC_CTX
*mem_ctx
)
1925 len
= rpcstr_push(temp
, queue
->file
, sizeof(temp
)-2, STR_TERMINATE
);
1927 data
->notify_data
.data
.length
= len
/ 2;
1928 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1930 if (!data
->notify_data
.data
.string
) {
1931 data
->notify_data
.data
.length
= 0;
1935 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1938 /*******************************************************************
1939 * fill a notify_info_data with job status
1940 ********************************************************************/
1941 static void spoolss_notify_job_status_string(int snum
,
1942 SPOOL_NOTIFY_INFO_DATA
*data
,
1943 print_queue_struct
*queue
,
1944 NT_PRINTER_INFO_LEVEL
*printer
,
1945 TALLOC_CTX
*mem_ctx
)
1948 * Now we're returning job status codes we just return a "" here. JRA.
1955 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
1958 switch (queue
->status
) {
1963 p
= ""; /* NT provides the paused string */
1972 #endif /* NO LONGER NEEDED. */
1974 len
= rpcstr_push(temp
, p
, sizeof(temp
) - 2, STR_TERMINATE
);
1976 data
->notify_data
.data
.length
= len
/ 2;
1977 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1979 if (!data
->notify_data
.data
.string
) {
1980 data
->notify_data
.data
.length
= 0;
1984 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1987 /*******************************************************************
1988 * fill a notify_info_data with job time
1989 ********************************************************************/
1990 static void spoolss_notify_job_time(int snum
,
1991 SPOOL_NOTIFY_INFO_DATA
*data
,
1992 print_queue_struct
*queue
,
1993 NT_PRINTER_INFO_LEVEL
*printer
,
1994 TALLOC_CTX
*mem_ctx
)
1996 data
->notify_data
.value
[0]=0x0;
1997 data
->notify_data
.value
[1]=0;
2000 /*******************************************************************
2001 * fill a notify_info_data with job size
2002 ********************************************************************/
2003 static void spoolss_notify_job_size(int snum
,
2004 SPOOL_NOTIFY_INFO_DATA
*data
,
2005 print_queue_struct
*queue
,
2006 NT_PRINTER_INFO_LEVEL
*printer
,
2007 TALLOC_CTX
*mem_ctx
)
2009 data
->notify_data
.value
[0]=queue
->size
;
2010 data
->notify_data
.value
[1]=0;
2013 /*******************************************************************
2014 * fill a notify_info_data with job position
2015 ********************************************************************/
2016 static void spoolss_notify_job_position(int snum
,
2017 SPOOL_NOTIFY_INFO_DATA
*data
,
2018 print_queue_struct
*queue
,
2019 NT_PRINTER_INFO_LEVEL
*printer
,
2020 TALLOC_CTX
*mem_ctx
)
2022 data
->notify_data
.value
[0]=queue
->job
;
2023 data
->notify_data
.value
[1]=0;
2026 /*******************************************************************
2027 * fill a notify_info_data with submitted time
2028 ********************************************************************/
2029 static void spoolss_notify_submitted_time(int snum
,
2030 SPOOL_NOTIFY_INFO_DATA
*data
,
2031 print_queue_struct
*queue
,
2032 NT_PRINTER_INFO_LEVEL
*printer
,
2033 TALLOC_CTX
*mem_ctx
)
2039 t
=gmtime(&queue
->time
);
2041 len
= sizeof(SYSTEMTIME
);
2043 data
->notify_data
.data
.length
= len
;
2044 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2046 if (!data
->notify_data
.data
.string
) {
2047 data
->notify_data
.data
.length
= 0;
2051 make_systemtime(&st
, t
);
2052 memcpy(data
->notify_data
.data
.string
,&st
,len
);
2057 struct s_notify_info_data_table
2063 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
2064 print_queue_struct
*queue
,
2065 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
2068 struct s_notify_info_data_table notify_info_data_table
[] =
2070 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", POINTER
, spoolss_notify_server_name
},
2071 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2072 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", POINTER
, spoolss_notify_share_name
},
2073 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2074 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2075 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", POINTER
, spoolss_notify_comment
},
2076 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", POINTER
, spoolss_notify_location
},
2077 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2078 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", POINTER
, spoolss_notify_sepfile
},
2079 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2080 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2081 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2082 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, spoolss_notify_security_desc
},
2083 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE
, spoolss_notify_attributes
},
2084 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2085 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE
, spoolss_notify_default_priority
},
2086 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2087 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2088 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_status
},
2089 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", POINTER
, NULL
},
2090 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", ONE_VALUE
, spoolss_notify_cjobs
},
2091 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE
, spoolss_notify_average_ppm
},
2092 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER
, NULL
},
2093 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER
, NULL
},
2094 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER
, NULL
},
2095 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER
, NULL
},
2096 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2097 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", POINTER
, spoolss_notify_server_name
},
2098 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2099 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", POINTER
, spoolss_notify_username
},
2100 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", POINTER
, spoolss_notify_username
},
2101 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2102 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2103 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2104 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2105 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2106 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_job_status
},
2107 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", POINTER
, spoolss_notify_job_status_string
},
2108 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, NULL
},
2109 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", POINTER
, spoolss_notify_job_name
},
2110 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2111 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", ONE_VALUE
, spoolss_notify_job_position
},
2112 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", POINTER
, spoolss_notify_submitted_time
},
2113 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2114 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2115 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", ONE_VALUE
, spoolss_notify_job_time
},
2116 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE
, NULL
},
2117 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE
, NULL
},
2118 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE
, spoolss_notify_job_size
},
2119 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_BYTES_PRINTED
, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE
, NULL
},
2120 { END
, END
, "", END
, NULL
}
2123 /*******************************************************************
2124 return the size of info_data structure
2125 ********************************************************************/
2126 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
2130 while (notify_info_data_table
[i
].type
!= END
)
2132 if ( (notify_info_data_table
[i
].type
== type
) &&
2133 (notify_info_data_table
[i
].field
== field
) )
2135 return (notify_info_data_table
[i
].size
);
2142 /*******************************************************************
2143 return the type of notify_info_data
2144 ********************************************************************/
2145 static BOOL
type_of_notify_info_data(uint16 type
, uint16 field
)
2149 while (notify_info_data_table
[i
].type
!= END
)
2151 if ( (notify_info_data_table
[i
].type
== type
) &&
2152 (notify_info_data_table
[i
].field
== field
) )
2154 if (notify_info_data_table
[i
].size
== POINTER
)
2168 /****************************************************************************
2169 ****************************************************************************/
2170 static int search_notify(uint16 type
, uint16 field
, int *value
)
2175 for (j
=0, found
=False
; found
==False
&& notify_info_data_table
[j
].type
!= END
; j
++)
2177 if ( (notify_info_data_table
[j
].type
== type
) &&
2178 (notify_info_data_table
[j
].field
== field
) )
2183 if ( found
&& (notify_info_data_table
[j
].fn
!= NULL
) )
2189 /****************************************************************************
2190 ****************************************************************************/
2191 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
2193 info_data
->type
= type
;
2194 info_data
->field
= field
;
2195 info_data
->reserved
= 0;
2197 info_data
->size
= size_of_notify_info_data(type
, field
);
2198 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
2202 /*******************************************************************
2204 * fill a notify_info struct with info asked
2206 ********************************************************************/
2207 static BOOL
construct_notify_printer_info(SPOOL_NOTIFY_INFO
*info
, int
2208 snum
, SPOOL_NOTIFY_OPTION_TYPE
2209 *option_type
, uint32 id
,
2210 TALLOC_CTX
*mem_ctx
)
2216 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
2217 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2218 print_queue_struct
*queue
=NULL
;
2220 type
=option_type
->type
;
2222 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
2223 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2224 option_type
->count
, lp_servicename(snum
)));
2226 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2229 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2230 field
= option_type
->fields
[field_num
];
2231 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
2233 if (!search_notify(type
, field
, &j
) )
2236 if((tid
=(SPOOL_NOTIFY_INFO_DATA
*)Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2237 DEBUG(0,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
2240 else info
->data
= tid
;
2242 current_data
=&info
->data
[info
->count
];
2244 construct_info_data(current_data
, type
, field
, id
);
2246 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
2247 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
2249 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2255 free_a_printer(&printer
, 2);
2259 /*******************************************************************
2261 * fill a notify_info struct with info asked
2263 ********************************************************************/
2264 static BOOL
construct_notify_jobs_info(print_queue_struct
*queue
,
2265 SPOOL_NOTIFY_INFO
*info
,
2266 NT_PRINTER_INFO_LEVEL
*printer
,
2267 int snum
, SPOOL_NOTIFY_OPTION_TYPE
2268 *option_type
, uint32 id
,
2269 TALLOC_CTX
*mem_ctx
)
2275 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
2277 DEBUG(4,("construct_notify_jobs_info\n"));
2279 type
= option_type
->type
;
2281 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
2282 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2283 option_type
->count
));
2285 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2286 field
= option_type
->fields
[field_num
];
2288 if (!search_notify(type
, field
, &j
) )
2291 if((tid
=Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2292 DEBUG(0,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
2295 else info
->data
= tid
;
2297 current_data
=&(info
->data
[info
->count
]);
2299 construct_info_data(current_data
, type
, field
, id
);
2300 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2309 * JFM: The enumeration is not that simple, it's even non obvious.
2311 * let's take an example: I want to monitor the PRINTER SERVER for
2312 * the printer's name and the number of jobs currently queued.
2313 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
2314 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
2316 * I have 3 printers on the back of my server.
2318 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
2321 * 1 printer 1 name 1
2322 * 2 printer 1 cjob 1
2323 * 3 printer 2 name 2
2324 * 4 printer 2 cjob 2
2325 * 5 printer 3 name 3
2326 * 6 printer 3 name 3
2328 * that's the print server case, the printer case is even worse.
2331 /*******************************************************************
2333 * enumerate all printers on the printserver
2334 * fill a notify_info struct with info asked
2336 ********************************************************************/
2338 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
2339 SPOOL_NOTIFY_INFO
*info
,
2340 TALLOC_CTX
*mem_ctx
)
2343 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2344 int n_services
=lp_numservices();
2347 SPOOL_NOTIFY_OPTION
*option
;
2348 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2350 DEBUG(4,("printserver_notify_info\n"));
2352 option
=Printer
->notify
.option
;
2358 for (i
=0; i
<option
->count
; i
++) {
2359 option_type
=&(option
->ctr
.type
[i
]);
2361 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
2364 for (snum
=0; snum
<n_services
; snum
++)
2365 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
2366 if (construct_notify_printer_info
2367 (info
, snum
, option_type
, id
, mem_ctx
))
2372 * Debugging information, don't delete.
2375 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2376 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2377 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2379 for (i=0; i<info->count; i++) {
2380 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2381 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2382 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2389 /*******************************************************************
2391 * fill a notify_info struct with info asked
2393 ********************************************************************/
2394 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
2395 TALLOC_CTX
*mem_ctx
)
2398 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2401 SPOOL_NOTIFY_OPTION
*option
;
2402 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2404 print_queue_struct
*queue
=NULL
;
2405 print_status_struct status
;
2407 DEBUG(4,("printer_notify_info\n"));
2409 option
=Printer
->notify
.option
;
2415 get_printer_snum(p
, hnd
, &snum
);
2417 for (i
=0; i
<option
->count
; i
++) {
2418 option_type
=&option
->ctr
.type
[i
];
2420 switch ( option_type
->type
) {
2421 case PRINTER_NOTIFY_TYPE
:
2422 if(construct_notify_printer_info(info
, snum
,
2428 case JOB_NOTIFY_TYPE
: {
2429 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2431 memset(&status
, 0, sizeof(status
));
2432 count
= print_queue_status(snum
, &queue
, &status
);
2434 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2,
2435 lp_servicename(snum
))))
2438 for (j
=0; j
<count
; j
++) {
2439 construct_notify_jobs_info(&queue
[j
], info
,
2446 free_a_printer(&printer
, 2);
2456 * Debugging information, don't delete.
2459 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2460 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2461 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2463 for (i=0; i<info->count; i++) {
2464 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2465 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2466 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2472 /********************************************************************
2474 ********************************************************************/
2476 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
2478 POLICY_HND
*handle
= &q_u
->handle
;
2479 /* uint32 change = q_u->change; - notused. */
2480 /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
2481 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
2483 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2484 WERROR result
= WERR_BADFID
;
2486 /* we always have a NOTIFY_INFO struct */
2490 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",
2491 OUR_HANDLE(handle
)));
2495 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
2497 /* jfm: the change value isn't used right now.
2498 * we will honour it when
2499 * a) we'll be able to send notification to the client
2500 * b) we'll have a way to communicate between the spoolss process.
2502 * same thing for option->flags
2503 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2504 * I don't have a global notification system, I'm sending back all the
2505 * informations even when _NOTHING_ has changed.
2508 /* just ignore the SPOOL_NOTIFY_OPTION */
2510 switch (Printer
->printer_type
) {
2511 case PRINTER_HANDLE_IS_PRINTSERVER
:
2512 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
2515 case PRINTER_HANDLE_IS_PRINTER
:
2516 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
2524 /********************************************************************
2525 * construct_printer_info_0
2526 * fill a printer_info_0 struct
2527 ********************************************************************/
2528 static BOOL
construct_printer_info_0(PRINTER_INFO_0
*printer
, int snum
)
2532 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2533 counter_printer_0
*session_counter
;
2534 uint32 global_counter
;
2538 print_queue_struct
*queue
=NULL
;
2539 print_status_struct status
;
2541 memset(&status
, 0, sizeof(status
));
2543 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2546 count
= print_queue_status(snum
, &queue
, &status
);
2548 /* check if we already have a counter for this printer */
2549 session_counter
= (counter_printer_0
*)ubi_dlFirst(&counter_list
);
2551 for(; session_counter
; session_counter
= (counter_printer_0
*)ubi_dlNext(session_counter
)) {
2552 if (session_counter
->snum
== snum
)
2556 /* it's the first time, add it to the list */
2557 if (session_counter
==NULL
) {
2558 if((session_counter
=(counter_printer_0
*)malloc(sizeof(counter_printer_0
))) == NULL
) {
2559 free_a_printer(&ntprinter
, 2);
2562 ZERO_STRUCTP(session_counter
);
2563 session_counter
->snum
=snum
;
2564 session_counter
->counter
=0;
2565 ubi_dlAddHead( &counter_list
, (ubi_dlNode
*)session_counter
);
2569 session_counter
->counter
++;
2572 * the global_counter should be stored in a TDB as it's common to all the clients
2573 * and should be zeroed on samba startup
2575 global_counter
=session_counter
->counter
;
2577 pstrcpy(chaine
,ntprinter
->info_2
->printername
);
2579 init_unistr(&printer
->printername
, chaine
);
2581 slprintf(chaine
,sizeof(chaine
)-1,"\\\\%s", global_myname
);
2582 init_unistr(&printer
->servername
, chaine
);
2584 printer
->cjobs
= count
;
2585 printer
->total_jobs
= 0;
2586 printer
->total_bytes
= 0;
2588 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
2589 t
=gmtime(&setuptime
);
2591 printer
->year
= t
->tm_year
+1900;
2592 printer
->month
= t
->tm_mon
+1;
2593 printer
->dayofweek
= t
->tm_wday
;
2594 printer
->day
= t
->tm_mday
;
2595 printer
->hour
= t
->tm_hour
;
2596 printer
->minute
= t
->tm_min
;
2597 printer
->second
= t
->tm_sec
;
2598 printer
->milliseconds
= 0;
2600 printer
->global_counter
= global_counter
;
2601 printer
->total_pages
= 0;
2602 printer
->major_version
= 0x0004; /* NT 4 */
2603 printer
->build_version
= 0x0565; /* build 1381 */
2604 printer
->unknown7
= 0x1;
2605 printer
->unknown8
= 0x0;
2606 printer
->unknown9
= 0x0;
2607 printer
->session_counter
= session_counter
->counter
;
2608 printer
->unknown11
= 0x0;
2609 printer
->printer_errors
= 0x0; /* number of print failure */
2610 printer
->unknown13
= 0x0;
2611 printer
->unknown14
= 0x1;
2612 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
2613 printer
->unknown16
= 0x0;
2614 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
2615 printer
->unknown18
= 0x0;
2616 printer
->status
= nt_printq_status(status
.status
);
2617 printer
->unknown20
= 0x0;
2618 printer
->c_setprinter
= ntprinter
->info_2
->c_setprinter
; /* how many times setprinter has been called */
2619 printer
->unknown22
= 0x0;
2620 printer
->unknown23
= 0x6; /* 6 ???*/
2621 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
2622 printer
->unknown25
= 0;
2623 printer
->unknown26
= 0;
2624 printer
->unknown27
= 0;
2625 printer
->unknown28
= 0;
2626 printer
->unknown29
= 0;
2629 free_a_printer(&ntprinter
,2);
2633 /********************************************************************
2634 * construct_printer_info_1
2635 * fill a printer_info_1 struct
2636 ********************************************************************/
2637 static BOOL
construct_printer_info_1(uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
2641 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2643 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2646 printer
->flags
=flags
;
2648 if (*ntprinter
->info_2
->comment
== '\0') {
2649 init_unistr(&printer
->comment
, lp_comment(snum
));
2650 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",global_myname
, ntprinter
->info_2
->printername
,
2651 ntprinter
->info_2
->drivername
, lp_comment(snum
));
2654 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2655 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",global_myname
, ntprinter
->info_2
->printername
,
2656 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
2659 slprintf(chaine2
,sizeof(chaine
)-1,"%s", ntprinter
->info_2
->printername
);
2661 init_unistr(&printer
->description
, chaine
);
2662 init_unistr(&printer
->name
, chaine2
);
2664 free_a_printer(&ntprinter
,2);
2669 /****************************************************************************
2670 Free a DEVMODE struct.
2671 ****************************************************************************/
2673 static void free_dev_mode(DEVICEMODE
*dev
)
2678 SAFE_FREE(dev
->private);
2682 /****************************************************************************
2683 Create a DEVMODE struct. Returns malloced memory.
2684 ****************************************************************************/
2686 static DEVICEMODE
*construct_dev_mode(int snum
)
2690 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2691 NT_DEVICEMODE
*ntdevmode
= NULL
;
2692 DEVICEMODE
*devmode
= NULL
;
2694 DEBUG(7,("construct_dev_mode\n"));
2696 DEBUGADD(8,("getting printer characteristics\n"));
2698 if ((devmode
= (DEVICEMODE
*)malloc(sizeof(DEVICEMODE
))) == NULL
) {
2699 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
2703 ZERO_STRUCTP(devmode
);
2705 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2708 if (printer
->info_2
->devmode
)
2709 ntdevmode
= dup_nt_devicemode(printer
->info_2
->devmode
);
2711 if (ntdevmode
== NULL
)
2714 DEBUGADD(8,("loading DEVICEMODE\n"));
2716 slprintf(adevice
, sizeof(adevice
)-1, printer
->info_2
->printername
);
2717 init_unistr(&devmode
->devicename
, adevice
);
2719 slprintf(aform
, sizeof(aform
)-1, ntdevmode
->formname
);
2720 init_unistr(&devmode
->formname
, aform
);
2722 devmode
->specversion
= ntdevmode
->specversion
;
2723 devmode
->driverversion
= ntdevmode
->driverversion
;
2724 devmode
->size
= ntdevmode
->size
;
2725 devmode
->driverextra
= ntdevmode
->driverextra
;
2726 devmode
->fields
= ntdevmode
->fields
;
2728 devmode
->orientation
= ntdevmode
->orientation
;
2729 devmode
->papersize
= ntdevmode
->papersize
;
2730 devmode
->paperlength
= ntdevmode
->paperlength
;
2731 devmode
->paperwidth
= ntdevmode
->paperwidth
;
2732 devmode
->scale
= ntdevmode
->scale
;
2733 devmode
->copies
= ntdevmode
->copies
;
2734 devmode
->defaultsource
= ntdevmode
->defaultsource
;
2735 devmode
->printquality
= ntdevmode
->printquality
;
2736 devmode
->color
= ntdevmode
->color
;
2737 devmode
->duplex
= ntdevmode
->duplex
;
2738 devmode
->yresolution
= ntdevmode
->yresolution
;
2739 devmode
->ttoption
= ntdevmode
->ttoption
;
2740 devmode
->collate
= ntdevmode
->collate
;
2741 devmode
->icmmethod
= ntdevmode
->icmmethod
;
2742 devmode
->icmintent
= ntdevmode
->icmintent
;
2743 devmode
->mediatype
= ntdevmode
->mediatype
;
2744 devmode
->dithertype
= ntdevmode
->dithertype
;
2746 if (ntdevmode
->private != NULL
) {
2747 if ((devmode
->private=(uint8
*)memdup(ntdevmode
->private, ntdevmode
->driverextra
)) == NULL
)
2751 free_nt_devicemode(&ntdevmode
);
2752 free_a_printer(&printer
,2);
2759 free_nt_devicemode(&ntdevmode
);
2761 free_a_printer(&printer
,2);
2762 free_dev_mode(devmode
);
2767 /********************************************************************
2768 * construct_printer_info_2
2769 * fill a printer_info_2 struct
2770 ********************************************************************/
2772 static BOOL
construct_printer_info_2(PRINTER_INFO_2
*printer
, int snum
)
2775 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2777 print_queue_struct
*queue
=NULL
;
2778 print_status_struct status
;
2779 memset(&status
, 0, sizeof(status
));
2781 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2784 memset(&status
, 0, sizeof(status
));
2785 count
= print_queue_status(snum
, &queue
, &status
);
2787 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
2788 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
2789 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
2790 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
2791 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
2793 if (*ntprinter
->info_2
->comment
== '\0')
2794 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
2796 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2798 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
2799 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
2800 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
2801 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
2802 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
2804 printer
->attributes
= ntprinter
->info_2
->attributes
;
2806 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
2807 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
2808 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
2809 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
2810 printer
->status
= nt_printq_status(status
.status
); /* status */
2811 printer
->cjobs
= count
; /* jobs */
2812 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
2814 if((printer
->devmode
= construct_dev_mode(snum
)) == NULL
) {
2815 DEBUG(8, ("Returning NULL Devicemode!\n"));
2818 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2819 /* steal the printer info sec_desc structure. [badly done]. */
2820 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2821 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen memory. */
2822 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen memory. */
2823 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen memory. */
2826 printer
->secdesc
= NULL
;
2829 free_a_printer(&ntprinter
, 2);
2834 /********************************************************************
2835 * construct_printer_info_3
2836 * fill a printer_info_3 struct
2837 ********************************************************************/
2838 static BOOL
construct_printer_info_3(PRINTER_INFO_3
**pp_printer
, int snum
)
2840 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2841 PRINTER_INFO_3
*printer
= NULL
;
2843 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2847 if ((printer
= (PRINTER_INFO_3
*)malloc(sizeof(PRINTER_INFO_3
))) == NULL
) {
2848 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
2852 ZERO_STRUCTP(printer
);
2854 printer
->flags
= 4; /* These are the components of the SD we are returning. */
2855 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2856 /* steal the printer info sec_desc structure. [badly done]. */
2857 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2861 * Set the flags for the components we are returning.
2864 if (printer
->secdesc
->owner_sid
)
2865 printer
->flags
|= OWNER_SECURITY_INFORMATION
;
2867 if (printer
->secdesc
->grp_sid
)
2868 printer
->flags
|= GROUP_SECURITY_INFORMATION
;
2870 if (printer
->secdesc
->dacl
)
2871 printer
->flags
|= DACL_SECURITY_INFORMATION
;
2873 if (printer
->secdesc
->sacl
)
2874 printer
->flags
|= SACL_SECURITY_INFORMATION
;
2877 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen the malloced memory. */
2878 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen the malloced memory. */
2879 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen the malloced memory. */
2882 free_a_printer(&ntprinter
, 2);
2884 *pp_printer
= printer
;
2888 /********************************************************************
2889 Spoolss_enumprinters.
2890 ********************************************************************/
2891 static WERROR
enum_all_printers_info_1(uint32 flags
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2895 int n_services
=lp_numservices();
2896 PRINTER_INFO_1
*tp
, *printers
=NULL
;
2897 PRINTER_INFO_1 current_prt
;
2899 DEBUG(4,("enum_all_printers_info_1\n"));
2901 for (snum
=0; snum
<n_services
; snum
++) {
2902 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
2903 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
2905 if (construct_printer_info_1(flags
, ¤t_prt
, snum
)) {
2906 if((tp
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_1
))) == NULL
) {
2907 DEBUG(0,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
2908 SAFE_FREE(printers
);
2913 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
2914 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
2920 /* check the required size. */
2921 for (i
=0; i
<*returned
; i
++)
2922 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
2924 if (!alloc_buffer_size(buffer
, *needed
))
2925 return WERR_INSUFFICIENT_BUFFER
;
2927 /* fill the buffer with the structures */
2928 for (i
=0; i
<*returned
; i
++)
2929 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
2932 SAFE_FREE(printers
);
2934 if (*needed
> offered
) {
2936 return WERR_INSUFFICIENT_BUFFER
;
2942 /********************************************************************
2943 enum_all_printers_info_1_local.
2944 *********************************************************************/
2945 static WERROR
enum_all_printers_info_1_local(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2947 DEBUG(4,("enum_all_printers_info_1_local\n"));
2949 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
2952 /********************************************************************
2953 enum_all_printers_info_1_name.
2954 *********************************************************************/
2955 static WERROR
enum_all_printers_info_1_name(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2959 DEBUG(4,("enum_all_printers_info_1_name\n"));
2961 if ((name
[0] == '\\') && (name
[1] == '\\'))
2964 if (is_myname_or_ipaddr(s
)) {
2965 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
2968 return WERR_INVALID_NAME
;
2971 /********************************************************************
2972 enum_all_printers_info_1_remote.
2973 *********************************************************************/
2974 static WERROR
enum_all_printers_info_1_remote(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2976 PRINTER_INFO_1
*printer
;
2977 fstring printername
;
2980 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2982 /* JFM: currently it's more a place holder than anything else.
2983 * In the spooler world there is a notion of server registration.
2984 * the print servers are registring (sp ?) on the PDC (in the same domain)
2986 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2989 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
2994 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", global_myname
);
2995 slprintf(desc
, sizeof(desc
)-1,"%s", global_myname
);
2996 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
2998 init_unistr(&printer
->description
, desc
);
2999 init_unistr(&printer
->name
, printername
);
3000 init_unistr(&printer
->comment
, comment
);
3001 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
3003 /* check the required size. */
3004 *needed
+= spoolss_size_printer_info_1(printer
);
3006 if (!alloc_buffer_size(buffer
, *needed
)) {
3008 return WERR_INSUFFICIENT_BUFFER
;
3011 /* fill the buffer with the structures */
3012 smb_io_printer_info_1("", buffer
, printer
, 0);
3017 if (*needed
> offered
) {
3019 return WERR_INSUFFICIENT_BUFFER
;
3025 /********************************************************************
3026 enum_all_printers_info_1_network.
3027 *********************************************************************/
3029 static WERROR
enum_all_printers_info_1_network(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
3031 DEBUG(4,("enum_all_printers_info_1_network\n"));
3033 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
3036 /********************************************************************
3037 * api_spoolss_enumprinters
3039 * called from api_spoolss_enumprinters (see this to understand)
3040 ********************************************************************/
3042 static WERROR
enum_all_printers_info_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
3046 int n_services
=lp_numservices();
3047 PRINTER_INFO_2
*tp
, *printers
=NULL
;
3048 PRINTER_INFO_2 current_prt
;
3050 for (snum
=0; snum
<n_services
; snum
++) {
3051 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
3052 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
3054 if (construct_printer_info_2(¤t_prt
, snum
)) {
3055 if((tp
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_2
))) == NULL
) {
3056 DEBUG(0,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
3057 SAFE_FREE(printers
);
3062 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
));
3063 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
3069 /* check the required size. */
3070 for (i
=0; i
<*returned
; i
++)
3071 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
3073 if (!alloc_buffer_size(buffer
, *needed
)) {
3074 for (i
=0; i
<*returned
; i
++) {
3075 free_devmode(printers
[i
].devmode
);
3077 SAFE_FREE(printers
);
3078 return WERR_INSUFFICIENT_BUFFER
;
3081 /* fill the buffer with the structures */
3082 for (i
=0; i
<*returned
; i
++)
3083 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
3086 for (i
=0; i
<*returned
; i
++) {
3087 free_devmode(printers
[i
].devmode
);
3089 SAFE_FREE(printers
);
3091 if (*needed
> offered
) {
3093 return WERR_INSUFFICIENT_BUFFER
;
3099 /********************************************************************
3100 * handle enumeration of printers at level 1
3101 ********************************************************************/
3102 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
3103 NEW_BUFFER
*buffer
, uint32 offered
,
3104 uint32
*needed
, uint32
*returned
)
3106 /* Not all the flags are equals */
3108 if (flags
& PRINTER_ENUM_LOCAL
)
3109 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
3111 if (flags
& PRINTER_ENUM_NAME
)
3112 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
3114 if (flags
& PRINTER_ENUM_REMOTE
)
3115 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
3117 if (flags
& PRINTER_ENUM_NETWORK
)
3118 return enum_all_printers_info_1_network(buffer
, offered
, needed
, returned
);
3120 return WERR_OK
; /* NT4sp5 does that */
3123 /********************************************************************
3124 * handle enumeration of printers at level 2
3125 ********************************************************************/
3126 static WERROR
enumprinters_level2( uint32 flags
, fstring servername
,
3127 NEW_BUFFER
*buffer
, uint32 offered
,
3128 uint32
*needed
, uint32
*returned
)
3130 char *s
= servername
;
3132 if (flags
& PRINTER_ENUM_LOCAL
) {
3133 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3136 if (flags
& PRINTER_ENUM_NAME
) {
3137 if ((servername
[0] == '\\') && (servername
[1] == '\\'))
3139 if (is_myname_or_ipaddr(s
))
3140 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3142 return WERR_INVALID_NAME
;
3145 if (flags
& PRINTER_ENUM_REMOTE
)
3146 return WERR_UNKNOWN_LEVEL
;
3151 /********************************************************************
3152 * handle enumeration of printers at level 5
3153 ********************************************************************/
3154 static WERROR
enumprinters_level5( uint32 flags
, fstring servername
,
3155 NEW_BUFFER
*buffer
, uint32 offered
,
3156 uint32
*needed
, uint32
*returned
)
3158 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
3162 /********************************************************************
3163 * api_spoolss_enumprinters
3165 * called from api_spoolss_enumprinters (see this to understand)
3166 ********************************************************************/
3168 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
3170 uint32 flags
= q_u
->flags
;
3171 UNISTR2
*servername
= &q_u
->servername
;
3172 uint32 level
= q_u
->level
;
3173 NEW_BUFFER
*buffer
= NULL
;
3174 uint32 offered
= q_u
->offered
;
3175 uint32
*needed
= &r_u
->needed
;
3176 uint32
*returned
= &r_u
->returned
;
3180 /* that's an [in out] buffer */
3181 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3182 buffer
= r_u
->buffer
;
3184 DEBUG(4,("_spoolss_enumprinters\n"));
3191 * flags==PRINTER_ENUM_NAME
3192 * if name=="" then enumerates all printers
3193 * if name!="" then enumerate the printer
3194 * flags==PRINTER_ENUM_REMOTE
3195 * name is NULL, enumerate printers
3196 * Level 2: name!="" enumerates printers, name can't be NULL
3197 * Level 3: doesn't exist
3198 * Level 4: does a local registry lookup
3199 * Level 5: same as Level 2
3202 unistr2_to_ascii(name
, servername
, sizeof(name
)-1);
3207 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
3209 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
3211 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
3216 return WERR_UNKNOWN_LEVEL
;
3219 /****************************************************************************
3220 ****************************************************************************/
3221 static WERROR
getprinter_level_0(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3223 PRINTER_INFO_0
*printer
=NULL
;
3225 if((printer
=(PRINTER_INFO_0
*)malloc(sizeof(PRINTER_INFO_0
))) == NULL
)
3228 construct_printer_info_0(printer
, snum
);
3230 /* check the required size. */
3231 *needed
+= spoolss_size_printer_info_0(printer
);
3233 if (!alloc_buffer_size(buffer
, *needed
)) {
3235 return WERR_INSUFFICIENT_BUFFER
;
3238 /* fill the buffer with the structures */
3239 smb_io_printer_info_0("", buffer
, printer
, 0);
3244 if (*needed
> offered
) {
3245 return WERR_INSUFFICIENT_BUFFER
;
3251 /****************************************************************************
3252 ****************************************************************************/
3253 static WERROR
getprinter_level_1(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3255 PRINTER_INFO_1
*printer
=NULL
;
3257 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
3260 construct_printer_info_1(PRINTER_ENUM_ICON8
, printer
, snum
);
3262 /* check the required size. */
3263 *needed
+= spoolss_size_printer_info_1(printer
);
3265 if (!alloc_buffer_size(buffer
, *needed
)) {
3267 return WERR_INSUFFICIENT_BUFFER
;
3270 /* fill the buffer with the structures */
3271 smb_io_printer_info_1("", buffer
, printer
, 0);
3276 if (*needed
> offered
) {
3277 return WERR_INSUFFICIENT_BUFFER
;
3283 /****************************************************************************
3284 ****************************************************************************/
3285 static WERROR
getprinter_level_2(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3287 PRINTER_INFO_2
*printer
=NULL
;
3289 if((printer
=(PRINTER_INFO_2
*)malloc(sizeof(PRINTER_INFO_2
)))==NULL
)
3292 construct_printer_info_2(printer
, snum
);
3294 /* check the required size. */
3295 *needed
+= spoolss_size_printer_info_2(printer
);
3297 if (!alloc_buffer_size(buffer
, *needed
)) {
3298 free_printer_info_2(printer
);
3299 return WERR_INSUFFICIENT_BUFFER
;
3302 /* fill the buffer with the structures */
3303 if (!smb_io_printer_info_2("", buffer
, printer
, 0)) {
3304 free_printer_info_2(printer
);
3309 free_printer_info_2(printer
);
3311 if (*needed
> offered
) {
3312 return WERR_INSUFFICIENT_BUFFER
;
3318 /****************************************************************************
3319 ****************************************************************************/
3320 static WERROR
getprinter_level_3(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3322 PRINTER_INFO_3
*printer
=NULL
;
3324 if (!construct_printer_info_3(&printer
, snum
))
3327 /* check the required size. */
3328 *needed
+= spoolss_size_printer_info_3(printer
);
3330 if (!alloc_buffer_size(buffer
, *needed
)) {
3331 free_printer_info_3(printer
);
3332 return WERR_INSUFFICIENT_BUFFER
;
3335 /* fill the buffer with the structures */
3336 smb_io_printer_info_3("", buffer
, printer
, 0);
3339 free_printer_info_3(printer
);
3341 if (*needed
> offered
) {
3342 return WERR_INSUFFICIENT_BUFFER
;
3348 /****************************************************************************
3349 ****************************************************************************/
3351 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
3353 POLICY_HND
*handle
= &q_u
->handle
;
3354 uint32 level
= q_u
->level
;
3355 NEW_BUFFER
*buffer
= NULL
;
3356 uint32 offered
= q_u
->offered
;
3357 uint32
*needed
= &r_u
->needed
;
3361 /* that's an [in out] buffer */
3362 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3363 buffer
= r_u
->buffer
;
3367 if (!get_printer_snum(p
, handle
, &snum
))
3372 return getprinter_level_0(snum
, buffer
, offered
, needed
);
3374 return getprinter_level_1(snum
, buffer
, offered
, needed
);
3376 return getprinter_level_2(snum
, buffer
, offered
, needed
);
3378 return getprinter_level_3(snum
, buffer
, offered
, needed
);
3380 return WERR_UNKNOWN_LEVEL
;
3383 /********************************************************************
3384 * fill a DRIVER_INFO_1 struct
3385 ********************************************************************/
3386 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
3388 init_unistr( &info
->name
, driver
.info_3
->name
);
3391 /********************************************************************
3392 * construct_printer_driver_info_1
3393 ********************************************************************/
3394 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3396 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3397 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3399 ZERO_STRUCT(driver
);
3401 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3402 return WERR_INVALID_PRINTER_NAME
;
3404 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
3405 return WERR_UNKNOWN_PRINTER_DRIVER
;
3407 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
3409 free_a_printer(&printer
,2);
3414 /********************************************************************
3415 * construct_printer_driver_info_2
3416 * fill a printer_info_2 struct
3417 ********************************************************************/
3418 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3422 info
->version
=driver
.info_3
->cversion
;
3424 init_unistr( &info
->name
, driver
.info_3
->name
);
3425 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3428 if (strlen(driver
.info_3
->driverpath
)) {
3429 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3430 init_unistr( &info
->driverpath
, temp
);
3432 init_unistr( &info
->driverpath
, "" );
3434 if (strlen(driver
.info_3
->datafile
)) {
3435 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3436 init_unistr( &info
->datafile
, temp
);
3438 init_unistr( &info
->datafile
, "" );
3440 if (strlen(driver
.info_3
->configfile
)) {
3441 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3442 init_unistr( &info
->configfile
, temp
);
3444 init_unistr( &info
->configfile
, "" );
3447 /********************************************************************
3448 * construct_printer_driver_info_2
3449 * fill a printer_info_2 struct
3450 ********************************************************************/
3451 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3453 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3454 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3456 ZERO_STRUCT(printer
);
3457 ZERO_STRUCT(driver
);
3459 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3460 return WERR_INVALID_PRINTER_NAME
;
3462 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
3463 return WERR_UNKNOWN_PRINTER_DRIVER
;
3465 fill_printer_driver_info_2(info
, driver
, servername
);
3467 free_a_printer(&printer
,2);
3472 /********************************************************************
3473 * copy a strings array and convert to UNICODE
3475 * convert an array of ascii string to a UNICODE string
3476 ********************************************************************/
3477 static void init_unistr_array(uint16
**uni_array
, fstring
*char_array
, char *servername
)
3485 DEBUG(6,("init_unistr_array\n"));
3489 if (char_array
== NULL
)
3493 if (!v
) v
= ""; /* hack to handle null lists */
3495 if (strlen(v
) == 0) break;
3496 slprintf(line
, sizeof(line
)-1, "\\\\%s%s", servername
, v
);
3497 DEBUGADD(6,("%d:%s:%d\n", i
, line
, strlen(line
)));
3498 if((tuary
=Realloc(*uni_array
, (j
+strlen(line
)+2)*sizeof(uint16
))) == NULL
) {
3499 DEBUG(0,("init_unistr_array: Realloc error\n" ));
3502 else *uni_array
= tuary
;
3503 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, 0)/ sizeof(uint16
));
3508 (*uni_array
)[j
]=0x0000;
3511 DEBUGADD(6,("last one:done\n"));
3514 /********************************************************************
3515 * construct_printer_info_3
3516 * fill a printer_info_3 struct
3517 ********************************************************************/
3518 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3524 info
->version
=driver
.info_3
->cversion
;
3526 init_unistr( &info
->name
, driver
.info_3
->name
);
3527 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3529 if (strlen(driver
.info_3
->driverpath
)) {
3530 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3531 init_unistr( &info
->driverpath
, temp
);
3533 init_unistr( &info
->driverpath
, "" );
3535 if (strlen(driver
.info_3
->datafile
)) {
3536 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3537 init_unistr( &info
->datafile
, temp
);
3539 init_unistr( &info
->datafile
, "" );
3541 if (strlen(driver
.info_3
->configfile
)) {
3542 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3543 init_unistr( &info
->configfile
, temp
);
3545 init_unistr( &info
->configfile
, "" );
3547 if (strlen(driver
.info_3
->helpfile
)) {
3548 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3549 init_unistr( &info
->helpfile
, temp
);
3551 init_unistr( &info
->helpfile
, "" );
3553 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3554 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3556 info
->dependentfiles
=NULL
;
3557 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3560 /********************************************************************
3561 * construct_printer_info_3
3562 * fill a printer_info_3 struct
3563 ********************************************************************/
3564 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3566 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3567 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3569 ZERO_STRUCT(driver
);
3571 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3572 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status
)));
3573 if (!W_ERROR_IS_OK(status
))
3574 return WERR_INVALID_PRINTER_NAME
;
3576 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3577 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status
)));
3578 if (!W_ERROR_IS_OK(status
)) {
3579 free_a_printer(&printer
,2);
3580 return WERR_UNKNOWN_PRINTER_DRIVER
;
3583 fill_printer_driver_info_3(info
, driver
, servername
);
3585 free_a_printer(&printer
,2);
3590 /********************************************************************
3591 * construct_printer_info_6
3592 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
3593 ********************************************************************/
3595 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3601 memset(&nullstr
, '\0', sizeof(fstring
));
3603 info
->version
=driver
.info_3
->cversion
;
3605 init_unistr( &info
->name
, driver
.info_3
->name
);
3606 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3608 if (strlen(driver
.info_3
->driverpath
)) {
3609 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3610 init_unistr( &info
->driverpath
, temp
);
3612 init_unistr( &info
->driverpath
, "" );
3614 if (strlen(driver
.info_3
->datafile
)) {
3615 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3616 init_unistr( &info
->datafile
, temp
);
3618 init_unistr( &info
->datafile
, "" );
3620 if (strlen(driver
.info_3
->configfile
)) {
3621 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3622 init_unistr( &info
->configfile
, temp
);
3624 init_unistr( &info
->configfile
, "" );
3626 if (strlen(driver
.info_3
->helpfile
)) {
3627 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3628 init_unistr( &info
->helpfile
, temp
);
3630 init_unistr( &info
->helpfile
, "" );
3632 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3633 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3635 info
->dependentfiles
=NULL
;
3636 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3638 info
->previousdrivernames
=NULL
;
3639 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
3641 info
->driver_date
.low
=0;
3642 info
->driver_date
.high
=0;
3645 info
->driver_version_low
=0;
3646 info
->driver_version_high
=0;
3648 init_unistr( &info
->mfgname
, "");
3649 init_unistr( &info
->oem_url
, "");
3650 init_unistr( &info
->hardware_id
, "");
3651 init_unistr( &info
->provider
, "");
3654 /********************************************************************
3655 * construct_printer_info_6
3656 * fill a printer_info_6 struct
3657 ********************************************************************/
3658 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3660 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3661 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3663 ZERO_STRUCT(driver
);
3665 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3666 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3667 if (!W_ERROR_IS_OK(status
))
3668 return WERR_INVALID_PRINTER_NAME
;
3670 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3671 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3672 if (!W_ERROR_IS_OK(status
)) {
3674 * Is this a W2k client ?
3678 free_a_printer(&printer
,2);
3679 return WERR_UNKNOWN_PRINTER_DRIVER
;
3682 /* Yes - try again with a WinNT driver. */
3684 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3685 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3686 if (!W_ERROR_IS_OK(status
)) {
3687 free_a_printer(&printer
,2);
3688 return WERR_UNKNOWN_PRINTER_DRIVER
;
3692 fill_printer_driver_info_6(info
, driver
, servername
);
3694 free_a_printer(&printer
,2);
3699 /****************************************************************************
3700 ****************************************************************************/
3702 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
3704 SAFE_FREE(info
->dependentfiles
);
3707 /****************************************************************************
3708 ****************************************************************************/
3710 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
3712 SAFE_FREE(info
->dependentfiles
);
3716 /****************************************************************************
3717 ****************************************************************************/
3718 static WERROR
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3720 DRIVER_INFO_1
*info
=NULL
;
3723 if((info
=(DRIVER_INFO_1
*)malloc(sizeof(DRIVER_INFO_1
))) == NULL
)
3726 status
=construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
3727 if (!W_ERROR_IS_OK(status
)) {
3732 /* check the required size. */
3733 *needed
+= spoolss_size_printer_driver_info_1(info
);
3735 if (!alloc_buffer_size(buffer
, *needed
)) {
3737 return WERR_INSUFFICIENT_BUFFER
;
3740 /* fill the buffer with the structures */
3741 smb_io_printer_driver_info_1("", buffer
, info
, 0);
3746 if (*needed
> offered
)
3747 return WERR_INSUFFICIENT_BUFFER
;
3752 /****************************************************************************
3753 ****************************************************************************/
3754 static WERROR
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3756 DRIVER_INFO_2
*info
=NULL
;
3759 if((info
=(DRIVER_INFO_2
*)malloc(sizeof(DRIVER_INFO_2
))) == NULL
)
3762 status
=construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
3763 if (!W_ERROR_IS_OK(status
)) {
3768 /* check the required size. */
3769 *needed
+= spoolss_size_printer_driver_info_2(info
);
3771 if (!alloc_buffer_size(buffer
, *needed
)) {
3773 return WERR_INSUFFICIENT_BUFFER
;
3776 /* fill the buffer with the structures */
3777 smb_io_printer_driver_info_2("", buffer
, info
, 0);
3782 if (*needed
> offered
)
3783 return WERR_INSUFFICIENT_BUFFER
;
3788 /****************************************************************************
3789 ****************************************************************************/
3790 static WERROR
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3797 status
=construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
3798 if (!W_ERROR_IS_OK(status
)) {
3802 /* check the required size. */
3803 *needed
+= spoolss_size_printer_driver_info_3(&info
);
3805 if (!alloc_buffer_size(buffer
, *needed
)) {
3806 free_printer_driver_info_3(&info
);
3807 return WERR_INSUFFICIENT_BUFFER
;
3810 /* fill the buffer with the structures */
3811 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
3813 free_printer_driver_info_3(&info
);
3815 if (*needed
> offered
)
3816 return WERR_INSUFFICIENT_BUFFER
;
3821 /****************************************************************************
3822 ****************************************************************************/
3823 static WERROR
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3830 status
=construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
3831 if (!W_ERROR_IS_OK(status
)) {
3835 /* check the required size. */
3836 *needed
+= spoolss_size_printer_driver_info_6(&info
);
3838 if (!alloc_buffer_size(buffer
, *needed
)) {
3839 free_printer_driver_info_6(&info
);
3840 return WERR_INSUFFICIENT_BUFFER
;
3843 /* fill the buffer with the structures */
3844 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
3846 free_printer_driver_info_6(&info
);
3848 if (*needed
> offered
)
3849 return WERR_INSUFFICIENT_BUFFER
;
3854 /****************************************************************************
3855 ****************************************************************************/
3857 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
3859 POLICY_HND
*handle
= &q_u
->handle
;
3860 UNISTR2
*uni_arch
= &q_u
->architecture
;
3861 uint32 level
= q_u
->level
;
3862 uint32 clientmajorversion
= q_u
->clientmajorversion
;
3863 /* uint32 clientminorversion = q_u->clientminorversion; - notused. */
3864 NEW_BUFFER
*buffer
= NULL
;
3865 uint32 offered
= q_u
->offered
;
3866 uint32
*needed
= &r_u
->needed
;
3867 uint32
*servermajorversion
= &r_u
->servermajorversion
;
3868 uint32
*serverminorversion
= &r_u
->serverminorversion
;
3871 fstring architecture
;
3874 /* that's an [in out] buffer */
3875 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3876 buffer
= r_u
->buffer
;
3878 DEBUG(4,("_spoolss_getprinterdriver2\n"));
3881 *servermajorversion
=0;
3882 *serverminorversion
=0;
3884 pstrcpy(servername
, global_myname
);
3885 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
)-1);
3887 if (!get_printer_snum(p
, handle
, &snum
))
3892 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3894 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3896 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3898 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3901 return WERR_UNKNOWN_LEVEL
;
3904 /****************************************************************************
3905 ****************************************************************************/
3907 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
3909 POLICY_HND
*handle
= &q_u
->handle
;
3911 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3914 Printer
->page_started
=True
;
3918 DEBUG(3,("Error in startpageprinter printer handle\n"));
3922 /****************************************************************************
3923 ****************************************************************************/
3925 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
3927 POLICY_HND
*handle
= &q_u
->handle
;
3929 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3932 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle
)));
3936 Printer
->page_started
=False
;
3941 /********************************************************************
3942 * api_spoolss_getprinter
3943 * called from the spoolss dispatcher
3945 ********************************************************************/
3947 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
3949 POLICY_HND
*handle
= &q_u
->handle
;
3950 /* uint32 level = q_u->doc_info_container.level; - notused. */
3951 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
3952 uint32
*jobid
= &r_u
->jobid
;
3954 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
3958 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3959 struct current_user user
;
3962 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
3966 get_current_user(&user
, p
);
3969 * a nice thing with NT is it doesn't listen to what you tell it.
3970 * when asked to send _only_ RAW datas, it tries to send datas
3973 * So I add checks like in NT Server ...
3975 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
3976 * there's a bug in NT client-side code, so we'll fix it in the
3977 * server-side code. *nnnnnggggh!*
3980 if (info_1
->p_datatype
!= 0) {
3981 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
3982 if (strcmp(datatype
, "RAW") != 0) {
3984 return WERR_INVALID_DATATYPE
;
3988 /* get the share number of the printer */
3989 if (!get_printer_snum(p
, handle
, &snum
)) {
3993 unistr2_to_ascii(jobname
, &info_1
->docname
, sizeof(jobname
));
3995 Printer
->jobid
= print_job_start(&user
, snum
, jobname
);
3997 /* An error occured in print_job_start() so return an appropriate
4000 if (Printer
->jobid
== -1) {
4001 return map_werror_from_unix(errno
);
4004 Printer
->document_started
=True
;
4005 (*jobid
) = Printer
->jobid
;
4010 /********************************************************************
4011 * api_spoolss_getprinter
4012 * called from the spoolss dispatcher
4014 ********************************************************************/
4016 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
4018 POLICY_HND
*handle
= &q_u
->handle
;
4020 return _spoolss_enddocprinter_internal(p
, handle
);
4023 /****************************************************************************
4024 ****************************************************************************/
4026 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
4028 POLICY_HND
*handle
= &q_u
->handle
;
4029 uint32 buffer_size
= q_u
->buffer_size
;
4030 uint8
*buffer
= q_u
->buffer
;
4031 uint32
*buffer_written
= &q_u
->buffer_size2
;
4033 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4036 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle
)));
4037 r_u
->buffer_written
= q_u
->buffer_size2
;
4041 (*buffer_written
) = print_job_write(Printer
->jobid
, (char *)buffer
, buffer_size
);
4044 r_u
->buffer_written
= q_u
->buffer_size2
;
4049 /********************************************************************
4050 * api_spoolss_getprinter
4051 * called from the spoolss dispatcher
4053 ********************************************************************/
4054 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
4057 struct current_user user
;
4059 WERROR errcode
= WERR_BADFUNC
;
4060 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4062 get_current_user(&user
, p
);
4065 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4069 if (!get_printer_snum(p
, handle
, &snum
))
4073 case PRINTER_CONTROL_PAUSE
:
4074 if (print_queue_pause(&user
, snum
, &errcode
)) {
4078 case PRINTER_CONTROL_RESUME
:
4079 case PRINTER_CONTROL_UNPAUSE
:
4080 if (print_queue_resume(&user
, snum
, &errcode
)) {
4084 case PRINTER_CONTROL_PURGE
:
4085 if (print_queue_purge(&user
, snum
, &errcode
)) {
4090 return WERR_UNKNOWN_LEVEL
;
4096 /********************************************************************
4097 * api_spoolss_abortprinter
4098 ********************************************************************/
4100 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
4102 POLICY_HND
*handle
= &q_u
->handle
;
4104 return control_printer(handle
, PRINTER_CONTROL_PURGE
, p
);
4107 /********************************************************************
4108 * called by spoolss_api_setprinter
4109 * when updating a printer description
4110 ********************************************************************/
4111 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
4112 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4113 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
4115 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
4116 struct current_user user
;
4120 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4122 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
)) {
4123 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n",
4124 OUR_HANDLE(handle
)));
4126 result
= WERR_BADFID
;
4130 /* NT seems to like setting the security descriptor even though
4131 nothing may have actually changed. This causes annoying
4132 dialog boxes when the user doesn't have permission to change
4133 the security descriptor. */
4135 nt_printing_getsec(p
->mem_ctx
, Printer
->dev
.handlename
, &old_secdesc_ctr
);
4137 if (DEBUGLEVEL
>= 10) {
4141 the_acl
= old_secdesc_ctr
->sec
->dacl
;
4142 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
4143 PRINTERNAME(snum
), the_acl
->num_aces
));
4145 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4148 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
4150 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4151 the_acl
->ace
[i
].info
.mask
));
4154 the_acl
= secdesc_ctr
->sec
->dacl
;
4157 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4158 PRINTERNAME(snum
), the_acl
->num_aces
));
4160 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4163 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
4165 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4166 the_acl
->ace
[i
].info
.mask
));
4169 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
4173 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
4175 if (sec_desc_equal(new_secdesc_ctr
->sec
, old_secdesc_ctr
->sec
)) {
4180 /* Work out which user is performing the operation */
4182 get_current_user(&user
, p
);
4184 /* Check the user has permissions to change the security
4185 descriptor. By experimentation with two NT machines, the user
4186 requires Full Access to the printer to change security
4189 if (!print_access_check(&user
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4190 result
= WERR_ACCESS_DENIED
;
4194 result
= nt_printing_setsec(Printer
->dev
.handlename
, new_secdesc_ctr
);
4201 /********************************************************************
4202 Do Samba sanity checks on a printer info struct.
4203 this has changed purpose: it now "canonicalises" printer
4204 info from a client rather than just checking it is correct
4205 ********************************************************************/
4207 static BOOL
check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
4209 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
4210 info
->servername
, info
->printername
, info
->sharename
, info
->portname
, info
->drivername
, info
->comment
, info
->location
));
4212 /* we force some elements to "correct" values */
4213 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname
);
4214 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
4215 global_myname
, lp_servicename(snum
));
4216 fstrcpy(info
->sharename
, lp_servicename(snum
));
4217 info
->attributes
= PRINTER_ATTRIBUTE_SHARED \
4218 | PRINTER_ATTRIBUTE_LOCAL \
4219 | PRINTER_ATTRIBUTE_RAW_ONLY \
4220 | PRINTER_ATTRIBUTE_QUEUED
;
4225 /****************************************************************************
4226 ****************************************************************************/
4227 static BOOL
add_printer_hook(NT_PRINTER_INFO_LEVEL
*printer
)
4229 char *cmd
= lp_addprinter_cmd();
4232 pstring driverlocation
;
4237 /* build driver path... only 9X architecture is needed for legacy reasons */
4238 slprintf(driverlocation
, sizeof(driverlocation
)-1, "\\\\%s\\print$\\WIN40\\0",
4240 /* change \ to \\ for the shell */
4241 all_string_sub(driverlocation
,"\\","\\\\",sizeof(pstring
));
4243 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4244 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
4245 printer
->info_2
->portname
, printer
->info_2
->drivername
,
4246 printer
->info_2
->location
, driverlocation
);
4248 DEBUG(10,("Running [%s]\n", command
));
4249 ret
= smbrun(command
, &fd
);
4250 DEBUGADD(10,("returned [%d]\n", ret
));
4259 /* Get lines and convert them back to dos-codepage */
4260 qlines
= fd_lines_load(fd
, &numlines
);
4261 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
4265 /* Set the portname to what the script says the portname should be. */
4266 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
4267 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
4269 /* Send SIGHUP to process group... is there a better way? */
4274 file_lines_free(qlines
);
4278 /* Return true if two devicemodes are equal */
4280 #define DEVMODE_CHECK_INT(field) \
4281 if (d1->field != d2->field) { \
4282 DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
4283 d1->field, d2->field)); \
4287 static BOOL
nt_devicemode_equal(NT_DEVICEMODE
*d1
, NT_DEVICEMODE
*d2
)
4289 if (!d1
&& !d2
) goto equal
; /* if both are NULL they are equal */
4292 DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
4293 return False
; /* if either is exclusively NULL are not equal */
4296 if (!strequal(d1
->devicename
, d2
->devicename
)) {
4297 DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1
->devicename
, d2
->devicename
));
4301 if (!strequal(d1
->formname
, d2
->formname
)) {
4302 DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1
->formname
, d2
->formname
));
4306 DEVMODE_CHECK_INT(specversion
);
4307 DEVMODE_CHECK_INT(driverversion
);
4308 DEVMODE_CHECK_INT(driverextra
);
4309 DEVMODE_CHECK_INT(orientation
);
4310 DEVMODE_CHECK_INT(papersize
);
4311 DEVMODE_CHECK_INT(paperlength
);
4312 DEVMODE_CHECK_INT(paperwidth
);
4313 DEVMODE_CHECK_INT(scale
);
4314 DEVMODE_CHECK_INT(copies
);
4315 DEVMODE_CHECK_INT(defaultsource
);
4316 DEVMODE_CHECK_INT(printquality
);
4317 DEVMODE_CHECK_INT(color
);
4318 DEVMODE_CHECK_INT(duplex
);
4319 DEVMODE_CHECK_INT(yresolution
);
4320 DEVMODE_CHECK_INT(ttoption
);
4321 DEVMODE_CHECK_INT(collate
);
4322 DEVMODE_CHECK_INT(logpixels
);
4324 DEVMODE_CHECK_INT(fields
);
4325 DEVMODE_CHECK_INT(bitsperpel
);
4326 DEVMODE_CHECK_INT(pelswidth
);
4327 DEVMODE_CHECK_INT(pelsheight
);
4328 DEVMODE_CHECK_INT(displayflags
);
4329 DEVMODE_CHECK_INT(displayfrequency
);
4330 DEVMODE_CHECK_INT(icmmethod
);
4331 DEVMODE_CHECK_INT(icmintent
);
4332 DEVMODE_CHECK_INT(mediatype
);
4333 DEVMODE_CHECK_INT(dithertype
);
4334 DEVMODE_CHECK_INT(reserved1
);
4335 DEVMODE_CHECK_INT(reserved2
);
4336 DEVMODE_CHECK_INT(panningwidth
);
4337 DEVMODE_CHECK_INT(panningheight
);
4339 /* compare the private data if it exists */
4340 if (!d1
->driverextra
&& !d2
->driverextra
) goto equal
;
4343 DEVMODE_CHECK_INT(driverextra
);
4345 if (memcmp(d1
->private, d2
->private, d1
->driverextra
)) {
4346 DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
4351 DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
4355 /* Return true if two NT_PRINTER_PARAM structures are equal */
4357 static BOOL
nt_printer_param_equal(NT_PRINTER_PARAM
*p1
,
4358 NT_PRINTER_PARAM
*p2
)
4360 if (!p1
&& !p2
) goto equal
;
4362 if ((!p1
&& p2
) || (p1
&& !p2
)) {
4363 DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
4367 /* Compare lists of printer parameters */
4371 NT_PRINTER_PARAM
*q
= p1
;
4373 /* Find the parameter in the second structure */
4377 if (strequal(p1
->value
, q
->value
)) {
4379 if (p1
->type
!= q
->type
) {
4380 DEBUG(10, ("nt_printer_param_equal():"
4381 "types for %s differ (%d != %d)\n",
4382 p1
->value
, p1
->type
,
4387 if (p1
->data_len
!= q
->data_len
) {
4388 DEBUG(10, ("nt_printer_param_equal():"
4389 "len for %s differs (%d != %d)\n",
4390 p1
->value
, p1
->data_len
,
4395 if (memcmp(p1
->data
, q
->data
, p1
->data_len
) == 0) {
4398 DEBUG(10, ("nt_printer_param_equal():"
4399 "data for %s differs\n", p1
->value
));
4409 DEBUG(10, ("nt_printer_param_equal(): param %s "
4410 "does not exist\n", p1
->value
));
4419 DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
4423 /********************************************************************
4424 * Called by update_printer when trying to work out whether to
4425 * actually update printer info.
4426 ********************************************************************/
4428 #define PI_CHECK_INT(field) \
4429 if (pi1->field != pi2->field) { \
4430 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
4431 pi1->field, pi2->field)); \
4435 #define PI_CHECK_STR(field) \
4436 if (!strequal(pi1->field, pi2->field)) { \
4437 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
4438 pi1->field, pi2->field)); \
4442 static BOOL
nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL
*p1
,
4443 NT_PRINTER_INFO_LEVEL
*p2
)
4445 NT_PRINTER_INFO_LEVEL_2
*pi1
, *pi2
;
4447 /* Trivial conditions */
4449 if ((!p1
&& !p2
) || (!p1
->info_2
&& !p2
->info_2
)) {
4453 if ((!p1
&& p2
) || (p1
&& !p2
) ||
4454 (!p1
->info_2
&& p2
->info_2
) ||
4455 (p1
->info_2
&& !p2
->info_2
)) {
4456 DEBUG(10, ("nt_printer_info_level_equal(): info levels "
4461 /* Compare two nt_printer_info_level structures. Don't compare
4462 status or cjobs as they seem to have something to do with the
4468 /* Don't check the attributes as we stomp on the value in
4469 check_printer_ok() anyway. */
4472 PI_CHECK_INT(attributes
);
4475 PI_CHECK_INT(priority
);
4476 PI_CHECK_INT(default_priority
);
4477 PI_CHECK_INT(starttime
);
4478 PI_CHECK_INT(untiltime
);
4479 PI_CHECK_INT(averageppm
);
4481 /* Yuck - don't check the printername or servername as the
4482 add_a_printer() code plays games with them. You can't
4483 change the printername or the sharename through this interface
4486 PI_CHECK_STR(sharename
);
4487 PI_CHECK_STR(portname
);
4488 PI_CHECK_STR(drivername
);
4489 PI_CHECK_STR(comment
);
4490 PI_CHECK_STR(location
);
4492 if (!nt_devicemode_equal(pi1
->devmode
, pi2
->devmode
)) {
4496 PI_CHECK_STR(sepfile
);
4497 PI_CHECK_STR(printprocessor
);
4498 PI_CHECK_STR(datatype
);
4499 PI_CHECK_STR(parameters
);
4501 if (!nt_printer_param_equal(pi1
->specific
, pi2
->specific
)) {
4505 if (!sec_desc_equal(pi1
->secdesc_buf
->sec
, pi2
->secdesc_buf
->sec
)) {
4509 PI_CHECK_INT(changeid
);
4510 PI_CHECK_INT(c_setprinter
);
4511 PI_CHECK_INT(setuptime
);
4514 DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
4518 /********************************************************************
4519 * called by spoolss_api_setprinter
4520 * when updating a printer description
4521 ********************************************************************/
4523 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
4524 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4525 DEVICEMODE
*devmode
)
4528 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
4529 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4532 DEBUG(8,("update_printer\n"));
4537 DEBUG(0,("Send a mail to samba@samba.org\n"));
4538 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
4539 result
= WERR_UNKNOWN_LEVEL
;
4544 result
= WERR_BADFID
;
4548 if (!get_printer_snum(p
, handle
, &snum
)) {
4549 result
= WERR_BADFID
;
4553 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))) ||
4554 (!W_ERROR_IS_OK(get_a_printer(&old_printer
, 2, lp_servicename(snum
))))) {
4555 result
= WERR_BADFID
;
4559 DEBUGADD(8,("Converting info_2 struct\n"));
4562 * convert_printer_info converts the incoming
4563 * info from the client and overwrites the info
4564 * just read from the tdb in the pointer 'printer'.
4567 if (!convert_printer_info(info
, printer
, level
)) {
4568 result
= WERR_NOMEM
;
4572 if (info
->info_2
->devmode_ptr
!= 0) {
4573 /* we have a valid devmode
4574 convert it and link it*/
4576 DEBUGADD(8,("Converting the devicemode struct\n"));
4577 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
4578 &printer
->info_2
->devmode
)) {
4579 result
= WERR_NOMEM
;
4584 /* Do sanity check on the requested changes for Samba */
4586 if (!check_printer_ok(printer
->info_2
, snum
)) {
4587 result
= WERR_INVALID_PARAM
;
4591 /* NT likes to call this function even though nothing has actually
4592 changed. Check this so the user doesn't end up with an
4593 annoying permission denied dialog box. */
4595 if (nt_printer_info_level_equal(printer
, old_printer
)) {
4596 DEBUG(3, ("printer info has not changed\n"));
4601 /* Check calling user has permission to update printer description */
4603 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4604 DEBUG(3, ("printer property change denied by security "
4606 result
= WERR_ACCESS_DENIED
;
4610 /* Call addprinter hook */
4612 if (*lp_addprinter_cmd()) {
4613 if (!add_printer_hook(printer
)) {
4614 result
= WERR_ACCESS_DENIED
;
4619 /* Update printer info */
4620 result
= add_a_printer(*printer
, 2);
4623 free_a_printer(&printer
, 2);
4624 free_a_printer(&old_printer
, 2);
4626 srv_spoolss_sendnotify(p
, handle
);
4631 /****************************************************************************
4632 ****************************************************************************/
4634 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
4636 POLICY_HND
*handle
= &q_u
->handle
;
4637 uint32 level
= q_u
->level
;
4638 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
4639 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
4640 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
4641 uint32 command
= q_u
->command
;
4643 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4646 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4650 /* check the level */
4653 return control_printer(handle
, command
, p
);
4655 return update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
4657 return update_printer_sec(handle
, level
, info
, p
,
4660 return WERR_UNKNOWN_LEVEL
;
4664 /****************************************************************************
4665 ****************************************************************************/
4667 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
4669 POLICY_HND
*handle
= &q_u
->handle
;
4671 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4674 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4678 if (Printer
->notify
.client_connected
==True
)
4679 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
4681 Printer
->notify
.flags
=0;
4682 Printer
->notify
.options
=0;
4683 Printer
->notify
.localmachine
[0]='\0';
4684 Printer
->notify
.printerlocal
=0;
4685 if (Printer
->notify
.option
)
4686 free_spool_notify_option(&Printer
->notify
.option
);
4687 Printer
->notify
.client_connected
=False
;
4692 /****************************************************************************
4693 ****************************************************************************/
4695 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
4697 /* that's an [in out] buffer (despite appearences to the contrary) */
4698 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4701 return WERR_INVALID_PARAM
; /* this is what a NT server
4702 returns for AddJob. AddJob
4703 must fail on non-local
4707 /****************************************************************************
4708 ****************************************************************************/
4709 static void fill_job_info_1(JOB_INFO_1
*job_info
, print_queue_struct
*queue
,
4710 int position
, int snum
)
4716 t
=gmtime(&queue
->time
);
4717 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
4719 job_info
->jobid
=queue
->job
;
4720 init_unistr(&job_info
->printername
, lp_servicename(snum
));
4721 init_unistr(&job_info
->machinename
, temp_name
);
4722 init_unistr(&job_info
->username
, queue
->user
);
4723 init_unistr(&job_info
->document
, queue
->file
);
4724 init_unistr(&job_info
->datatype
, "RAW");
4725 init_unistr(&job_info
->text_status
, "");
4726 job_info
->status
=nt_printj_status(queue
->status
);
4727 job_info
->priority
=queue
->priority
;
4728 job_info
->position
=position
;
4729 job_info
->totalpages
=0;
4730 job_info
->pagesprinted
=0;
4732 make_systemtime(&job_info
->submitted
, t
);
4735 /****************************************************************************
4736 ****************************************************************************/
4737 static BOOL
fill_job_info_2(JOB_INFO_2
*job_info
, print_queue_struct
*queue
,
4738 int position
, int snum
,
4739 NT_PRINTER_INFO_LEVEL
*ntprinter
)
4745 t
=gmtime(&queue
->time
);
4746 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
4748 job_info
->jobid
=queue
->job
;
4750 slprintf(chaine
, sizeof(chaine
)-1, "\\\\%s\\%s", global_myname
, ntprinter
->info_2
->printername
);
4752 init_unistr(&job_info
->printername
, chaine
);
4754 init_unistr(&job_info
->machinename
, temp_name
);
4755 init_unistr(&job_info
->username
, queue
->user
);
4756 init_unistr(&job_info
->document
, queue
->file
);
4757 init_unistr(&job_info
->notifyname
, queue
->user
);
4758 init_unistr(&job_info
->datatype
, "RAW");
4759 init_unistr(&job_info
->printprocessor
, "winprint");
4760 init_unistr(&job_info
->parameters
, "");
4761 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
4762 init_unistr(&job_info
->text_status
, "");
4764 /* and here the security descriptor */
4766 job_info
->status
=nt_printj_status(queue
->status
);
4767 job_info
->priority
=queue
->priority
;
4768 job_info
->position
=position
;
4769 job_info
->starttime
=0;
4770 job_info
->untiltime
=0;
4771 job_info
->totalpages
=0;
4772 job_info
->size
=queue
->size
;
4773 make_systemtime(&(job_info
->submitted
), t
);
4774 job_info
->timeelapsed
=0;
4775 job_info
->pagesprinted
=0;
4777 if((job_info
->devmode
= construct_dev_mode(snum
)) == NULL
) {
4784 /****************************************************************************
4785 Enumjobs at level 1.
4786 ****************************************************************************/
4787 static WERROR
enumjobs_level1(print_queue_struct
*queue
, int snum
,
4788 NEW_BUFFER
*buffer
, uint32 offered
,
4789 uint32
*needed
, uint32
*returned
)
4794 info
=(JOB_INFO_1
*)malloc(*returned
*sizeof(JOB_INFO_1
));
4801 for (i
=0; i
<*returned
; i
++)
4802 fill_job_info_1(&info
[i
], &queue
[i
], i
, snum
);
4806 /* check the required size. */
4807 for (i
=0; i
<*returned
; i
++)
4808 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
4810 if (!alloc_buffer_size(buffer
, *needed
)) {
4812 return WERR_INSUFFICIENT_BUFFER
;
4815 /* fill the buffer with the structures */
4816 for (i
=0; i
<*returned
; i
++)
4817 smb_io_job_info_1("", buffer
, &info
[i
], 0);
4822 if (*needed
> offered
) {
4824 return WERR_INSUFFICIENT_BUFFER
;
4830 /****************************************************************************
4831 Enumjobs at level 2.
4832 ****************************************************************************/
4833 static WERROR
enumjobs_level2(print_queue_struct
*queue
, int snum
,
4834 NEW_BUFFER
*buffer
, uint32 offered
,
4835 uint32
*needed
, uint32
*returned
)
4837 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4842 info
=(JOB_INFO_2
*)malloc(*returned
*sizeof(JOB_INFO_2
));
4848 result
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
4849 if (!W_ERROR_IS_OK(result
)) {
4854 for (i
=0; i
<*returned
; i
++)
4855 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
);
4857 free_a_printer(&ntprinter
, 2);
4860 /* check the required size. */
4861 for (i
=0; i
<*returned
; i
++)
4862 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
4864 if (!alloc_buffer_size(buffer
, *needed
)) {
4866 return WERR_INSUFFICIENT_BUFFER
;
4869 /* fill the buffer with the structures */
4870 for (i
=0; i
<*returned
; i
++)
4871 smb_io_job_info_2("", buffer
, &info
[i
], 0);
4874 for (i
= 0; i
< *returned
; i
++)
4875 free_job_info_2(&info
[i
]);
4879 if (*needed
> offered
) {
4881 return WERR_INSUFFICIENT_BUFFER
;
4887 /****************************************************************************
4889 ****************************************************************************/
4891 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
4893 POLICY_HND
*handle
= &q_u
->handle
;
4894 /* uint32 firstjob = q_u->firstjob; - notused. */
4895 /* uint32 numofjobs = q_u->numofjobs; - notused. */
4896 uint32 level
= q_u
->level
;
4897 NEW_BUFFER
*buffer
= NULL
;
4898 uint32 offered
= q_u
->offered
;
4899 uint32
*needed
= &r_u
->needed
;
4900 uint32
*returned
= &r_u
->returned
;
4903 print_queue_struct
*queue
=NULL
;
4904 print_status_struct prt_status
;
4906 /* that's an [in out] buffer */
4907 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4908 buffer
= r_u
->buffer
;
4910 DEBUG(4,("_spoolss_enumjobs\n"));
4912 ZERO_STRUCT(prt_status
);
4917 if (!get_printer_snum(p
, handle
, &snum
))
4920 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
4921 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
4923 if (*returned
== 0) {
4930 return enumjobs_level1(queue
, snum
, buffer
, offered
, needed
, returned
);
4932 return enumjobs_level2(queue
, snum
, buffer
, offered
, needed
, returned
);
4936 return WERR_UNKNOWN_LEVEL
;
4940 /****************************************************************************
4941 ****************************************************************************/
4943 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
4948 /****************************************************************************
4949 ****************************************************************************/
4951 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
4953 POLICY_HND
*handle
= &q_u
->handle
;
4954 uint32 jobid
= q_u
->jobid
;
4955 /* uint32 level = q_u->level; - notused. */
4956 /* JOB_INFO *ctr = &q_u->ctr; - notused. */
4957 uint32 command
= q_u
->command
;
4959 struct current_user user
;
4960 print_status_struct prt_status
;
4962 WERROR errcode
= WERR_BADFUNC
;
4964 memset(&prt_status
, 0, sizeof(prt_status
));
4966 if (!get_printer_snum(p
, handle
, &snum
)) {
4970 if (!print_job_exists(jobid
)) {
4971 return WERR_INVALID_PRINTER_NAME
;
4974 get_current_user(&user
, p
);
4977 case JOB_CONTROL_CANCEL
:
4978 case JOB_CONTROL_DELETE
:
4979 if (print_job_delete(&user
, jobid
, &errcode
)) {
4983 case JOB_CONTROL_PAUSE
:
4984 if (print_job_pause(&user
, jobid
, &errcode
)) {
4988 case JOB_CONTROL_RESTART
:
4989 case JOB_CONTROL_RESUME
:
4990 if (print_job_resume(&user
, jobid
, &errcode
)) {
4995 return WERR_UNKNOWN_LEVEL
;
5001 /****************************************************************************
5002 Enumerates all printer drivers at level 1.
5003 ****************************************************************************/
5004 static WERROR
enumprinterdrivers_level1(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5009 fstring
*list
= NULL
;
5011 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5012 DRIVER_INFO_1
*tdi1
, *driver_info_1
=NULL
;
5016 #define MAX_VERSION 4
5018 for (version
=0; version
<MAX_VERSION
; version
++) {
5020 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5021 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5027 if((tdi1
=(DRIVER_INFO_1
*)Realloc(driver_info_1
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_1
))) == NULL
) {
5028 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
5029 SAFE_FREE(driver_info_1
);
5033 else driver_info_1
= tdi1
;
5036 for (i
=0; i
<ndrivers
; i
++) {
5038 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5039 ZERO_STRUCT(driver
);
5040 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5041 architecture
, version
);
5042 if (!W_ERROR_IS_OK(status
)) {
5046 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
5047 free_a_printer_driver(driver
, 3);
5050 *returned
+=ndrivers
;
5054 /* check the required size. */
5055 for (i
=0; i
<*returned
; i
++) {
5056 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5057 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
5060 if (!alloc_buffer_size(buffer
, *needed
)) {
5061 SAFE_FREE(driver_info_1
);
5062 return WERR_INSUFFICIENT_BUFFER
;
5065 /* fill the buffer with the driver structures */
5066 for (i
=0; i
<*returned
; i
++) {
5067 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5068 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
5071 SAFE_FREE(driver_info_1
);
5073 if (*needed
> offered
) {
5075 return WERR_INSUFFICIENT_BUFFER
;
5081 /****************************************************************************
5082 Enumerates all printer drivers at level 2.
5083 ****************************************************************************/
5084 static WERROR
enumprinterdrivers_level2(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5089 fstring
*list
= NULL
;
5091 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5092 DRIVER_INFO_2
*tdi2
, *driver_info_2
=NULL
;
5096 #define MAX_VERSION 4
5098 for (version
=0; version
<MAX_VERSION
; version
++) {
5100 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5101 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5107 if((tdi2
=(DRIVER_INFO_2
*)Realloc(driver_info_2
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_2
))) == NULL
) {
5108 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
5109 SAFE_FREE(driver_info_2
);
5113 else driver_info_2
= tdi2
;
5116 for (i
=0; i
<ndrivers
; i
++) {
5119 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5120 ZERO_STRUCT(driver
);
5121 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5122 architecture
, version
);
5123 if (!W_ERROR_IS_OK(status
)) {
5127 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
5128 free_a_printer_driver(driver
, 3);
5131 *returned
+=ndrivers
;
5135 /* check the required size. */
5136 for (i
=0; i
<*returned
; i
++) {
5137 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5138 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
5141 if (!alloc_buffer_size(buffer
, *needed
)) {
5142 SAFE_FREE(driver_info_2
);
5143 return WERR_INSUFFICIENT_BUFFER
;
5146 /* fill the buffer with the form structures */
5147 for (i
=0; i
<*returned
; i
++) {
5148 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5149 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
5152 SAFE_FREE(driver_info_2
);
5154 if (*needed
> offered
) {
5156 return WERR_INSUFFICIENT_BUFFER
;
5162 /****************************************************************************
5163 Enumerates all printer drivers at level 3.
5164 ****************************************************************************/
5165 static WERROR
enumprinterdrivers_level3(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5170 fstring
*list
= NULL
;
5172 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5173 DRIVER_INFO_3
*tdi3
, *driver_info_3
=NULL
;
5177 #define MAX_VERSION 4
5179 for (version
=0; version
<MAX_VERSION
; version
++) {
5181 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5182 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5188 if((tdi3
=(DRIVER_INFO_3
*)Realloc(driver_info_3
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_3
))) == NULL
) {
5189 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
5190 SAFE_FREE(driver_info_3
);
5194 else driver_info_3
= tdi3
;
5197 for (i
=0; i
<ndrivers
; i
++) {
5200 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5201 ZERO_STRUCT(driver
);
5202 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5203 architecture
, version
);
5204 if (!W_ERROR_IS_OK(status
)) {
5208 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
5209 free_a_printer_driver(driver
, 3);
5212 *returned
+=ndrivers
;
5216 /* check the required size. */
5217 for (i
=0; i
<*returned
; i
++) {
5218 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5219 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
5222 if (!alloc_buffer_size(buffer
, *needed
)) {
5223 SAFE_FREE(driver_info_3
);
5224 return WERR_INSUFFICIENT_BUFFER
;
5227 /* fill the buffer with the driver structures */
5228 for (i
=0; i
<*returned
; i
++) {
5229 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5230 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
5233 for (i
=0; i
<*returned
; i
++)
5234 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
5236 SAFE_FREE(driver_info_3
);
5238 if (*needed
> offered
) {
5240 return WERR_INSUFFICIENT_BUFFER
;
5246 /****************************************************************************
5247 Enumerates all printer drivers.
5248 ****************************************************************************/
5250 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
5252 /* UNISTR2 *name = &q_u->name; - notused. */
5253 UNISTR2
*environment
= &q_u
->environment
;
5254 uint32 level
= q_u
->level
;
5255 NEW_BUFFER
*buffer
= NULL
;
5256 uint32 offered
= q_u
->offered
;
5257 uint32
*needed
= &r_u
->needed
;
5258 uint32
*returned
= &r_u
->returned
;
5260 fstring
*list
= NULL
;
5262 fstring architecture
;
5264 /* that's an [in out] buffer */
5265 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5266 buffer
= r_u
->buffer
;
5268 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
5269 fstrcpy(servername
, global_myname
);
5273 unistr2_to_ascii(architecture
, environment
, sizeof(architecture
)-1);
5277 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
5279 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
5281 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
5285 return WERR_UNKNOWN_LEVEL
;
5289 /****************************************************************************
5290 ****************************************************************************/
5292 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
5294 form
->flag
=list
->flag
;
5295 init_unistr(&form
->name
, list
->name
);
5296 form
->width
=list
->width
;
5297 form
->length
=list
->length
;
5298 form
->left
=list
->left
;
5299 form
->top
=list
->top
;
5300 form
->right
=list
->right
;
5301 form
->bottom
=list
->bottom
;
5304 /****************************************************************************
5305 ****************************************************************************/
5307 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
5309 /* POLICY_HND *handle = &q_u->handle; - notused. */
5310 uint32 level
= q_u
->level
;
5311 NEW_BUFFER
*buffer
= NULL
;
5312 uint32 offered
= q_u
->offered
;
5313 uint32
*needed
= &r_u
->needed
;
5314 uint32
*numofforms
= &r_u
->numofforms
;
5315 uint32 numbuiltinforms
;
5317 nt_forms_struct
*list
=NULL
;
5318 nt_forms_struct
*builtinlist
=NULL
;
5323 /* that's an [in out] buffer */
5324 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5325 buffer
= r_u
->buffer
;
5327 DEBUG(4,("_spoolss_enumforms\n"));
5328 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5329 DEBUGADD(5,("Info level [%d]\n", level
));
5331 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
5332 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
5333 *numofforms
= get_ntforms(&list
);
5334 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
5335 *numofforms
+= numbuiltinforms
;
5337 if (*numofforms
== 0) return WERR_NO_MORE_ITEMS
;
5341 if ((forms_1
=(FORM_1
*)malloc(*numofforms
* sizeof(FORM_1
))) == NULL
) {
5346 /* construct the list of form structures */
5347 for (i
=0; i
<numbuiltinforms
; i
++) {
5348 DEBUGADD(6,("Filling form number [%d]\n",i
));
5349 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
5352 SAFE_FREE(builtinlist
);
5354 for (; i
<*numofforms
; i
++) {
5355 DEBUGADD(6,("Filling form number [%d]\n",i
));
5356 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
5361 /* check the required size. */
5362 for (i
=0; i
<numbuiltinforms
; i
++) {
5363 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5364 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5366 for (; i
<*numofforms
; i
++) {
5367 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5368 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5371 *needed
=buffer_size
;
5373 if (!alloc_buffer_size(buffer
, buffer_size
)){
5375 return WERR_INSUFFICIENT_BUFFER
;
5378 /* fill the buffer with the form structures */
5379 for (i
=0; i
<numbuiltinforms
; i
++) {
5380 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5381 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5383 for (; i
<*numofforms
; i
++) {
5384 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5385 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5390 if (*needed
> offered
) {
5392 return WERR_INSUFFICIENT_BUFFER
;
5399 SAFE_FREE(builtinlist
);
5400 return WERR_UNKNOWN_LEVEL
;
5405 /****************************************************************************
5406 ****************************************************************************/
5408 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
5410 /* POLICY_HND *handle = &q_u->handle; - notused. */
5411 uint32 level
= q_u
->level
;
5412 UNISTR2
*uni_formname
= &q_u
->formname
;
5413 NEW_BUFFER
*buffer
= NULL
;
5414 uint32 offered
= q_u
->offered
;
5415 uint32
*needed
= &r_u
->needed
;
5417 nt_forms_struct
*list
=NULL
;
5418 nt_forms_struct builtin_form
;
5423 int numofforms
=0, i
=0;
5425 /* that's an [in out] buffer */
5426 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5427 buffer
= r_u
->buffer
;
5429 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
)-1);
5431 DEBUG(4,("_spoolss_getform\n"));
5432 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5433 DEBUGADD(5,("Info level [%d]\n", level
));
5435 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
5436 if (!foundBuiltin
) {
5437 numofforms
= get_ntforms(&list
);
5438 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
5440 if (numofforms
== 0)
5447 fill_form_1(&form_1
, &builtin_form
);
5450 /* Check if the requested name is in the list of form structures */
5451 for (i
=0; i
<numofforms
; i
++) {
5453 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
5455 if (strequal(form_name
, list
[i
].name
)) {
5456 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
5457 fill_form_1(&form_1
, &list
[i
]);
5463 if (i
== numofforms
) {
5467 /* check the required size. */
5469 *needed
=spoolss_size_form_1(&form_1
);
5471 if (!alloc_buffer_size(buffer
, buffer_size
)){
5472 return WERR_INSUFFICIENT_BUFFER
;
5475 if (*needed
> offered
) {
5476 return WERR_INSUFFICIENT_BUFFER
;
5479 /* fill the buffer with the form structures */
5480 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
5481 smb_io_form_1("", buffer
, &form_1
, 0);
5487 return WERR_UNKNOWN_LEVEL
;
5491 /****************************************************************************
5492 ****************************************************************************/
5493 static void fill_port_1(PORT_INFO_1
*port
, char *name
)
5495 init_unistr(&port
->port_name
, name
);
5498 /****************************************************************************
5499 ****************************************************************************/
5500 static void fill_port_2(PORT_INFO_2
*port
, char *name
)
5502 init_unistr(&port
->port_name
, name
);
5503 init_unistr(&port
->monitor_name
, "Local Monitor");
5504 init_unistr(&port
->description
, "Local Port");
5505 #define PORT_TYPE_WRITE 1
5506 port
->port_type
=PORT_TYPE_WRITE
;
5510 /****************************************************************************
5512 ****************************************************************************/
5513 static WERROR
enumports_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5515 PORT_INFO_1
*ports
=NULL
;
5518 if (*lp_enumports_cmd()) {
5519 char *cmd
= lp_enumports_cmd();
5526 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 1);
5528 DEBUG(10,("Running [%s]\n", command
));
5529 ret
= smbrun(command
, &fd
);
5530 DEBUG(10,("Returned [%d]\n", ret
));
5534 /* Is this the best error to return here? */
5535 return WERR_ACCESS_DENIED
;
5539 qlines
= fd_lines_load(fd
, &numlines
);
5540 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5544 if((ports
=(PORT_INFO_1
*)malloc( numlines
* sizeof(PORT_INFO_1
) )) == NULL
) {
5545 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
5546 werror_str(WERR_NOMEM
)));
5547 file_lines_free(qlines
);
5551 for (i
=0; i
<numlines
; i
++) {
5552 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5553 fill_port_1(&ports
[i
], qlines
[i
]);
5556 file_lines_free(qlines
);
5559 *returned
= numlines
;
5562 *returned
= 1; /* Sole Samba port returned. */
5564 if((ports
=(PORT_INFO_1
*)malloc( sizeof(PORT_INFO_1
) )) == NULL
)
5567 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5569 fill_port_1(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5572 /* check the required size. */
5573 for (i
=0; i
<*returned
; i
++) {
5574 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5575 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
5578 if (!alloc_buffer_size(buffer
, *needed
)) {
5580 return WERR_INSUFFICIENT_BUFFER
;
5583 /* fill the buffer with the ports structures */
5584 for (i
=0; i
<*returned
; i
++) {
5585 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5586 smb_io_port_1("", buffer
, &ports
[i
], 0);
5591 if (*needed
> offered
) {
5593 return WERR_INSUFFICIENT_BUFFER
;
5599 /****************************************************************************
5601 ****************************************************************************/
5603 static WERROR
enumports_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5605 PORT_INFO_2
*ports
=NULL
;
5608 if (*lp_enumports_cmd()) {
5609 char *cmd
= lp_enumports_cmd();
5618 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME
)))
5619 path
= lp_pathname(lp_servicenumber(PRINTERS_NAME
));
5621 path
= lp_lockdir();
5623 slprintf(tmp_file
, sizeof(tmp_file
)-1, "%s/smbcmd.%u.", path
, (unsigned int)sys_getpid());
5624 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 2);
5627 DEBUG(10,("Running [%s > %s]\n", command
,tmp_file
));
5628 ret
= smbrun(command
, &fd
);
5629 DEBUGADD(10,("returned [%d]\n", ret
));
5633 /* Is this the best error to return here? */
5634 return WERR_ACCESS_DENIED
;
5638 qlines
= fd_lines_load(fd
, &numlines
);
5639 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5643 if((ports
=(PORT_INFO_2
*)malloc( numlines
* sizeof(PORT_INFO_2
) )) == NULL
) {
5644 file_lines_free(qlines
);
5648 for (i
=0; i
<numlines
; i
++) {
5649 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5650 fill_port_2(&(ports
[i
]), qlines
[i
]);
5653 file_lines_free(qlines
);
5656 *returned
= numlines
;
5662 if((ports
=(PORT_INFO_2
*)malloc( sizeof(PORT_INFO_2
) )) == NULL
)
5665 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5667 fill_port_2(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5670 /* check the required size. */
5671 for (i
=0; i
<*returned
; i
++) {
5672 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5673 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
5676 if (!alloc_buffer_size(buffer
, *needed
)) {
5678 return WERR_INSUFFICIENT_BUFFER
;
5681 /* fill the buffer with the ports structures */
5682 for (i
=0; i
<*returned
; i
++) {
5683 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5684 smb_io_port_2("", buffer
, &ports
[i
], 0);
5689 if (*needed
> offered
) {
5691 return WERR_INSUFFICIENT_BUFFER
;
5697 /****************************************************************************
5699 ****************************************************************************/
5701 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
5703 /* UNISTR2 *name = &q_u->name; - notused. */
5704 uint32 level
= q_u
->level
;
5705 NEW_BUFFER
*buffer
= NULL
;
5706 uint32 offered
= q_u
->offered
;
5707 uint32
*needed
= &r_u
->needed
;
5708 uint32
*returned
= &r_u
->returned
;
5710 /* that's an [in out] buffer */
5711 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5712 buffer
= r_u
->buffer
;
5714 DEBUG(4,("_spoolss_enumports\n"));
5721 return enumports_level_1(buffer
, offered
, needed
, returned
);
5723 return enumports_level_2(buffer
, offered
, needed
, returned
);
5725 return WERR_UNKNOWN_LEVEL
;
5729 /****************************************************************************
5730 ****************************************************************************/
5731 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
5732 const SPOOL_PRINTER_INFO_LEVEL
*info
,
5733 uint32 unk0
, uint32 unk1
, uint32 unk2
, uint32 unk3
,
5734 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
5737 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5740 WERROR err
= WERR_OK
;
5742 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
5743 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
5747 ZERO_STRUCTP(printer
);
5749 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
5750 if (!convert_printer_info(info
, printer
, 2)) {
5751 free_a_printer(&printer
, 2);
5755 /* check to see if the printer already exists */
5757 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
5758 DEBUG(5, ("_spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed!\n",
5759 printer
->info_2
->sharename
));
5760 free_a_printer(&printer
, 2);
5761 return WERR_PRINTER_ALREADY_EXISTS
;
5764 if (*lp_addprinter_cmd() )
5765 if ( !add_printer_hook(printer
) ) {
5766 free_a_printer(&printer
,2);
5767 return WERR_ACCESS_DENIED
;
5770 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname
,
5771 printer
->info_2
->sharename
);
5773 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
5774 free_a_printer(&printer
,2);
5775 return WERR_ACCESS_DENIED
;
5778 /* you must be a printer admin to add a new printer */
5779 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
5780 free_a_printer(&printer
,2);
5781 return WERR_ACCESS_DENIED
;
5785 * Do sanity check on the requested changes for Samba.
5788 if (!check_printer_ok(printer
->info_2
, snum
)) {
5789 free_a_printer(&printer
,2);
5790 return WERR_INVALID_PARAM
;
5794 * When a printer is created, the drivername bound to the printer is used
5795 * to lookup previously saved driver initialization info, which is then
5796 * bound to the new printer, simulating what happens in the Windows arch.
5798 set_driver_init(printer
, 2);
5800 /* write the ASCII on disk */
5801 err
= add_a_printer(*printer
, 2);
5802 if (!W_ERROR_IS_OK(err
)) {
5803 free_a_printer(&printer
,2);
5807 if (!open_printer_hnd(p
, handle
, name
)) {
5808 /* Handle open failed - remove addition. */
5809 del_a_printer(printer
->info_2
->sharename
);
5810 free_a_printer(&printer
,2);
5811 return WERR_ACCESS_DENIED
;
5814 free_a_printer(&printer
,2);
5816 srv_spoolss_sendnotify(p
, handle
);
5821 /****************************************************************************
5822 ****************************************************************************/
5824 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
5826 UNISTR2
*uni_srv_name
= &q_u
->server_name
;
5827 uint32 level
= q_u
->level
;
5828 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
5829 uint32 unk0
= q_u
->unk0
;
5830 uint32 unk1
= q_u
->unk1
;
5831 uint32 unk2
= q_u
->unk2
;
5832 uint32 unk3
= q_u
->unk3
;
5833 uint32 user_switch
= q_u
->user_switch
;
5834 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
5835 POLICY_HND
*handle
= &r_u
->handle
;
5839 /* we don't handle yet */
5840 /* but I know what to do ... */
5841 return WERR_UNKNOWN_LEVEL
;
5843 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
5844 unk0
, unk1
, unk2
, unk3
,
5845 user_switch
, user
, handle
);
5847 return WERR_UNKNOWN_LEVEL
;
5851 /****************************************************************************
5852 ****************************************************************************/
5854 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
5856 /* UNISTR2 *server_name = &q_u->server_name; - notused. */
5857 uint32 level
= q_u
->level
;
5858 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
5859 WERROR err
= WERR_OK
;
5860 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5861 struct current_user user
;
5863 ZERO_STRUCT(driver
);
5865 get_current_user(&user
, p
);
5867 if (!convert_printer_driver_info(info
, &driver
, level
)) {
5872 DEBUG(5,("Cleaning driver's information\n"));
5873 err
= clean_up_driver_struct(driver
, level
, &user
);
5874 if (!W_ERROR_IS_OK(err
))
5877 DEBUG(5,("Moving driver to final destination\n"));
5878 if(!move_driver_to_download_area(driver
, level
, &user
, &err
)) {
5879 if (W_ERROR_IS_OK(err
))
5880 err
= WERR_ACCESS_DENIED
;
5884 if (add_a_printer_driver(driver
, level
)!=0) {
5885 err
= WERR_ACCESS_DENIED
;
5890 free_a_printer_driver(driver
, level
);
5894 /****************************************************************************
5895 ****************************************************************************/
5896 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
5898 init_unistr(&info
->name
, name
);
5901 /****************************************************************************
5902 ****************************************************************************/
5903 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5907 pstring short_archi
;
5908 DRIVER_DIRECTORY_1
*info
=NULL
;
5910 unistr2_to_ascii(long_archi
, uni_environment
, sizeof(long_archi
)-1);
5912 if (get_short_archi(short_archi
, long_archi
)==False
)
5913 return WERR_INVALID_ENVIRONMENT
;
5915 if((info
=(DRIVER_DIRECTORY_1
*)malloc(sizeof(DRIVER_DIRECTORY_1
))) == NULL
)
5918 slprintf(path
, sizeof(path
)-1, "\\\\%s\\print$\\%s", global_myname
, short_archi
);
5920 DEBUG(4,("printer driver directory: [%s]\n", path
));
5922 fill_driverdir_1(info
, path
);
5924 *needed
+= spoolss_size_driverdir_info_1(info
);
5926 if (!alloc_buffer_size(buffer
, *needed
)) {
5928 return WERR_INSUFFICIENT_BUFFER
;
5931 smb_io_driverdir_1("", buffer
, info
, 0);
5935 if (*needed
> offered
)
5936 return WERR_INSUFFICIENT_BUFFER
;
5941 /****************************************************************************
5942 ****************************************************************************/
5944 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
5946 UNISTR2
*name
= &q_u
->name
;
5947 UNISTR2
*uni_environment
= &q_u
->environment
;
5948 uint32 level
= q_u
->level
;
5949 NEW_BUFFER
*buffer
= NULL
;
5950 uint32 offered
= q_u
->offered
;
5951 uint32
*needed
= &r_u
->needed
;
5953 /* that's an [in out] buffer */
5954 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5955 buffer
= r_u
->buffer
;
5957 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
5963 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
5965 return WERR_UNKNOWN_LEVEL
;
5969 /****************************************************************************
5970 ****************************************************************************/
5972 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
5974 POLICY_HND
*handle
= &q_u
->handle
;
5975 uint32 idx
= q_u
->index
;
5976 uint32 in_value_len
= q_u
->valuesize
;
5977 uint32 in_data_len
= q_u
->datasize
;
5978 uint32
*out_max_value_len
= &r_u
->valuesize
;
5979 uint16
**out_value
= &r_u
->value
;
5980 uint32
*out_value_len
= &r_u
->realvaluesize
;
5981 uint32
*out_type
= &r_u
->type
;
5982 uint32
*out_max_data_len
= &r_u
->datasize
;
5983 uint8
**data_out
= &r_u
->data
;
5984 uint32
*out_data_len
= &r_u
->realdatasize
;
5986 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5991 uint32 biggest_valuesize
;
5992 uint32 biggest_datasize
;
5994 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6000 ZERO_STRUCT(printer
);
6004 *out_max_data_len
=0;
6008 DEBUG(5,("spoolss_enumprinterdata\n"));
6011 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6015 if (!get_printer_snum(p
,handle
, &snum
))
6018 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6019 if (!W_ERROR_IS_OK(result
))
6023 * The NT machine wants to know the biggest size of value and data
6025 * cf: MSDN EnumPrinterData remark section
6027 if ( (in_value_len
==0) && (in_data_len
==0) ) {
6028 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
6032 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
6033 * if this parameter size doesn't exist.
6034 * Ok - my opinion here is that the client is not asking for the greatest
6035 * possible size of all the parameters, but is asking specifically for the size needed
6036 * for this specific parameter. In that case we can remove the loop below and
6037 * simplify this lookup code considerably. JF - comments welcome. JRA.
6040 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
6042 free_a_printer(&printer
, 2);
6043 return WERR_NO_MORE_ITEMS
;
6050 biggest_valuesize
=0;
6053 while (get_specific_param_by_index(*printer
, 2, param_index
, value
, &data
, &type
, &data_len
)) {
6054 if (strlen(value
) > biggest_valuesize
) biggest_valuesize
=strlen(value
);
6055 if (data_len
> biggest_datasize
) biggest_datasize
=data_len
;
6057 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
, biggest_datasize
));
6063 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
6064 *out_value_len
=2*(1+biggest_valuesize
);
6065 *out_data_len
=biggest_datasize
;
6067 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
6069 free_a_printer(&printer
, 2);
6074 * the value len is wrong in NT sp3
6075 * that's the number of bytes not the number of unicode chars
6078 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
6081 free_a_printer(&printer
, 2);
6083 /* out_value should default to "" or else NT4 has
6084 problems unmarshalling the response */
6086 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
6087 if((*out_value
=(uint16
*)malloc(in_value_len
*sizeof(uint8
))) == NULL
)
6090 ZERO_STRUCTP(*out_value
);
6091 *out_value_len
= rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
6093 /* the data is counted in bytes */
6094 *out_max_data_len
= in_data_len
;
6095 *out_data_len
= in_data_len
;
6096 if((*data_out
=(uint8
*)malloc(in_data_len
*sizeof(uint8
))) == NULL
)
6099 memset(*data_out
,'\0',in_data_len
);
6101 return WERR_NO_MORE_ITEMS
;
6104 free_a_printer(&printer
, 2);
6108 * - counted in bytes in the request
6109 * - counted in UNICODE chars in the max reply
6110 * - counted in bytes in the real size
6112 * take a pause *before* coding not *during* coding
6115 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
6116 if((*out_value
=(uint16
*)talloc_zero(p
->mem_ctx
,in_value_len
*sizeof(uint8
))) == NULL
) {
6121 *out_value_len
= rpcstr_push((char *)*out_value
,value
, in_value_len
, 0);
6125 /* the data is counted in bytes */
6126 *out_max_data_len
=in_data_len
;
6127 if((*data_out
=(uint8
*)talloc_zero(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) {
6132 memcpy(*data_out
, data
, (size_t)data_len
);
6133 *out_data_len
=data_len
;
6140 /****************************************************************************
6141 ****************************************************************************/
6143 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
6145 POLICY_HND
*handle
= &q_u
->handle
;
6146 UNISTR2
*value
= &q_u
->value
;
6147 uint32 type
= q_u
->type
;
6148 /* uint32 max_len = q_u->max_len; - notused. */
6149 uint8
*data
= q_u
->data
;
6150 uint32 real_len
= q_u
->real_len
;
6151 /* uint32 numeric_data = q_u->numeric_data; - notused. */
6153 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6154 NT_PRINTER_PARAM
*param
= NULL
, old_param
;
6156 WERROR status
= WERR_OK
;
6157 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6159 DEBUG(5,("spoolss_setprinterdata\n"));
6162 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6166 if (!get_printer_snum(p
,handle
, &snum
))
6169 ZERO_STRUCT(old_param
);
6172 * Access check : NT returns "access denied" if you make a
6173 * SetPrinterData call without the necessary privildge.
6174 * we were originally returning OK if nothing changed
6175 * which made Win2k issue **a lot** of SetPrinterData
6176 * when connecting to a printer --jerry
6179 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6180 DEBUG(3, ("security descriptor change denied by existing "
6181 "security descriptor\n"));
6182 status
= WERR_ACCESS_DENIED
;
6186 /* Check if we are making any changes or not. Return true if
6187 nothing is actually changing. This is not needed anymore but
6188 has been left in as an optimization to keep from from
6189 writing to disk as often --jerry */
6191 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6192 if (!W_ERROR_IS_OK(status
))
6195 convert_specific_param(¶m
, value
, type
, data
, real_len
);
6198 if (get_specific_param(*printer
, 2, param
->value
, &old_param
.data
,
6199 &old_param
.type
, (uint32
*)&old_param
.data_len
)) {
6201 if (param
->type
== old_param
.type
&&
6202 param
->data_len
== old_param
.data_len
&&
6203 memcmp(param
->data
, old_param
.data
,
6204 old_param
.data_len
) == 0) {
6206 DEBUG(3, ("setprinterdata hasn't changed\n"));
6212 unlink_specific_param_if_exist(printer
->info_2
, param
);
6215 * When client side code sets a magic printer data key, detect it and save
6216 * the current printer data and the magic key's data (its the DEVMODE) for
6217 * future printer/driver initializations.
6219 if (param
->type
==3 && !strcmp( param
->value
, PHANTOM_DEVMODE_KEY
)) {
6221 * Set devmode and printer initialization info
6223 status
= save_driver_init(printer
, 2, param
);
6226 add_a_specific_param(printer
->info_2
, ¶m
);
6227 status
= mod_a_printer(*printer
, 2);
6231 free_a_printer(&printer
, 2);
6233 free_nt_printer_param(¶m
);
6234 SAFE_FREE(old_param
.data
);
6239 /****************************************************************************
6240 ****************************************************************************/
6242 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
6244 POLICY_HND
*handle
= &q_u
->handle
;
6245 UNISTR2
*value
= &q_u
->valuename
;
6247 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6248 NT_PRINTER_PARAM param
;
6250 WERROR status
= WERR_OK
;
6251 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6253 DEBUG(5,("spoolss_deleteprinterdata\n"));
6256 DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6260 if (!get_printer_snum(p
, handle
, &snum
))
6263 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6264 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
6265 "change denied by existing security descriptor\n"));
6266 return WERR_ACCESS_DENIED
;
6269 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6270 if (!W_ERROR_IS_OK(status
))
6273 ZERO_STRUCTP(¶m
);
6274 unistr2_to_ascii(param
.value
, value
, sizeof(param
.value
)-1);
6276 if(!unlink_specific_param_if_exist(printer
->info_2
, ¶m
))
6277 status
= WERR_INVALID_PARAM
;
6279 status
= mod_a_printer(*printer
, 2);
6281 free_a_printer(&printer
, 2);
6285 /****************************************************************************
6286 ****************************************************************************/
6288 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
6290 POLICY_HND
*handle
= &q_u
->handle
;
6291 /* uint32 level = q_u->level; - notused. */
6292 FORM
*form
= &q_u
->form
;
6293 nt_forms_struct tmpForm
;
6296 nt_forms_struct
*list
=NULL
;
6297 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6299 DEBUG(5,("spoolss_addform\n"));
6302 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6306 /* can't add if builtin */
6307 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6308 return WERR_INVALID_PARAM
;
6311 count
=get_ntforms(&list
);
6312 if(!add_a_form(&list
, form
, &count
))
6314 write_ntforms(&list
, count
);
6321 /****************************************************************************
6322 ****************************************************************************/
6324 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
6326 POLICY_HND
*handle
= &q_u
->handle
;
6327 UNISTR2
*form_name
= &q_u
->name
;
6328 nt_forms_struct tmpForm
;
6330 WERROR ret
= WERR_OK
;
6331 nt_forms_struct
*list
=NULL
;
6332 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6334 DEBUG(5,("spoolss_deleteform\n"));
6337 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6341 /* can't delete if builtin */
6342 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
6343 return WERR_INVALID_PARAM
;
6346 count
= get_ntforms(&list
);
6347 if(!delete_a_form(&list
, form_name
, &count
, &ret
))
6348 return WERR_INVALID_PARAM
;
6355 /****************************************************************************
6356 ****************************************************************************/
6358 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
6360 POLICY_HND
*handle
= &q_u
->handle
;
6361 /* UNISTR2 *uni_name = &q_u->name; - notused. */
6362 /* uint32 level = q_u->level; - notused. */
6363 FORM
*form
= &q_u
->form
;
6364 nt_forms_struct tmpForm
;
6367 nt_forms_struct
*list
=NULL
;
6368 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6370 DEBUG(5,("spoolss_setform\n"));
6373 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6376 /* can't set if builtin */
6377 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6378 return WERR_INVALID_PARAM
;
6381 count
=get_ntforms(&list
);
6382 update_a_form(&list
, form
, count
);
6383 write_ntforms(&list
, count
);
6390 /****************************************************************************
6391 enumprintprocessors level 1.
6392 ****************************************************************************/
6393 static WERROR
enumprintprocessors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6395 PRINTPROCESSOR_1
*info_1
=NULL
;
6397 if((info_1
= (PRINTPROCESSOR_1
*)malloc(sizeof(PRINTPROCESSOR_1
))) == NULL
)
6402 init_unistr(&info_1
->name
, "winprint");
6404 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
6406 if (!alloc_buffer_size(buffer
, *needed
))
6407 return WERR_INSUFFICIENT_BUFFER
;
6409 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
6413 if (*needed
> offered
) {
6415 return WERR_INSUFFICIENT_BUFFER
;
6421 /****************************************************************************
6422 ****************************************************************************/
6424 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
6426 /* UNISTR2 *name = &q_u->name; - notused. */
6427 /* UNISTR2 *environment = &q_u->environment; - notused. */
6428 uint32 level
= q_u
->level
;
6429 NEW_BUFFER
*buffer
= NULL
;
6430 uint32 offered
= q_u
->offered
;
6431 uint32
*needed
= &r_u
->needed
;
6432 uint32
*returned
= &r_u
->returned
;
6434 /* that's an [in out] buffer */
6435 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6436 buffer
= r_u
->buffer
;
6438 DEBUG(5,("spoolss_enumprintprocessors\n"));
6441 * Enumerate the print processors ...
6443 * Just reply with "winprint", to keep NT happy
6444 * and I can use my nice printer checker.
6452 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
6454 return WERR_UNKNOWN_LEVEL
;
6458 /****************************************************************************
6459 enumprintprocdatatypes level 1.
6460 ****************************************************************************/
6461 static WERROR
enumprintprocdatatypes_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6463 PRINTPROCDATATYPE_1
*info_1
=NULL
;
6465 if((info_1
= (PRINTPROCDATATYPE_1
*)malloc(sizeof(PRINTPROCDATATYPE_1
))) == NULL
)
6470 init_unistr(&info_1
->name
, "RAW");
6472 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
6474 if (!alloc_buffer_size(buffer
, *needed
))
6475 return WERR_INSUFFICIENT_BUFFER
;
6477 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
6481 if (*needed
> offered
) {
6483 return WERR_INSUFFICIENT_BUFFER
;
6489 /****************************************************************************
6490 ****************************************************************************/
6492 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
6494 /* UNISTR2 *name = &q_u->name; - notused. */
6495 /* UNISTR2 *processor = &q_u->processor; - notused. */
6496 uint32 level
= q_u
->level
;
6497 NEW_BUFFER
*buffer
= NULL
;
6498 uint32 offered
= q_u
->offered
;
6499 uint32
*needed
= &r_u
->needed
;
6500 uint32
*returned
= &r_u
->returned
;
6502 /* that's an [in out] buffer */
6503 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6504 buffer
= r_u
->buffer
;
6506 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
6513 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
6515 return WERR_UNKNOWN_LEVEL
;
6519 /****************************************************************************
6520 enumprintmonitors level 1.
6521 ****************************************************************************/
6523 static WERROR
enumprintmonitors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6525 PRINTMONITOR_1
*info_1
=NULL
;
6527 if((info_1
= (PRINTMONITOR_1
*)malloc(sizeof(PRINTMONITOR_1
))) == NULL
)
6532 init_unistr(&info_1
->name
, "Local Port");
6534 *needed
+= spoolss_size_printmonitor_info_1(info_1
);
6536 if (!alloc_buffer_size(buffer
, *needed
))
6537 return WERR_INSUFFICIENT_BUFFER
;
6539 smb_io_printmonitor_info_1("", buffer
, info_1
, 0);
6543 if (*needed
> offered
) {
6545 return WERR_INSUFFICIENT_BUFFER
;
6551 /****************************************************************************
6552 enumprintmonitors level 2.
6553 ****************************************************************************/
6554 static WERROR
enumprintmonitors_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6556 PRINTMONITOR_2
*info_2
=NULL
;
6558 if((info_2
= (PRINTMONITOR_2
*)malloc(sizeof(PRINTMONITOR_2
))) == NULL
)
6563 init_unistr(&info_2
->name
, "Local Port");
6564 init_unistr(&info_2
->environment
, "Windows NT X86");
6565 init_unistr(&info_2
->dll_name
, "localmon.dll");
6567 *needed
+= spoolss_size_printmonitor_info_2(info_2
);
6569 if (!alloc_buffer_size(buffer
, *needed
))
6570 return WERR_INSUFFICIENT_BUFFER
;
6572 smb_io_printmonitor_info_2("", buffer
, info_2
, 0);
6576 if (*needed
> offered
) {
6578 return WERR_INSUFFICIENT_BUFFER
;
6584 /****************************************************************************
6585 ****************************************************************************/
6587 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
6589 /* UNISTR2 *name = &q_u->name; - notused. */
6590 uint32 level
= q_u
->level
;
6591 NEW_BUFFER
*buffer
= NULL
;
6592 uint32 offered
= q_u
->offered
;
6593 uint32
*needed
= &r_u
->needed
;
6594 uint32
*returned
= &r_u
->returned
;
6596 /* that's an [in out] buffer */
6597 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6598 buffer
= r_u
->buffer
;
6600 DEBUG(5,("spoolss_enumprintmonitors\n"));
6603 * Enumerate the print monitors ...
6605 * Just reply with "Local Port", to keep NT happy
6606 * and I can use my nice printer checker.
6614 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
6616 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
6618 return WERR_UNKNOWN_LEVEL
;
6622 /****************************************************************************
6623 ****************************************************************************/
6624 static WERROR
getjob_level_1(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6628 JOB_INFO_1
*info_1
=NULL
;
6630 info_1
=(JOB_INFO_1
*)malloc(sizeof(JOB_INFO_1
));
6632 if (info_1
== NULL
) {
6637 for (i
=0; i
<count
&& found
==False
; i
++) {
6638 if (queue
[i
].job
==(int)jobid
)
6645 /* NT treats not found as bad param... yet another bad choice */
6646 return WERR_INVALID_PARAM
;
6649 fill_job_info_1(info_1
, &(queue
[i
-1]), i
, snum
);
6653 *needed
+= spoolss_size_job_info_1(info_1
);
6655 if (!alloc_buffer_size(buffer
, *needed
)) {
6657 return WERR_INSUFFICIENT_BUFFER
;
6660 smb_io_job_info_1("", buffer
, info_1
, 0);
6664 if (*needed
> offered
)
6665 return WERR_INSUFFICIENT_BUFFER
;
6671 /****************************************************************************
6672 ****************************************************************************/
6673 static WERROR
getjob_level_2(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6678 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6681 info_2
=(JOB_INFO_2
*)malloc(sizeof(JOB_INFO_2
));
6683 ZERO_STRUCTP(info_2
);
6685 if (info_2
== NULL
) {
6690 for (i
=0; i
<count
&& found
==False
; i
++) {
6691 if (queue
[i
].job
==(int)jobid
)
6698 /* NT treats not found as bad param... yet another bad choice */
6699 return WERR_INVALID_PARAM
;
6702 ret
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
6703 if (!W_ERROR_IS_OK(ret
)) {
6708 fill_job_info_2(info_2
, &(queue
[i
-1]), i
, snum
, ntprinter
);
6710 free_a_printer(&ntprinter
, 2);
6713 *needed
+= spoolss_size_job_info_2(info_2
);
6715 if (!alloc_buffer_size(buffer
, *needed
)) {
6717 return WERR_INSUFFICIENT_BUFFER
;
6720 smb_io_job_info_2("", buffer
, info_2
, 0);
6722 free_job_info_2(info_2
);
6725 if (*needed
> offered
)
6726 return WERR_INSUFFICIENT_BUFFER
;
6731 /****************************************************************************
6732 ****************************************************************************/
6734 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
6736 POLICY_HND
*handle
= &q_u
->handle
;
6737 uint32 jobid
= q_u
->jobid
;
6738 uint32 level
= q_u
->level
;
6739 NEW_BUFFER
*buffer
= NULL
;
6740 uint32 offered
= q_u
->offered
;
6741 uint32
*needed
= &r_u
->needed
;
6745 print_queue_struct
*queue
=NULL
;
6746 print_status_struct prt_status
;
6748 /* that's an [in out] buffer */
6749 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6750 buffer
= r_u
->buffer
;
6752 DEBUG(5,("spoolss_getjob\n"));
6754 memset(&prt_status
, 0, sizeof(prt_status
));
6758 if (!get_printer_snum(p
, handle
, &snum
))
6761 count
= print_queue_status(snum
, &queue
, &prt_status
);
6763 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
6764 count
, prt_status
.status
, prt_status
.message
));
6768 return getjob_level_1(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
6770 return getjob_level_2(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
6773 return WERR_UNKNOWN_LEVEL
;
6777 /********************************************************************
6778 * spoolss_getprinterdataex
6779 ********************************************************************/
6781 WERROR
_spoolss_getprinterdataex(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATAEX
*q_u
, SPOOL_R_GETPRINTERDATAEX
*r_u
)
6783 POLICY_HND
*handle
= &q_u
->handle
;
6784 uint32 in_size
= q_u
->size
;
6785 uint32
*type
= &r_u
->type
;
6786 uint32
*out_size
= &r_u
->size
;
6787 uint8
**data
= &r_u
->data
;
6788 uint32
*needed
= &r_u
->needed
;
6791 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6794 DEBUG(4,("_spoolss_getprinterdataex\n"));
6796 unistr2_to_ascii(key
, &q_u
->keyname
, sizeof(key
) - 1);
6797 unistr2_to_ascii(value
, &q_u
->valuename
, sizeof(value
) - 1);
6799 /* in case of problem, return some default values */
6806 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, 4*sizeof(uint8
))) == NULL
)
6808 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6813 /* Is the handle to a printer or to the server? */
6815 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
6817 DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
6818 return WERR_INVALID_PARAM
;
6823 * From MSDN documentation of GetPrinterDataEx: pass request
6824 * to GetPrinterData if key is "PrinterDriverData". This is
6825 * the only key we really support. Other keys to implement:
6831 if (strcmp(key
, "PrinterDriverData") != 0)
6832 return WERR_INVALID_PARAM
;
6834 DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
6835 found
= getprinterdata_printer(p
, p
->mem_ctx
, handle
, value
,
6836 type
, data
, needed
, in_size
);
6841 DEBUG(5, ("value not found, allocating %d\n", *out_size
));
6843 /* reply this param doesn't exist */
6845 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
)
6851 return WERR_INVALID_PARAM
;
6854 if (*needed
> *out_size
)
6855 return WERR_MORE_DATA
;
6860 /********************************************************************
6861 * spoolss_setprinterdata
6862 ********************************************************************/
6864 WERROR
_spoolss_setprinterdataex(pipes_struct
*p
, SPOOL_Q_SETPRINTERDATAEX
*q_u
, SPOOL_R_SETPRINTERDATAEX
*r_u
)
6866 SPOOL_Q_SETPRINTERDATA q_u_local
;
6867 SPOOL_R_SETPRINTERDATA r_u_local
;
6870 DEBUG(4,("_spoolss_setprinterdataex\n"));
6872 /* From MSDN documentation of SetPrinterDataEx: pass request to
6873 SetPrinterData if key is "PrinterDriverData" */
6875 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
) - 1);
6877 if (strcmp(key
, "PrinterDriverData") == 0)
6878 return WERR_INVALID_PARAM
;
6880 ZERO_STRUCT(q_u_local
);
6881 ZERO_STRUCT(r_u_local
);
6883 /* make a copy to call _spoolss_setprinterdata() */
6885 memcpy(&q_u_local
.handle
, &q_u
->handle
, sizeof(POLICY_HND
));
6886 copy_unistr2(&q_u_local
.value
, &q_u
->value
);
6887 q_u_local
.type
= q_u
->type
;
6888 q_u_local
.max_len
= q_u
->max_len
;
6889 q_u_local
.data
= q_u
->data
;
6890 q_u_local
.real_len
= q_u
->real_len
;
6891 q_u_local
.numeric_data
= q_u
->numeric_data
;
6893 return _spoolss_setprinterdata(p
, &q_u_local
, &r_u_local
);
6896 /********************************************************************
6897 * spoolss_enumprinterkey
6898 ********************************************************************/
6900 /* constants for EnumPrinterKey() */
6901 #define ENUMERATED_KEY_SIZE 19
6903 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
6906 uint16 enumkeys
[ENUMERATED_KEY_SIZE
+1];
6909 char *PrinterKey
= "PrinterDriverData";
6911 DEBUG(4,("_spoolss_enumprinterkey\n"));
6913 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
) - 1);
6916 * we only support enumating all keys (key == "")
6917 * Of course, the only key we support is the "PrinterDriverData"
6920 if (strlen(key
) == 0)
6922 r_u
->needed
= ENUMERATED_KEY_SIZE
*2;
6923 if (q_u
->size
< r_u
->needed
)
6924 return WERR_MORE_DATA
;
6927 for (i
=0; i
<ENUMERATED_KEY_SIZE
-2; i
++)
6929 enumkeys
[i
] = (uint16
)(*ptr
);
6933 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, ENUMERATED_KEY_SIZE
, enumkeys
))
6934 return WERR_BADFILE
;
6939 /* The "PrinterDriverData" key should have no subkeys */
6940 if (strcmp(key
, PrinterKey
) == 0)
6943 if (q_u
->size
< r_u
->needed
)
6944 return WERR_MORE_DATA
;
6946 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, 1, enumkeys
))
6947 return WERR_BADFILE
;
6953 /* The return value for an unknown key is documented in MSDN
6954 EnumPrinterKey description */
6955 return WERR_BADFILE
;
6958 /********************************************************************
6959 * spoolss_enumprinterdataex
6960 ********************************************************************/
6962 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
6964 POLICY_HND
*handle
= &q_u
->handle
;
6965 uint32 in_size
= q_u
->size
;
6968 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6969 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
6971 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6980 DEBUG(4,("_spoolss_enumprinterdataex\n"));
6983 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6989 * The only key we support is "PrinterDriverData". This should return
6990 > an array of all the key/value pairs returned by EnumPrinterDataSee
6991 * _spoolss_getprinterdataex() for details --jerry
6994 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
) - 1);
6995 if (strcmp(key
, "PrinterDriverData") != 0)
6997 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
6998 return WERR_INVALID_PARAM
;
7002 if (!get_printer_snum(p
,handle
, &snum
))
7005 ZERO_STRUCT(printer
);
7006 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7007 if (!W_ERROR_IS_OK(result
))
7012 * loop through all params and build the array to pass
7013 * back to the client
7020 while (get_specific_param_by_index(*printer
, 2, param_index
, value
, &data
, &type
, &data_len
))
7022 PRINTER_ENUM_VALUES
*ptr
;
7025 DEBUG(10,("retrieved value number [%d] [%s]\n", num_entries
, value
));
7027 if ((ptr
=talloc_realloc(p
->mem_ctx
, enum_values
, (num_entries
+1) * sizeof(PRINTER_ENUM_VALUES
))) == NULL
)
7029 DEBUG(0,("talloc_realloc failed to allocate more memory!\n"));
7030 result
= WERR_NOMEM
;
7036 init_unistr(&enum_values
[num_entries
].valuename
, value
);
7037 enum_values
[num_entries
].value_len
= (strlen(value
)+1) * 2;
7038 enum_values
[num_entries
].type
= type
;
7041 * NULL terminate REG_SZ
7042 * FIXME!!! We should not be correctly problems in the way
7043 * we store PrinterData here. Need to investogate
7044 * SetPrinterData[Ex] --jerry
7047 if (type
== REG_SZ
) {
7048 /* fix alignment if the string was stored
7049 in a bizarre fashion */
7050 if ((data_len
% 2) == 0)
7053 add_len
= data_len
% 2;
7056 if (!(enum_values
[num_entries
].data
=talloc_zero(p
->mem_ctx
, data_len
+add_len
))) {
7057 DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n"));
7058 result
= WERR_NOMEM
;
7061 memcpy(enum_values
[num_entries
].data
, data
, data_len
);
7062 enum_values
[num_entries
].data_len
= data_len
+ add_len
;
7064 /* keep track of the size of the array in bytes */
7066 needed
+= spoolss_size_printer_enum_values(&enum_values
[num_entries
]);
7072 r_u
->needed
= needed
;
7073 r_u
->returned
= num_entries
;
7075 if (needed
> in_size
) {
7076 result
= WERR_MORE_DATA
;
7080 /* copy data into the reply */
7082 r_u
->ctr
.size
= r_u
->needed
;
7083 r_u
->ctr
.size_of_array
= r_u
->returned
;
7084 r_u
->ctr
.values
= enum_values
;
7089 free_a_printer(&printer
, 2);