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.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
26 up, all the errors returned are DOS errors, not NT status codes. */
30 extern int DEBUGLEVEL
;
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
)
144 SPOOL_NOTIFY_OPTION
*sp
= *pp
;
152 safe_free(sp
->ctr
.type
);
157 /***************************************************************************
158 Disconnect from the client
159 ****************************************************************************/
161 static void srv_spoolss_replycloseprinter(POLICY_HND
*handle
)
165 /* weird if the test succeds !!! */
166 if (smb_connections
==0) {
167 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
171 if(!cli_spoolss_reply_close_printer(&cli
, handle
, &status
))
172 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n"));
174 /* if it's the last connection, deconnect the IPC$ share */
175 if (smb_connections
==1) {
176 if(!spoolss_disconnect_from_client(&cli
))
179 message_deregister(MSG_PRINTER_NOTIFY
);
185 /****************************************************************************
186 Functions to free a printer entry datastruct.
187 ****************************************************************************/
189 static void free_printer_entry(void *ptr
)
191 Printer_entry
*Printer
= (Printer_entry
*)ptr
;
193 if (Printer
->notify
.client_connected
==True
)
194 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
196 Printer
->notify
.flags
=0;
197 Printer
->notify
.options
=0;
198 Printer
->notify
.localmachine
[0]='\0';
199 Printer
->notify
.printerlocal
=0;
200 free_spool_notify_option(&Printer
->notify
.option
);
201 Printer
->notify
.option
=NULL
;
202 Printer
->notify
.client_connected
=False
;
207 /****************************************************************************
208 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
209 ****************************************************************************/
211 SPOOL_NOTIFY_OPTION
*dup_spool_notify_option(SPOOL_NOTIFY_OPTION
*sp
)
213 SPOOL_NOTIFY_OPTION
*new_sp
= NULL
;
218 new_sp
= (SPOOL_NOTIFY_OPTION
*)malloc(sizeof(SPOOL_NOTIFY_OPTION
));
225 new_sp
->ctr
.type
= (SPOOL_NOTIFY_OPTION_TYPE
*)memdup(sp
->ctr
.type
, sizeof(SPOOL_NOTIFY_OPTION_TYPE
) * sp
->ctr
.count
);
227 if (!new_sp
->ctr
.type
) {
236 /****************************************************************************
237 find printer index by handle
238 ****************************************************************************/
240 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
242 Printer_entry
*find_printer
= NULL
;
244 if(!find_policy_by_hnd(p
,hnd
,(void **)&find_printer
)) {
245 DEBUG(3,("find_printer_index_by_hnd: Printer handle not found: "));
252 /****************************************************************************
253 close printer index by handle
254 ****************************************************************************/
256 static BOOL
close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
258 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
261 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
265 close_policy_hnd(p
, hnd
);
270 /****************************************************************************
271 delete a printer given a handle
272 ****************************************************************************/
273 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
275 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
278 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
282 if (del_a_printer(Printer
->dev
.handlename
) != 0) {
283 DEBUG(3,("Error deleting printer %s\n", Printer
->dev
.handlename
));
287 /* Check calling user has permission to delete printer. Note that
288 since we set the snum parameter to -1 only administrators can
289 delete the printer. This stops people with the Full Control
290 permission from deleting the printer. */
292 if (!print_access_check(NULL
, -1, PRINTER_ACCESS_ADMINISTER
)) {
293 DEBUG(3, ("printer delete denied by security descriptor\n"));
294 return WERR_ACCESS_DENIED
;
297 if (*lp_deleteprinter_cmd()) {
299 char *cmd
= lp_deleteprinter_cmd();
304 /* Printer->dev.handlename equals portname equals sharename */
305 slprintf(command
, sizeof(command
)-1, "%s \"%s\"", cmd
,
306 Printer
->dev
.handlename
);
308 DEBUG(10,("Running [%s]\n", command
));
309 ret
= smbrun(command
, NULL
);
311 return WERR_BADFID
; /* What to return here? */
313 DEBUGADD(10,("returned [%d]\n", ret
));
315 /* Send SIGHUP to process group... is there a better way? */
318 if ( ( i
= lp_servicenumber( Printer
->dev
.handlename
) ) >= 0 ) {
322 return WERR_ACCESS_DENIED
;
328 /****************************************************************************
329 return the snum of a printer corresponding to an handle
330 ****************************************************************************/
331 static BOOL
get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
)
333 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
336 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
340 switch (Printer
->printer_type
) {
341 case PRINTER_HANDLE_IS_PRINTER
:
342 DEBUG(4,("short name:%s\n", Printer
->dev
.handlename
));
343 *number
= print_queue_snum(Printer
->dev
.handlename
);
344 return (*number
!= -1);
345 case PRINTER_HANDLE_IS_PRINTSERVER
:
352 /****************************************************************************
353 set printer handle type.
354 ****************************************************************************/
355 static BOOL
set_printer_hnd_accesstype(pipes_struct
*p
, POLICY_HND
*hnd
, uint32 access_required
)
357 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
360 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd
)));
364 DEBUG(4,("Setting printer access=%x\n", access_required
));
365 Printer
->access
= access_required
;
369 /****************************************************************************
370 Set printer handle type.
371 Check if it's \\server or \\server\printer
372 ****************************************************************************/
374 static BOOL
set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
376 DEBUG(3,("Setting printer type=%s\n", handlename
));
378 if ( strlen(handlename
) < 3 ) {
379 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
383 /* it's a print server */
384 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
385 DEBUGADD(4,("Printer is a print server\n"));
386 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTSERVER
;
390 DEBUGADD(4,("Printer is a printer\n"));
391 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTER
;
397 /****************************************************************************
398 Set printer handle name.
399 ****************************************************************************/
401 static BOOL
set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
403 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
405 int n_services
=lp_numservices();
409 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename
, strlen(handlename
)));
411 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTSERVER
) {
412 ZERO_STRUCT(Printer
->dev
.printerservername
);
413 strncpy(Printer
->dev
.printerservername
, handlename
, strlen(handlename
));
417 if (Printer
->printer_type
!=PRINTER_HANDLE_IS_PRINTER
)
420 if (*handlename
=='\\') {
421 aprinter
=strchr_m(handlename
+2, '\\');
428 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter
, strlen(aprinter
)));
431 * store the Samba share name in it
432 * in back we have the long printer name
433 * need to iterate all the snum and do a
434 * get_a_printer each time to find the printer
435 * faster to do it here than later.
438 for (snum
=0;snum
<n_services
&& found
==False
;snum
++) {
441 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
444 DEBUGADD(5,("share:%s\n",lp_servicename(snum
)));
446 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
449 printername
=strchr_m(printer
->info_2
->printername
+2, '\\');
452 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
453 printer
->info_2
->printername
, aprinter
));
455 if ( strlen(printername
) != strlen(aprinter
) ) {
456 free_a_printer(&printer
, 2);
460 if ( strncasecmp(printername
, aprinter
, strlen(aprinter
))) {
461 free_a_printer(&printer
, 2);
469 * if we haven't found a printer with the given handlename
470 * then it can be a share name as you can open both \\server\printer and
475 * we still check if the printer description file exists as NT won't be happy
476 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
480 DEBUGADD(5,("Printer not found, checking for share now\n"));
482 for (snum
=0;snum
<n_services
&& found
==False
;snum
++) {
484 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
487 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum
)));
489 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
492 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
493 printer
->info_2
->printername
, aprinter
));
495 if ( strlen(lp_servicename(snum
)) != strlen(aprinter
) ) {
496 free_a_printer(&printer
, 2);
500 if ( strncasecmp(lp_servicename(snum
), aprinter
, strlen(aprinter
))) {
501 free_a_printer(&printer
, 2);
510 DEBUGADD(4,("Printer not found\n"));
515 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
516 printer
->info_2
->printername
, lp_servicename(snum
),snum
));
518 ZERO_STRUCT(Printer
->dev
.handlename
);
519 strncpy(Printer
->dev
.handlename
, lp_servicename(snum
), strlen(lp_servicename(snum
)));
521 free_a_printer(&printer
, 2);
526 /****************************************************************************
527 find first available printer slot. creates a printer handle for you.
528 ****************************************************************************/
530 static BOOL
open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
)
532 Printer_entry
*new_printer
;
534 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
536 if((new_printer
=(Printer_entry
*)malloc(sizeof(Printer_entry
))) == NULL
)
539 ZERO_STRUCTP(new_printer
);
541 new_printer
->notify
.option
=NULL
;
543 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
544 safe_free(new_printer
);
548 if (!set_printer_hnd_printertype(new_printer
, name
)) {
549 close_printer_handle(p
, hnd
);
553 if (!set_printer_hnd_name(new_printer
, name
)) {
554 close_printer_handle(p
, hnd
);
558 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
563 /********************************************************************
564 Return True is the handle is a print server.
565 ********************************************************************/
567 static BOOL
handle_is_printserver(pipes_struct
*p
, POLICY_HND
*handle
)
569 Printer_entry
*Printer
=find_printer_index_by_hnd(p
,handle
);
574 if (Printer
->printer_type
!= PRINTER_HANDLE_IS_PRINTSERVER
)
580 /****************************************************************************
581 allocate more memory for a BUFFER.
582 ****************************************************************************/
583 static BOOL
alloc_buffer_size(NEW_BUFFER
*buffer
, uint32 buffer_size
)
591 /* damn, I'm doing the reverse operation of prs_grow() :) */
592 if (buffer_size
< prs_data_size(ps
))
595 extra_space
= buffer_size
- prs_data_size(ps
);
598 * save the offset and move to the end of the buffer
599 * prs_grow() checks the extra_space against the offset
601 old_offset
=prs_offset(ps
);
602 prs_set_offset(ps
, prs_data_size(ps
));
604 if (!prs_grow(ps
, extra_space
))
607 prs_set_offset(ps
, old_offset
);
609 buffer
->string_at_end
=prs_data_size(ps
);
614 /***************************************************************************
615 receive the notify message
616 ****************************************************************************/
618 static void srv_spoolss_receive_message(int msg_type
, pid_t src
, void *buf
, size_t len
)
622 struct pipes_struct
*p
;
624 struct handle_list
*hl
;
627 fstrcpy(printer
,buf
);
630 DEBUG(0,("srv_spoolss_receive_message: got null message !\n"));
634 DEBUG(10,("srv_spoolss_receive_message: Got message about printer %s\n", printer
));
637 * We need to enumerate all printers. The handle list is shared
638 * across pipes of the same name, so just find the first open
643 for ( p
= get_first_pipe(); p
; get_next_pipe(p
)) {
644 if (strequal(p
->name
, "spoolss")) {
645 hl
= p
->pipe_handles
;
651 DEBUG(0,("srv_spoolss_receive_message: no handle list on spoolss pipe !\n"));
655 /* Iterate the printer list on this pipe. */
656 for (pol
= hl
->Policy
; pol
; pol
= pol
->next
) {
657 Printer_entry
*find_printer
= (Printer_entry
*)pol
->data_ptr
;
663 * if the entry is the given printer or if it's a printerserver
664 * we send the message
667 if (find_printer
->printer_type
==PRINTER_HANDLE_IS_PRINTER
)
668 if (strcmp(find_printer
->dev
.handlename
, printer
))
671 if (find_printer
->notify
.client_connected
==True
)
672 cli_spoolss_reply_rrpcn(&cli
, &find_printer
->notify
.client_hnd
, PRINTER_CHANGE_ALL
, 0x0, &status
);
676 /***************************************************************************
678 ****************************************************************************/
679 static BOOL
srv_spoolss_sendnotify(pipes_struct
*p
, POLICY_HND
*handle
)
683 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
686 DEBUG(0,("srv_spoolss_sendnotify: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
690 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTER
)
691 fstrcpy(printer
, Printer
->dev
.handlename
);
693 fstrcpy(printer
, "");
695 /*srv_spoolss_receive_message(printer);*/
696 DEBUG(10,("srv_spoolss_sendnotify: Sending message about printer %s\n", printer
));
698 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY
, printer
, strlen(printer
) + 1, False
); /* Null terminate... */
703 /********************************************************************
704 * spoolss_open_printer
706 * called from the spoolss dispatcher
707 ********************************************************************/
709 WERROR
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
712 WERROR result
= WERR_OK
;
715 UNISTR2
*printername
= NULL
;
716 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
717 /* uint32 user_switch = q_u->user_switch; - notused */
718 /* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
719 POLICY_HND
*handle
= &r_u
->handle
;
723 struct current_user user
;
725 if (q_u
->printername_ptr
!= 0)
726 printername
= &q_u
->printername
;
728 if (printername
== NULL
)
729 return WERR_INVALID_PRINTER_NAME
;
731 /* some sanity check because you can open a printer or a print server */
732 /* aka: \\server\printer or \\server */
733 unistr2_to_ascii(name
, printername
, sizeof(name
)-1);
735 DEBUGADD(3,("checking name: %s\n",name
));
737 if (!open_printer_hnd(p
, handle
, name
))
738 return WERR_INVALID_PRINTER_NAME
;
741 if (printer_default->datatype_ptr != NULL)
743 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
744 set_printer_hnd_datatype(handle, datatype);
747 set_printer_hnd_datatype(handle, "");
750 if (!set_printer_hnd_accesstype(p
, handle
, printer_default
->access_required
)) {
751 close_printer_handle(p
, handle
);
752 return WERR_ACCESS_DENIED
;
756 First case: the user is opening the print server:
758 Disallow MS AddPrinterWizard if parameter disables it. A Win2k
759 client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
761 Then both Win2k and WinNT clients try an OpenPrinterEx with
762 SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
763 or if the user is listed in the smb.conf printer admin parameter.
765 Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
766 client view printer folder, but does not show the MSAPW.
768 Note: this test needs code to check access rights here too. Jeremy
769 could you look at this?
772 Second case: the user is opening a printer:
773 NT doesn't let us connect to a printer if the connecting user
774 doesn't have print permission.
778 get_current_user(&user
, p
);
780 if (handle_is_printserver(p
, handle
)) {
781 if (printer_default
->access_required
== 0) {
784 else if ((printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
) == SERVER_ACCESS_ADMINISTER
) {
786 /* Printserver handles use global struct... */
789 if (!lp_ms_add_printer_wizard()) {
790 close_printer_handle(p
, handle
);
791 return WERR_ACCESS_DENIED
;
793 else if (user
.uid
== 0 || user_in_list(uidtoname(user
.uid
), lp_printer_admin(snum
))) {
797 close_printer_handle(p
, handle
);
798 return WERR_ACCESS_DENIED
;
804 /* NT doesn't let us connect to a printer if the connecting user
805 doesn't have print permission. */
807 if (!get_printer_snum(p
, handle
, &snum
))
810 /* map an empty access mask to the minimum access mask */
811 if (printer_default
->access_required
== 0x0)
812 printer_default
->access_required
= PRINTER_ACCESS_USE
;
815 * If we are not serving the printer driver for this printer,
816 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
817 * will keep NT clients happy --jerry
820 if (lp_use_client_driver(snum
)
821 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
823 printer_default
->access_required
= PRINTER_ACCESS_USE
;
826 if (!print_access_check(&user
, snum
, printer_default
->access_required
)) {
827 DEBUG(3, ("access DENIED for printer open\n"));
828 close_printer_handle(p
, handle
);
829 return WERR_ACCESS_DENIED
;
833 * If we have a default device pointer in the
834 * printer_default struct, then we need to get
835 * the printer info from the tdb and if there is
836 * no default devicemode there then we do a *SET*
837 * here ! This is insanity.... JRA.
841 * If the openprinterex rpc call contains a devmode,
842 * it's a per-user one. This per-user devmode is derivated
843 * from the global devmode. Openprinterex() contains a per-user
844 * devmode for when you do EMF printing and spooling.
845 * In the EMF case, the NT workstation is only doing half the job
846 * of rendering the page. The other half is done by running the printer
847 * driver on the server.
848 * The EMF file doesn't contain the page description (paper size, orientation, ...).
849 * The EMF file only contains what is to be printed on the page.
850 * So in order for the server to know how to print, the NT client sends
851 * a devicemode attached to the openprinterex call.
852 * But this devicemode is short lived, it's only valid for the current print job.
854 * If Samba would have supported EMF spooling, this devicemode would
855 * have been attached to the handle, to sent it to the driver to correctly
856 * rasterize the EMF file.
858 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
859 * we just act as a pass-thru between windows and the printer.
861 * In order to know that Samba supports only RAW spooling, NT has to call
862 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
863 * and until NT sends a RAW job, we refuse it.
865 * But to call getprinter() or startdoc(), you first need a valid handle,
866 * and to get an handle you have to call openprintex(). Hence why you have
867 * a devicemode in the openprinterex() call.
870 * Differences between NT4 and NT 2000.
873 * On NT4, you only have a global devicemode. This global devicemode can be changed
874 * by the administrator (or by a user with enough privs). Everytime a user
875 * wants to print, the devicemode is resetted to the default. In Word, everytime
876 * you print, the printer's characteristics are always reset to the global devicemode.
880 * In W2K, there is the notion of per-user devicemode. The first time you use
881 * a printer, a per-user devicemode is build from the global devicemode.
882 * If you change your per-user devicemode, it is saved in the registry, under the
883 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
884 * printer preferences available.
886 * To change the per-user devicemode: it's the "Printing Preferences ..." button
887 * on the General Tab of the printer properties windows.
889 * To change the global devicemode: it's the "Printing Defaults..." button
890 * on the Advanced Tab of the printer properties window.
898 if (printer_default
->devmode_cont
.devmode
!= NULL
) {
899 result
= printer_write_default_dev( snum
, printer_default
);
901 close_printer_handle(p
, handle
);
911 /****************************************************************************
912 ****************************************************************************/
913 static BOOL
convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
914 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
918 uni_2_asc_printer_info_2(uni
->info_2
, &printer
->info_2
);
927 static BOOL
convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
928 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
934 printer
->info_3
=NULL
;
935 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
939 printer
->info_6
=NULL
;
940 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
950 BOOL
convert_devicemode(char *printername
, const DEVICEMODE
*devmode
,
951 NT_DEVICEMODE
**pp_nt_devmode
)
953 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
956 * Ensure nt_devmode is a valid pointer
957 * as we will be overwriting it.
960 if (nt_devmode
== NULL
) {
961 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
962 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
966 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
967 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
969 nt_devmode
->specversion
=devmode
->specversion
;
970 nt_devmode
->driverversion
=devmode
->driverversion
;
971 nt_devmode
->size
=devmode
->size
;
972 nt_devmode
->fields
=devmode
->fields
;
973 nt_devmode
->orientation
=devmode
->orientation
;
974 nt_devmode
->papersize
=devmode
->papersize
;
975 nt_devmode
->paperlength
=devmode
->paperlength
;
976 nt_devmode
->paperwidth
=devmode
->paperwidth
;
977 nt_devmode
->scale
=devmode
->scale
;
978 nt_devmode
->copies
=devmode
->copies
;
979 nt_devmode
->defaultsource
=devmode
->defaultsource
;
980 nt_devmode
->printquality
=devmode
->printquality
;
981 nt_devmode
->color
=devmode
->color
;
982 nt_devmode
->duplex
=devmode
->duplex
;
983 nt_devmode
->yresolution
=devmode
->yresolution
;
984 nt_devmode
->ttoption
=devmode
->ttoption
;
985 nt_devmode
->collate
=devmode
->collate
;
987 nt_devmode
->logpixels
=devmode
->logpixels
;
988 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
989 nt_devmode
->pelswidth
=devmode
->pelswidth
;
990 nt_devmode
->pelsheight
=devmode
->pelsheight
;
991 nt_devmode
->displayflags
=devmode
->displayflags
;
992 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
993 nt_devmode
->icmmethod
=devmode
->icmmethod
;
994 nt_devmode
->icmintent
=devmode
->icmintent
;
995 nt_devmode
->mediatype
=devmode
->mediatype
;
996 nt_devmode
->dithertype
=devmode
->dithertype
;
997 nt_devmode
->reserved1
=devmode
->reserved1
;
998 nt_devmode
->reserved2
=devmode
->reserved2
;
999 nt_devmode
->panningwidth
=devmode
->panningwidth
;
1000 nt_devmode
->panningheight
=devmode
->panningheight
;
1003 * Only change private and driverextra if the incoming devmode
1004 * has a new one. JRA.
1007 if ((devmode
->driverextra
!= 0) && (devmode
->private != NULL
)) {
1008 safe_free(nt_devmode
->private);
1009 nt_devmode
->driverextra
=devmode
->driverextra
;
1010 if((nt_devmode
->private=(uint8
*)malloc(nt_devmode
->driverextra
* sizeof(uint8
))) == NULL
)
1012 memcpy(nt_devmode
->private, devmode
->private, nt_devmode
->driverextra
);
1015 *pp_nt_devmode
= nt_devmode
;
1020 /********************************************************************
1021 * _spoolss_enddocprinter_internal.
1022 ********************************************************************/
1024 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1026 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1029 DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
1033 Printer
->document_started
=False
;
1034 print_job_end(Printer
->jobid
,True
);
1035 /* error codes unhandled so far ... */
1040 /********************************************************************
1041 * api_spoolss_closeprinter
1042 ********************************************************************/
1044 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1046 POLICY_HND
*handle
= &q_u
->handle
;
1048 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1050 if (Printer
&& Printer
->document_started
)
1051 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1053 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1055 if (!close_printer_handle(p
, handle
))
1061 /********************************************************************
1062 * api_spoolss_deleteprinter
1064 ********************************************************************/
1066 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1068 POLICY_HND
*handle
= &q_u
->handle
;
1069 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1072 if (Printer
&& Printer
->document_started
)
1073 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1075 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1077 result
= delete_printer_handle(p
, handle
);
1079 if (W_ERROR_IS_OK(result
)) {
1080 srv_spoolss_sendnotify(p
, handle
);
1086 /*******************************************************************
1087 * static function to lookup the version id corresponding to an
1088 * long architecture string
1089 ******************************************************************/
1090 static int get_version_id (char * arch
)
1093 struct table_node archi_table
[]= {
1095 {"Windows 4.0", "WIN40", 0 },
1096 {"Windows NT x86", "W32X86", 2 },
1097 {"Windows NT R4000", "W32MIPS", 2 },
1098 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1099 {"Windows NT PowerPC", "W32PPC", 2 },
1103 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1105 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1106 return (archi_table
[i
].version
);
1112 /********************************************************************
1113 * _spoolss_deleteprinterdriver
1115 * We currently delete the driver for the architecture only.
1116 * This can leave the driver for other archtectures. However,
1117 * since every printer associates a "Windows NT x86" driver name
1118 * and we cannot delete that one while it is in use, **and** since
1119 * it is impossible to assign a driver to a Samba printer without
1120 * having the "Windows NT x86" driver installed,...
1122 * ....we should not get into trouble here.
1125 ********************************************************************/
1127 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
,
1128 SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
1132 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1135 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
)-1 );
1136 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
)-1 );
1138 /* check that we have a valid driver name first */
1139 if ((version
=get_version_id(arch
)) == -1) {
1140 return WERR_INVALID_ENVIRONMENT
;
1144 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
1145 return WERR_UNKNOWN_PRINTER_DRIVER
;
1149 if (printer_driver_in_use(arch
, driver
))
1151 return WERR_PRINTER_DRIVER_IN_USE
;
1154 return delete_printer_driver(info
.info_3
);
1158 /********************************************************************
1159 GetPrinterData on a printer server Handle.
1160 ********************************************************************/
1161 static BOOL
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
1165 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
1167 if (!strcmp(value
, "BeepEnabled")) {
1169 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1171 SIVAL(*data
, 0, 0x01);
1176 if (!strcmp(value
, "EventLog")) {
1178 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1180 SIVAL(*data
, 0, 0x1B);
1185 if (!strcmp(value
, "NetPopup")) {
1187 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1189 SIVAL(*data
, 0, 0x01);
1194 if (!strcmp(value
, "MajorVersion")) {
1196 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1198 SIVAL(*data
, 0, 0x02);
1203 if (!strcmp(value
, "DefaultSpoolDirectory")) {
1204 pstring string
="You are using a Samba server";
1206 *needed
= 2*(strlen(string
)+1);
1207 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1209 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1211 /* it's done by hand ready to go on the wire */
1212 for (i
=0; i
<strlen(string
); i
++) {
1213 (*data
)[2*i
]=string
[i
];
1214 (*data
)[2*i
+1]='\0';
1219 if (!strcmp(value
, "Architecture")) {
1220 pstring string
="Windows NT x86";
1222 *needed
= 2*(strlen(string
)+1);
1223 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1225 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1226 for (i
=0; i
<strlen(string
); i
++) {
1227 (*data
)[2*i
]=string
[i
];
1228 (*data
)[2*i
+1]='\0';
1236 /********************************************************************
1237 GetPrinterData on a printer Handle.
1238 ********************************************************************/
1239 static BOOL
getprinterdata_printer(pipes_struct
*p
, TALLOC_CTX
*ctx
, POLICY_HND
*handle
,
1240 fstring value
, uint32
*type
,
1241 uint8
**data
, uint32
*needed
, uint32 in_size
)
1243 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1247 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1249 DEBUG(5,("getprinterdata_printer\n"));
1252 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1256 if(!get_printer_snum(p
, handle
, &snum
))
1259 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
1262 if (!get_specific_param(*printer
, 2, value
, &idata
, type
, &len
)) {
1263 free_a_printer(&printer
, 2);
1267 free_a_printer(&printer
, 2);
1269 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size
));
1272 if((*data
= (uint8
*)talloc(ctx
, in_size
*sizeof(uint8
) )) == NULL
) {
1276 memset(*data
, 0, in_size
*sizeof(uint8
));
1277 /* copy the min(in_size, len) */
1278 memcpy(*data
, idata
, (len
>in_size
)?in_size
:len
*sizeof(uint8
));
1285 DEBUG(5,("getprinterdata_printer:copy done\n"));
1292 /********************************************************************
1293 * spoolss_getprinterdata
1294 ********************************************************************/
1296 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
1298 POLICY_HND
*handle
= &q_u
->handle
;
1299 UNISTR2
*valuename
= &q_u
->valuename
;
1300 uint32 in_size
= q_u
->size
;
1301 uint32
*type
= &r_u
->type
;
1302 uint32
*out_size
= &r_u
->size
;
1303 uint8
**data
= &r_u
->data
;
1304 uint32
*needed
= &r_u
->needed
;
1308 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1311 * Reminder: when it's a string, the length is in BYTES
1312 * even if UNICODE is negociated.
1319 /* in case of problem, return some default values */
1323 DEBUG(4,("_spoolss_getprinterdata\n"));
1326 if((*data
=(uint8
*)malloc(4*sizeof(uint8
))) == NULL
)
1328 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1332 unistr2_to_ascii(value
, valuename
, sizeof(value
)-1);
1334 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
1335 found
=getprinterdata_printer_server(p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
1337 found
= getprinterdata_printer(p
, p
->mem_ctx
, handle
, value
, type
, data
, needed
, *out_size
);
1340 DEBUG(5, ("value not found, allocating %d\n", *out_size
));
1341 /* reply this param doesn't exist */
1343 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
)
1349 return WERR_INVALID_PARAM
;
1352 if (*needed
> *out_size
)
1353 return WERR_STATUS_MORE_ENTRIES
;
1359 /***************************************************************************
1360 connect to the client
1361 ****************************************************************************/
1362 static BOOL
srv_spoolss_replyopenprinter(char *printer
, uint32 localprinter
, uint32 type
, POLICY_HND
*handle
)
1367 * If it's the first connection, contact the client
1368 * and connect to the IPC$ share anonumously
1370 if (smb_connections
==0) {
1371 fstring unix_printer
;
1373 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
1375 if(!spoolss_connect_to_client(&cli
, unix_printer
))
1377 message_register(MSG_PRINTER_NOTIFY
, srv_spoolss_receive_message
);
1383 if(!cli_spoolss_reply_open_printer(&cli
, printer
, localprinter
, type
, &status
, handle
))
1389 /********************************************************************
1391 * ReplyFindFirstPrinterChangeNotifyEx
1393 * jfmxxxx: before replying OK: status=0
1394 * should do a rpc call to the workstation asking ReplyOpenPrinter
1395 * have to code it, later.
1397 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
1398 * called from api_spoolss_rffpcnex
1399 ********************************************************************/
1401 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
1403 POLICY_HND
*handle
= &q_u
->handle
;
1404 uint32 flags
= q_u
->flags
;
1405 uint32 options
= q_u
->options
;
1406 UNISTR2
*localmachine
= &q_u
->localmachine
;
1407 uint32 printerlocal
= q_u
->printerlocal
;
1408 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
1410 /* store the notify value in the printer struct */
1412 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1415 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1419 Printer
->notify
.flags
=flags
;
1420 Printer
->notify
.options
=options
;
1421 Printer
->notify
.printerlocal
=printerlocal
;
1423 if (Printer
->notify
.option
)
1424 free_spool_notify_option(&Printer
->notify
.option
);
1426 Printer
->notify
.option
=dup_spool_notify_option(option
);
1428 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
, sizeof(Printer
->notify
.localmachine
)-1);
1430 /* connect to the client machine and send a ReplyOpenPrinter */
1431 if(srv_spoolss_replyopenprinter(Printer
->notify
.localmachine
,
1432 Printer
->notify
.printerlocal
, 1,
1433 &Printer
->notify
.client_hnd
))
1434 Printer
->notify
.client_connected
=True
;
1439 /*******************************************************************
1440 * fill a notify_info_data with the servername
1441 ********************************************************************/
1443 static void spoolss_notify_server_name(int snum
,
1444 SPOOL_NOTIFY_INFO_DATA
*data
,
1445 print_queue_struct
*queue
,
1446 NT_PRINTER_INFO_LEVEL
*printer
,
1447 TALLOC_CTX
*mem_ctx
)
1449 pstring temp_name
, temp
;
1452 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
1454 len
= rpcstr_push(temp
, temp_name
, sizeof(temp
)-2, 0);
1456 data
->notify_data
.data
.length
= len
/ 2 - 1;
1457 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1459 if (!data
->notify_data
.data
.string
) {
1460 data
->notify_data
.data
.length
= 0;
1464 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1467 /*******************************************************************
1468 * fill a notify_info_data with the printername (not including the servername).
1469 ********************************************************************/
1470 static void spoolss_notify_printer_name(int snum
,
1471 SPOOL_NOTIFY_INFO_DATA
*data
,
1472 print_queue_struct
*queue
,
1473 NT_PRINTER_INFO_LEVEL
*printer
,
1474 TALLOC_CTX
*mem_ctx
)
1479 /* the notify name should not contain the \\server\ part */
1480 char *p
= strrchr_m(printer
->info_2
->printername
, '\\');
1483 p
= printer
->info_2
->printername
;
1488 len
= rpcstr_push(temp
, p
, sizeof(temp
)-2, 0);
1489 data
->notify_data
.data
.length
= len
/ 2 - 1;
1490 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1492 if (!data
->notify_data
.data
.string
) {
1493 data
->notify_data
.data
.length
= 0;
1497 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1500 /*******************************************************************
1501 * fill a notify_info_data with the servicename
1502 ********************************************************************/
1503 static void spoolss_notify_share_name(int snum
,
1504 SPOOL_NOTIFY_INFO_DATA
*data
,
1505 print_queue_struct
*queue
,
1506 NT_PRINTER_INFO_LEVEL
*printer
,
1507 TALLOC_CTX
*mem_ctx
)
1512 len
= rpcstr_push(temp
, lp_servicename(snum
), sizeof(temp
) - 2, 0);
1514 data
->notify_data
.data
.length
= len
/ 2 - 1;
1515 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1517 if (!data
->notify_data
.data
.string
) {
1518 data
->notify_data
.data
.length
= 0;
1522 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1525 /*******************************************************************
1526 * fill a notify_info_data with the port name
1527 ********************************************************************/
1528 static void spoolss_notify_port_name(int snum
,
1529 SPOOL_NOTIFY_INFO_DATA
*data
,
1530 print_queue_struct
*queue
,
1531 NT_PRINTER_INFO_LEVEL
*printer
,
1532 TALLOC_CTX
*mem_ctx
)
1537 /* even if it's strange, that's consistant in all the code */
1539 len
= rpcstr_push(temp
, printer
->info_2
->portname
, sizeof(temp
) - 2, 0);
1541 data
->notify_data
.data
.length
= len
/ 2 - 1;
1542 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1544 if (!data
->notify_data
.data
.string
) {
1545 data
->notify_data
.data
.length
= 0;
1549 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1552 /*******************************************************************
1553 * fill a notify_info_data with the printername
1554 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
1555 * but it doesn't exist, have to see what to do
1556 ********************************************************************/
1557 static void spoolss_notify_driver_name(int snum
,
1558 SPOOL_NOTIFY_INFO_DATA
*data
,
1559 print_queue_struct
*queue
,
1560 NT_PRINTER_INFO_LEVEL
*printer
,
1561 TALLOC_CTX
*mem_ctx
)
1566 len
= rpcstr_push(temp
, printer
->info_2
->drivername
, sizeof(temp
) - 2, 0);
1567 data
->notify_data
.data
.length
= len
/ 2 - 1;
1568 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1570 if (!data
->notify_data
.data
.string
) {
1571 data
->notify_data
.data
.length
= 0;
1575 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1578 /*******************************************************************
1579 * fill a notify_info_data with the comment
1580 ********************************************************************/
1581 static void spoolss_notify_comment(int snum
,
1582 SPOOL_NOTIFY_INFO_DATA
*data
,
1583 print_queue_struct
*queue
,
1584 NT_PRINTER_INFO_LEVEL
*printer
,
1585 TALLOC_CTX
*mem_ctx
)
1590 if (*printer
->info_2
->comment
== '\0')
1591 len
= rpcstr_push(temp
, lp_comment(snum
), sizeof(temp
) - 2, 0);
1594 len
= rpcstr_push(temp
, printer
->info_2
->comment
, sizeof(temp
) - 2, 0);
1596 data
->notify_data
.data
.length
= len
/ 2 - 1;
1597 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1599 if (!data
->notify_data
.data
.string
) {
1600 data
->notify_data
.data
.length
= 0;
1604 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1607 /*******************************************************************
1608 * fill a notify_info_data with the comment
1609 * jfm:xxxx incorrect, have to create a new smb.conf option
1610 * location = "Room 1, floor 2, building 3"
1611 ********************************************************************/
1612 static void spoolss_notify_location(int snum
,
1613 SPOOL_NOTIFY_INFO_DATA
*data
,
1614 print_queue_struct
*queue
,
1615 NT_PRINTER_INFO_LEVEL
*printer
,
1616 TALLOC_CTX
*mem_ctx
)
1621 len
= rpcstr_push(temp
, printer
->info_2
->location
,sizeof(temp
) - 2, 0);
1623 data
->notify_data
.data
.length
= len
/ 2 - 1;
1624 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1626 if (!data
->notify_data
.data
.string
) {
1627 data
->notify_data
.data
.length
= 0;
1631 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1634 /*******************************************************************
1635 * fill a notify_info_data with the device mode
1636 * jfm:xxxx don't to it for know but that's a real problem !!!
1637 ********************************************************************/
1638 static void spoolss_notify_devmode(int snum
,
1639 SPOOL_NOTIFY_INFO_DATA
*data
,
1640 print_queue_struct
*queue
,
1641 NT_PRINTER_INFO_LEVEL
*printer
,
1642 TALLOC_CTX
*mem_ctx
)
1646 /*******************************************************************
1647 * fill a notify_info_data with the separator file name
1648 * jfm:xxxx just return no file could add an option to smb.conf
1649 * separator file = "separator.txt"
1650 ********************************************************************/
1651 static void spoolss_notify_sepfile(int snum
,
1652 SPOOL_NOTIFY_INFO_DATA
*data
,
1653 print_queue_struct
*queue
,
1654 NT_PRINTER_INFO_LEVEL
*printer
,
1655 TALLOC_CTX
*mem_ctx
)
1660 len
= rpcstr_push(temp
, printer
->info_2
->sepfile
, sizeof(temp
) - 2, 0);
1662 data
->notify_data
.data
.length
= len
/ 2 - 1;
1663 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1665 if (!data
->notify_data
.data
.string
) {
1666 data
->notify_data
.data
.length
= 0;
1670 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1673 /*******************************************************************
1674 * fill a notify_info_data with the print processor
1675 * jfm:xxxx return always winprint to indicate we don't do anything to it
1676 ********************************************************************/
1677 static void spoolss_notify_print_processor(int snum
,
1678 SPOOL_NOTIFY_INFO_DATA
*data
,
1679 print_queue_struct
*queue
,
1680 NT_PRINTER_INFO_LEVEL
*printer
,
1681 TALLOC_CTX
*mem_ctx
)
1686 len
= rpcstr_push(temp
, printer
->info_2
->printprocessor
, sizeof(temp
) - 2, 0);
1688 data
->notify_data
.data
.length
= len
/ 2 - 1;
1689 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1691 if (!data
->notify_data
.data
.string
) {
1692 data
->notify_data
.data
.length
= 0;
1696 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1699 /*******************************************************************
1700 * fill a notify_info_data with the print processor options
1701 * jfm:xxxx send an empty string
1702 ********************************************************************/
1703 static void spoolss_notify_parameters(int snum
,
1704 SPOOL_NOTIFY_INFO_DATA
*data
,
1705 print_queue_struct
*queue
,
1706 NT_PRINTER_INFO_LEVEL
*printer
,
1707 TALLOC_CTX
*mem_ctx
)
1712 len
= rpcstr_push(temp
, printer
->info_2
->parameters
, sizeof(temp
) -
1715 data
->notify_data
.data
.length
= len
/ 2 - 1;
1716 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1718 if (!data
->notify_data
.data
.string
) {
1719 data
->notify_data
.data
.length
= 0;
1723 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1726 /*******************************************************************
1727 * fill a notify_info_data with the data type
1728 * jfm:xxxx always send RAW as data type
1729 ********************************************************************/
1730 static void spoolss_notify_datatype(int snum
,
1731 SPOOL_NOTIFY_INFO_DATA
*data
,
1732 print_queue_struct
*queue
,
1733 NT_PRINTER_INFO_LEVEL
*printer
,
1734 TALLOC_CTX
*mem_ctx
)
1739 len
= rpcstr_push(temp
, printer
->info_2
->datatype
, sizeof(pstring
)-2, 0);
1741 data
->notify_data
.data
.length
= len
/ 2 - 1;
1742 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1744 if (!data
->notify_data
.data
.string
) {
1745 data
->notify_data
.data
.length
= 0;
1749 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1752 /*******************************************************************
1753 * fill a notify_info_data with the security descriptor
1754 * jfm:xxxx send an null pointer to say no security desc
1755 * have to implement security before !
1756 ********************************************************************/
1757 static void spoolss_notify_security_desc(int snum
,
1758 SPOOL_NOTIFY_INFO_DATA
*data
,
1759 print_queue_struct
*queue
,
1760 NT_PRINTER_INFO_LEVEL
*printer
,
1761 TALLOC_CTX
*mem_ctx
)
1763 data
->notify_data
.data
.length
=0;
1764 data
->notify_data
.data
.string
= NULL
;
1767 /*******************************************************************
1768 * fill a notify_info_data with the attributes
1769 * jfm:xxxx a samba printer is always shared
1770 ********************************************************************/
1771 static void spoolss_notify_attributes(int snum
,
1772 SPOOL_NOTIFY_INFO_DATA
*data
,
1773 print_queue_struct
*queue
,
1774 NT_PRINTER_INFO_LEVEL
*printer
,
1775 TALLOC_CTX
*mem_ctx
)
1777 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
1780 /*******************************************************************
1781 * fill a notify_info_data with the priority
1782 ********************************************************************/
1783 static void spoolss_notify_priority(int snum
,
1784 SPOOL_NOTIFY_INFO_DATA
*data
,
1785 print_queue_struct
*queue
,
1786 NT_PRINTER_INFO_LEVEL
*printer
,
1787 TALLOC_CTX
*mem_ctx
)
1789 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
1792 /*******************************************************************
1793 * fill a notify_info_data with the default priority
1794 ********************************************************************/
1795 static void spoolss_notify_default_priority(int snum
,
1796 SPOOL_NOTIFY_INFO_DATA
*data
,
1797 print_queue_struct
*queue
,
1798 NT_PRINTER_INFO_LEVEL
*printer
,
1799 TALLOC_CTX
*mem_ctx
)
1801 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
1804 /*******************************************************************
1805 * fill a notify_info_data with the start time
1806 ********************************************************************/
1807 static void spoolss_notify_start_time(int snum
,
1808 SPOOL_NOTIFY_INFO_DATA
*data
,
1809 print_queue_struct
*queue
,
1810 NT_PRINTER_INFO_LEVEL
*printer
,
1811 TALLOC_CTX
*mem_ctx
)
1813 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
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
;
1828 /*******************************************************************
1829 * fill a notify_info_data with the status
1830 ********************************************************************/
1831 static void spoolss_notify_status(int snum
,
1832 SPOOL_NOTIFY_INFO_DATA
*data
,
1833 print_queue_struct
*queue
,
1834 NT_PRINTER_INFO_LEVEL
*printer
,
1835 TALLOC_CTX
*mem_ctx
)
1837 print_queue_struct
*q
=NULL
;
1838 print_status_struct status
;
1840 memset(&status
, 0, sizeof(status
));
1841 print_queue_status(snum
, &q
, &status
);
1842 data
->notify_data
.value
[0]=(uint32
) status
.status
;
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 print_queue_struct
*q
=NULL
;
1856 print_status_struct status
;
1858 memset(&status
, 0, sizeof(status
));
1859 data
->notify_data
.value
[0] = print_queue_status(snum
, &q
, &status
);
1863 /*******************************************************************
1864 * fill a notify_info_data with the average ppm
1865 ********************************************************************/
1866 static void spoolss_notify_average_ppm(int snum
,
1867 SPOOL_NOTIFY_INFO_DATA
*data
,
1868 print_queue_struct
*queue
,
1869 NT_PRINTER_INFO_LEVEL
*printer
,
1870 TALLOC_CTX
*mem_ctx
)
1872 /* always respond 8 pages per minutes */
1873 /* a little hard ! */
1874 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
1877 /*******************************************************************
1878 * fill a notify_info_data with username
1879 ********************************************************************/
1880 static void spoolss_notify_username(int snum
,
1881 SPOOL_NOTIFY_INFO_DATA
*data
,
1882 print_queue_struct
*queue
,
1883 NT_PRINTER_INFO_LEVEL
*printer
,
1884 TALLOC_CTX
*mem_ctx
)
1889 len
= rpcstr_push(temp
, queue
->user
, sizeof(temp
) - 2, 0);
1892 data
->notify_data
.data
.length
= len
/ 2 - 1;
1893 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1895 if (!data
->notify_data
.data
.string
) {
1896 data
->notify_data
.data
.length
= 0;
1900 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1903 /*******************************************************************
1904 * fill a notify_info_data with job status
1905 ********************************************************************/
1906 static void spoolss_notify_job_status(int snum
,
1907 SPOOL_NOTIFY_INFO_DATA
*data
,
1908 print_queue_struct
*queue
,
1909 NT_PRINTER_INFO_LEVEL
*printer
,
1910 TALLOC_CTX
*mem_ctx
)
1912 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
1915 /*******************************************************************
1916 * fill a notify_info_data with job name
1917 ********************************************************************/
1918 static void spoolss_notify_job_name(int snum
,
1919 SPOOL_NOTIFY_INFO_DATA
*data
,
1920 print_queue_struct
*queue
,
1921 NT_PRINTER_INFO_LEVEL
*printer
,
1922 TALLOC_CTX
*mem_ctx
)
1927 len
= rpcstr_push(temp
, queue
->file
, sizeof(temp
) - 2, 0);
1929 data
->notify_data
.data
.length
= len
/ 2 - 1;
1930 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1932 if (!data
->notify_data
.data
.string
) {
1933 data
->notify_data
.data
.length
= 0;
1937 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1940 /*******************************************************************
1941 * fill a notify_info_data with job status
1942 ********************************************************************/
1943 static void spoolss_notify_job_status_string(int snum
,
1944 SPOOL_NOTIFY_INFO_DATA
*data
,
1945 print_queue_struct
*queue
,
1946 NT_PRINTER_INFO_LEVEL
*printer
,
1947 TALLOC_CTX
*mem_ctx
)
1950 * Now we're returning job status codes we just return a "" here. JRA.
1957 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
1960 switch (queue
->status
) {
1965 p
= ""; /* NT provides the paused string */
1974 #endif /* NO LONGER NEEDED. */
1976 len
= rpcstr_push(temp
, p
, sizeof(temp
) - 2, 0);
1978 data
->notify_data
.data
.length
= len
/ 2 - 1;
1979 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1981 if (!data
->notify_data
.data
.string
) {
1982 data
->notify_data
.data
.length
= 0;
1986 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1989 /*******************************************************************
1990 * fill a notify_info_data with job time
1991 ********************************************************************/
1992 static void spoolss_notify_job_time(int snum
,
1993 SPOOL_NOTIFY_INFO_DATA
*data
,
1994 print_queue_struct
*queue
,
1995 NT_PRINTER_INFO_LEVEL
*printer
,
1996 TALLOC_CTX
*mem_ctx
)
1998 data
->notify_data
.value
[0]=0x0;
2001 /*******************************************************************
2002 * fill a notify_info_data with job size
2003 ********************************************************************/
2004 static void spoolss_notify_job_size(int snum
,
2005 SPOOL_NOTIFY_INFO_DATA
*data
,
2006 print_queue_struct
*queue
,
2007 NT_PRINTER_INFO_LEVEL
*printer
,
2008 TALLOC_CTX
*mem_ctx
)
2010 data
->notify_data
.value
[0]=queue
->size
;
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
;
2025 /*******************************************************************
2026 * fill a notify_info_data with submitted time
2027 ********************************************************************/
2028 static void spoolss_notify_submitted_time(int snum
,
2029 SPOOL_NOTIFY_INFO_DATA
*data
,
2030 print_queue_struct
*queue
,
2031 NT_PRINTER_INFO_LEVEL
*printer
,
2032 TALLOC_CTX
*mem_ctx
)
2038 t
=gmtime(&queue
->time
);
2040 len
= sizeof(SYSTEMTIME
);
2042 data
->notify_data
.data
.length
= len
/2 - 1;
2043 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2045 if (!data
->notify_data
.data
.string
) {
2046 data
->notify_data
.data
.length
= 0;
2050 make_systemtime(&st
, t
);
2051 memcpy(data
->notify_data
.data
.string
,&st
,len
);
2056 struct s_notify_info_data_table
2062 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
2063 print_queue_struct
*queue
,
2064 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
2067 struct s_notify_info_data_table notify_info_data_table
[] =
2069 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", POINTER
, spoolss_notify_server_name
},
2070 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2071 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", POINTER
, spoolss_notify_share_name
},
2072 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2073 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2074 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", POINTER
, spoolss_notify_comment
},
2075 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", POINTER
, spoolss_notify_location
},
2076 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2077 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", POINTER
, spoolss_notify_sepfile
},
2078 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2079 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2080 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2081 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, spoolss_notify_security_desc
},
2082 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE
, spoolss_notify_attributes
},
2083 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2084 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE
, spoolss_notify_default_priority
},
2085 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2086 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2087 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_status
},
2088 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", POINTER
, NULL
},
2089 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", ONE_VALUE
, spoolss_notify_cjobs
},
2090 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE
, spoolss_notify_average_ppm
},
2091 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER
, NULL
},
2092 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER
, NULL
},
2093 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER
, NULL
},
2094 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER
, NULL
},
2095 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2096 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", POINTER
, spoolss_notify_server_name
},
2097 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2098 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", POINTER
, spoolss_notify_username
},
2099 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", POINTER
, spoolss_notify_username
},
2100 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2101 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2102 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2103 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2104 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2105 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_job_status
},
2106 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", POINTER
, spoolss_notify_job_status_string
},
2107 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, NULL
},
2108 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", POINTER
, spoolss_notify_job_name
},
2109 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2110 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", ONE_VALUE
, spoolss_notify_job_position
},
2111 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", POINTER
, spoolss_notify_submitted_time
},
2112 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2113 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2114 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", ONE_VALUE
, spoolss_notify_job_time
},
2115 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE
, NULL
},
2116 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE
, NULL
},
2117 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE
, spoolss_notify_job_size
},
2118 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_BYTES_PRINTED
, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE
, NULL
},
2119 { END
, END
, "", END
, NULL
}
2122 /*******************************************************************
2123 return the size of info_data structure
2124 ********************************************************************/
2125 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
2129 while (notify_info_data_table
[i
].type
!= END
)
2131 if ( (notify_info_data_table
[i
].type
== type
) &&
2132 (notify_info_data_table
[i
].field
== field
) )
2134 return (notify_info_data_table
[i
].size
);
2141 /*******************************************************************
2142 return the type of notify_info_data
2143 ********************************************************************/
2144 static BOOL
type_of_notify_info_data(uint16 type
, uint16 field
)
2148 while (notify_info_data_table
[i
].type
!= END
)
2150 if ( (notify_info_data_table
[i
].type
== type
) &&
2151 (notify_info_data_table
[i
].field
== field
) )
2153 if (notify_info_data_table
[i
].size
== POINTER
)
2167 /****************************************************************************
2168 ****************************************************************************/
2169 static int search_notify(uint16 type
, uint16 field
, int *value
)
2174 for (j
=0, found
=False
; found
==False
&& notify_info_data_table
[j
].type
!= END
; j
++)
2176 if ( (notify_info_data_table
[j
].type
== type
) &&
2177 (notify_info_data_table
[j
].field
== field
) )
2182 if ( found
&& (notify_info_data_table
[j
].fn
!= NULL
) )
2188 /****************************************************************************
2189 ****************************************************************************/
2190 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
2192 info_data
->type
= type
;
2193 info_data
->field
= field
;
2194 info_data
->reserved
= 0;
2196 info_data
->size
= size_of_notify_info_data(type
, field
);
2197 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
2201 /*******************************************************************
2203 * fill a notify_info struct with info asked
2205 ********************************************************************/
2206 static BOOL
construct_notify_printer_info(SPOOL_NOTIFY_INFO
*info
, int
2207 snum
, SPOOL_NOTIFY_OPTION_TYPE
2208 *option_type
, uint32 id
,
2209 TALLOC_CTX
*mem_ctx
)
2215 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
2216 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2217 print_queue_struct
*queue
=NULL
;
2219 type
=option_type
->type
;
2221 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
2222 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2223 option_type
->count
, lp_servicename(snum
)));
2225 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2228 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2229 field
= option_type
->fields
[field_num
];
2230 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
2232 if (!search_notify(type
, field
, &j
) )
2235 if((tid
=(SPOOL_NOTIFY_INFO_DATA
*)Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2236 DEBUG(0,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
2239 else info
->data
= tid
;
2241 current_data
=&info
->data
[info
->count
];
2243 construct_info_data(current_data
, type
, field
, id
);
2245 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
2246 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
2248 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2254 free_a_printer(&printer
, 2);
2258 /*******************************************************************
2260 * fill a notify_info struct with info asked
2262 ********************************************************************/
2263 static BOOL
construct_notify_jobs_info(print_queue_struct
*queue
,
2264 SPOOL_NOTIFY_INFO
*info
,
2265 NT_PRINTER_INFO_LEVEL
*printer
,
2266 int snum
, SPOOL_NOTIFY_OPTION_TYPE
2267 *option_type
, uint32 id
,
2268 TALLOC_CTX
*mem_ctx
)
2274 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
2276 DEBUG(4,("construct_notify_jobs_info\n"));
2278 type
= option_type
->type
;
2280 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
2281 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2282 option_type
->count
));
2284 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2285 field
= option_type
->fields
[field_num
];
2287 if (!search_notify(type
, field
, &j
) )
2290 if((tid
=Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2291 DEBUG(0,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
2294 else info
->data
= tid
;
2296 current_data
=&(info
->data
[info
->count
]);
2298 construct_info_data(current_data
, type
, field
, id
);
2299 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2308 * JFM: The enumeration is not that simple, it's even non obvious.
2310 * let's take an example: I want to monitor the PRINTER SERVER for
2311 * the printer's name and the number of jobs currently queued.
2312 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
2313 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
2315 * I have 3 printers on the back of my server.
2317 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
2320 * 1 printer 1 name 1
2321 * 2 printer 1 cjob 1
2322 * 3 printer 2 name 2
2323 * 4 printer 2 cjob 2
2324 * 5 printer 3 name 3
2325 * 6 printer 3 name 3
2327 * that's the print server case, the printer case is even worse.
2330 /*******************************************************************
2332 * enumerate all printers on the printserver
2333 * fill a notify_info struct with info asked
2335 ********************************************************************/
2337 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
2338 SPOOL_NOTIFY_INFO
*info
,
2339 TALLOC_CTX
*mem_ctx
)
2342 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2343 int n_services
=lp_numservices();
2346 SPOOL_NOTIFY_OPTION
*option
;
2347 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2349 DEBUG(4,("printserver_notify_info\n"));
2351 option
=Printer
->notify
.option
;
2357 for (i
=0; i
<option
->count
; i
++) {
2358 option_type
=&(option
->ctr
.type
[i
]);
2360 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
2363 for (snum
=0; snum
<n_services
; snum
++)
2364 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
2365 if (construct_notify_printer_info
2366 (info
, snum
, option_type
, id
, mem_ctx
))
2371 * Debugging information, don't delete.
2374 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2375 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2376 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2378 for (i=0; i<info->count; i++) {
2379 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2380 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2381 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2388 /*******************************************************************
2390 * fill a notify_info struct with info asked
2392 ********************************************************************/
2393 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
2394 TALLOC_CTX
*mem_ctx
)
2397 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2400 SPOOL_NOTIFY_OPTION
*option
;
2401 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2403 print_queue_struct
*queue
=NULL
;
2404 print_status_struct status
;
2406 DEBUG(4,("printer_notify_info\n"));
2408 option
=Printer
->notify
.option
;
2414 get_printer_snum(p
, hnd
, &snum
);
2416 for (i
=0; i
<option
->count
; i
++) {
2417 option_type
=&option
->ctr
.type
[i
];
2419 switch ( option_type
->type
) {
2420 case PRINTER_NOTIFY_TYPE
:
2421 if(construct_notify_printer_info(info
, snum
,
2427 case JOB_NOTIFY_TYPE
: {
2428 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2430 memset(&status
, 0, sizeof(status
));
2431 count
= print_queue_status(snum
, &queue
, &status
);
2433 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2,
2434 lp_servicename(snum
))))
2437 for (j
=0; j
<count
; j
++) {
2438 construct_notify_jobs_info(&queue
[j
], info
,
2445 free_a_printer(&printer
, 2);
2455 * Debugging information, don't delete.
2458 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2459 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2460 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2462 for (i=0; i<info->count; i++) {
2463 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2464 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2465 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2471 /********************************************************************
2473 ********************************************************************/
2475 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
2477 POLICY_HND
*handle
= &q_u
->handle
;
2478 /* uint32 change = q_u->change; - notused. */
2479 /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
2480 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
2482 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2483 WERROR result
= WERR_BADFID
;
2485 /* we always have a NOTIFY_INFO struct */
2489 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",
2490 OUR_HANDLE(handle
)));
2494 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
2496 /* jfm: the change value isn't used right now.
2497 * we will honour it when
2498 * a) we'll be able to send notification to the client
2499 * b) we'll have a way to communicate between the spoolss process.
2501 * same thing for option->flags
2502 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2503 * I don't have a global notification system, I'm sending back all the
2504 * informations even when _NOTHING_ has changed.
2507 /* just ignore the SPOOL_NOTIFY_OPTION */
2509 switch (Printer
->printer_type
) {
2510 case PRINTER_HANDLE_IS_PRINTSERVER
:
2511 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
2514 case PRINTER_HANDLE_IS_PRINTER
:
2515 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
2523 /********************************************************************
2524 * construct_printer_info_0
2525 * fill a printer_info_0 struct
2526 ********************************************************************/
2527 static BOOL
construct_printer_info_0(PRINTER_INFO_0
*printer
, int snum
)
2531 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2532 counter_printer_0
*session_counter
;
2533 uint32 global_counter
;
2537 print_queue_struct
*queue
=NULL
;
2538 print_status_struct status
;
2540 memset(&status
, 0, sizeof(status
));
2542 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2545 count
= print_queue_status(snum
, &queue
, &status
);
2547 /* check if we already have a counter for this printer */
2548 session_counter
= (counter_printer_0
*)ubi_dlFirst(&counter_list
);
2550 for(; session_counter
; session_counter
= (counter_printer_0
*)ubi_dlNext(session_counter
)) {
2551 if (session_counter
->snum
== snum
)
2555 /* it's the first time, add it to the list */
2556 if (session_counter
==NULL
) {
2557 if((session_counter
=(counter_printer_0
*)malloc(sizeof(counter_printer_0
))) == NULL
) {
2558 free_a_printer(&ntprinter
, 2);
2561 ZERO_STRUCTP(session_counter
);
2562 session_counter
->snum
=snum
;
2563 session_counter
->counter
=0;
2564 ubi_dlAddHead( &counter_list
, (ubi_dlNode
*)session_counter
);
2568 session_counter
->counter
++;
2571 * the global_counter should be stored in a TDB as it's common to all the clients
2572 * and should be zeroed on samba startup
2574 global_counter
=session_counter
->counter
;
2576 pstrcpy(chaine
,ntprinter
->info_2
->printername
);
2578 init_unistr(&printer
->printername
, chaine
);
2580 slprintf(chaine
,sizeof(chaine
)-1,"\\\\%s", global_myname
);
2581 init_unistr(&printer
->servername
, chaine
);
2583 printer
->cjobs
= count
;
2584 printer
->total_jobs
= 0;
2585 printer
->total_bytes
= 0;
2587 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
2588 t
=gmtime(&setuptime
);
2590 printer
->year
= t
->tm_year
+1900;
2591 printer
->month
= t
->tm_mon
+1;
2592 printer
->dayofweek
= t
->tm_wday
;
2593 printer
->day
= t
->tm_mday
;
2594 printer
->hour
= t
->tm_hour
;
2595 printer
->minute
= t
->tm_min
;
2596 printer
->second
= t
->tm_sec
;
2597 printer
->milliseconds
= 0;
2599 printer
->global_counter
= global_counter
;
2600 printer
->total_pages
= 0;
2601 printer
->major_version
= 0x0004; /* NT 4 */
2602 printer
->build_version
= 0x0565; /* build 1381 */
2603 printer
->unknown7
= 0x1;
2604 printer
->unknown8
= 0x0;
2605 printer
->unknown9
= 0x0;
2606 printer
->session_counter
= session_counter
->counter
;
2607 printer
->unknown11
= 0x0;
2608 printer
->printer_errors
= 0x0; /* number of print failure */
2609 printer
->unknown13
= 0x0;
2610 printer
->unknown14
= 0x1;
2611 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
2612 printer
->unknown16
= 0x0;
2613 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
2614 printer
->unknown18
= 0x0;
2615 printer
->status
= nt_printq_status(status
.status
);
2616 printer
->unknown20
= 0x0;
2617 printer
->c_setprinter
= ntprinter
->info_2
->c_setprinter
; /* how many times setprinter has been called */
2618 printer
->unknown22
= 0x0;
2619 printer
->unknown23
= 0x6; /* 6 ???*/
2620 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
2621 printer
->unknown25
= 0;
2622 printer
->unknown26
= 0;
2623 printer
->unknown27
= 0;
2624 printer
->unknown28
= 0;
2625 printer
->unknown29
= 0;
2628 free_a_printer(&ntprinter
,2);
2632 /********************************************************************
2633 * construct_printer_info_1
2634 * fill a printer_info_1 struct
2635 ********************************************************************/
2636 static BOOL
construct_printer_info_1(uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
2640 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2642 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2645 printer
->flags
=flags
;
2647 if (*ntprinter
->info_2
->comment
== '\0') {
2648 init_unistr(&printer
->comment
, lp_comment(snum
));
2649 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",global_myname
, ntprinter
->info_2
->printername
,
2650 ntprinter
->info_2
->drivername
, lp_comment(snum
));
2653 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2654 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",global_myname
, ntprinter
->info_2
->printername
,
2655 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
2658 slprintf(chaine2
,sizeof(chaine
)-1,"%s", ntprinter
->info_2
->printername
);
2660 init_unistr(&printer
->description
, chaine
);
2661 init_unistr(&printer
->name
, chaine2
);
2663 free_a_printer(&ntprinter
,2);
2668 /****************************************************************************
2669 Free a DEVMODE struct.
2670 ****************************************************************************/
2672 static void free_dev_mode(DEVICEMODE
*dev
)
2678 safe_free(dev
->private);
2683 /****************************************************************************
2684 Create a DEVMODE struct. Returns malloced memory.
2685 ****************************************************************************/
2687 static DEVICEMODE
*construct_dev_mode(int snum
)
2691 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2692 NT_DEVICEMODE
*ntdevmode
= NULL
;
2693 DEVICEMODE
*devmode
= NULL
;
2695 DEBUG(7,("construct_dev_mode\n"));
2697 DEBUGADD(8,("getting printer characteristics\n"));
2699 if ((devmode
= (DEVICEMODE
*)malloc(sizeof(DEVICEMODE
))) == NULL
) {
2700 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
2704 ZERO_STRUCTP(devmode
);
2706 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2709 if (printer
->info_2
->devmode
)
2710 ntdevmode
= dup_nt_devicemode(printer
->info_2
->devmode
);
2712 if (ntdevmode
== NULL
)
2715 DEBUGADD(8,("loading DEVICEMODE\n"));
2717 slprintf(adevice
, sizeof(adevice
)-1, printer
->info_2
->printername
);
2718 init_unistr(&devmode
->devicename
, adevice
);
2720 slprintf(aform
, sizeof(aform
)-1, ntdevmode
->formname
);
2721 init_unistr(&devmode
->formname
, aform
);
2723 devmode
->specversion
= ntdevmode
->specversion
;
2724 devmode
->driverversion
= ntdevmode
->driverversion
;
2725 devmode
->size
= ntdevmode
->size
;
2726 devmode
->driverextra
= ntdevmode
->driverextra
;
2727 devmode
->fields
= ntdevmode
->fields
;
2729 devmode
->orientation
= ntdevmode
->orientation
;
2730 devmode
->papersize
= ntdevmode
->papersize
;
2731 devmode
->paperlength
= ntdevmode
->paperlength
;
2732 devmode
->paperwidth
= ntdevmode
->paperwidth
;
2733 devmode
->scale
= ntdevmode
->scale
;
2734 devmode
->copies
= ntdevmode
->copies
;
2735 devmode
->defaultsource
= ntdevmode
->defaultsource
;
2736 devmode
->printquality
= ntdevmode
->printquality
;
2737 devmode
->color
= ntdevmode
->color
;
2738 devmode
->duplex
= ntdevmode
->duplex
;
2739 devmode
->yresolution
= ntdevmode
->yresolution
;
2740 devmode
->ttoption
= ntdevmode
->ttoption
;
2741 devmode
->collate
= ntdevmode
->collate
;
2742 devmode
->icmmethod
= ntdevmode
->icmmethod
;
2743 devmode
->icmintent
= ntdevmode
->icmintent
;
2744 devmode
->mediatype
= ntdevmode
->mediatype
;
2745 devmode
->dithertype
= ntdevmode
->dithertype
;
2747 if (ntdevmode
->private != NULL
) {
2748 if ((devmode
->private=(uint8
*)memdup(ntdevmode
->private, ntdevmode
->driverextra
)) == NULL
)
2752 free_nt_devicemode(&ntdevmode
);
2753 free_a_printer(&printer
,2);
2760 free_nt_devicemode(&ntdevmode
);
2762 free_a_printer(&printer
,2);
2763 free_dev_mode(devmode
);
2768 /********************************************************************
2769 * construct_printer_info_2
2770 * fill a printer_info_2 struct
2771 ********************************************************************/
2773 static BOOL
construct_printer_info_2(PRINTER_INFO_2
*printer
, int snum
)
2776 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2778 print_queue_struct
*queue
=NULL
;
2779 print_status_struct status
;
2780 memset(&status
, 0, sizeof(status
));
2782 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2785 memset(&status
, 0, sizeof(status
));
2786 count
= print_queue_status(snum
, &queue
, &status
);
2788 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
2789 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
2790 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
2791 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
2792 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
2794 if (*ntprinter
->info_2
->comment
== '\0')
2795 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
2797 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2799 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
2800 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
2801 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
2802 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
2803 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
2805 printer
->attributes
= ntprinter
->info_2
->attributes
;
2807 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
2808 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
2809 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
2810 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
2811 printer
->status
= nt_printq_status(status
.status
); /* status */
2812 printer
->cjobs
= count
; /* jobs */
2813 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
2815 if((printer
->devmode
= construct_dev_mode(snum
)) == NULL
) {
2816 DEBUG(8, ("Returning NULL Devicemode!\n"));
2819 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2820 /* steal the printer info sec_desc structure. [badly done]. */
2821 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2822 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen memory. */
2823 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen memory. */
2824 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen memory. */
2827 printer
->secdesc
= NULL
;
2830 free_a_printer(&ntprinter
, 2);
2835 /********************************************************************
2836 * construct_printer_info_3
2837 * fill a printer_info_3 struct
2838 ********************************************************************/
2839 static BOOL
construct_printer_info_3(PRINTER_INFO_3
**pp_printer
, int snum
)
2841 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2842 PRINTER_INFO_3
*printer
= NULL
;
2844 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2848 if ((printer
= (PRINTER_INFO_3
*)malloc(sizeof(PRINTER_INFO_3
))) == NULL
) {
2849 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
2853 ZERO_STRUCTP(printer
);
2855 printer
->flags
= 4; /* These are the components of the SD we are returning. */
2856 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2857 /* steal the printer info sec_desc structure. [badly done]. */
2858 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2862 * Set the flags for the components we are returning.
2865 if (printer
->secdesc
->owner_sid
)
2866 printer
->flags
|= OWNER_SECURITY_INFORMATION
;
2868 if (printer
->secdesc
->grp_sid
)
2869 printer
->flags
|= GROUP_SECURITY_INFORMATION
;
2871 if (printer
->secdesc
->dacl
)
2872 printer
->flags
|= DACL_SECURITY_INFORMATION
;
2874 if (printer
->secdesc
->sacl
)
2875 printer
->flags
|= SACL_SECURITY_INFORMATION
;
2878 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen the malloced memory. */
2879 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen the malloced memory. */
2880 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen the malloced memory. */
2883 free_a_printer(&ntprinter
, 2);
2885 *pp_printer
= printer
;
2889 /********************************************************************
2890 Spoolss_enumprinters.
2891 ********************************************************************/
2892 static WERROR
enum_all_printers_info_1(uint32 flags
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2896 int n_services
=lp_numservices();
2897 PRINTER_INFO_1
*tp
, *printers
=NULL
;
2898 PRINTER_INFO_1 current_prt
;
2900 DEBUG(4,("enum_all_printers_info_1\n"));
2902 for (snum
=0; snum
<n_services
; snum
++) {
2903 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
2904 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
2906 if (construct_printer_info_1(flags
, ¤t_prt
, snum
)) {
2907 if((tp
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_1
))) == NULL
) {
2908 DEBUG(0,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
2909 safe_free(printers
);
2914 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
2915 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
2921 /* check the required size. */
2922 for (i
=0; i
<*returned
; i
++)
2923 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
2925 if (!alloc_buffer_size(buffer
, *needed
))
2926 return WERR_INSUFFICIENT_BUFFER
;
2928 /* fill the buffer with the structures */
2929 for (i
=0; i
<*returned
; i
++)
2930 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
2933 safe_free(printers
);
2935 if (*needed
> offered
) {
2937 return WERR_INSUFFICIENT_BUFFER
;
2943 /********************************************************************
2944 enum_all_printers_info_1_local.
2945 *********************************************************************/
2946 static WERROR
enum_all_printers_info_1_local(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2948 DEBUG(4,("enum_all_printers_info_1_local\n"));
2950 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
2953 /********************************************************************
2954 enum_all_printers_info_1_name.
2955 *********************************************************************/
2956 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 fstrcpy(temp
, "\\\\");
2962 fstrcat(temp
, global_myname
);
2964 if (strequal(name
, temp
)) {
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
)
3132 fstrcpy(temp
, "\\\\");
3133 fstrcat(temp
, global_myname
);
3135 if (flags
& PRINTER_ENUM_LOCAL
) {
3136 if (strequal(servername
, temp
))
3137 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3139 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3142 if (flags
& PRINTER_ENUM_NAME
) {
3143 if (strequal(servername
, temp
))
3144 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3146 return WERR_INVALID_NAME
;
3149 if (flags
& PRINTER_ENUM_REMOTE
)
3150 return WERR_UNKNOWN_LEVEL
;
3155 /********************************************************************
3156 * handle enumeration of printers at level 5
3157 ********************************************************************/
3158 static WERROR
enumprinters_level5( uint32 flags
, fstring servername
,
3159 NEW_BUFFER
*buffer
, uint32 offered
,
3160 uint32
*needed
, uint32
*returned
)
3162 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
3166 /********************************************************************
3167 * api_spoolss_enumprinters
3169 * called from api_spoolss_enumprinters (see this to understand)
3170 ********************************************************************/
3172 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
3174 uint32 flags
= q_u
->flags
;
3175 UNISTR2
*servername
= &q_u
->servername
;
3176 uint32 level
= q_u
->level
;
3177 NEW_BUFFER
*buffer
= NULL
;
3178 uint32 offered
= q_u
->offered
;
3179 uint32
*needed
= &r_u
->needed
;
3180 uint32
*returned
= &r_u
->returned
;
3183 /* that's an [in out] buffer */
3184 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3185 buffer
= r_u
->buffer
;
3187 DEBUG(4,("_spoolss_enumprinters\n"));
3194 * flags==PRINTER_ENUM_NAME
3195 * if name=="" then enumerates all printers
3196 * if name!="" then enumerate the printer
3197 * flags==PRINTER_ENUM_REMOTE
3198 * name is NULL, enumerate printers
3199 * Level 2: name!="" enumerates printers, name can't be NULL
3200 * Level 3: doesn't exist
3201 * Level 4: does a local registry lookup
3202 * Level 5: same as Level 2
3205 unistr2_to_ascii(name
, servername
, sizeof(name
)-1);
3210 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
3212 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
3214 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
3219 return WERR_UNKNOWN_LEVEL
;
3222 /****************************************************************************
3223 ****************************************************************************/
3224 static WERROR
getprinter_level_0(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3226 PRINTER_INFO_0
*printer
=NULL
;
3228 if((printer
=(PRINTER_INFO_0
*)malloc(sizeof(PRINTER_INFO_0
))) == NULL
)
3231 construct_printer_info_0(printer
, snum
);
3233 /* check the required size. */
3234 *needed
+= spoolss_size_printer_info_0(printer
);
3236 if (!alloc_buffer_size(buffer
, *needed
)) {
3238 return WERR_INSUFFICIENT_BUFFER
;
3241 /* fill the buffer with the structures */
3242 smb_io_printer_info_0("", buffer
, printer
, 0);
3247 if (*needed
> offered
) {
3248 return WERR_INSUFFICIENT_BUFFER
;
3254 /****************************************************************************
3255 ****************************************************************************/
3256 static WERROR
getprinter_level_1(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3258 PRINTER_INFO_1
*printer
=NULL
;
3260 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
3263 construct_printer_info_1(PRINTER_ENUM_ICON8
, printer
, snum
);
3265 /* check the required size. */
3266 *needed
+= spoolss_size_printer_info_1(printer
);
3268 if (!alloc_buffer_size(buffer
, *needed
)) {
3270 return WERR_INSUFFICIENT_BUFFER
;
3273 /* fill the buffer with the structures */
3274 smb_io_printer_info_1("", buffer
, printer
, 0);
3279 if (*needed
> offered
) {
3280 return WERR_INSUFFICIENT_BUFFER
;
3286 /****************************************************************************
3287 ****************************************************************************/
3288 static WERROR
getprinter_level_2(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3290 PRINTER_INFO_2
*printer
=NULL
;
3292 if((printer
=(PRINTER_INFO_2
*)malloc(sizeof(PRINTER_INFO_2
)))==NULL
)
3295 construct_printer_info_2(printer
, snum
);
3297 /* check the required size. */
3298 *needed
+= spoolss_size_printer_info_2(printer
);
3300 if (!alloc_buffer_size(buffer
, *needed
)) {
3301 free_printer_info_2(printer
);
3302 return WERR_INSUFFICIENT_BUFFER
;
3305 /* fill the buffer with the structures */
3306 if (!smb_io_printer_info_2("", buffer
, printer
, 0)) {
3307 free_printer_info_2(printer
);
3312 free_printer_info_2(printer
);
3314 if (*needed
> offered
) {
3315 return WERR_INSUFFICIENT_BUFFER
;
3321 /****************************************************************************
3322 ****************************************************************************/
3323 static WERROR
getprinter_level_3(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3325 PRINTER_INFO_3
*printer
=NULL
;
3327 if (!construct_printer_info_3(&printer
, snum
))
3330 /* check the required size. */
3331 *needed
+= spoolss_size_printer_info_3(printer
);
3333 if (!alloc_buffer_size(buffer
, *needed
)) {
3334 free_printer_info_3(printer
);
3335 return WERR_INSUFFICIENT_BUFFER
;
3338 /* fill the buffer with the structures */
3339 smb_io_printer_info_3("", buffer
, printer
, 0);
3342 free_printer_info_3(printer
);
3344 if (*needed
> offered
) {
3345 return WERR_INSUFFICIENT_BUFFER
;
3351 /****************************************************************************
3352 ****************************************************************************/
3354 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
3356 POLICY_HND
*handle
= &q_u
->handle
;
3357 uint32 level
= q_u
->level
;
3358 NEW_BUFFER
*buffer
= NULL
;
3359 uint32 offered
= q_u
->offered
;
3360 uint32
*needed
= &r_u
->needed
;
3364 /* that's an [in out] buffer */
3365 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3366 buffer
= r_u
->buffer
;
3370 if (!get_printer_snum(p
, handle
, &snum
))
3375 return getprinter_level_0(snum
, buffer
, offered
, needed
);
3377 return getprinter_level_1(snum
, buffer
, offered
, needed
);
3379 return getprinter_level_2(snum
, buffer
, offered
, needed
);
3381 return getprinter_level_3(snum
, buffer
, offered
, needed
);
3383 return WERR_UNKNOWN_LEVEL
;
3386 /********************************************************************
3387 * fill a DRIVER_INFO_1 struct
3388 ********************************************************************/
3389 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
3391 init_unistr( &info
->name
, driver
.info_3
->name
);
3394 /********************************************************************
3395 * construct_printer_driver_info_1
3396 ********************************************************************/
3397 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3399 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3400 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3402 ZERO_STRUCT(driver
);
3404 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3405 return WERR_INVALID_PRINTER_NAME
;
3407 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
3408 return WERR_UNKNOWN_PRINTER_DRIVER
;
3410 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
3412 free_a_printer(&printer
,2);
3417 /********************************************************************
3418 * construct_printer_driver_info_2
3419 * fill a printer_info_2 struct
3420 ********************************************************************/
3421 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3425 info
->version
=driver
.info_3
->cversion
;
3427 init_unistr( &info
->name
, driver
.info_3
->name
);
3428 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3431 if (strlen(driver
.info_3
->driverpath
)) {
3432 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3433 init_unistr( &info
->driverpath
, temp
);
3435 init_unistr( &info
->driverpath
, "" );
3437 if (strlen(driver
.info_3
->datafile
)) {
3438 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3439 init_unistr( &info
->datafile
, temp
);
3441 init_unistr( &info
->datafile
, "" );
3443 if (strlen(driver
.info_3
->configfile
)) {
3444 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3445 init_unistr( &info
->configfile
, temp
);
3447 init_unistr( &info
->configfile
, "" );
3450 /********************************************************************
3451 * construct_printer_driver_info_2
3452 * fill a printer_info_2 struct
3453 ********************************************************************/
3454 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3456 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3457 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3459 ZERO_STRUCT(printer
);
3460 ZERO_STRUCT(driver
);
3462 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3463 return WERR_INVALID_PRINTER_NAME
;
3465 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
3466 return WERR_UNKNOWN_PRINTER_DRIVER
;
3468 fill_printer_driver_info_2(info
, driver
, servername
);
3470 free_a_printer(&printer
,2);
3475 /********************************************************************
3476 * copy a strings array and convert to UNICODE
3478 * convert an array of ascii string to a UNICODE string
3479 ********************************************************************/
3480 static void init_unistr_array(uint16
**uni_array
, fstring
*char_array
, char *servername
)
3488 DEBUG(6,("init_unistr_array\n"));
3492 if (char_array
== NULL
)
3496 if (!v
) v
= ""; /* hack to handle null lists */
3498 if (strlen(v
) == 0) break;
3499 slprintf(line
, sizeof(line
)-1, "\\\\%s%s", servername
, v
);
3500 DEBUGADD(6,("%d:%s:%d\n", i
, line
, strlen(line
)));
3501 if((tuary
=Realloc(*uni_array
, (j
+strlen(line
)+2)*sizeof(uint16
))) == NULL
) {
3502 DEBUG(0,("init_unistr_array: Realloc error\n" ));
3505 else *uni_array
= tuary
;
3506 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, 0)/ sizeof(uint16
));
3511 (*uni_array
)[j
]=0x0000;
3514 DEBUGADD(6,("last one:done\n"));
3517 /********************************************************************
3518 * construct_printer_info_3
3519 * fill a printer_info_3 struct
3520 ********************************************************************/
3521 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3527 info
->version
=driver
.info_3
->cversion
;
3529 init_unistr( &info
->name
, driver
.info_3
->name
);
3530 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3532 if (strlen(driver
.info_3
->driverpath
)) {
3533 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3534 init_unistr( &info
->driverpath
, temp
);
3536 init_unistr( &info
->driverpath
, "" );
3538 if (strlen(driver
.info_3
->datafile
)) {
3539 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3540 init_unistr( &info
->datafile
, temp
);
3542 init_unistr( &info
->datafile
, "" );
3544 if (strlen(driver
.info_3
->configfile
)) {
3545 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3546 init_unistr( &info
->configfile
, temp
);
3548 init_unistr( &info
->configfile
, "" );
3550 if (strlen(driver
.info_3
->helpfile
)) {
3551 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3552 init_unistr( &info
->helpfile
, temp
);
3554 init_unistr( &info
->helpfile
, "" );
3556 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3557 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3559 info
->dependentfiles
=NULL
;
3560 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3563 /********************************************************************
3564 * construct_printer_info_3
3565 * fill a printer_info_3 struct
3566 ********************************************************************/
3567 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3569 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3570 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3572 ZERO_STRUCT(driver
);
3574 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3575 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status
)));
3576 if (!W_ERROR_IS_OK(status
))
3577 return WERR_INVALID_PRINTER_NAME
;
3579 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3580 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status
)));
3581 if (!W_ERROR_IS_OK(status
)) {
3582 free_a_printer(&printer
,2);
3583 return WERR_UNKNOWN_PRINTER_DRIVER
;
3586 fill_printer_driver_info_3(info
, driver
, servername
);
3588 free_a_printer(&printer
,2);
3593 /********************************************************************
3594 * construct_printer_info_6
3595 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
3596 ********************************************************************/
3598 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3604 memset(&nullstr
, '\0', sizeof(fstring
));
3606 info
->version
=driver
.info_3
->cversion
;
3608 init_unistr( &info
->name
, driver
.info_3
->name
);
3609 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3611 if (strlen(driver
.info_3
->driverpath
)) {
3612 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3613 init_unistr( &info
->driverpath
, temp
);
3615 init_unistr( &info
->driverpath
, "" );
3617 if (strlen(driver
.info_3
->datafile
)) {
3618 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3619 init_unistr( &info
->datafile
, temp
);
3621 init_unistr( &info
->datafile
, "" );
3623 if (strlen(driver
.info_3
->configfile
)) {
3624 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3625 init_unistr( &info
->configfile
, temp
);
3627 init_unistr( &info
->configfile
, "" );
3629 if (strlen(driver
.info_3
->helpfile
)) {
3630 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3631 init_unistr( &info
->helpfile
, temp
);
3633 init_unistr( &info
->helpfile
, "" );
3635 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3636 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3638 info
->dependentfiles
=NULL
;
3639 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3641 info
->previousdrivernames
=NULL
;
3642 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
3644 info
->driver_date
.low
=0;
3645 info
->driver_date
.high
=0;
3648 info
->driver_version_low
=0;
3649 info
->driver_version_high
=0;
3651 init_unistr( &info
->mfgname
, "");
3652 init_unistr( &info
->oem_url
, "");
3653 init_unistr( &info
->hardware_id
, "");
3654 init_unistr( &info
->provider
, "");
3657 /********************************************************************
3658 * construct_printer_info_6
3659 * fill a printer_info_6 struct
3660 ********************************************************************/
3661 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3663 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3664 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3666 ZERO_STRUCT(driver
);
3668 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3669 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3670 if (!W_ERROR_IS_OK(status
))
3671 return WERR_INVALID_PRINTER_NAME
;
3673 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3674 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3675 if (!W_ERROR_IS_OK(status
)) {
3677 * Is this a W2k client ?
3681 free_a_printer(&printer
,2);
3682 return WERR_UNKNOWN_PRINTER_DRIVER
;
3685 /* Yes - try again with a WinNT driver. */
3687 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3688 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3689 if (!W_ERROR_IS_OK(status
)) {
3690 free_a_printer(&printer
,2);
3691 return WERR_UNKNOWN_PRINTER_DRIVER
;
3695 fill_printer_driver_info_6(info
, driver
, servername
);
3697 free_a_printer(&printer
,2);
3702 /****************************************************************************
3703 ****************************************************************************/
3705 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
3707 safe_free(info
->dependentfiles
);
3710 /****************************************************************************
3711 ****************************************************************************/
3713 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
3715 safe_free(info
->dependentfiles
);
3719 /****************************************************************************
3720 ****************************************************************************/
3721 static WERROR
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3723 DRIVER_INFO_1
*info
=NULL
;
3726 if((info
=(DRIVER_INFO_1
*)malloc(sizeof(DRIVER_INFO_1
))) == NULL
)
3729 status
=construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
3730 if (!W_ERROR_IS_OK(status
)) {
3735 /* check the required size. */
3736 *needed
+= spoolss_size_printer_driver_info_1(info
);
3738 if (!alloc_buffer_size(buffer
, *needed
)) {
3740 return WERR_INSUFFICIENT_BUFFER
;
3743 /* fill the buffer with the structures */
3744 smb_io_printer_driver_info_1("", buffer
, info
, 0);
3749 if (*needed
> offered
)
3750 return WERR_INSUFFICIENT_BUFFER
;
3755 /****************************************************************************
3756 ****************************************************************************/
3757 static WERROR
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3759 DRIVER_INFO_2
*info
=NULL
;
3762 if((info
=(DRIVER_INFO_2
*)malloc(sizeof(DRIVER_INFO_2
))) == NULL
)
3765 status
=construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
3766 if (!W_ERROR_IS_OK(status
)) {
3771 /* check the required size. */
3772 *needed
+= spoolss_size_printer_driver_info_2(info
);
3774 if (!alloc_buffer_size(buffer
, *needed
)) {
3776 return WERR_INSUFFICIENT_BUFFER
;
3779 /* fill the buffer with the structures */
3780 smb_io_printer_driver_info_2("", buffer
, info
, 0);
3785 if (*needed
> offered
)
3786 return WERR_INSUFFICIENT_BUFFER
;
3791 /****************************************************************************
3792 ****************************************************************************/
3793 static WERROR
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3800 status
=construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
3801 if (!W_ERROR_IS_OK(status
)) {
3805 /* check the required size. */
3806 *needed
+= spoolss_size_printer_driver_info_3(&info
);
3808 if (!alloc_buffer_size(buffer
, *needed
)) {
3809 free_printer_driver_info_3(&info
);
3810 return WERR_INSUFFICIENT_BUFFER
;
3813 /* fill the buffer with the structures */
3814 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
3816 free_printer_driver_info_3(&info
);
3818 if (*needed
> offered
)
3819 return WERR_INSUFFICIENT_BUFFER
;
3824 /****************************************************************************
3825 ****************************************************************************/
3826 static WERROR
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3833 status
=construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
3834 if (!W_ERROR_IS_OK(status
)) {
3838 /* check the required size. */
3839 *needed
+= spoolss_size_printer_driver_info_6(&info
);
3841 if (!alloc_buffer_size(buffer
, *needed
)) {
3842 free_printer_driver_info_6(&info
);
3843 return WERR_INSUFFICIENT_BUFFER
;
3846 /* fill the buffer with the structures */
3847 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
3849 free_printer_driver_info_6(&info
);
3851 if (*needed
> offered
)
3852 return WERR_INSUFFICIENT_BUFFER
;
3857 /****************************************************************************
3858 ****************************************************************************/
3860 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
3862 POLICY_HND
*handle
= &q_u
->handle
;
3863 UNISTR2
*uni_arch
= &q_u
->architecture
;
3864 uint32 level
= q_u
->level
;
3865 uint32 clientmajorversion
= q_u
->clientmajorversion
;
3866 /* uint32 clientminorversion = q_u->clientminorversion; - notused. */
3867 NEW_BUFFER
*buffer
= NULL
;
3868 uint32 offered
= q_u
->offered
;
3869 uint32
*needed
= &r_u
->needed
;
3870 uint32
*servermajorversion
= &r_u
->servermajorversion
;
3871 uint32
*serverminorversion
= &r_u
->serverminorversion
;
3874 fstring architecture
;
3877 /* that's an [in out] buffer */
3878 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3879 buffer
= r_u
->buffer
;
3881 DEBUG(4,("_spoolss_getprinterdriver2\n"));
3884 *servermajorversion
=0;
3885 *serverminorversion
=0;
3887 pstrcpy(servername
, global_myname
);
3888 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
)-1);
3890 if (!get_printer_snum(p
, handle
, &snum
))
3895 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3897 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3899 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3901 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3903 return WERR_UNKNOWN_LEVEL
;
3906 /****************************************************************************
3907 ****************************************************************************/
3909 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
3911 POLICY_HND
*handle
= &q_u
->handle
;
3913 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3916 Printer
->page_started
=True
;
3920 DEBUG(3,("Error in startpageprinter printer handle\n"));
3924 /****************************************************************************
3925 ****************************************************************************/
3927 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
3929 POLICY_HND
*handle
= &q_u
->handle
;
3931 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3934 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle
)));
3938 Printer
->page_started
=False
;
3943 /********************************************************************
3944 * api_spoolss_getprinter
3945 * called from the spoolss dispatcher
3947 ********************************************************************/
3949 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
3951 POLICY_HND
*handle
= &q_u
->handle
;
3952 /* uint32 level = q_u->doc_info_container.level; - notused. */
3953 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
3954 uint32
*jobid
= &r_u
->jobid
;
3956 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
3960 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3961 struct current_user user
;
3964 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
3968 get_current_user(&user
, p
);
3971 * a nice thing with NT is it doesn't listen to what you tell it.
3972 * when asked to send _only_ RAW datas, it tries to send datas
3975 * So I add checks like in NT Server ...
3977 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
3978 * there's a bug in NT client-side code, so we'll fix it in the
3979 * server-side code. *nnnnnggggh!*
3982 if (info_1
->p_datatype
!= 0) {
3983 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
3984 if (strcmp(datatype
, "RAW") != 0) {
3986 return WERR_INVALID_DATATYPE
;
3990 /* get the share number of the printer */
3991 if (!get_printer_snum(p
, handle
, &snum
)) {
3995 unistr2_to_ascii(jobname
, &info_1
->docname
, sizeof(jobname
));
3997 Printer
->jobid
= print_job_start(&user
, snum
, jobname
);
3999 /* An error occured in print_job_start() so return an appropriate
4002 if (Printer
->jobid
== -1) {
4003 return map_werror_from_unix(errno
);
4006 Printer
->document_started
=True
;
4007 (*jobid
) = Printer
->jobid
;
4012 /********************************************************************
4013 * api_spoolss_getprinter
4014 * called from the spoolss dispatcher
4016 ********************************************************************/
4018 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
4020 POLICY_HND
*handle
= &q_u
->handle
;
4022 return _spoolss_enddocprinter_internal(p
, handle
);
4025 /****************************************************************************
4026 ****************************************************************************/
4028 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
4030 POLICY_HND
*handle
= &q_u
->handle
;
4031 uint32 buffer_size
= q_u
->buffer_size
;
4032 uint8
*buffer
= q_u
->buffer
;
4033 uint32
*buffer_written
= &q_u
->buffer_size2
;
4035 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4038 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle
)));
4039 r_u
->buffer_written
= q_u
->buffer_size2
;
4043 (*buffer_written
) = print_job_write(Printer
->jobid
, (char *)buffer
, buffer_size
);
4046 r_u
->buffer_written
= q_u
->buffer_size2
;
4051 /********************************************************************
4052 * api_spoolss_getprinter
4053 * called from the spoolss dispatcher
4055 ********************************************************************/
4056 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
4059 struct current_user user
;
4061 WERROR errcode
= WERR_BADFUNC
;
4062 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4064 get_current_user(&user
, p
);
4067 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4071 if (!get_printer_snum(p
, handle
, &snum
))
4075 case PRINTER_CONTROL_PAUSE
:
4076 if (print_queue_pause(&user
, snum
, &errcode
)) {
4080 case PRINTER_CONTROL_RESUME
:
4081 case PRINTER_CONTROL_UNPAUSE
:
4082 if (print_queue_resume(&user
, snum
, &errcode
)) {
4086 case PRINTER_CONTROL_PURGE
:
4087 if (print_queue_purge(&user
, snum
, &errcode
)) {
4092 return WERR_UNKNOWN_LEVEL
;
4098 /********************************************************************
4099 * api_spoolss_abortprinter
4100 ********************************************************************/
4102 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
4104 POLICY_HND
*handle
= &q_u
->handle
;
4106 return control_printer(handle
, PRINTER_CONTROL_PURGE
, p
);
4109 /********************************************************************
4110 * called by spoolss_api_setprinter
4111 * when updating a printer description
4112 ********************************************************************/
4113 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
4114 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4115 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
4117 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
4118 struct current_user user
;
4122 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4124 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
)) {
4125 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n",
4126 OUR_HANDLE(handle
)));
4128 result
= WERR_BADFID
;
4132 /* NT seems to like setting the security descriptor even though
4133 nothing may have actually changed. This causes annoying
4134 dialog boxes when the user doesn't have permission to change
4135 the security descriptor. */
4137 nt_printing_getsec(p
->mem_ctx
, Printer
->dev
.handlename
, &old_secdesc_ctr
);
4139 if (DEBUGLEVEL
>= 10) {
4143 the_acl
= old_secdesc_ctr
->sec
->dacl
;
4144 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
4145 PRINTERNAME(snum
), the_acl
->num_aces
));
4147 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4150 sid_to_string(sid_str
, &the_acl
->ace
[i
].sid
);
4152 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4153 the_acl
->ace
[i
].info
.mask
));
4156 the_acl
= secdesc_ctr
->sec
->dacl
;
4159 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4160 PRINTERNAME(snum
), the_acl
->num_aces
));
4162 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4165 sid_to_string(sid_str
, &the_acl
->ace
[i
].sid
);
4167 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4168 the_acl
->ace
[i
].info
.mask
));
4171 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
4175 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
4177 if (sec_desc_equal(new_secdesc_ctr
->sec
, old_secdesc_ctr
->sec
)) {
4182 /* Work out which user is performing the operation */
4184 get_current_user(&user
, p
);
4186 /* Check the user has permissions to change the security
4187 descriptor. By experimentation with two NT machines, the user
4188 requires Full Access to the printer to change security
4191 if (!print_access_check(&user
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4192 result
= WERR_ACCESS_DENIED
;
4196 result
= nt_printing_setsec(Printer
->dev
.handlename
, new_secdesc_ctr
);
4203 /********************************************************************
4204 Do Samba sanity checks on a printer info struct.
4205 this has changed purpose: it now "canonicalises" printer
4206 info from a client rather than just checking it is correct
4207 ********************************************************************/
4209 static BOOL
check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
4211 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
4212 info
->servername
, info
->printername
, info
->sharename
, info
->portname
, info
->drivername
, info
->comment
, info
->location
));
4214 /* we force some elements to "correct" values */
4215 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname
);
4216 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
4217 global_myname
, lp_servicename(snum
));
4218 fstrcpy(info
->sharename
, lp_servicename(snum
));
4219 info
->attributes
= PRINTER_ATTRIBUTE_SHARED \
4220 | PRINTER_ATTRIBUTE_LOCAL \
4221 | PRINTER_ATTRIBUTE_RAW_ONLY \
4222 | PRINTER_ATTRIBUTE_QUEUED
;
4227 /****************************************************************************
4228 ****************************************************************************/
4229 static BOOL
add_printer_hook(NT_PRINTER_INFO_LEVEL
*printer
)
4231 char *cmd
= lp_addprinter_cmd();
4234 pstring driverlocation
;
4239 /* build driver path... only 9X architecture is needed for legacy reasons */
4240 slprintf(driverlocation
, sizeof(driverlocation
)-1, "\\\\%s\\print$\\WIN40\\0",
4242 /* change \ to \\ for the shell */
4243 all_string_sub(driverlocation
,"\\","\\\\",sizeof(pstring
));
4245 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4246 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
4247 printer
->info_2
->portname
, printer
->info_2
->drivername
,
4248 printer
->info_2
->location
, driverlocation
);
4250 DEBUG(10,("Running [%s]\n", command
));
4251 ret
= smbrun(command
, &fd
);
4252 DEBUGADD(10,("returned [%d]\n", ret
));
4261 /* Get lines and convert them back to dos-codepage */
4262 qlines
= fd_lines_load(fd
, &numlines
);
4263 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
4267 /* Set the portname to what the script says the portname should be. */
4268 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
4269 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
4271 /* Send SIGHUP to process group... is there a better way? */
4276 file_lines_free(qlines
);
4280 /* Return true if two devicemodes are equal */
4282 #define DEVMODE_CHECK_INT(field) \
4283 if (d1->field != d2->field) { \
4284 DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
4285 d1->field, d2->field)); \
4289 static BOOL
nt_devicemode_equal(NT_DEVICEMODE
*d1
, NT_DEVICEMODE
*d2
)
4291 if (!d1
&& !d2
) goto equal
; /* if both are NULL they are equal */
4294 DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
4295 return False
; /* if either is exclusively NULL are not equal */
4298 if (!strequal(d1
->devicename
, d2
->devicename
)) {
4299 DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1
->devicename
, d2
->devicename
));
4303 if (!strequal(d1
->formname
, d2
->formname
)) {
4304 DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1
->formname
, d2
->formname
));
4308 DEVMODE_CHECK_INT(specversion
);
4309 DEVMODE_CHECK_INT(driverversion
);
4310 DEVMODE_CHECK_INT(driverextra
);
4311 DEVMODE_CHECK_INT(orientation
);
4312 DEVMODE_CHECK_INT(papersize
);
4313 DEVMODE_CHECK_INT(paperlength
);
4314 DEVMODE_CHECK_INT(paperwidth
);
4315 DEVMODE_CHECK_INT(scale
);
4316 DEVMODE_CHECK_INT(copies
);
4317 DEVMODE_CHECK_INT(defaultsource
);
4318 DEVMODE_CHECK_INT(printquality
);
4319 DEVMODE_CHECK_INT(color
);
4320 DEVMODE_CHECK_INT(duplex
);
4321 DEVMODE_CHECK_INT(yresolution
);
4322 DEVMODE_CHECK_INT(ttoption
);
4323 DEVMODE_CHECK_INT(collate
);
4324 DEVMODE_CHECK_INT(logpixels
);
4326 DEVMODE_CHECK_INT(fields
);
4327 DEVMODE_CHECK_INT(bitsperpel
);
4328 DEVMODE_CHECK_INT(pelswidth
);
4329 DEVMODE_CHECK_INT(pelsheight
);
4330 DEVMODE_CHECK_INT(displayflags
);
4331 DEVMODE_CHECK_INT(displayfrequency
);
4332 DEVMODE_CHECK_INT(icmmethod
);
4333 DEVMODE_CHECK_INT(icmintent
);
4334 DEVMODE_CHECK_INT(mediatype
);
4335 DEVMODE_CHECK_INT(dithertype
);
4336 DEVMODE_CHECK_INT(reserved1
);
4337 DEVMODE_CHECK_INT(reserved2
);
4338 DEVMODE_CHECK_INT(panningwidth
);
4339 DEVMODE_CHECK_INT(panningheight
);
4341 /* compare the private data if it exists */
4342 if (!d1
->driverextra
&& !d2
->driverextra
) goto equal
;
4345 DEVMODE_CHECK_INT(driverextra
);
4347 if (memcmp(d1
->private, d2
->private, d1
->driverextra
)) {
4348 DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
4353 DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
4357 /* Return true if two NT_PRINTER_PARAM structures are equal */
4359 static BOOL
nt_printer_param_equal(NT_PRINTER_PARAM
*p1
,
4360 NT_PRINTER_PARAM
*p2
)
4362 if (!p1
&& !p2
) goto equal
;
4364 if ((!p1
&& p2
) || (p1
&& !p2
)) {
4365 DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
4369 /* Compare lists of printer parameters */
4373 NT_PRINTER_PARAM
*q
= p1
;
4375 /* Find the parameter in the second structure */
4379 if (strequal(p1
->value
, q
->value
)) {
4381 if (p1
->type
!= q
->type
) {
4382 DEBUG(10, ("nt_printer_param_equal():"
4383 "types for %s differ (%d != %d)\n",
4384 p1
->value
, p1
->type
,
4389 if (p1
->data_len
!= q
->data_len
) {
4390 DEBUG(10, ("nt_printer_param_equal():"
4391 "len for %s differs (%d != %d)\n",
4392 p1
->value
, p1
->data_len
,
4397 if (memcmp(p1
->data
, q
->data
, p1
->data_len
) == 0) {
4400 DEBUG(10, ("nt_printer_param_equal():"
4401 "data for %s differs\n", p1
->value
));
4411 DEBUG(10, ("nt_printer_param_equal(): param %s "
4412 "does not exist\n", p1
->value
));
4421 DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
4425 /********************************************************************
4426 * Called by update_printer when trying to work out whether to
4427 * actually update printer info.
4428 ********************************************************************/
4430 #define PI_CHECK_INT(field) \
4431 if (pi1->field != pi2->field) { \
4432 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
4433 pi1->field, pi2->field)); \
4437 #define PI_CHECK_STR(field) \
4438 if (!strequal(pi1->field, pi2->field)) { \
4439 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
4440 pi1->field, pi2->field)); \
4444 static BOOL
nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL
*p1
,
4445 NT_PRINTER_INFO_LEVEL
*p2
)
4447 NT_PRINTER_INFO_LEVEL_2
*pi1
, *pi2
;
4449 /* Trivial conditions */
4451 if ((!p1
&& !p2
) || (!p1
->info_2
&& !p2
->info_2
)) {
4455 if ((!p1
&& p2
) || (p1
&& !p2
) ||
4456 (!p1
->info_2
&& p2
->info_2
) ||
4457 (p1
->info_2
&& !p2
->info_2
)) {
4458 DEBUG(10, ("nt_printer_info_level_equal(): info levels "
4463 /* Compare two nt_printer_info_level structures. Don't compare
4464 status or cjobs as they seem to have something to do with the
4470 /* Don't check the attributes as we stomp on the value in
4471 check_printer_ok() anyway. */
4474 PI_CHECK_INT(attributes
);
4477 PI_CHECK_INT(priority
);
4478 PI_CHECK_INT(default_priority
);
4479 PI_CHECK_INT(starttime
);
4480 PI_CHECK_INT(untiltime
);
4481 PI_CHECK_INT(averageppm
);
4483 /* Yuck - don't check the printername or servername as the
4484 add_a_printer() code plays games with them. You can't
4485 change the printername or the sharename through this interface
4488 PI_CHECK_STR(sharename
);
4489 PI_CHECK_STR(portname
);
4490 PI_CHECK_STR(drivername
);
4491 PI_CHECK_STR(comment
);
4492 PI_CHECK_STR(location
);
4494 if (!nt_devicemode_equal(pi1
->devmode
, pi2
->devmode
)) {
4498 PI_CHECK_STR(sepfile
);
4499 PI_CHECK_STR(printprocessor
);
4500 PI_CHECK_STR(datatype
);
4501 PI_CHECK_STR(parameters
);
4503 if (!nt_printer_param_equal(pi1
->specific
, pi2
->specific
)) {
4507 if (!sec_desc_equal(pi1
->secdesc_buf
->sec
, pi2
->secdesc_buf
->sec
)) {
4511 PI_CHECK_INT(changeid
);
4512 PI_CHECK_INT(c_setprinter
);
4513 PI_CHECK_INT(setuptime
);
4516 DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
4520 /********************************************************************
4521 * called by spoolss_api_setprinter
4522 * when updating a printer description
4523 ********************************************************************/
4525 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
4526 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4527 DEVICEMODE
*devmode
)
4530 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
4531 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4534 DEBUG(8,("update_printer\n"));
4539 DEBUG(0,("Send a mail to samba@samba.org\n"));
4540 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
4541 result
= WERR_UNKNOWN_LEVEL
;
4546 result
= WERR_BADFID
;
4550 if (!get_printer_snum(p
, handle
, &snum
)) {
4551 result
= WERR_BADFID
;
4555 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))) ||
4556 (!W_ERROR_IS_OK(get_a_printer(&old_printer
, 2, lp_servicename(snum
))))) {
4557 result
= WERR_BADFID
;
4561 DEBUGADD(8,("Converting info_2 struct\n"));
4564 * convert_printer_info converts the incoming
4565 * info from the client and overwrites the info
4566 * just read from the tdb in the pointer 'printer'.
4569 convert_printer_info(info
, printer
, level
);
4571 if (info
->info_2
->devmode_ptr
!= 0) {
4572 /* we have a valid devmode
4573 convert it and link it*/
4575 DEBUGADD(8,("Converting the devicemode struct\n"));
4576 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
4577 &printer
->info_2
->devmode
)) {
4578 result
= WERR_NOMEM
;
4583 /* Do sanity check on the requested changes for Samba */
4585 if (!check_printer_ok(printer
->info_2
, snum
)) {
4586 result
= WERR_INVALID_PARAM
;
4590 /* NT likes to call this function even though nothing has actually
4591 changed. Check this so the user doesn't end up with an
4592 annoying permission denied dialog box. */
4594 if (nt_printer_info_level_equal(printer
, old_printer
)) {
4595 DEBUG(3, ("printer info has not changed\n"));
4600 /* Check calling user has permission to update printer description */
4602 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4603 DEBUG(3, ("printer property change denied by security "
4605 result
= WERR_ACCESS_DENIED
;
4609 /* Call addprinter hook */
4611 if (*lp_addprinter_cmd()) {
4612 if (!add_printer_hook(printer
)) {
4613 result
= WERR_ACCESS_DENIED
;
4618 /* Update printer info */
4619 result
= add_a_printer(*printer
, 2);
4622 free_a_printer(&printer
, 2);
4623 free_a_printer(&old_printer
, 2);
4625 srv_spoolss_sendnotify(p
, handle
);
4630 /****************************************************************************
4631 ****************************************************************************/
4633 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
4635 POLICY_HND
*handle
= &q_u
->handle
;
4636 uint32 level
= q_u
->level
;
4637 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
4638 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
4639 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
4640 uint32 command
= q_u
->command
;
4642 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4645 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4649 /* check the level */
4652 return control_printer(handle
, command
, p
);
4654 return update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
4656 return update_printer_sec(handle
, level
, info
, p
,
4659 return WERR_UNKNOWN_LEVEL
;
4663 /****************************************************************************
4664 ****************************************************************************/
4666 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
4668 POLICY_HND
*handle
= &q_u
->handle
;
4670 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4673 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4677 if (Printer
->notify
.client_connected
==True
)
4678 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
4680 Printer
->notify
.flags
=0;
4681 Printer
->notify
.options
=0;
4682 Printer
->notify
.localmachine
[0]='\0';
4683 Printer
->notify
.printerlocal
=0;
4684 if (Printer
->notify
.option
)
4685 free_spool_notify_option(&Printer
->notify
.option
);
4686 Printer
->notify
.client_connected
=False
;
4691 /****************************************************************************
4692 ****************************************************************************/
4694 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
4696 /* that's an [in out] buffer (despite appearences to the contrary) */
4697 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4700 return WERR_INVALID_PARAM
; /* this is what a NT server
4701 returns for AddJob. AddJob
4702 must fail on non-local
4706 /****************************************************************************
4707 ****************************************************************************/
4708 static void fill_job_info_1(JOB_INFO_1
*job_info
, print_queue_struct
*queue
,
4709 int position
, int snum
)
4715 t
=gmtime(&queue
->time
);
4716 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
4718 job_info
->jobid
=queue
->job
;
4719 init_unistr(&job_info
->printername
, lp_servicename(snum
));
4720 init_unistr(&job_info
->machinename
, temp_name
);
4721 init_unistr(&job_info
->username
, queue
->user
);
4722 init_unistr(&job_info
->document
, queue
->file
);
4723 init_unistr(&job_info
->datatype
, "RAW");
4724 init_unistr(&job_info
->text_status
, "");
4725 job_info
->status
=nt_printj_status(queue
->status
);
4726 job_info
->priority
=queue
->priority
;
4727 job_info
->position
=position
;
4728 job_info
->totalpages
=0;
4729 job_info
->pagesprinted
=0;
4731 make_systemtime(&job_info
->submitted
, t
);
4734 /****************************************************************************
4735 ****************************************************************************/
4736 static BOOL
fill_job_info_2(JOB_INFO_2
*job_info
, print_queue_struct
*queue
,
4737 int position
, int snum
,
4738 NT_PRINTER_INFO_LEVEL
*ntprinter
)
4744 t
=gmtime(&queue
->time
);
4745 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
4747 job_info
->jobid
=queue
->job
;
4749 slprintf(chaine
, sizeof(chaine
)-1, "\\\\%s\\%s", global_myname
, ntprinter
->info_2
->printername
);
4751 init_unistr(&job_info
->printername
, chaine
);
4753 init_unistr(&job_info
->machinename
, temp_name
);
4754 init_unistr(&job_info
->username
, queue
->user
);
4755 init_unistr(&job_info
->document
, queue
->file
);
4756 init_unistr(&job_info
->notifyname
, queue
->user
);
4757 init_unistr(&job_info
->datatype
, "RAW");
4758 init_unistr(&job_info
->printprocessor
, "winprint");
4759 init_unistr(&job_info
->parameters
, "");
4760 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
4761 init_unistr(&job_info
->text_status
, "");
4763 /* and here the security descriptor */
4765 job_info
->status
=nt_printj_status(queue
->status
);
4766 job_info
->priority
=queue
->priority
;
4767 job_info
->position
=position
;
4768 job_info
->starttime
=0;
4769 job_info
->untiltime
=0;
4770 job_info
->totalpages
=0;
4771 job_info
->size
=queue
->size
;
4772 make_systemtime(&(job_info
->submitted
), t
);
4773 job_info
->timeelapsed
=0;
4774 job_info
->pagesprinted
=0;
4776 if((job_info
->devmode
= construct_dev_mode(snum
)) == NULL
) {
4783 /****************************************************************************
4784 Enumjobs at level 1.
4785 ****************************************************************************/
4786 static WERROR
enumjobs_level1(print_queue_struct
*queue
, int snum
,
4787 NEW_BUFFER
*buffer
, uint32 offered
,
4788 uint32
*needed
, uint32
*returned
)
4793 info
=(JOB_INFO_1
*)malloc(*returned
*sizeof(JOB_INFO_1
));
4800 for (i
=0; i
<*returned
; i
++)
4801 fill_job_info_1(&info
[i
], &queue
[i
], i
, snum
);
4805 /* check the required size. */
4806 for (i
=0; i
<*returned
; i
++)
4807 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
4809 if (!alloc_buffer_size(buffer
, *needed
)) {
4811 return WERR_INSUFFICIENT_BUFFER
;
4814 /* fill the buffer with the structures */
4815 for (i
=0; i
<*returned
; i
++)
4816 smb_io_job_info_1("", buffer
, &info
[i
], 0);
4821 if (*needed
> offered
) {
4823 return WERR_INSUFFICIENT_BUFFER
;
4829 /****************************************************************************
4830 Enumjobs at level 2.
4831 ****************************************************************************/
4832 static WERROR
enumjobs_level2(print_queue_struct
*queue
, int snum
,
4833 NEW_BUFFER
*buffer
, uint32 offered
,
4834 uint32
*needed
, uint32
*returned
)
4836 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4841 info
=(JOB_INFO_2
*)malloc(*returned
*sizeof(JOB_INFO_2
));
4847 result
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
4848 if (!W_ERROR_IS_OK(result
)) {
4853 for (i
=0; i
<*returned
; i
++)
4854 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
);
4856 free_a_printer(&ntprinter
, 2);
4859 /* check the required size. */
4860 for (i
=0; i
<*returned
; i
++)
4861 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
4863 if (!alloc_buffer_size(buffer
, *needed
)) {
4865 return WERR_INSUFFICIENT_BUFFER
;
4868 /* fill the buffer with the structures */
4869 for (i
=0; i
<*returned
; i
++)
4870 smb_io_job_info_2("", buffer
, &info
[i
], 0);
4873 for (i
= 0; i
< *returned
; i
++)
4874 free_job_info_2(&info
[i
]);
4878 if (*needed
> offered
) {
4880 return WERR_INSUFFICIENT_BUFFER
;
4886 /****************************************************************************
4888 ****************************************************************************/
4890 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
4892 POLICY_HND
*handle
= &q_u
->handle
;
4893 /* uint32 firstjob = q_u->firstjob; - notused. */
4894 /* uint32 numofjobs = q_u->numofjobs; - notused. */
4895 uint32 level
= q_u
->level
;
4896 NEW_BUFFER
*buffer
= NULL
;
4897 uint32 offered
= q_u
->offered
;
4898 uint32
*needed
= &r_u
->needed
;
4899 uint32
*returned
= &r_u
->returned
;
4902 print_queue_struct
*queue
=NULL
;
4903 print_status_struct prt_status
;
4905 /* that's an [in out] buffer */
4906 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4907 buffer
= r_u
->buffer
;
4909 DEBUG(4,("_spoolss_enumjobs\n"));
4911 ZERO_STRUCT(prt_status
);
4916 if (!get_printer_snum(p
, handle
, &snum
))
4919 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
4920 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
4922 if (*returned
== 0) {
4929 return enumjobs_level1(queue
, snum
, buffer
, offered
, needed
, returned
);
4931 return enumjobs_level2(queue
, snum
, buffer
, offered
, needed
, returned
);
4935 return WERR_UNKNOWN_LEVEL
;
4939 /****************************************************************************
4940 ****************************************************************************/
4942 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
4947 /****************************************************************************
4948 ****************************************************************************/
4950 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
4952 POLICY_HND
*handle
= &q_u
->handle
;
4953 uint32 jobid
= q_u
->jobid
;
4954 /* uint32 level = q_u->level; - notused. */
4955 /* JOB_INFO *ctr = &q_u->ctr; - notused. */
4956 uint32 command
= q_u
->command
;
4958 struct current_user user
;
4959 print_status_struct prt_status
;
4961 WERROR errcode
= WERR_BADFUNC
;
4963 memset(&prt_status
, 0, sizeof(prt_status
));
4965 if (!get_printer_snum(p
, handle
, &snum
)) {
4969 if (!print_job_exists(jobid
)) {
4970 return WERR_INVALID_PRINTER_NAME
;
4973 get_current_user(&user
, p
);
4976 case JOB_CONTROL_CANCEL
:
4977 case JOB_CONTROL_DELETE
:
4978 if (print_job_delete(&user
, jobid
, &errcode
)) {
4982 case JOB_CONTROL_PAUSE
:
4983 if (print_job_pause(&user
, jobid
, &errcode
)) {
4987 case JOB_CONTROL_RESTART
:
4988 case JOB_CONTROL_RESUME
:
4989 if (print_job_resume(&user
, jobid
, &errcode
)) {
4994 return WERR_UNKNOWN_LEVEL
;
5000 /****************************************************************************
5001 Enumerates all printer drivers at level 1.
5002 ****************************************************************************/
5003 static WERROR
enumprinterdrivers_level1(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5008 fstring
*list
= NULL
;
5009 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5010 DRIVER_INFO_1
*tdi1
, *driver_info_1
=NULL
;
5014 #define MAX_VERSION 4
5016 for (version
=0; version
<MAX_VERSION
; version
++) {
5018 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5019 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5025 if((tdi1
=(DRIVER_INFO_1
*)Realloc(driver_info_1
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_1
))) == NULL
) {
5026 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
5027 safe_free(driver_info_1
);
5031 else driver_info_1
= tdi1
;
5034 for (i
=0; i
<ndrivers
; i
++) {
5036 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5037 ZERO_STRUCT(driver
);
5038 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5039 architecture
, version
);
5040 if (!W_ERROR_IS_OK(status
)) {
5044 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
5045 free_a_printer_driver(driver
, 3);
5048 *returned
+=ndrivers
;
5052 /* check the required size. */
5053 for (i
=0; i
<*returned
; i
++) {
5054 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5055 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
5058 if (!alloc_buffer_size(buffer
, *needed
)) {
5059 safe_free(driver_info_1
);
5060 return WERR_INSUFFICIENT_BUFFER
;
5063 /* fill the buffer with the driver structures */
5064 for (i
=0; i
<*returned
; i
++) {
5065 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5066 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
5069 safe_free(driver_info_1
);
5071 if (*needed
> offered
) {
5073 return WERR_INSUFFICIENT_BUFFER
;
5079 /****************************************************************************
5080 Enumerates all printer drivers at level 2.
5081 ****************************************************************************/
5082 static WERROR
enumprinterdrivers_level2(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5087 fstring
*list
= NULL
;
5088 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5089 DRIVER_INFO_2
*tdi2
, *driver_info_2
=NULL
;
5093 #define MAX_VERSION 4
5095 for (version
=0; version
<MAX_VERSION
; version
++) {
5097 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5098 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5104 if((tdi2
=(DRIVER_INFO_2
*)Realloc(driver_info_2
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_2
))) == NULL
) {
5105 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
5106 safe_free(driver_info_2
);
5110 else driver_info_2
= tdi2
;
5113 for (i
=0; i
<ndrivers
; i
++) {
5116 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5117 ZERO_STRUCT(driver
);
5118 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5119 architecture
, version
);
5120 if (!W_ERROR_IS_OK(status
)) {
5124 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
5125 free_a_printer_driver(driver
, 3);
5128 *returned
+=ndrivers
;
5132 /* check the required size. */
5133 for (i
=0; i
<*returned
; i
++) {
5134 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5135 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
5138 if (!alloc_buffer_size(buffer
, *needed
)) {
5139 safe_free(driver_info_2
);
5140 return WERR_INSUFFICIENT_BUFFER
;
5143 /* fill the buffer with the form structures */
5144 for (i
=0; i
<*returned
; i
++) {
5145 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5146 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
5149 safe_free(driver_info_2
);
5151 if (*needed
> offered
) {
5153 return WERR_INSUFFICIENT_BUFFER
;
5159 /****************************************************************************
5160 Enumerates all printer drivers at level 3.
5161 ****************************************************************************/
5162 static WERROR
enumprinterdrivers_level3(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5167 fstring
*list
= NULL
;
5168 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5169 DRIVER_INFO_3
*tdi3
, *driver_info_3
=NULL
;
5173 #define MAX_VERSION 4
5175 for (version
=0; version
<MAX_VERSION
; version
++) {
5177 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5178 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5184 if((tdi3
=(DRIVER_INFO_3
*)Realloc(driver_info_3
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_3
))) == NULL
) {
5185 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
5186 safe_free(driver_info_3
);
5190 else driver_info_3
= tdi3
;
5193 for (i
=0; i
<ndrivers
; i
++) {
5196 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5197 ZERO_STRUCT(driver
);
5198 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5199 architecture
, version
);
5200 if (!W_ERROR_IS_OK(status
)) {
5204 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
5205 free_a_printer_driver(driver
, 3);
5208 *returned
+=ndrivers
;
5212 /* check the required size. */
5213 for (i
=0; i
<*returned
; i
++) {
5214 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5215 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
5218 if (!alloc_buffer_size(buffer
, *needed
)) {
5219 safe_free(driver_info_3
);
5220 return WERR_INSUFFICIENT_BUFFER
;
5223 /* fill the buffer with the driver structures */
5224 for (i
=0; i
<*returned
; i
++) {
5225 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5226 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
5229 for (i
=0; i
<*returned
; i
++)
5230 safe_free(driver_info_3
[i
].dependentfiles
);
5232 safe_free(driver_info_3
);
5234 if (*needed
> offered
) {
5236 return WERR_INSUFFICIENT_BUFFER
;
5242 /****************************************************************************
5243 Enumerates all printer drivers.
5244 ****************************************************************************/
5246 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
5248 /* UNISTR2 *name = &q_u->name; - notused. */
5249 UNISTR2
*environment
= &q_u
->environment
;
5250 uint32 level
= q_u
->level
;
5251 NEW_BUFFER
*buffer
= NULL
;
5252 uint32 offered
= q_u
->offered
;
5253 uint32
*needed
= &r_u
->needed
;
5254 uint32
*returned
= &r_u
->returned
;
5256 fstring
*list
= NULL
;
5258 fstring architecture
;
5260 /* that's an [in out] buffer */
5261 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5262 buffer
= r_u
->buffer
;
5264 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
5265 fstrcpy(servername
, global_myname
);
5269 unistr2_to_ascii(architecture
, environment
, sizeof(architecture
)-1);
5273 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
5275 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
5277 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
5281 return WERR_UNKNOWN_LEVEL
;
5285 /****************************************************************************
5286 ****************************************************************************/
5288 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
5290 form
->flag
=list
->flag
;
5291 init_unistr(&form
->name
, list
->name
);
5292 form
->width
=list
->width
;
5293 form
->length
=list
->length
;
5294 form
->left
=list
->left
;
5295 form
->top
=list
->top
;
5296 form
->right
=list
->right
;
5297 form
->bottom
=list
->bottom
;
5300 /****************************************************************************
5301 ****************************************************************************/
5303 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
5305 /* POLICY_HND *handle = &q_u->handle; - notused. */
5306 uint32 level
= q_u
->level
;
5307 NEW_BUFFER
*buffer
= NULL
;
5308 uint32 offered
= q_u
->offered
;
5309 uint32
*needed
= &r_u
->needed
;
5310 uint32
*numofforms
= &r_u
->numofforms
;
5311 uint32 numbuiltinforms
;
5313 nt_forms_struct
*list
=NULL
;
5314 nt_forms_struct
*builtinlist
=NULL
;
5319 /* that's an [in out] buffer */
5320 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5321 buffer
= r_u
->buffer
;
5323 DEBUG(4,("_spoolss_enumforms\n"));
5324 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5325 DEBUGADD(5,("Info level [%d]\n", level
));
5327 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
5328 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
5329 *numofforms
= get_ntforms(&list
);
5330 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
5331 *numofforms
+= numbuiltinforms
;
5333 if (*numofforms
== 0) return WERR_NO_MORE_ITEMS
;
5337 if ((forms_1
=(FORM_1
*)malloc(*numofforms
* sizeof(FORM_1
))) == NULL
) {
5342 /* construct the list of form structures */
5343 for (i
=0; i
<numbuiltinforms
; i
++) {
5344 DEBUGADD(6,("Filling form number [%d]\n",i
));
5345 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
5348 safe_free(builtinlist
);
5350 for (; i
<*numofforms
; i
++) {
5351 DEBUGADD(6,("Filling form number [%d]\n",i
));
5352 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
5357 /* check the required size. */
5358 for (i
=0; i
<numbuiltinforms
; i
++) {
5359 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5360 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5362 for (; i
<*numofforms
; i
++) {
5363 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5364 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5367 *needed
=buffer_size
;
5369 if (!alloc_buffer_size(buffer
, buffer_size
)){
5371 return WERR_INSUFFICIENT_BUFFER
;
5374 /* fill the buffer with the form structures */
5375 for (i
=0; i
<numbuiltinforms
; i
++) {
5376 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5377 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5379 for (; i
<*numofforms
; i
++) {
5380 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5381 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5386 if (*needed
> offered
) {
5388 return WERR_INSUFFICIENT_BUFFER
;
5395 safe_free(builtinlist
);
5396 return WERR_UNKNOWN_LEVEL
;
5401 /****************************************************************************
5402 ****************************************************************************/
5404 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
5406 /* POLICY_HND *handle = &q_u->handle; - notused. */
5407 uint32 level
= q_u
->level
;
5408 UNISTR2
*uni_formname
= &q_u
->formname
;
5409 NEW_BUFFER
*buffer
= NULL
;
5410 uint32 offered
= q_u
->offered
;
5411 uint32
*needed
= &r_u
->needed
;
5413 nt_forms_struct
*list
=NULL
;
5414 nt_forms_struct builtin_form
;
5419 int numofforms
=0, i
=0;
5421 /* that's an [in out] buffer */
5422 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5423 buffer
= r_u
->buffer
;
5425 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
)-1);
5427 DEBUG(4,("_spoolss_getform\n"));
5428 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5429 DEBUGADD(5,("Info level [%d]\n", level
));
5431 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
5432 if (!foundBuiltin
) {
5433 numofforms
= get_ntforms(&list
);
5434 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
5436 if (numofforms
== 0)
5443 fill_form_1(&form_1
, &builtin_form
);
5446 /* Check if the requested name is in the list of form structures */
5447 for (i
=0; i
<numofforms
; i
++) {
5449 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
5451 if (strequal(form_name
, list
[i
].name
)) {
5452 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
5453 fill_form_1(&form_1
, &list
[i
]);
5459 if (i
== numofforms
) {
5463 /* check the required size. */
5465 *needed
=spoolss_size_form_1(&form_1
);
5467 if (!alloc_buffer_size(buffer
, buffer_size
)){
5468 return WERR_INSUFFICIENT_BUFFER
;
5471 if (*needed
> offered
) {
5472 return WERR_INSUFFICIENT_BUFFER
;
5475 /* fill the buffer with the form structures */
5476 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
5477 smb_io_form_1("", buffer
, &form_1
, 0);
5483 return WERR_UNKNOWN_LEVEL
;
5487 /****************************************************************************
5488 ****************************************************************************/
5489 static void fill_port_1(PORT_INFO_1
*port
, char *name
)
5491 init_unistr(&port
->port_name
, name
);
5494 /****************************************************************************
5495 ****************************************************************************/
5496 static void fill_port_2(PORT_INFO_2
*port
, char *name
)
5498 init_unistr(&port
->port_name
, name
);
5499 init_unistr(&port
->monitor_name
, "Local Monitor");
5500 init_unistr(&port
->description
, "Local Port");
5501 #define PORT_TYPE_WRITE 1
5502 port
->port_type
=PORT_TYPE_WRITE
;
5506 /****************************************************************************
5508 ****************************************************************************/
5509 static WERROR
enumports_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5511 PORT_INFO_1
*ports
=NULL
;
5514 if (*lp_enumports_cmd()) {
5515 char *cmd
= lp_enumports_cmd();
5522 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 1);
5524 DEBUG(10,("Running [%s]\n", command
));
5525 ret
= smbrun(command
, &fd
);
5526 DEBUG(10,("Returned [%d]\n", ret
));
5530 /* Is this the best error to return here? */
5531 return WERR_ACCESS_DENIED
;
5535 qlines
= fd_lines_load(fd
, &numlines
);
5536 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5540 if((ports
=(PORT_INFO_1
*)malloc( numlines
* sizeof(PORT_INFO_1
) )) == NULL
) {
5541 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
5542 werror_str(WERR_NOMEM
)));
5543 file_lines_free(qlines
);
5547 for (i
=0; i
<numlines
; i
++) {
5548 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5549 fill_port_1(&ports
[i
], qlines
[i
]);
5552 file_lines_free(qlines
);
5555 *returned
= numlines
;
5558 *returned
= 1; /* Sole Samba port returned. */
5560 if((ports
=(PORT_INFO_1
*)malloc( sizeof(PORT_INFO_1
) )) == NULL
)
5563 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5565 fill_port_1(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5568 /* check the required size. */
5569 for (i
=0; i
<*returned
; i
++) {
5570 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5571 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
5574 if (!alloc_buffer_size(buffer
, *needed
)) {
5576 return WERR_INSUFFICIENT_BUFFER
;
5579 /* fill the buffer with the ports structures */
5580 for (i
=0; i
<*returned
; i
++) {
5581 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5582 smb_io_port_1("", buffer
, &ports
[i
], 0);
5587 if (*needed
> offered
) {
5589 return WERR_INSUFFICIENT_BUFFER
;
5595 /****************************************************************************
5597 ****************************************************************************/
5599 static WERROR
enumports_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5601 PORT_INFO_2
*ports
=NULL
;
5604 if (*lp_enumports_cmd()) {
5605 char *cmd
= lp_enumports_cmd();
5614 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME
)))
5615 path
= lp_pathname(lp_servicenumber(PRINTERS_NAME
));
5617 path
= lp_lockdir();
5619 slprintf(tmp_file
, sizeof(tmp_file
)-1, "%s/smbcmd.%u.", path
, (unsigned int)sys_getpid());
5620 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 2);
5623 DEBUG(10,("Running [%s > %s]\n", command
,tmp_file
));
5624 ret
= smbrun(command
, &fd
);
5625 DEBUGADD(10,("returned [%d]\n", ret
));
5629 /* Is this the best error to return here? */
5630 return WERR_ACCESS_DENIED
;
5634 qlines
= fd_lines_load(fd
, &numlines
);
5635 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5639 if((ports
=(PORT_INFO_2
*)malloc( numlines
* sizeof(PORT_INFO_2
) )) == NULL
) {
5640 file_lines_free(qlines
);
5644 for (i
=0; i
<numlines
; i
++) {
5645 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5646 fill_port_2(&(ports
[i
]), qlines
[i
]);
5649 file_lines_free(qlines
);
5652 *returned
= numlines
;
5658 if((ports
=(PORT_INFO_2
*)malloc( sizeof(PORT_INFO_2
) )) == NULL
)
5661 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5663 fill_port_2(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5666 /* check the required size. */
5667 for (i
=0; i
<*returned
; i
++) {
5668 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5669 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
5672 if (!alloc_buffer_size(buffer
, *needed
)) {
5674 return WERR_INSUFFICIENT_BUFFER
;
5677 /* fill the buffer with the ports structures */
5678 for (i
=0; i
<*returned
; i
++) {
5679 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5680 smb_io_port_2("", buffer
, &ports
[i
], 0);
5685 if (*needed
> offered
) {
5687 return WERR_INSUFFICIENT_BUFFER
;
5693 /****************************************************************************
5695 ****************************************************************************/
5697 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
5699 /* UNISTR2 *name = &q_u->name; - notused. */
5700 uint32 level
= q_u
->level
;
5701 NEW_BUFFER
*buffer
= NULL
;
5702 uint32 offered
= q_u
->offered
;
5703 uint32
*needed
= &r_u
->needed
;
5704 uint32
*returned
= &r_u
->returned
;
5706 /* that's an [in out] buffer */
5707 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5708 buffer
= r_u
->buffer
;
5710 DEBUG(4,("_spoolss_enumports\n"));
5717 return enumports_level_1(buffer
, offered
, needed
, returned
);
5719 return enumports_level_2(buffer
, offered
, needed
, returned
);
5721 return WERR_UNKNOWN_LEVEL
;
5725 /****************************************************************************
5726 ****************************************************************************/
5727 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
5728 const SPOOL_PRINTER_INFO_LEVEL
*info
,
5729 uint32 unk0
, uint32 unk1
, uint32 unk2
, uint32 unk3
,
5730 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
5733 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5738 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
5739 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
5743 ZERO_STRUCTP(printer
);
5745 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
5746 convert_printer_info(info
, printer
, 2);
5748 if (*lp_addprinter_cmd() )
5749 if ( !add_printer_hook(printer
) ) {
5750 free_a_printer(&printer
,2);
5751 return WERR_ACCESS_DENIED
;
5754 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname
,
5755 printer
->info_2
->sharename
);
5757 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
5758 free_a_printer(&printer
,2);
5759 return WERR_ACCESS_DENIED
;
5762 /* you must be a printer admin to add a new printer */
5763 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
5764 free_a_printer(&printer
,2);
5765 return WERR_ACCESS_DENIED
;
5769 * Do sanity check on the requested changes for Samba.
5772 if (!check_printer_ok(printer
->info_2
, snum
)) {
5773 free_a_printer(&printer
,2);
5774 return WERR_INVALID_PARAM
;
5778 * When a printer is created, the drivername bound to the printer is used
5779 * to lookup previously saved driver initialization info, which is then
5780 * bound to the new printer, simulating what happens in the Windows arch.
5782 set_driver_init(printer
, 2);
5784 /* write the ASCII on disk */
5785 err
= add_a_printer(*printer
, 2);
5786 if (!W_ERROR_IS_OK(err
)) {
5787 free_a_printer(&printer
,2);
5791 if (!open_printer_hnd(p
, handle
, name
)) {
5792 /* Handle open failed - remove addition. */
5793 del_a_printer(printer
->info_2
->sharename
);
5794 free_a_printer(&printer
,2);
5795 return WERR_ACCESS_DENIED
;
5798 free_a_printer(&printer
,2);
5800 srv_spoolss_sendnotify(p
, handle
);
5805 /****************************************************************************
5806 ****************************************************************************/
5808 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
5810 UNISTR2
*uni_srv_name
= &q_u
->server_name
;
5811 uint32 level
= q_u
->level
;
5812 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
5813 uint32 unk0
= q_u
->unk0
;
5814 uint32 unk1
= q_u
->unk1
;
5815 uint32 unk2
= q_u
->unk2
;
5816 uint32 unk3
= q_u
->unk3
;
5817 uint32 user_switch
= q_u
->user_switch
;
5818 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
5819 POLICY_HND
*handle
= &r_u
->handle
;
5823 /* we don't handle yet */
5824 /* but I know what to do ... */
5825 return WERR_UNKNOWN_LEVEL
;
5827 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
5828 unk0
, unk1
, unk2
, unk3
,
5829 user_switch
, user
, handle
);
5831 return WERR_UNKNOWN_LEVEL
;
5835 /****************************************************************************
5836 ****************************************************************************/
5838 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
5840 /* UNISTR2 *server_name = &q_u->server_name; - notused. */
5841 uint32 level
= q_u
->level
;
5842 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
5843 WERROR err
= WERR_OK
;
5844 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5845 struct current_user user
;
5847 ZERO_STRUCT(driver
);
5849 get_current_user(&user
, p
);
5851 if (!convert_printer_driver_info(info
, &driver
, level
)) {
5856 DEBUG(5,("Cleaning driver's information\n"));
5857 err
= clean_up_driver_struct(driver
, level
, &user
);
5858 if (!W_ERROR_IS_OK(err
))
5861 DEBUG(5,("Moving driver to final destination\n"));
5862 if(!move_driver_to_download_area(driver
, level
, &user
, &err
)) {
5863 if (W_ERROR_IS_OK(err
))
5864 err
= WERR_ACCESS_DENIED
;
5868 if (add_a_printer_driver(driver
, level
)!=0) {
5869 err
= WERR_ACCESS_DENIED
;
5874 free_a_printer_driver(driver
, level
);
5878 /****************************************************************************
5879 ****************************************************************************/
5880 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
5882 init_unistr(&info
->name
, name
);
5885 /****************************************************************************
5886 ****************************************************************************/
5887 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5891 pstring short_archi
;
5892 DRIVER_DIRECTORY_1
*info
=NULL
;
5894 unistr2_to_ascii(long_archi
, uni_environment
, sizeof(long_archi
)-1);
5896 if (get_short_archi(short_archi
, long_archi
)==FALSE
)
5897 return WERR_INVALID_ENVIRONMENT
;
5899 if((info
=(DRIVER_DIRECTORY_1
*)malloc(sizeof(DRIVER_DIRECTORY_1
))) == NULL
)
5902 slprintf(path
, sizeof(path
)-1, "\\\\%s\\print$\\%s", global_myname
, short_archi
);
5904 DEBUG(4,("printer driver directory: [%s]\n", path
));
5906 fill_driverdir_1(info
, path
);
5908 *needed
+= spoolss_size_driverdir_info_1(info
);
5910 if (!alloc_buffer_size(buffer
, *needed
)) {
5912 return WERR_INSUFFICIENT_BUFFER
;
5915 smb_io_driverdir_1("", buffer
, info
, 0);
5919 if (*needed
> offered
)
5920 return WERR_INSUFFICIENT_BUFFER
;
5925 /****************************************************************************
5926 ****************************************************************************/
5928 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
5930 UNISTR2
*name
= &q_u
->name
;
5931 UNISTR2
*uni_environment
= &q_u
->environment
;
5932 uint32 level
= q_u
->level
;
5933 NEW_BUFFER
*buffer
= NULL
;
5934 uint32 offered
= q_u
->offered
;
5935 uint32
*needed
= &r_u
->needed
;
5937 /* that's an [in out] buffer */
5938 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5939 buffer
= r_u
->buffer
;
5941 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
5947 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
5949 return WERR_UNKNOWN_LEVEL
;
5953 /****************************************************************************
5954 ****************************************************************************/
5956 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
5958 POLICY_HND
*handle
= &q_u
->handle
;
5959 uint32 idx
= q_u
->index
;
5960 uint32 in_value_len
= q_u
->valuesize
;
5961 uint32 in_data_len
= q_u
->datasize
;
5962 uint32
*out_max_value_len
= &r_u
->valuesize
;
5963 uint16
**out_value
= &r_u
->value
;
5964 uint32
*out_value_len
= &r_u
->realvaluesize
;
5965 uint32
*out_type
= &r_u
->type
;
5966 uint32
*out_max_data_len
= &r_u
->datasize
;
5967 uint8
**data_out
= &r_u
->data
;
5968 uint32
*out_data_len
= &r_u
->realdatasize
;
5970 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5975 uint32 biggest_valuesize
;
5976 uint32 biggest_datasize
;
5978 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5984 ZERO_STRUCT(printer
);
5986 *out_max_value_len
=0;
5992 *out_max_data_len
=0;
5996 DEBUG(5,("spoolss_enumprinterdata\n"));
5999 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6003 if (!get_printer_snum(p
,handle
, &snum
))
6006 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6007 if (!W_ERROR_IS_OK(result
))
6011 * The NT machine wants to know the biggest size of value and data
6013 * cf: MSDN EnumPrinterData remark section
6015 if ( (in_value_len
==0) && (in_data_len
==0) ) {
6016 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
6020 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
6021 * if this parameter size doesn't exist.
6022 * Ok - my opinion here is that the client is not asking for the greatest
6023 * possible size of all the parameters, but is asking specifically for the size needed
6024 * for this specific parameter. In that case we can remove the loop below and
6025 * simplify this lookup code considerably. JF - comments welcome. JRA.
6028 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
6030 free_a_printer(&printer
, 2);
6031 return WERR_NO_MORE_ITEMS
;
6039 biggest_valuesize
=0;
6042 while (get_specific_param_by_index(*printer
, 2, param_index
, value
, &data
, &type
, &data_len
)) {
6043 if (strlen(value
) > biggest_valuesize
) biggest_valuesize
=strlen(value
);
6044 if (data_len
> biggest_datasize
) biggest_datasize
=data_len
;
6046 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
, biggest_datasize
));
6054 * I think this is correct, it doesn't break APW and
6055 * allows Gerald's Win32 test programs to work correctly,
6056 * but may need altering.... JRA.
6059 if (param_index
== 0) {
6060 /* No parameters found. */
6061 free_a_printer(&printer
, 2);
6062 return WERR_NO_MORE_ITEMS
;
6065 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
6066 *out_value_len
=2*(1+biggest_valuesize
);
6067 *out_data_len
=biggest_datasize
;
6069 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
6071 free_a_printer(&printer
, 2);
6076 * the value len is wrong in NT sp3
6077 * that's the number of bytes not the number of unicode chars
6080 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
6082 free_a_printer(&printer
, 2);
6083 return WERR_NO_MORE_ITEMS
;
6086 free_a_printer(&printer
, 2);
6090 * - counted in bytes in the request
6091 * - counted in UNICODE chars in the max reply
6092 * - counted in bytes in the real size
6094 * take a pause *before* coding not *during* coding
6097 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
6098 if((*out_value
=(uint16
*)talloc_zero(p
->mem_ctx
,in_value_len
*sizeof(uint8
))) == NULL
) {
6103 *out_value_len
= rpcstr_push((char *)*out_value
,value
, in_value_len
, 0);
6107 /* the data is counted in bytes */
6108 *out_max_data_len
=in_data_len
;
6109 if((*data_out
=(uint8
*)talloc_zero(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) {
6114 memcpy(*data_out
, data
, (size_t)data_len
);
6115 *out_data_len
=data_len
;
6122 /****************************************************************************
6123 ****************************************************************************/
6125 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
6127 POLICY_HND
*handle
= &q_u
->handle
;
6128 UNISTR2
*value
= &q_u
->value
;
6129 uint32 type
= q_u
->type
;
6130 /* uint32 max_len = q_u->max_len; - notused. */
6131 uint8
*data
= q_u
->data
;
6132 uint32 real_len
= q_u
->real_len
;
6133 /* uint32 numeric_data = q_u->numeric_data; - notused. */
6135 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6136 NT_PRINTER_PARAM
*param
= NULL
, old_param
;
6138 WERROR status
= WERR_OK
;
6139 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6141 DEBUG(5,("spoolss_setprinterdata\n"));
6144 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6148 if (!get_printer_snum(p
,handle
, &snum
))
6151 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6152 if (!W_ERROR_IS_OK(status
))
6155 convert_specific_param(¶m
, value
, type
, data
, real_len
);
6157 ZERO_STRUCT(old_param
);
6160 * Access check : NT returns "access denied" if you make a
6161 * SetPrinterData call without the necessary privildge.
6162 * we were originally returning OK if nothing changed
6163 * which made Win2k issue **a lot** of SetPrinterData
6164 * when connecting to a printer --jerry
6167 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6168 DEBUG(3, ("security descriptor change denied by existing "
6169 "security descriptor\n"));
6170 status
= ERROR_ACCESS_DENIED
;
6175 /* Check if we are making any changes or not. Return true if
6176 nothing is actually changing. This is not needed anymore but
6177 has been left in as an optimization to keep from from
6178 writing to disk as often --jerry */
6180 if (get_specific_param(*printer
, 2, param
->value
, &old_param
.data
,
6181 &old_param
.type
, (uint32
*)&old_param
.data_len
)) {
6183 if (param
->type
== old_param
.type
&&
6184 param
->data_len
== old_param
.data_len
&&
6185 memcmp(param
->data
, old_param
.data
,
6186 old_param
.data_len
) == 0) {
6188 DEBUG(3, ("setprinterdata hasn't changed\n"));
6194 unlink_specific_param_if_exist(printer
->info_2
, param
);
6197 * When client side code sets a magic printer data key, detect it and save
6198 * the current printer data and the magic key's data (its the DEVMODE) for
6199 * future printer/driver initializations.
6201 if (param
->type
==3 && !strcmp( param
->value
, PHANTOM_DEVMODE_KEY
)) {
6203 * Set devmode and printer initialization info
6205 status
= save_driver_init(printer
, 2, param
);
6208 add_a_specific_param(printer
->info_2
, ¶m
);
6209 status
= mod_a_printer(*printer
, 2);
6213 free_a_printer(&printer
, 2);
6215 free_nt_printer_param(¶m
);
6216 safe_free(old_param
.data
);
6221 /****************************************************************************
6222 ****************************************************************************/
6224 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
6226 POLICY_HND
*handle
= &q_u
->handle
;
6227 UNISTR2
*value
= &q_u
->valuename
;
6229 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6230 NT_PRINTER_PARAM param
;
6232 WERROR status
= WERR_OK
;
6233 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6235 DEBUG(5,("spoolss_deleteprinterdata\n"));
6238 DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6242 if (!get_printer_snum(p
, handle
, &snum
))
6245 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6246 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
6247 "change denied by existing security descriptor\n"));
6248 return WERR_ACCESS_DENIED
;
6251 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6252 if (!W_ERROR_IS_OK(status
))
6255 ZERO_STRUCTP(¶m
);
6256 unistr2_to_ascii(param
.value
, value
, sizeof(param
.value
)-1);
6258 if(!unlink_specific_param_if_exist(printer
->info_2
, ¶m
))
6259 status
= WERR_INVALID_PARAM
;
6261 status
= mod_a_printer(*printer
, 2);
6263 free_a_printer(&printer
, 2);
6267 /****************************************************************************
6268 ****************************************************************************/
6270 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
6272 POLICY_HND
*handle
= &q_u
->handle
;
6273 /* uint32 level = q_u->level; - notused. */
6274 FORM
*form
= &q_u
->form
;
6275 nt_forms_struct tmpForm
;
6278 nt_forms_struct
*list
=NULL
;
6279 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6281 DEBUG(5,("spoolss_addform\n"));
6284 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6288 /* can't add if builtin */
6289 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6290 return WERR_INVALID_PARAM
;
6293 count
=get_ntforms(&list
);
6294 if(!add_a_form(&list
, form
, &count
))
6296 write_ntforms(&list
, count
);
6303 /****************************************************************************
6304 ****************************************************************************/
6306 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
6308 POLICY_HND
*handle
= &q_u
->handle
;
6309 UNISTR2
*form_name
= &q_u
->name
;
6310 nt_forms_struct tmpForm
;
6312 WERROR ret
= WERR_OK
;
6313 nt_forms_struct
*list
=NULL
;
6314 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6316 DEBUG(5,("spoolss_deleteform\n"));
6319 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6323 /* can't delete if builtin */
6324 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
6325 return WERR_INVALID_PARAM
;
6328 count
= get_ntforms(&list
);
6329 if (!delete_a_form(&list
, form_name
, &count
, &ret
))
6330 return WERR_INVALID_PARAM
;
6337 /****************************************************************************
6338 ****************************************************************************/
6340 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
6342 POLICY_HND
*handle
= &q_u
->handle
;
6343 /* UNISTR2 *uni_name = &q_u->name; - notused. */
6344 /* uint32 level = q_u->level; - notused. */
6345 FORM
*form
= &q_u
->form
;
6346 nt_forms_struct tmpForm
;
6349 nt_forms_struct
*list
=NULL
;
6350 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6352 DEBUG(5,("spoolss_setform\n"));
6355 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6358 /* can't set if builtin */
6359 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6360 return WERR_INVALID_PARAM
;
6363 count
=get_ntforms(&list
);
6364 update_a_form(&list
, form
, count
);
6365 write_ntforms(&list
, count
);
6372 /****************************************************************************
6373 enumprintprocessors level 1.
6374 ****************************************************************************/
6375 static WERROR
enumprintprocessors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6377 PRINTPROCESSOR_1
*info_1
=NULL
;
6379 if((info_1
= (PRINTPROCESSOR_1
*)malloc(sizeof(PRINTPROCESSOR_1
))) == NULL
)
6384 init_unistr(&info_1
->name
, "winprint");
6386 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
6388 if (!alloc_buffer_size(buffer
, *needed
))
6389 return WERR_INSUFFICIENT_BUFFER
;
6391 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
6395 if (*needed
> offered
) {
6397 return WERR_INSUFFICIENT_BUFFER
;
6403 /****************************************************************************
6404 ****************************************************************************/
6406 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
6408 /* UNISTR2 *name = &q_u->name; - notused. */
6409 /* UNISTR2 *environment = &q_u->environment; - notused. */
6410 uint32 level
= q_u
->level
;
6411 NEW_BUFFER
*buffer
= NULL
;
6412 uint32 offered
= q_u
->offered
;
6413 uint32
*needed
= &r_u
->needed
;
6414 uint32
*returned
= &r_u
->returned
;
6416 /* that's an [in out] buffer */
6417 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6418 buffer
= r_u
->buffer
;
6420 DEBUG(5,("spoolss_enumprintprocessors\n"));
6423 * Enumerate the print processors ...
6425 * Just reply with "winprint", to keep NT happy
6426 * and I can use my nice printer checker.
6434 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
6436 return WERR_UNKNOWN_LEVEL
;
6440 /****************************************************************************
6441 enumprintprocdatatypes level 1.
6442 ****************************************************************************/
6443 static WERROR
enumprintprocdatatypes_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6445 PRINTPROCDATATYPE_1
*info_1
=NULL
;
6447 if((info_1
= (PRINTPROCDATATYPE_1
*)malloc(sizeof(PRINTPROCDATATYPE_1
))) == NULL
)
6452 init_unistr(&info_1
->name
, "RAW");
6454 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
6456 if (!alloc_buffer_size(buffer
, *needed
))
6457 return WERR_INSUFFICIENT_BUFFER
;
6459 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
6463 if (*needed
> offered
) {
6465 return WERR_INSUFFICIENT_BUFFER
;
6471 /****************************************************************************
6472 ****************************************************************************/
6474 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
6476 /* UNISTR2 *name = &q_u->name; - notused. */
6477 /* UNISTR2 *processor = &q_u->processor; - notused. */
6478 uint32 level
= q_u
->level
;
6479 NEW_BUFFER
*buffer
= NULL
;
6480 uint32 offered
= q_u
->offered
;
6481 uint32
*needed
= &r_u
->needed
;
6482 uint32
*returned
= &r_u
->returned
;
6484 /* that's an [in out] buffer */
6485 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6486 buffer
= r_u
->buffer
;
6488 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
6495 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
6497 return WERR_UNKNOWN_LEVEL
;
6501 /****************************************************************************
6502 enumprintmonitors level 1.
6503 ****************************************************************************/
6505 static WERROR
enumprintmonitors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6507 PRINTMONITOR_1
*info_1
=NULL
;
6509 if((info_1
= (PRINTMONITOR_1
*)malloc(sizeof(PRINTMONITOR_1
))) == NULL
)
6514 init_unistr(&info_1
->name
, "Local Port");
6516 *needed
+= spoolss_size_printmonitor_info_1(info_1
);
6518 if (!alloc_buffer_size(buffer
, *needed
))
6519 return WERR_INSUFFICIENT_BUFFER
;
6521 smb_io_printmonitor_info_1("", buffer
, info_1
, 0);
6525 if (*needed
> offered
) {
6527 return WERR_INSUFFICIENT_BUFFER
;
6533 /****************************************************************************
6534 enumprintmonitors level 2.
6535 ****************************************************************************/
6536 static WERROR
enumprintmonitors_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6538 PRINTMONITOR_2
*info_2
=NULL
;
6540 if((info_2
= (PRINTMONITOR_2
*)malloc(sizeof(PRINTMONITOR_2
))) == NULL
)
6545 init_unistr(&info_2
->name
, "Local Port");
6546 init_unistr(&info_2
->environment
, "Windows NT X86");
6547 init_unistr(&info_2
->dll_name
, "localmon.dll");
6549 *needed
+= spoolss_size_printmonitor_info_2(info_2
);
6551 if (!alloc_buffer_size(buffer
, *needed
))
6552 return WERR_INSUFFICIENT_BUFFER
;
6554 smb_io_printmonitor_info_2("", buffer
, info_2
, 0);
6558 if (*needed
> offered
) {
6560 return WERR_INSUFFICIENT_BUFFER
;
6566 /****************************************************************************
6567 ****************************************************************************/
6569 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
6571 /* UNISTR2 *name = &q_u->name; - notused. */
6572 uint32 level
= q_u
->level
;
6573 NEW_BUFFER
*buffer
= NULL
;
6574 uint32 offered
= q_u
->offered
;
6575 uint32
*needed
= &r_u
->needed
;
6576 uint32
*returned
= &r_u
->returned
;
6578 /* that's an [in out] buffer */
6579 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6580 buffer
= r_u
->buffer
;
6582 DEBUG(5,("spoolss_enumprintmonitors\n"));
6585 * Enumerate the print monitors ...
6587 * Just reply with "Local Port", to keep NT happy
6588 * and I can use my nice printer checker.
6596 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
6598 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
6600 return WERR_UNKNOWN_LEVEL
;
6604 /****************************************************************************
6605 ****************************************************************************/
6606 static WERROR
getjob_level_1(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6610 JOB_INFO_1
*info_1
=NULL
;
6612 info_1
=(JOB_INFO_1
*)malloc(sizeof(JOB_INFO_1
));
6614 if (info_1
== NULL
) {
6619 for (i
=0; i
<count
&& found
==False
; i
++) {
6620 if (queue
[i
].job
==(int)jobid
)
6627 /* I shoud reply something else ... I can't find the good one */
6631 fill_job_info_1(info_1
, &(queue
[i
-1]), i
, snum
);
6635 *needed
+= spoolss_size_job_info_1(info_1
);
6637 if (!alloc_buffer_size(buffer
, *needed
)) {
6639 return WERR_INSUFFICIENT_BUFFER
;
6642 smb_io_job_info_1("", buffer
, info_1
, 0);
6646 if (*needed
> offered
)
6647 return WERR_INSUFFICIENT_BUFFER
;
6653 /****************************************************************************
6654 ****************************************************************************/
6655 static WERROR
getjob_level_2(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6660 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6663 info_2
=(JOB_INFO_2
*)malloc(sizeof(JOB_INFO_2
));
6665 ZERO_STRUCTP(info_2
);
6667 if (info_2
== NULL
) {
6672 for (i
=0; i
<count
&& found
==False
; i
++) {
6673 if (queue
[i
].job
==(int)jobid
)
6680 /* I shoud reply something else ... I can't find the good one */
6684 ret
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
6685 if (!W_ERROR_IS_OK(ret
)) {
6690 fill_job_info_2(info_2
, &(queue
[i
-1]), i
, snum
, ntprinter
);
6692 free_a_printer(&ntprinter
, 2);
6695 *needed
+= spoolss_size_job_info_2(info_2
);
6697 if (!alloc_buffer_size(buffer
, *needed
)) {
6699 return WERR_INSUFFICIENT_BUFFER
;
6702 smb_io_job_info_2("", buffer
, info_2
, 0);
6704 free_job_info_2(info_2
);
6707 if (*needed
> offered
)
6708 return WERR_INSUFFICIENT_BUFFER
;
6713 /****************************************************************************
6714 ****************************************************************************/
6716 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
6718 POLICY_HND
*handle
= &q_u
->handle
;
6719 uint32 jobid
= q_u
->jobid
;
6720 uint32 level
= q_u
->level
;
6721 NEW_BUFFER
*buffer
= NULL
;
6722 uint32 offered
= q_u
->offered
;
6723 uint32
*needed
= &r_u
->needed
;
6727 print_queue_struct
*queue
=NULL
;
6728 print_status_struct prt_status
;
6730 /* that's an [in out] buffer */
6731 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6732 buffer
= r_u
->buffer
;
6734 DEBUG(5,("spoolss_getjob\n"));
6736 memset(&prt_status
, 0, sizeof(prt_status
));
6740 if (!get_printer_snum(p
, handle
, &snum
))
6743 count
= print_queue_status(snum
, &queue
, &prt_status
);
6745 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
6746 count
, prt_status
.status
, prt_status
.message
));
6750 return getjob_level_1(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
6752 return getjob_level_2(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
6755 return WERR_UNKNOWN_LEVEL
;