2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 * Copyright (C) Jean François Micouleau 1998-2000.
8 * Copyright (C) Jeremy Allison 2001.
9 * Copyright (C) Gerald Carter 2000-2001.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27 up, all the errors returned are DOS errors, not NT status codes. */
31 #ifndef MAX_OPEN_PRINTER_EXS
32 #define MAX_OPEN_PRINTER_EXS 50
35 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
36 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
37 #define PRINTER_HANDLE_IS_PRINTER 0
38 #define PRINTER_HANDLE_IS_PRINTSERVER 1
47 /* structure to store the printer handles */
48 /* and a reference to what it's pointing to */
49 /* and the notify info asked about */
50 /* that's the central struct */
51 typedef struct _Printer
{
52 struct _Printer
*prev
, *next
;
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 static Printer_entry
*printers_list
;
80 typedef struct _counter_printer_0
{
88 static ubi_dlList counter_list
;
90 static struct cli_state cli
;
91 static uint32 smb_connections
=0;
93 #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
94 ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
96 /* translate between internal status numbers and NT status numbers */
97 static int nt_printj_status(int v
)
103 return JOB_STATUS_PAUSED
;
105 return JOB_STATUS_SPOOLING
;
107 return JOB_STATUS_PRINTING
;
109 return JOB_STATUS_ERROR
;
111 return JOB_STATUS_DELETING
;
113 return JOB_STATUS_OFFLINE
;
115 return JOB_STATUS_PAPEROUT
;
117 return JOB_STATUS_PRINTED
;
119 return JOB_STATUS_DELETED
;
121 return JOB_STATUS_BLOCKED
;
122 case LPQ_USER_INTERVENTION
:
123 return JOB_STATUS_USER_INTERVENTION
;
128 static int nt_printq_status(int v
)
132 return PRINTER_STATUS_PAUSED
;
141 /****************************************************************************
142 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
143 ****************************************************************************/
145 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION
**pp
)
150 SAFE_FREE((*pp
)->ctr
.type
);
154 /***************************************************************************
155 Disconnect from the client
156 ****************************************************************************/
158 static void srv_spoolss_replycloseprinter(POLICY_HND
*handle
)
162 /* weird if the test succeds !!! */
163 if (smb_connections
==0) {
164 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
168 if(!cli_spoolss_reply_close_printer(&cli
, handle
, &status
))
169 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n"));
171 /* if it's the last connection, deconnect the IPC$ share */
172 if (smb_connections
==1) {
173 if(!spoolss_disconnect_from_client(&cli
))
176 message_deregister(MSG_PRINTER_NOTIFY
);
182 /****************************************************************************
183 Functions to free a printer entry datastruct.
184 ****************************************************************************/
186 static void free_printer_entry(void *ptr
)
188 Printer_entry
*Printer
= (Printer_entry
*)ptr
;
190 if (Printer
->notify
.client_connected
==True
)
191 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
193 Printer
->notify
.flags
=0;
194 Printer
->notify
.options
=0;
195 Printer
->notify
.localmachine
[0]='\0';
196 Printer
->notify
.printerlocal
=0;
197 free_spool_notify_option(&Printer
->notify
.option
);
198 Printer
->notify
.option
=NULL
;
199 Printer
->notify
.client_connected
=False
;
201 /* Remove from the internal list. */
202 DLIST_REMOVE(printers_list
, Printer
);
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(2,("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(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
265 close_policy_hnd(p
, hnd
);
270 /****************************************************************************
271 Delete a printer given a handle.
272 ****************************************************************************/
274 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
276 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
279 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
283 if (del_a_printer(Printer
->dev
.handlename
) != 0) {
284 DEBUG(3,("Error deleting printer %s\n", Printer
->dev
.handlename
));
288 /* Check calling user has permission to delete printer. Note that
289 since we set the snum parameter to -1 only administrators can
290 delete the printer. This stops people with the Full Control
291 permission from deleting the printer. */
293 if (!print_access_check(NULL
, -1, PRINTER_ACCESS_ADMINISTER
)) {
294 DEBUG(3, ("printer delete denied by security descriptor\n"));
295 return WERR_ACCESS_DENIED
;
298 if (*lp_deleteprinter_cmd()) {
300 char *cmd
= lp_deleteprinter_cmd();
305 /* Printer->dev.handlename equals portname equals sharename */
306 slprintf(command
, sizeof(command
)-1, "%s \"%s\"", cmd
,
307 Printer
->dev
.handlename
);
308 dos_to_unix(command
, True
); /* Convert printername to unix-codepage */
310 DEBUG(10,("Running [%s]\n", command
));
311 ret
= smbrun(command
, NULL
);
313 return WERR_BADFID
; /* What to return here? */
315 DEBUGADD(10,("returned [%d]\n", ret
));
317 /* Send SIGHUP to process group... is there a better way? */
320 if ( ( i
= lp_servicenumber( Printer
->dev
.handlename
) ) >= 0 ) {
324 return WERR_ACCESS_DENIED
;
330 /****************************************************************************
331 return the snum of a printer corresponding to an handle
332 ****************************************************************************/
333 static BOOL
get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
)
335 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
338 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
342 switch (Printer
->printer_type
) {
343 case PRINTER_HANDLE_IS_PRINTER
:
344 DEBUG(4,("short name:%s\n", Printer
->dev
.handlename
));
345 *number
= print_queue_snum(Printer
->dev
.handlename
);
346 return (*number
!= -1);
347 case PRINTER_HANDLE_IS_PRINTSERVER
:
354 /****************************************************************************
355 set printer handle type.
356 ****************************************************************************/
357 static BOOL
set_printer_hnd_accesstype(pipes_struct
*p
, POLICY_HND
*hnd
, uint32 access_required
)
359 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
362 DEBUG(2,("set_printer_hnd_accesstype: Invalid handle (%s:%u:%u)", OUR_HANDLE(hnd
)));
366 DEBUG(4,("Setting printer access=%x\n", access_required
));
367 Printer
->access
= access_required
;
371 /****************************************************************************
372 Set printer handle type.
373 Check if it's \\server or \\server\printer
374 ****************************************************************************/
376 static BOOL
set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
378 DEBUG(3,("Setting printer type=%s\n", handlename
));
380 if ( strlen(handlename
) < 3 ) {
381 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
385 /* it's a print server */
386 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr(handlename
+2, '\\')) {
387 DEBUGADD(4,("Printer is a print server\n"));
388 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTSERVER
;
392 DEBUGADD(4,("Printer is a printer\n"));
393 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTER
;
399 /****************************************************************************
400 Set printer handle name.
401 ****************************************************************************/
403 static BOOL
set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
406 int n_services
=lp_numservices();
411 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename
, strlen(handlename
)));
413 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTSERVER
) {
414 ZERO_STRUCT(Printer
->dev
.printerservername
);
415 strncpy(Printer
->dev
.printerservername
, handlename
, strlen(handlename
));
419 if (Printer
->printer_type
!=PRINTER_HANDLE_IS_PRINTER
)
422 if (*handlename
=='\\') {
423 aprinter
=strchr(handlename
+2, '\\');
430 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter
, strlen(aprinter
)));
433 * The original code allowed smbd to store a printer name that
434 * was different from the share name. This is not possible
435 * anymore, so I've simplified this loop greatly. Here
436 * we are just verifying that the printer name is a valid
437 * printer service defined in smb.conf
438 * --jerry [Fri Feb 15 11:17:46 CST 2002]
441 for (snum
=0; snum
<n_services
; snum
++) {
443 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
446 fstrcpy(sname
, lp_servicename(snum
));
448 DEBUGADD(5,("share:%s\n",sname
));
450 if (! StrCaseCmp(sname
, aprinter
)) {
459 DEBUGADD(4,("Printer not found\n"));
463 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
465 ZERO_STRUCT(Printer
->dev
.handlename
);
466 fstrcpy(Printer
->dev
.handlename
, sname
);
471 /****************************************************************************
472 find first available printer slot. creates a printer handle for you.
473 ****************************************************************************/
475 static BOOL
open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
)
477 Printer_entry
*new_printer
;
479 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
481 if((new_printer
=(Printer_entry
*)malloc(sizeof(Printer_entry
))) == NULL
)
484 ZERO_STRUCTP(new_printer
);
486 new_printer
->notify
.option
=NULL
;
488 /* Add to the internal list. */
489 DLIST_ADD(printers_list
, new_printer
);
491 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
492 SAFE_FREE(new_printer
);
496 if (!set_printer_hnd_printertype(new_printer
, name
)) {
497 close_printer_handle(p
, hnd
);
501 if (!set_printer_hnd_name(new_printer
, name
)) {
502 close_printer_handle(p
, hnd
);
506 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
511 /********************************************************************
512 Return True if the handle is a print server.
513 ********************************************************************/
515 static BOOL
handle_is_printserver(pipes_struct
*p
, POLICY_HND
*handle
)
517 Printer_entry
*Printer
=find_printer_index_by_hnd(p
,handle
);
522 if (Printer
->printer_type
!= PRINTER_HANDLE_IS_PRINTSERVER
)
528 /****************************************************************************
529 allocate more memory for a BUFFER.
530 ****************************************************************************/
531 static BOOL
alloc_buffer_size(NEW_BUFFER
*buffer
, uint32 buffer_size
)
539 /* damn, I'm doing the reverse operation of prs_grow() :) */
540 if (buffer_size
< prs_data_size(ps
))
543 extra_space
= buffer_size
- prs_data_size(ps
);
546 * save the offset and move to the end of the buffer
547 * prs_grow() checks the extra_space against the offset
549 old_offset
=prs_offset(ps
);
550 prs_set_offset(ps
, prs_data_size(ps
));
552 if (!prs_grow(ps
, extra_space
))
555 prs_set_offset(ps
, old_offset
);
557 buffer
->string_at_end
=prs_data_size(ps
);
562 /***************************************************************************
563 Receive the notify message.
564 ****************************************************************************/
566 static void srv_spoolss_receive_message(int msg_type
, pid_t src
, void *buf
, size_t len
)
568 Printer_entry
*find_printer
;
573 if (len
!= sizeof(msg
)) {
574 DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len
));
578 memcpy(msg
, buf
, len
);
582 DEBUG(10,("srv_spoolss_receive_message: Got message printer change low=0x%x high=0x%x\n", (unsigned int)low
,
583 (unsigned int)high
));
585 find_printer
= printers_list
;
587 /* Iterate the printer list */
588 for(; find_printer
; find_printer
= find_printer
->next
) {
591 * If the entry has a connected client we send the message.
595 if (find_printer
->notify
.client_connected
==True
) {
596 DEBUG(10,("srv_spoolss_receive_message: printerserver [%s]\n", find_printer
->dev
.printerservername
));
597 if (cli_spoolss_reply_rrpcn(&cli
, &find_printer
->notify
.client_hnd
, low
, high
, &status
))
598 DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn status = 0x%x\n",
599 (unsigned int)W_ERROR_V(status
)));
601 DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn failed\n"));
606 /***************************************************************************
608 ****************************************************************************/
610 static BOOL
srv_spoolss_sendnotify(uint32 high
, uint32 low
)
616 DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x\n", low
, high
));
618 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY
, msg
, sizeof(msg
), False
);
622 /********************************************************************
623 * spoolss_open_printer
625 * called from the spoolss dispatcher
626 ********************************************************************/
628 WERROR
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
631 WERROR result
= WERR_OK
;
634 UNISTR2
*printername
= NULL
;
635 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
636 /* uint32 user_switch = q_u->user_switch; - notused */
637 /* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
638 POLICY_HND
*handle
= &r_u
->handle
;
642 struct current_user user
;
644 if (q_u
->printername_ptr
!= 0)
645 printername
= &q_u
->printername
;
647 if (printername
== NULL
)
648 return WERR_INVALID_PRINTER_NAME
;
650 /* some sanity check because you can open a printer or a print server */
651 /* aka: \\server\printer or \\server */
652 unistr2_to_ascii(name
, printername
, sizeof(name
)-1);
654 DEBUGADD(3,("checking name: %s\n",name
));
656 if (!open_printer_hnd(p
, handle
, name
))
657 return WERR_INVALID_PRINTER_NAME
;
660 if (printer_default->datatype_ptr != NULL)
662 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
663 set_printer_hnd_datatype(handle, datatype);
666 set_printer_hnd_datatype(handle, "");
669 if (!set_printer_hnd_accesstype(p
, handle
, printer_default
->access_required
)) {
670 close_printer_handle(p
, handle
);
671 return WERR_ACCESS_DENIED
;
675 First case: the user is opening the print server:
677 Disallow MS AddPrinterWizard if parameter disables it. A Win2k
678 client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
680 Then both Win2k and WinNT clients try an OpenPrinterEx with
681 SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
682 or if the user is listed in the smb.conf printer admin parameter.
684 Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
685 client view printer folder, but does not show the MSAPW.
687 Note: this test needs code to check access rights here too. Jeremy
688 could you look at this?
691 Second case: the user is opening a printer:
692 NT doesn't let us connect to a printer if the connecting user
693 doesn't have print permission.
697 get_current_user(&user
, p
);
699 if (handle_is_printserver(p
, handle
)) {
700 if (printer_default
->access_required
== 0) {
703 else if ((printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
) == SERVER_ACCESS_ADMINISTER
) {
705 /* Printserver handles use global struct... */
708 if (!lp_ms_add_printer_wizard()) {
709 close_printer_handle(p
, handle
);
710 return WERR_ACCESS_DENIED
;
712 else if (user
.uid
== 0 || user_in_list(uidtoname(user
.uid
), lp_printer_admin(snum
))) {
716 close_printer_handle(p
, handle
);
717 return WERR_ACCESS_DENIED
;
723 /* NT doesn't let us connect to a printer if the connecting user
724 doesn't have print permission. */
726 if (!get_printer_snum(p
, handle
, &snum
))
729 /* map an empty access mask to the minimum access mask */
730 if (printer_default
->access_required
== 0x0)
731 printer_default
->access_required
= PRINTER_ACCESS_USE
;
735 * If we are not serving the printer driver for this printer,
736 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
737 * will keep NT clients happy --jerry
740 if (lp_use_client_driver(snum
)
741 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
743 printer_default
->access_required
= PRINTER_ACCESS_USE
;
746 if (!print_access_check(&user
, snum
, printer_default
->access_required
)) {
747 DEBUG(3, ("access DENIED for printer open\n"));
748 close_printer_handle(p
, handle
);
749 return WERR_ACCESS_DENIED
;
753 * If we have a default device pointer in the
754 * printer_default struct, then we need to get
755 * the printer info from the tdb and if there is
756 * no default devicemode there then we do a *SET*
757 * here ! This is insanity.... JRA.
761 * If the openprinterex rpc call contains a devmode,
762 * it's a per-user one. This per-user devmode is derivated
763 * from the global devmode. Openprinterex() contains a per-user
764 * devmode for when you do EMF printing and spooling.
765 * In the EMF case, the NT workstation is only doing half the job
766 * of rendering the page. The other half is done by running the printer
767 * driver on the server.
768 * The EMF file doesn't contain the page description (paper size, orientation, ...).
769 * The EMF file only contains what is to be printed on the page.
770 * So in order for the server to know how to print, the NT client sends
771 * a devicemode attached to the openprinterex call.
772 * But this devicemode is short lived, it's only valid for the current print job.
774 * If Samba would have supported EMF spooling, this devicemode would
775 * have been attached to the handle, to sent it to the driver to correctly
776 * rasterize the EMF file.
778 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
779 * we just act as a pass-thru between windows and the printer.
781 * In order to know that Samba supports only RAW spooling, NT has to call
782 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
783 * and until NT sends a RAW job, we refuse it.
785 * But to call getprinter() or startdoc(), you first need a valid handle,
786 * and to get an handle you have to call openprintex(). Hence why you have
787 * a devicemode in the openprinterex() call.
790 * Differences between NT4 and NT 2000.
793 * On NT4, you only have a global devicemode. This global devicemode can be changed
794 * by the administrator (or by a user with enough privs). Everytime a user
795 * wants to print, the devicemode is resetted to the default. In Word, everytime
796 * you print, the printer's characteristics are always reset to the global devicemode.
800 * In W2K, there is the notion of per-user devicemode. The first time you use
801 * a printer, a per-user devicemode is build from the global devicemode.
802 * If you change your per-user devicemode, it is saved in the registry, under the
803 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
804 * printer preferences available.
806 * To change the per-user devicemode: it's the "Printing Preferences ..." button
807 * on the General Tab of the printer properties windows.
809 * To change the global devicemode: it's the "Printing Defaults..." button
810 * on the Advanced Tab of the printer properties window.
818 if (printer_default
->devmode_cont
.devmode
!= NULL
) {
819 result
= printer_write_default_dev( snum
, printer_default
);
821 close_printer_handle(p
, handle
);
831 /****************************************************************************
832 ****************************************************************************/
833 static BOOL
convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
834 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
840 ret
= uni_2_asc_printer_info_2(uni
->info_2
, &printer
->info_2
);
849 static BOOL
convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
850 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
856 printer
->info_3
=NULL
;
857 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
861 printer
->info_6
=NULL
;
862 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
872 BOOL
convert_devicemode(char *printername
, const DEVICEMODE
*devmode
,
873 NT_DEVICEMODE
**pp_nt_devmode
)
875 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
878 * Ensure nt_devmode is a valid pointer
879 * as we will be overwriting it.
882 if (nt_devmode
== NULL
) {
883 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
884 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
888 unistr_to_dos(nt_devmode
->devicename
, (const char *)devmode
->devicename
.buffer
, 31);
889 unistr_to_dos(nt_devmode
->formname
, (const char *)devmode
->formname
.buffer
, 31);
891 nt_devmode
->specversion
=devmode
->specversion
;
892 nt_devmode
->driverversion
=devmode
->driverversion
;
893 nt_devmode
->size
=devmode
->size
;
894 nt_devmode
->fields
=devmode
->fields
;
895 nt_devmode
->orientation
=devmode
->orientation
;
896 nt_devmode
->papersize
=devmode
->papersize
;
897 nt_devmode
->paperlength
=devmode
->paperlength
;
898 nt_devmode
->paperwidth
=devmode
->paperwidth
;
899 nt_devmode
->scale
=devmode
->scale
;
900 nt_devmode
->copies
=devmode
->copies
;
901 nt_devmode
->defaultsource
=devmode
->defaultsource
;
902 nt_devmode
->printquality
=devmode
->printquality
;
903 nt_devmode
->color
=devmode
->color
;
904 nt_devmode
->duplex
=devmode
->duplex
;
905 nt_devmode
->yresolution
=devmode
->yresolution
;
906 nt_devmode
->ttoption
=devmode
->ttoption
;
907 nt_devmode
->collate
=devmode
->collate
;
909 nt_devmode
->logpixels
=devmode
->logpixels
;
910 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
911 nt_devmode
->pelswidth
=devmode
->pelswidth
;
912 nt_devmode
->pelsheight
=devmode
->pelsheight
;
913 nt_devmode
->displayflags
=devmode
->displayflags
;
914 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
915 nt_devmode
->icmmethod
=devmode
->icmmethod
;
916 nt_devmode
->icmintent
=devmode
->icmintent
;
917 nt_devmode
->mediatype
=devmode
->mediatype
;
918 nt_devmode
->dithertype
=devmode
->dithertype
;
919 nt_devmode
->reserved1
=devmode
->reserved1
;
920 nt_devmode
->reserved2
=devmode
->reserved2
;
921 nt_devmode
->panningwidth
=devmode
->panningwidth
;
922 nt_devmode
->panningheight
=devmode
->panningheight
;
925 * Only change private and driverextra if the incoming devmode
926 * has a new one. JRA.
929 if ((devmode
->driverextra
!= 0) && (devmode
->private != NULL
)) {
930 SAFE_FREE(nt_devmode
->private);
931 nt_devmode
->driverextra
=devmode
->driverextra
;
932 if((nt_devmode
->private=(uint8
*)malloc(nt_devmode
->driverextra
* sizeof(uint8
))) == NULL
)
934 memcpy(nt_devmode
->private, devmode
->private, nt_devmode
->driverextra
);
937 *pp_nt_devmode
= nt_devmode
;
942 /********************************************************************
943 * _spoolss_enddocprinter_internal.
944 ********************************************************************/
946 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
948 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
951 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
955 Printer
->document_started
=False
;
956 print_job_end(Printer
->jobid
,True
);
957 /* error codes unhandled so far ... */
962 /********************************************************************
963 * api_spoolss_closeprinter
964 ********************************************************************/
966 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
968 POLICY_HND
*handle
= &q_u
->handle
;
970 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
972 if (Printer
&& Printer
->document_started
)
973 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
975 if (!close_printer_handle(p
, handle
))
978 /* clear the returned printer handle. Observed behavior
979 from Win2k server. Don't think this really matters.
980 Previous code just copied the value of the closed
983 memset(&r_u
->handle
, '\0', sizeof(r_u
->handle
));
988 /********************************************************************
989 * api_spoolss_deleteprinter
991 ********************************************************************/
993 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
995 POLICY_HND
*handle
= &q_u
->handle
;
996 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
999 if (Printer
&& Printer
->document_started
)
1000 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1002 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1004 result
= delete_printer_handle(p
, handle
);
1006 update_c_setprinter(FALSE
);
1008 if (W_ERROR_IS_OK(result
)) {
1009 srv_spoolss_sendnotify(0, PRINTER_CHANGE_DELETE_PRINTER
);
1015 /*******************************************************************
1016 * static function to lookup the version id corresponding to an
1017 * long architecture string
1018 ******************************************************************/
1019 static int get_version_id (char * arch
)
1022 struct table_node archi_table
[]= {
1024 {"Windows 4.0", "WIN40", 0 },
1025 {"Windows NT x86", "W32X86", 2 },
1026 {"Windows NT R4000", "W32MIPS", 2 },
1027 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1028 {"Windows NT PowerPC", "W32PPC", 2 },
1032 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1034 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1035 return (archi_table
[i
].version
);
1041 /********************************************************************
1042 * _spoolss_deleteprinterdriver
1044 * We currently delete the driver for the architecture only.
1045 * This can leave the driver for other archtectures. However,
1046 * since every printer associates a "Windows NT x86" driver name
1047 * and we cannot delete that one while it is in use, **and** since
1048 * it is impossible to assign a driver to a Samba printer without
1049 * having the "Windows NT x86" driver installed,...
1051 * ....we should not get into trouble here.
1054 ********************************************************************/
1056 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
,
1057 SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
1061 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1064 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
)-1 );
1065 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
)-1 );
1067 /* check that we have a valid driver name first */
1068 if ((version
=get_version_id(arch
)) == -1) {
1069 /* this is what NT returns */
1070 return WERR_INVALID_ENVIRONMENT
;
1074 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
1075 return WERR_UNKNOWN_PRINTER_DRIVER
;
1079 if (printer_driver_in_use(arch
, driver
))
1081 return WERR_PRINTER_DRIVER_IN_USE
;
1084 return delete_printer_driver(info
.info_3
);
1088 /********************************************************************
1089 GetPrinterData on a printer server Handle.
1090 ********************************************************************/
1091 static BOOL
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
1095 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
1097 if (!strcmp(value
, "W3SvcInstalled")) {
1099 if((*data
= (uint8
*)talloc_zero(ctx
, 4*sizeof(uint8
) )) == NULL
)
1105 if (!strcmp(value
, "BeepEnabled")) {
1107 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1109 SIVAL(*data
, 0, 0x01);
1114 if (!strcmp(value
, "EventLog")) {
1116 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1118 SIVAL(*data
, 0, 0x1B);
1123 if (!strcmp(value
, "NetPopup")) {
1125 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1127 SIVAL(*data
, 0, 0x01);
1132 if (!strcmp(value
, "MajorVersion")) {
1134 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1136 SIVAL(*data
, 0, 0x02);
1141 if (!strcmp(value
, "DefaultSpoolDirectory")) {
1142 pstring string
="You are using a Samba server";
1144 *needed
= 2*(strlen(string
)+1);
1145 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1147 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1149 /* it's done by hand ready to go on the wire */
1150 for (i
=0; i
<strlen(string
); i
++) {
1151 (*data
)[2*i
]=string
[i
];
1152 (*data
)[2*i
+1]='\0';
1157 if (!strcmp(value
, "Architecture")) {
1158 pstring string
="Windows NT x86";
1160 *needed
= 2*(strlen(string
)+1);
1161 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1163 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1164 for (i
=0; i
<strlen(string
); i
++) {
1165 (*data
)[2*i
]=string
[i
];
1166 (*data
)[2*i
+1]='\0';
1174 /********************************************************************
1175 GetPrinterData on a printer Handle.
1176 ********************************************************************/
1177 static BOOL
getprinterdata_printer(pipes_struct
*p
, TALLOC_CTX
*ctx
, POLICY_HND
*handle
,
1178 fstring value
, uint32
*type
,
1179 uint8
**data
, uint32
*needed
, uint32 in_size
)
1181 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1185 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1187 DEBUG(5,("getprinterdata_printer\n"));
1190 DEBUG(2,("getprinterdata_printer: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
1194 if(!get_printer_snum(p
, handle
, &snum
))
1197 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
1200 if (!get_specific_param(*printer
, 2, value
, &idata
, type
, &len
)) {
1201 free_a_printer(&printer
, 2);
1205 free_a_printer(&printer
, 2);
1207 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size
));
1210 if((*data
= (uint8
*)talloc(ctx
, in_size
*sizeof(uint8
) )) == NULL
) {
1214 memset(*data
, 0, in_size
*sizeof(uint8
));
1215 /* copy the min(in_size, len) */
1216 memcpy(*data
, idata
, (len
>in_size
)?in_size
:len
*sizeof(uint8
));
1223 DEBUG(5,("getprinterdata_printer:copy done\n"));
1230 /********************************************************************
1231 * spoolss_getprinterdata
1232 ********************************************************************/
1234 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
1236 POLICY_HND
*handle
= &q_u
->handle
;
1237 UNISTR2
*valuename
= &q_u
->valuename
;
1238 uint32 in_size
= q_u
->size
;
1239 uint32
*type
= &r_u
->type
;
1240 uint32
*out_size
= &r_u
->size
;
1241 uint8
**data
= &r_u
->data
;
1242 uint32
*needed
= &r_u
->needed
;
1246 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1249 * Reminder: when it's a string, the length is in BYTES
1250 * even if UNICODE is negociated.
1257 /* in case of problem, return some default values */
1261 DEBUG(4,("_spoolss_getprinterdata\n"));
1264 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, 4*sizeof(uint8
))) == NULL
)
1266 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
1270 unistr2_to_ascii(value
, valuename
, sizeof(value
)-1);
1272 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
1273 found
=getprinterdata_printer_server(p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
1275 found
= getprinterdata_printer(p
, p
->mem_ctx
, handle
, value
, type
, data
, needed
, *out_size
);
1278 DEBUG(5, ("value not found, allocating %d\n", *out_size
));
1279 /* reply this param doesn't exist */
1281 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
)
1287 return WERR_INVALID_PARAM
;
1290 if (*needed
> *out_size
)
1291 return WERR_STATUS_MORE_ENTRIES
;
1296 /***************************************************************************
1297 connect to the client
1298 ****************************************************************************/
1299 static BOOL
srv_spoolss_replyopenprinter(char *printer
, uint32 localprinter
, uint32 type
, POLICY_HND
*handle
)
1304 * If it's the first connection, contact the client
1305 * and connect to the IPC$ share anonumously
1307 if (smb_connections
==0) {
1308 fstring unix_printer
;
1310 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
1311 dos_to_unix(unix_printer
, True
);
1313 if(!spoolss_connect_to_client(&cli
, unix_printer
))
1315 message_register(MSG_PRINTER_NOTIFY
, srv_spoolss_receive_message
);
1321 if(!cli_spoolss_reply_open_printer(&cli
, printer
, localprinter
, type
, &status
, handle
))
1327 /********************************************************************
1329 * ReplyFindFirstPrinterChangeNotifyEx
1331 * jfmxxxx: before replying OK: status=0
1332 * should do a rpc call to the workstation asking ReplyOpenPrinter
1333 * have to code it, later.
1335 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
1336 * called from api_spoolss_rffpcnex
1337 ********************************************************************/
1339 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
1341 POLICY_HND
*handle
= &q_u
->handle
;
1342 uint32 flags
= q_u
->flags
;
1343 uint32 options
= q_u
->options
;
1344 UNISTR2
*localmachine
= &q_u
->localmachine
;
1345 uint32 printerlocal
= q_u
->printerlocal
;
1346 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
1348 /* store the notify value in the printer struct */
1350 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1353 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
1357 Printer
->notify
.flags
=flags
;
1358 Printer
->notify
.options
=options
;
1359 Printer
->notify
.printerlocal
=printerlocal
;
1361 if (Printer
->notify
.option
)
1362 free_spool_notify_option(&Printer
->notify
.option
);
1364 Printer
->notify
.option
=dup_spool_notify_option(option
);
1366 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
, sizeof(Printer
->notify
.localmachine
)-1);
1368 /* connect to the client machine and send a ReplyOpenPrinter */
1369 if(srv_spoolss_replyopenprinter(Printer
->notify
.localmachine
,
1370 Printer
->notify
.printerlocal
, 1,
1371 &Printer
->notify
.client_hnd
))
1372 Printer
->notify
.client_connected
=True
;
1377 /*******************************************************************
1378 * fill a notify_info_data with the servername
1379 ********************************************************************/
1381 static void spoolss_notify_server_name(int snum
,
1382 SPOOL_NOTIFY_INFO_DATA
*data
,
1383 print_queue_struct
*queue
,
1384 NT_PRINTER_INFO_LEVEL
*printer
,
1385 TALLOC_CTX
*mem_ctx
)
1387 pstring temp_name
, temp
;
1390 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", get_called_name());
1392 len
= (uint32
)dos_PutUniCode(temp
, temp_name
, sizeof(temp
) - 2, True
);
1394 data
->notify_data
.data
.length
= len
/ 2 - 1;
1395 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1397 if (!data
->notify_data
.data
.string
) {
1398 data
->notify_data
.data
.length
= 0;
1402 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1405 /*******************************************************************
1406 * fill a notify_info_data with the printername (not including the servername).
1407 ********************************************************************/
1408 static void spoolss_notify_printer_name(int snum
,
1409 SPOOL_NOTIFY_INFO_DATA
*data
,
1410 print_queue_struct
*queue
,
1411 NT_PRINTER_INFO_LEVEL
*printer
,
1412 TALLOC_CTX
*mem_ctx
)
1417 /* the notify name should not contain the \\server\ part */
1418 char *p
= strrchr(printer
->info_2
->printername
, '\\');
1421 p
= printer
->info_2
->printername
;
1426 len
= (uint32
)dos_PutUniCode(temp
, p
, sizeof(temp
) - 2, True
);
1428 data
->notify_data
.data
.length
= len
/ 2 - 1;
1429 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1431 if (!data
->notify_data
.data
.string
) {
1432 data
->notify_data
.data
.length
= 0;
1436 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1439 /*******************************************************************
1440 * fill a notify_info_data with the servicename
1441 ********************************************************************/
1442 static void spoolss_notify_share_name(int snum
,
1443 SPOOL_NOTIFY_INFO_DATA
*data
,
1444 print_queue_struct
*queue
,
1445 NT_PRINTER_INFO_LEVEL
*printer
,
1446 TALLOC_CTX
*mem_ctx
)
1451 len
= (uint32
)dos_PutUniCode(temp
, lp_servicename(snum
),
1452 sizeof(temp
) - 2, True
);
1454 data
->notify_data
.data
.length
= len
/ 2 - 1;
1455 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1457 if (!data
->notify_data
.data
.string
) {
1458 data
->notify_data
.data
.length
= 0;
1462 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1465 /*******************************************************************
1466 * fill a notify_info_data with the port name
1467 ********************************************************************/
1468 static void spoolss_notify_port_name(int snum
,
1469 SPOOL_NOTIFY_INFO_DATA
*data
,
1470 print_queue_struct
*queue
,
1471 NT_PRINTER_INFO_LEVEL
*printer
,
1472 TALLOC_CTX
*mem_ctx
)
1477 /* even if it's strange, that's consistant in all the code */
1479 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->portname
,
1480 sizeof(temp
) - 2, True
);
1482 data
->notify_data
.data
.length
= len
/ 2 - 1;
1483 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1485 if (!data
->notify_data
.data
.string
) {
1486 data
->notify_data
.data
.length
= 0;
1490 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1493 /*******************************************************************
1494 * fill a notify_info_data with the printername
1495 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
1496 * but it doesn't exist, have to see what to do
1497 ********************************************************************/
1498 static void spoolss_notify_driver_name(int snum
,
1499 SPOOL_NOTIFY_INFO_DATA
*data
,
1500 print_queue_struct
*queue
,
1501 NT_PRINTER_INFO_LEVEL
*printer
,
1502 TALLOC_CTX
*mem_ctx
)
1507 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->drivername
,
1508 sizeof(temp
) - 2, True
);
1510 data
->notify_data
.data
.length
= len
/ 2 - 1;
1511 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1513 if (!data
->notify_data
.data
.string
) {
1514 data
->notify_data
.data
.length
= 0;
1518 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1521 /*******************************************************************
1522 * fill a notify_info_data with the comment
1523 ********************************************************************/
1524 static void spoolss_notify_comment(int snum
,
1525 SPOOL_NOTIFY_INFO_DATA
*data
,
1526 print_queue_struct
*queue
,
1527 NT_PRINTER_INFO_LEVEL
*printer
,
1528 TALLOC_CTX
*mem_ctx
)
1533 if (*printer
->info_2
->comment
== '\0')
1534 len
= (uint32
)dos_PutUniCode(temp
, lp_comment(snum
),
1535 sizeof(temp
) - 2, True
);
1537 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->comment
,
1538 sizeof(temp
) - 2, True
);
1540 data
->notify_data
.data
.length
= len
/ 2 - 1;
1541 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1543 if (!data
->notify_data
.data
.string
) {
1544 data
->notify_data
.data
.length
= 0;
1548 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1551 /*******************************************************************
1552 * fill a notify_info_data with the comment
1553 * jfm:xxxx incorrect, have to create a new smb.conf option
1554 * location = "Room 1, floor 2, building 3"
1555 ********************************************************************/
1556 static void spoolss_notify_location(int snum
,
1557 SPOOL_NOTIFY_INFO_DATA
*data
,
1558 print_queue_struct
*queue
,
1559 NT_PRINTER_INFO_LEVEL
*printer
,
1560 TALLOC_CTX
*mem_ctx
)
1565 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->location
,
1566 sizeof(temp
) - 2, True
);
1568 data
->notify_data
.data
.length
= len
/ 2 - 1;
1569 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1571 if (!data
->notify_data
.data
.string
) {
1572 data
->notify_data
.data
.length
= 0;
1576 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1579 /*******************************************************************
1580 * fill a notify_info_data with the device mode
1581 * jfm:xxxx don't to it for know but that's a real problem !!!
1582 ********************************************************************/
1583 static void spoolss_notify_devmode(int snum
,
1584 SPOOL_NOTIFY_INFO_DATA
*data
,
1585 print_queue_struct
*queue
,
1586 NT_PRINTER_INFO_LEVEL
*printer
,
1587 TALLOC_CTX
*mem_ctx
)
1591 /*******************************************************************
1592 * fill a notify_info_data with the separator file name
1593 * jfm:xxxx just return no file could add an option to smb.conf
1594 * separator file = "separator.txt"
1595 ********************************************************************/
1596 static void spoolss_notify_sepfile(int snum
,
1597 SPOOL_NOTIFY_INFO_DATA
*data
,
1598 print_queue_struct
*queue
,
1599 NT_PRINTER_INFO_LEVEL
*printer
,
1600 TALLOC_CTX
*mem_ctx
)
1605 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->sepfile
,
1606 sizeof(temp
) - 2, True
);
1608 data
->notify_data
.data
.length
= len
/ 2 - 1;
1609 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1611 if (!data
->notify_data
.data
.string
) {
1612 data
->notify_data
.data
.length
= 0;
1616 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1619 /*******************************************************************
1620 * fill a notify_info_data with the print processor
1621 * jfm:xxxx return always winprint to indicate we don't do anything to it
1622 ********************************************************************/
1623 static void spoolss_notify_print_processor(int snum
,
1624 SPOOL_NOTIFY_INFO_DATA
*data
,
1625 print_queue_struct
*queue
,
1626 NT_PRINTER_INFO_LEVEL
*printer
,
1627 TALLOC_CTX
*mem_ctx
)
1632 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->printprocessor
,
1633 sizeof(temp
) - 2, True
);
1635 data
->notify_data
.data
.length
= len
/ 2 - 1;
1636 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1638 if (!data
->notify_data
.data
.string
) {
1639 data
->notify_data
.data
.length
= 0;
1643 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1646 /*******************************************************************
1647 * fill a notify_info_data with the print processor options
1648 * jfm:xxxx send an empty string
1649 ********************************************************************/
1650 static void spoolss_notify_parameters(int snum
,
1651 SPOOL_NOTIFY_INFO_DATA
*data
,
1652 print_queue_struct
*queue
,
1653 NT_PRINTER_INFO_LEVEL
*printer
,
1654 TALLOC_CTX
*mem_ctx
)
1659 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->parameters
,
1660 sizeof(temp
) - 2, True
);
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 data type
1675 * jfm:xxxx always send RAW as data type
1676 ********************************************************************/
1677 static void spoolss_notify_datatype(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
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->datatype
,
1687 sizeof(pstring
) - 2, True
);
1689 data
->notify_data
.data
.length
= len
/ 2 - 1;
1690 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1692 if (!data
->notify_data
.data
.string
) {
1693 data
->notify_data
.data
.length
= 0;
1697 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1700 /*******************************************************************
1701 * fill a notify_info_data with the security descriptor
1702 * jfm:xxxx send an null pointer to say no security desc
1703 * have to implement security before !
1704 ********************************************************************/
1705 static void spoolss_notify_security_desc(int snum
,
1706 SPOOL_NOTIFY_INFO_DATA
*data
,
1707 print_queue_struct
*queue
,
1708 NT_PRINTER_INFO_LEVEL
*printer
,
1709 TALLOC_CTX
*mem_ctx
)
1711 data
->notify_data
.data
.length
=0;
1712 data
->notify_data
.data
.string
= NULL
;
1715 /*******************************************************************
1716 * fill a notify_info_data with the attributes
1717 * jfm:xxxx a samba printer is always shared
1718 ********************************************************************/
1719 static void spoolss_notify_attributes(int snum
,
1720 SPOOL_NOTIFY_INFO_DATA
*data
,
1721 print_queue_struct
*queue
,
1722 NT_PRINTER_INFO_LEVEL
*printer
,
1723 TALLOC_CTX
*mem_ctx
)
1725 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
1726 data
->notify_data
.value
[1] = 0;
1729 /*******************************************************************
1730 * fill a notify_info_data with the priority
1731 ********************************************************************/
1732 static void spoolss_notify_priority(int snum
,
1733 SPOOL_NOTIFY_INFO_DATA
*data
,
1734 print_queue_struct
*queue
,
1735 NT_PRINTER_INFO_LEVEL
*printer
,
1736 TALLOC_CTX
*mem_ctx
)
1738 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
1739 data
->notify_data
.value
[1] = 0;
1742 /*******************************************************************
1743 * fill a notify_info_data with the default priority
1744 ********************************************************************/
1745 static void spoolss_notify_default_priority(int snum
,
1746 SPOOL_NOTIFY_INFO_DATA
*data
,
1747 print_queue_struct
*queue
,
1748 NT_PRINTER_INFO_LEVEL
*printer
,
1749 TALLOC_CTX
*mem_ctx
)
1751 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
1752 data
->notify_data
.value
[1] = 0;
1755 /*******************************************************************
1756 * fill a notify_info_data with the start time
1757 ********************************************************************/
1758 static void spoolss_notify_start_time(int snum
,
1759 SPOOL_NOTIFY_INFO_DATA
*data
,
1760 print_queue_struct
*queue
,
1761 NT_PRINTER_INFO_LEVEL
*printer
,
1762 TALLOC_CTX
*mem_ctx
)
1764 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
1765 data
->notify_data
.value
[1] = 0;
1768 /*******************************************************************
1769 * fill a notify_info_data with the until time
1770 ********************************************************************/
1771 static void spoolss_notify_until_time(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
->untiltime
;
1778 data
->notify_data
.value
[1] = 0;
1781 /*******************************************************************
1782 * fill a notify_info_data with the status
1783 ********************************************************************/
1784 static void spoolss_notify_status(int snum
,
1785 SPOOL_NOTIFY_INFO_DATA
*data
,
1786 print_queue_struct
*queue
,
1787 NT_PRINTER_INFO_LEVEL
*printer
,
1788 TALLOC_CTX
*mem_ctx
)
1790 print_status_struct status
;
1792 print_queue_length(snum
, &status
);
1793 data
->notify_data
.value
[0]=(uint32
) status
.status
;
1794 data
->notify_data
.value
[1] = 0;
1797 /*******************************************************************
1798 * fill a notify_info_data with the number of jobs queued
1799 ********************************************************************/
1800 static void spoolss_notify_cjobs(int snum
,
1801 SPOOL_NOTIFY_INFO_DATA
*data
,
1802 print_queue_struct
*queue
,
1803 NT_PRINTER_INFO_LEVEL
*printer
,
1804 TALLOC_CTX
*mem_ctx
)
1806 data
->notify_data
.value
[0] = print_queue_length(snum
, NULL
);
1807 data
->notify_data
.value
[1] = 0;
1810 /*******************************************************************
1811 * fill a notify_info_data with the average ppm
1812 ********************************************************************/
1813 static void spoolss_notify_average_ppm(int snum
,
1814 SPOOL_NOTIFY_INFO_DATA
*data
,
1815 print_queue_struct
*queue
,
1816 NT_PRINTER_INFO_LEVEL
*printer
,
1817 TALLOC_CTX
*mem_ctx
)
1819 /* always respond 8 pages per minutes */
1820 /* a little hard ! */
1821 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
1822 data
->notify_data
.value
[1] = 0;
1825 /*******************************************************************
1826 * fill a notify_info_data with username
1827 ********************************************************************/
1828 static void spoolss_notify_username(int snum
,
1829 SPOOL_NOTIFY_INFO_DATA
*data
,
1830 print_queue_struct
*queue
,
1831 NT_PRINTER_INFO_LEVEL
*printer
,
1832 TALLOC_CTX
*mem_ctx
)
1837 len
= (uint32
)dos_PutUniCode(temp
, queue
->user
,
1838 sizeof(temp
) - 2, True
);
1840 data
->notify_data
.data
.length
= len
/ 2 - 1;
1841 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1843 if (!data
->notify_data
.data
.string
) {
1844 data
->notify_data
.data
.length
= 0;
1848 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1851 /*******************************************************************
1852 * fill a notify_info_data with job status
1853 ********************************************************************/
1854 static void spoolss_notify_job_status(int snum
,
1855 SPOOL_NOTIFY_INFO_DATA
*data
,
1856 print_queue_struct
*queue
,
1857 NT_PRINTER_INFO_LEVEL
*printer
,
1858 TALLOC_CTX
*mem_ctx
)
1860 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
1861 data
->notify_data
.value
[1] = 0;
1864 /*******************************************************************
1865 * fill a notify_info_data with job name
1866 ********************************************************************/
1867 static void spoolss_notify_job_name(int snum
,
1868 SPOOL_NOTIFY_INFO_DATA
*data
,
1869 print_queue_struct
*queue
,
1870 NT_PRINTER_INFO_LEVEL
*printer
,
1871 TALLOC_CTX
*mem_ctx
)
1876 len
= (uint32
)dos_PutUniCode(temp
, queue
->file
, sizeof(temp
) - 2,
1879 data
->notify_data
.data
.length
= len
/ 2 - 1;
1880 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1882 if (!data
->notify_data
.data
.string
) {
1883 data
->notify_data
.data
.length
= 0;
1887 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1890 /*******************************************************************
1891 * fill a notify_info_data with job status
1892 ********************************************************************/
1893 static void spoolss_notify_job_status_string(int snum
,
1894 SPOOL_NOTIFY_INFO_DATA
*data
,
1895 print_queue_struct
*queue
,
1896 NT_PRINTER_INFO_LEVEL
*printer
,
1897 TALLOC_CTX
*mem_ctx
)
1900 * Now we're returning job status codes we just return a "" here. JRA.
1907 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
1910 switch (queue
->status
) {
1915 p
= ""; /* NT provides the paused string */
1924 #endif /* NO LONGER NEEDED. */
1926 len
= (uint32
)dos_PutUniCode(temp
, p
, sizeof(temp
) - 2, True
);
1928 data
->notify_data
.data
.length
= len
/ 2 - 1;
1929 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1931 if (!data
->notify_data
.data
.string
) {
1932 data
->notify_data
.data
.length
= 0;
1936 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1939 /*******************************************************************
1940 * fill a notify_info_data with job time
1941 ********************************************************************/
1942 static void spoolss_notify_job_time(int snum
,
1943 SPOOL_NOTIFY_INFO_DATA
*data
,
1944 print_queue_struct
*queue
,
1945 NT_PRINTER_INFO_LEVEL
*printer
,
1946 TALLOC_CTX
*mem_ctx
)
1948 data
->notify_data
.value
[0]=0x0;
1949 data
->notify_data
.value
[1]=0;
1952 /*******************************************************************
1953 * fill a notify_info_data with job size
1954 ********************************************************************/
1955 static void spoolss_notify_job_size(int snum
,
1956 SPOOL_NOTIFY_INFO_DATA
*data
,
1957 print_queue_struct
*queue
,
1958 NT_PRINTER_INFO_LEVEL
*printer
,
1959 TALLOC_CTX
*mem_ctx
)
1961 data
->notify_data
.value
[0]=queue
->size
;
1962 data
->notify_data
.value
[1]=0;
1965 /*******************************************************************
1966 Fill a notify_info_data with job position.
1967 ********************************************************************/
1969 static void spoolss_notify_job_position(int snum
,
1970 SPOOL_NOTIFY_INFO_DATA
*data
,
1971 print_queue_struct
*queue
,
1972 NT_PRINTER_INFO_LEVEL
*printer
,
1973 TALLOC_CTX
*mem_ctx
)
1975 data
->notify_data
.value
[0]=queue
->job
;
1976 data
->notify_data
.value
[1]=0;
1979 /*******************************************************************
1980 Fill a notify_info_data with submitted time.
1981 ********************************************************************/
1983 static void spoolss_notify_submitted_time(int snum
,
1984 SPOOL_NOTIFY_INFO_DATA
*data
,
1985 print_queue_struct
*queue
,
1986 NT_PRINTER_INFO_LEVEL
*printer
,
1987 TALLOC_CTX
*mem_ctx
)
1994 t
=gmtime(&queue
->time
);
1996 len
= sizeof(SYSTEMTIME
);
1998 data
->notify_data
.data
.length
= len
;
1999 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2001 if (!data
->notify_data
.data
.string
) {
2002 data
->notify_data
.data
.length
= 0;
2006 make_systemtime(&st
, t
);
2009 * Systemtime must be linearized as a set of UINT16's.
2010 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
2013 p
= (char *)data
->notify_data
.data
.string
;
2014 SSVAL(p
, 0, st
.year
);
2015 SSVAL(p
, 2, st
.month
);
2016 SSVAL(p
, 4, st
.dayofweek
);
2017 SSVAL(p
, 6, st
.day
);
2018 SSVAL(p
, 8, st
.hour
);
2019 SSVAL(p
, 10, st
.minute
);
2020 SSVAL(p
, 12, st
.second
);
2021 SSVAL(p
, 14, st
.milliseconds
);
2026 struct s_notify_info_data_table
2032 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
2033 print_queue_struct
*queue
,
2034 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
2037 struct s_notify_info_data_table notify_info_data_table
[] =
2039 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", POINTER
, spoolss_notify_server_name
},
2040 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2041 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", POINTER
, spoolss_notify_share_name
},
2042 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2043 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2044 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", POINTER
, spoolss_notify_comment
},
2045 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", POINTER
, spoolss_notify_location
},
2046 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2047 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", POINTER
, spoolss_notify_sepfile
},
2048 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2049 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2050 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2051 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, spoolss_notify_security_desc
},
2052 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE
, spoolss_notify_attributes
},
2053 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2054 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE
, spoolss_notify_default_priority
},
2055 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2056 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2057 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_status
},
2058 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", POINTER
, NULL
},
2059 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", ONE_VALUE
, spoolss_notify_cjobs
},
2060 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE
, spoolss_notify_average_ppm
},
2061 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER
, NULL
},
2062 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER
, NULL
},
2063 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER
, NULL
},
2064 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER
, NULL
},
2065 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2066 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", POINTER
, spoolss_notify_server_name
},
2067 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2068 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", POINTER
, spoolss_notify_username
},
2069 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", POINTER
, spoolss_notify_username
},
2070 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2071 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2072 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2073 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2074 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2075 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_job_status
},
2076 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", POINTER
, spoolss_notify_job_status_string
},
2077 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, NULL
},
2078 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", POINTER
, spoolss_notify_job_name
},
2079 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2080 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", ONE_VALUE
, spoolss_notify_job_position
},
2081 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", POINTER
, spoolss_notify_submitted_time
},
2082 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2083 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2084 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", ONE_VALUE
, spoolss_notify_job_time
},
2085 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE
, NULL
},
2086 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE
, NULL
},
2087 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE
, spoolss_notify_job_size
},
2088 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_BYTES_PRINTED
, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE
, NULL
},
2089 { END
, END
, "", END
, NULL
}
2092 /*******************************************************************
2093 return the size of info_data structure
2094 ********************************************************************/
2095 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
2099 while (notify_info_data_table
[i
].type
!= END
)
2101 if ( (notify_info_data_table
[i
].type
== type
) &&
2102 (notify_info_data_table
[i
].field
== field
) )
2104 return (notify_info_data_table
[i
].size
);
2111 /*******************************************************************
2112 return the type of notify_info_data
2113 ********************************************************************/
2114 static BOOL
type_of_notify_info_data(uint16 type
, uint16 field
)
2118 while (notify_info_data_table
[i
].type
!= END
)
2120 if ( (notify_info_data_table
[i
].type
== type
) &&
2121 (notify_info_data_table
[i
].field
== field
) )
2123 if (notify_info_data_table
[i
].size
== POINTER
)
2137 /****************************************************************************
2138 ****************************************************************************/
2139 static int search_notify(uint16 type
, uint16 field
, int *value
)
2144 for (j
=0, found
=False
; found
==False
&& notify_info_data_table
[j
].type
!= END
; j
++)
2146 if ( (notify_info_data_table
[j
].type
== type
) &&
2147 (notify_info_data_table
[j
].field
== field
) )
2152 if ( found
&& (notify_info_data_table
[j
].fn
!= NULL
) )
2158 /****************************************************************************
2159 ****************************************************************************/
2160 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
2162 info_data
->type
= type
;
2163 info_data
->field
= field
;
2164 info_data
->reserved
= 0;
2166 info_data
->size
= size_of_notify_info_data(type
, field
);
2167 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
2171 /*******************************************************************
2173 * fill a notify_info struct with info asked
2175 ********************************************************************/
2176 static BOOL
construct_notify_printer_info(SPOOL_NOTIFY_INFO
*info
, int
2177 snum
, SPOOL_NOTIFY_OPTION_TYPE
2178 *option_type
, uint32 id
,
2179 TALLOC_CTX
*mem_ctx
)
2185 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
2186 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2187 print_queue_struct
*queue
=NULL
;
2189 type
=option_type
->type
;
2191 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
2192 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2193 option_type
->count
, lp_servicename(snum
)));
2195 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2198 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2199 field
= option_type
->fields
[field_num
];
2200 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
2202 if (!search_notify(type
, field
, &j
) )
2205 if((tid
=(SPOOL_NOTIFY_INFO_DATA
*)Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2206 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
2209 else info
->data
= tid
;
2211 current_data
=&info
->data
[info
->count
];
2213 construct_info_data(current_data
, type
, field
, id
);
2215 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
2216 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
2218 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2224 free_a_printer(&printer
, 2);
2228 /*******************************************************************
2230 * fill a notify_info struct with info asked
2232 ********************************************************************/
2233 static BOOL
construct_notify_jobs_info(print_queue_struct
*queue
,
2234 SPOOL_NOTIFY_INFO
*info
,
2235 NT_PRINTER_INFO_LEVEL
*printer
,
2236 int snum
, SPOOL_NOTIFY_OPTION_TYPE
2237 *option_type
, uint32 id
,
2238 TALLOC_CTX
*mem_ctx
)
2244 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
2246 DEBUG(4,("construct_notify_jobs_info\n"));
2248 type
= option_type
->type
;
2250 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
2251 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2252 option_type
->count
));
2254 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2255 field
= option_type
->fields
[field_num
];
2257 if (!search_notify(type
, field
, &j
) )
2260 if((tid
=Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2261 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
2264 else info
->data
= tid
;
2266 current_data
=&(info
->data
[info
->count
]);
2268 construct_info_data(current_data
, type
, field
, id
);
2269 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2278 * JFM: The enumeration is not that simple, it's even non obvious.
2280 * let's take an example: I want to monitor the PRINTER SERVER for
2281 * the printer's name and the number of jobs currently queued.
2282 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
2283 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
2285 * I have 3 printers on the back of my server.
2287 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
2290 * 1 printer 1 name 1
2291 * 2 printer 1 cjob 1
2292 * 3 printer 2 name 2
2293 * 4 printer 2 cjob 2
2294 * 5 printer 3 name 3
2295 * 6 printer 3 name 3
2297 * that's the print server case, the printer case is even worse.
2300 /*******************************************************************
2302 * enumerate all printers on the printserver
2303 * fill a notify_info struct with info asked
2305 ********************************************************************/
2307 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
2308 SPOOL_NOTIFY_INFO
*info
,
2309 TALLOC_CTX
*mem_ctx
)
2312 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2313 int n_services
=lp_numservices();
2316 SPOOL_NOTIFY_OPTION
*option
;
2317 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2319 DEBUG(4,("printserver_notify_info\n"));
2324 option
=Printer
->notify
.option
;
2330 for (i
=0; i
<option
->count
; i
++) {
2331 option_type
=&(option
->ctr
.type
[i
]);
2333 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
2336 for (snum
=0; snum
<n_services
; snum
++)
2337 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
2338 if (construct_notify_printer_info
2339 (info
, snum
, option_type
, id
, mem_ctx
))
2344 * Debugging information, don't delete.
2347 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2348 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2349 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2351 for (i=0; i<info->count; i++) {
2352 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2353 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2354 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2361 /*******************************************************************
2363 * fill a notify_info struct with info asked
2365 ********************************************************************/
2366 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
2367 TALLOC_CTX
*mem_ctx
)
2370 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2373 SPOOL_NOTIFY_OPTION
*option
;
2374 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2376 print_queue_struct
*queue
=NULL
;
2377 print_status_struct status
;
2379 DEBUG(4,("printer_notify_info\n"));
2384 option
=Printer
->notify
.option
;
2390 get_printer_snum(p
, hnd
, &snum
);
2392 for (i
=0; i
<option
->count
; i
++) {
2393 option_type
=&option
->ctr
.type
[i
];
2395 switch ( option_type
->type
) {
2396 case PRINTER_NOTIFY_TYPE
:
2397 if(construct_notify_printer_info(info
, snum
,
2403 case JOB_NOTIFY_TYPE
: {
2404 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2406 count
= print_queue_status(snum
, &queue
, &status
);
2408 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2,
2409 lp_servicename(snum
))))
2412 for (j
=0; j
<count
; j
++) {
2413 construct_notify_jobs_info(&queue
[j
], info
,
2420 free_a_printer(&printer
, 2);
2430 * Debugging information, don't delete.
2433 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2434 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2435 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2437 for (i=0; i<info->count; i++) {
2438 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2439 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2440 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2446 /********************************************************************
2448 ********************************************************************/
2450 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
2452 POLICY_HND
*handle
= &q_u
->handle
;
2453 /* uint32 change = q_u->change; - notused. */
2454 /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
2455 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
2457 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2458 WERROR result
= WERR_BADFID
;
2460 /* we always have a NOTIFY_INFO struct */
2464 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
2465 OUR_HANDLE(handle
)));
2469 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
2471 /* jfm: the change value isn't used right now.
2472 * we will honour it when
2473 * a) we'll be able to send notification to the client
2474 * b) we'll have a way to communicate between the spoolss process.
2476 * same thing for option->flags
2477 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2478 * I don't have a global notification system, I'm sending back all the
2479 * informations even when _NOTHING_ has changed.
2482 /* just ignore the SPOOL_NOTIFY_OPTION */
2484 switch (Printer
->printer_type
) {
2485 case PRINTER_HANDLE_IS_PRINTSERVER
:
2486 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
2489 case PRINTER_HANDLE_IS_PRINTER
:
2490 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
2498 /********************************************************************
2499 * construct_printer_info_0
2500 * fill a printer_info_0 struct
2501 ********************************************************************/
2502 static BOOL
construct_printer_info_0(PRINTER_INFO_0
*printer
, int snum
)
2506 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2507 counter_printer_0
*session_counter
;
2508 uint32 global_counter
;
2511 print_status_struct status
;
2513 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2516 count
= print_queue_length(snum
, &status
);
2518 /* check if we already have a counter for this printer */
2519 session_counter
= (counter_printer_0
*)ubi_dlFirst(&counter_list
);
2521 for(; session_counter
; session_counter
= (counter_printer_0
*)ubi_dlNext(session_counter
)) {
2522 if (session_counter
->snum
== snum
)
2526 /* it's the first time, add it to the list */
2527 if (session_counter
==NULL
) {
2528 if((session_counter
=(counter_printer_0
*)malloc(sizeof(counter_printer_0
))) == NULL
) {
2529 free_a_printer(&ntprinter
, 2);
2532 ZERO_STRUCTP(session_counter
);
2533 session_counter
->snum
=snum
;
2534 session_counter
->counter
=0;
2535 ubi_dlAddHead( &counter_list
, (ubi_dlNode
*)session_counter
);
2539 session_counter
->counter
++;
2542 * the global_counter should be stored in a TDB as it's common to all the clients
2543 * and should be zeroed on samba startup
2545 global_counter
=session_counter
->counter
;
2547 pstrcpy(chaine
,ntprinter
->info_2
->printername
);
2549 init_unistr(&printer
->printername
, chaine
);
2551 slprintf(chaine
,sizeof(chaine
)-1,"\\\\%s", get_called_name());
2552 init_unistr(&printer
->servername
, chaine
);
2554 printer
->cjobs
= count
;
2555 printer
->total_jobs
= 0;
2556 printer
->total_bytes
= 0;
2558 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
2559 t
=gmtime(&setuptime
);
2561 printer
->year
= t
->tm_year
+1900;
2562 printer
->month
= t
->tm_mon
+1;
2563 printer
->dayofweek
= t
->tm_wday
;
2564 printer
->day
= t
->tm_mday
;
2565 printer
->hour
= t
->tm_hour
;
2566 printer
->minute
= t
->tm_min
;
2567 printer
->second
= t
->tm_sec
;
2568 printer
->milliseconds
= 0;
2570 printer
->global_counter
= global_counter
;
2571 printer
->total_pages
= 0;
2572 printer
->major_version
= 0x0004; /* NT 4 */
2573 printer
->build_version
= 0x0565; /* build 1381 */
2574 printer
->unknown7
= 0x1;
2575 printer
->unknown8
= 0x0;
2576 printer
->unknown9
= 0x0;
2577 printer
->session_counter
= session_counter
->counter
;
2578 printer
->unknown11
= 0x0;
2579 printer
->printer_errors
= 0x0; /* number of print failure */
2580 printer
->unknown13
= 0x0;
2581 printer
->unknown14
= 0x1;
2582 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
2583 printer
->unknown16
= 0x0;
2584 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
2585 printer
->unknown18
= 0x0;
2586 printer
->status
= nt_printq_status(status
.status
);
2587 printer
->unknown20
= 0x0;
2588 printer
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
2589 printer
->unknown22
= 0x0;
2590 printer
->unknown23
= 0x6; /* 6 ???*/
2591 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
2592 printer
->unknown25
= 0;
2593 printer
->unknown26
= 0;
2594 printer
->unknown27
= 0;
2595 printer
->unknown28
= 0;
2596 printer
->unknown29
= 0;
2598 free_a_printer(&ntprinter
,2);
2602 /********************************************************************
2603 * construct_printer_info_1
2604 * fill a printer_info_1 struct
2605 ********************************************************************/
2606 static BOOL
construct_printer_info_1(uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
2610 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2612 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2615 printer
->flags
=flags
;
2617 if (*ntprinter
->info_2
->comment
== '\0') {
2618 init_unistr(&printer
->comment
, lp_comment(snum
));
2619 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",get_called_name(), ntprinter
->info_2
->printername
,
2620 ntprinter
->info_2
->drivername
, lp_comment(snum
));
2623 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2624 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",get_called_name(), ntprinter
->info_2
->printername
,
2625 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
2628 slprintf(chaine2
,sizeof(chaine
)-1,"%s", ntprinter
->info_2
->printername
);
2630 init_unistr(&printer
->description
, chaine
);
2631 init_unistr(&printer
->name
, chaine2
);
2633 free_a_printer(&ntprinter
,2);
2638 /****************************************************************************
2639 Free a DEVMODE struct.
2640 ****************************************************************************/
2642 static void free_dev_mode(DEVICEMODE
*dev
)
2647 SAFE_FREE(dev
->private);
2651 /****************************************************************************
2652 Create a DEVMODE struct. Returns malloced memory.
2653 ****************************************************************************/
2655 static DEVICEMODE
*construct_dev_mode(int snum
)
2659 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2660 NT_DEVICEMODE
*ntdevmode
= NULL
;
2661 DEVICEMODE
*devmode
= NULL
;
2663 DEBUG(7,("construct_dev_mode\n"));
2665 DEBUGADD(8,("getting printer characteristics\n"));
2667 if ((devmode
= (DEVICEMODE
*)malloc(sizeof(DEVICEMODE
))) == NULL
) {
2668 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
2672 ZERO_STRUCTP(devmode
);
2674 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2677 if (printer
->info_2
->devmode
)
2678 ntdevmode
= dup_nt_devicemode(printer
->info_2
->devmode
);
2680 if (ntdevmode
== NULL
)
2683 DEBUGADD(8,("loading DEVICEMODE\n"));
2685 slprintf(adevice
, sizeof(adevice
)-1, printer
->info_2
->printername
);
2686 init_unistr(&devmode
->devicename
, adevice
);
2688 slprintf(aform
, sizeof(aform
)-1, ntdevmode
->formname
);
2689 init_unistr(&devmode
->formname
, aform
);
2691 devmode
->specversion
= ntdevmode
->specversion
;
2692 devmode
->driverversion
= ntdevmode
->driverversion
;
2693 devmode
->size
= ntdevmode
->size
;
2694 devmode
->driverextra
= ntdevmode
->driverextra
;
2695 devmode
->fields
= ntdevmode
->fields
;
2697 devmode
->orientation
= ntdevmode
->orientation
;
2698 devmode
->papersize
= ntdevmode
->papersize
;
2699 devmode
->paperlength
= ntdevmode
->paperlength
;
2700 devmode
->paperwidth
= ntdevmode
->paperwidth
;
2701 devmode
->scale
= ntdevmode
->scale
;
2702 devmode
->copies
= ntdevmode
->copies
;
2703 devmode
->defaultsource
= ntdevmode
->defaultsource
;
2704 devmode
->printquality
= ntdevmode
->printquality
;
2705 devmode
->color
= ntdevmode
->color
;
2706 devmode
->duplex
= ntdevmode
->duplex
;
2707 devmode
->yresolution
= ntdevmode
->yresolution
;
2708 devmode
->ttoption
= ntdevmode
->ttoption
;
2709 devmode
->collate
= ntdevmode
->collate
;
2710 devmode
->icmmethod
= ntdevmode
->icmmethod
;
2711 devmode
->icmintent
= ntdevmode
->icmintent
;
2712 devmode
->mediatype
= ntdevmode
->mediatype
;
2713 devmode
->dithertype
= ntdevmode
->dithertype
;
2715 if (ntdevmode
->private != NULL
) {
2716 if ((devmode
->private=(uint8
*)memdup(ntdevmode
->private, ntdevmode
->driverextra
)) == NULL
)
2720 free_nt_devicemode(&ntdevmode
);
2721 free_a_printer(&printer
,2);
2728 free_nt_devicemode(&ntdevmode
);
2730 free_a_printer(&printer
,2);
2731 free_dev_mode(devmode
);
2736 /********************************************************************
2737 * construct_printer_info_2
2738 * fill a printer_info_2 struct
2739 ********************************************************************/
2741 static BOOL
construct_printer_info_2(PRINTER_INFO_2
*printer
, int snum
)
2744 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2746 print_status_struct status
;
2748 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2751 count
= print_queue_length(snum
, &status
);
2753 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
2754 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
2755 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
2756 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
2757 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
2759 if (*ntprinter
->info_2
->comment
== '\0')
2760 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
2762 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2764 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
2765 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
2766 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
2767 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
2768 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
2770 printer
->attributes
= ntprinter
->info_2
->attributes
;
2772 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
2773 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
2774 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
2775 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
2776 printer
->status
= nt_printq_status(status
.status
); /* status */
2777 printer
->cjobs
= count
; /* jobs */
2778 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
2780 if((printer
->devmode
= construct_dev_mode(snum
)) == NULL
) {
2781 DEBUG(8, ("Returning NULL Devicemode!\n"));
2784 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2785 /* steal the printer info sec_desc structure. [badly done]. */
2786 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2787 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen memory. */
2788 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen memory. */
2789 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen memory. */
2792 printer
->secdesc
= NULL
;
2795 free_a_printer(&ntprinter
, 2);
2799 /********************************************************************
2800 * construct_printer_info_3
2801 * fill a printer_info_3 struct
2802 ********************************************************************/
2803 static BOOL
construct_printer_info_3(PRINTER_INFO_3
**pp_printer
, int snum
)
2805 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2806 PRINTER_INFO_3
*printer
= NULL
;
2808 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2812 if ((printer
= (PRINTER_INFO_3
*)malloc(sizeof(PRINTER_INFO_3
))) == NULL
) {
2813 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
2817 ZERO_STRUCTP(printer
);
2819 printer
->flags
= 4; /* These are the components of the SD we are returning. */
2820 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2821 /* steal the printer info sec_desc structure. [badly done]. */
2822 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2826 * Set the flags for the components we are returning.
2829 if (printer
->secdesc
->owner_sid
)
2830 printer
->flags
|= OWNER_SECURITY_INFORMATION
;
2832 if (printer
->secdesc
->grp_sid
)
2833 printer
->flags
|= GROUP_SECURITY_INFORMATION
;
2835 if (printer
->secdesc
->dacl
)
2836 printer
->flags
|= DACL_SECURITY_INFORMATION
;
2838 if (printer
->secdesc
->sacl
)
2839 printer
->flags
|= SACL_SECURITY_INFORMATION
;
2842 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen the malloced memory. */
2843 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen the malloced memory. */
2844 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen the malloced memory. */
2847 free_a_printer(&ntprinter
, 2);
2849 *pp_printer
= printer
;
2853 /********************************************************************
2854 * construct_printer_info_4
2855 * fill a printer_info_4 struct
2856 ********************************************************************/
2858 static BOOL
construct_printer_info_4(PRINTER_INFO_4
*printer
, int snum
)
2860 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2862 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2865 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
2866 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
2867 printer
->attributes
= ntprinter
->info_2
->attributes
;
2869 free_a_printer(&ntprinter
, 2);
2873 /********************************************************************
2874 * construct_printer_info_5
2875 * fill a printer_info_5 struct
2876 ********************************************************************/
2878 static BOOL
construct_printer_info_5(PRINTER_INFO_5
*printer
, int snum
)
2880 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2882 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
2885 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
2886 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* portname */
2887 printer
->attributes
= ntprinter
->info_2
->attributes
;
2888 printer
->device_not_selected_timeout
= 0x3a98;
2889 printer
->transmission_retry_timeout
= 0xafc8;
2891 free_a_printer(&ntprinter
, 2);
2896 /********************************************************************
2897 Spoolss_enumprinters.
2898 ********************************************************************/
2899 static WERROR
enum_all_printers_info_1(uint32 flags
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2903 int n_services
=lp_numservices();
2904 PRINTER_INFO_1
*tp
, *printers
=NULL
;
2905 PRINTER_INFO_1 current_prt
;
2907 DEBUG(4,("enum_all_printers_info_1\n"));
2909 for (snum
=0; snum
<n_services
; snum
++) {
2910 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
2911 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
2913 if (construct_printer_info_1(flags
, ¤t_prt
, snum
)) {
2914 if((tp
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_1
))) == NULL
) {
2915 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
2916 SAFE_FREE(printers
);
2921 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
2922 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
2928 /* check the required size. */
2929 for (i
=0; i
<*returned
; i
++)
2930 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
2932 if (!alloc_buffer_size(buffer
, *needed
))
2933 return WERR_INSUFFICIENT_BUFFER
;
2935 /* fill the buffer with the structures */
2936 for (i
=0; i
<*returned
; i
++)
2937 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
2940 SAFE_FREE(printers
);
2942 if (*needed
> offered
) {
2944 return WERR_INSUFFICIENT_BUFFER
;
2950 /********************************************************************
2951 enum_all_printers_info_1_local.
2952 *********************************************************************/
2953 static WERROR
enum_all_printers_info_1_local(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2955 DEBUG(4,("enum_all_printers_info_1_local\n"));
2957 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
2960 /********************************************************************
2961 enum_all_printers_info_1_name.
2962 *********************************************************************/
2963 static WERROR
enum_all_printers_info_1_name(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2967 DEBUG(4,("enum_all_printers_info_1_name\n"));
2969 if ((name
[0] == '\\') && (name
[1] == '\\'))
2972 if (is_myname_or_ipaddr(s
)) {
2973 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
2976 return WERR_INVALID_NAME
;
2979 /********************************************************************
2980 enum_all_printers_info_1_remote.
2981 *********************************************************************/
2982 static WERROR
enum_all_printers_info_1_remote(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2984 PRINTER_INFO_1
*printer
;
2985 fstring printername
;
2988 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2990 /* JFM: currently it's more a place holder than anything else.
2991 * In the spooler world there is a notion of server registration.
2992 * the print servers are registring (sp ?) on the PDC (in the same domain)
2994 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2997 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
3002 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name());
3003 slprintf(desc
, sizeof(desc
)-1,"%s", get_called_name());
3004 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
3006 init_unistr(&printer
->description
, desc
);
3007 init_unistr(&printer
->name
, printername
);
3008 init_unistr(&printer
->comment
, comment
);
3009 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
3011 /* check the required size. */
3012 *needed
+= spoolss_size_printer_info_1(printer
);
3014 if (!alloc_buffer_size(buffer
, *needed
)) {
3016 return WERR_INSUFFICIENT_BUFFER
;
3019 /* fill the buffer with the structures */
3020 smb_io_printer_info_1("", buffer
, printer
, 0);
3025 if (*needed
> offered
) {
3027 return WERR_INSUFFICIENT_BUFFER
;
3033 /********************************************************************
3034 enum_all_printers_info_1_network.
3035 *********************************************************************/
3037 static WERROR
enum_all_printers_info_1_network(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
3039 DEBUG(4,("enum_all_printers_info_1_network\n"));
3041 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
3044 /********************************************************************
3045 * api_spoolss_enumprinters
3047 * called from api_spoolss_enumprinters (see this to understand)
3048 ********************************************************************/
3050 static WERROR
enum_all_printers_info_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
3054 int n_services
=lp_numservices();
3055 PRINTER_INFO_2
*tp
, *printers
=NULL
;
3056 PRINTER_INFO_2 current_prt
;
3058 for (snum
=0; snum
<n_services
; snum
++) {
3059 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
3060 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
3062 if (construct_printer_info_2(¤t_prt
, snum
)) {
3063 if((tp
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_2
))) == NULL
) {
3064 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
3065 SAFE_FREE(printers
);
3070 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
));
3071 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
3077 /* check the required size. */
3078 for (i
=0; i
<*returned
; i
++)
3079 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
3081 if (!alloc_buffer_size(buffer
, *needed
)) {
3082 for (i
=0; i
<*returned
; i
++) {
3083 free_devmode(printers
[i
].devmode
);
3085 SAFE_FREE(printers
);
3086 return WERR_INSUFFICIENT_BUFFER
;
3089 /* fill the buffer with the structures */
3090 for (i
=0; i
<*returned
; i
++)
3091 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
3094 for (i
=0; i
<*returned
; i
++) {
3095 free_devmode(printers
[i
].devmode
);
3097 SAFE_FREE(printers
);
3099 if (*needed
> offered
) {
3101 return WERR_INSUFFICIENT_BUFFER
;
3107 /********************************************************************
3108 * handle enumeration of printers at level 1
3109 ********************************************************************/
3110 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
3111 NEW_BUFFER
*buffer
, uint32 offered
,
3112 uint32
*needed
, uint32
*returned
)
3114 /* Not all the flags are equals */
3116 if (flags
& PRINTER_ENUM_LOCAL
)
3117 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
3119 if (flags
& PRINTER_ENUM_NAME
)
3120 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
3122 if (flags
& PRINTER_ENUM_REMOTE
)
3123 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
3125 if (flags
& PRINTER_ENUM_NETWORK
)
3126 return enum_all_printers_info_1_network(buffer
, offered
, needed
, returned
);
3128 return WERR_OK
; /* NT4sp5 does that */
3131 /********************************************************************
3132 * handle enumeration of printers at level 2
3133 ********************************************************************/
3134 static WERROR
enumprinters_level2( uint32 flags
, fstring servername
,
3135 NEW_BUFFER
*buffer
, uint32 offered
,
3136 uint32
*needed
, uint32
*returned
)
3138 char *s
= servername
;
3140 if (flags
& PRINTER_ENUM_LOCAL
) {
3141 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3144 if (flags
& PRINTER_ENUM_NAME
) {
3145 if ((servername
[0] == '\\') && (servername
[1] == '\\'))
3147 if (is_myname_or_ipaddr(s
))
3148 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3150 return WERR_INVALID_NAME
;
3153 if (flags
& PRINTER_ENUM_REMOTE
)
3154 return WERR_UNKNOWN_LEVEL
;
3159 /********************************************************************
3160 * handle enumeration of printers at level 5
3161 ********************************************************************/
3162 static WERROR
enumprinters_level5( uint32 flags
, fstring servername
,
3163 NEW_BUFFER
*buffer
, uint32 offered
,
3164 uint32
*needed
, uint32
*returned
)
3166 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
3170 /********************************************************************
3171 * api_spoolss_enumprinters
3173 * called from api_spoolss_enumprinters (see this to understand)
3174 ********************************************************************/
3176 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
3178 uint32 flags
= q_u
->flags
;
3179 UNISTR2
*servername
= &q_u
->servername
;
3180 uint32 level
= q_u
->level
;
3181 NEW_BUFFER
*buffer
= NULL
;
3182 uint32 offered
= q_u
->offered
;
3183 uint32
*needed
= &r_u
->needed
;
3184 uint32
*returned
= &r_u
->returned
;
3188 /* that's an [in out] buffer */
3189 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3190 buffer
= r_u
->buffer
;
3192 DEBUG(4,("_spoolss_enumprinters\n"));
3199 * flags==PRINTER_ENUM_NAME
3200 * if name=="" then enumerates all printers
3201 * if name!="" then enumerate the printer
3202 * flags==PRINTER_ENUM_REMOTE
3203 * name is NULL, enumerate printers
3204 * Level 2: name!="" enumerates printers, name can't be NULL
3205 * Level 3: doesn't exist
3206 * Level 4: does a local registry lookup
3207 * Level 5: same as Level 2
3210 unistr2_to_ascii(name
, servername
, sizeof(name
)-1);
3215 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
3217 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
3219 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
3224 return WERR_UNKNOWN_LEVEL
;
3227 /****************************************************************************
3228 ****************************************************************************/
3229 static WERROR
getprinter_level_0(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3231 PRINTER_INFO_0
*printer
=NULL
;
3233 if((printer
=(PRINTER_INFO_0
*)malloc(sizeof(PRINTER_INFO_0
))) == NULL
)
3236 construct_printer_info_0(printer
, snum
);
3238 /* check the required size. */
3239 *needed
+= spoolss_size_printer_info_0(printer
);
3241 if (!alloc_buffer_size(buffer
, *needed
)) {
3243 return WERR_INSUFFICIENT_BUFFER
;
3246 /* fill the buffer with the structures */
3247 smb_io_printer_info_0("", buffer
, printer
, 0);
3252 if (*needed
> offered
) {
3253 return WERR_INSUFFICIENT_BUFFER
;
3259 /****************************************************************************
3260 ****************************************************************************/
3261 static WERROR
getprinter_level_1(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3263 PRINTER_INFO_1
*printer
=NULL
;
3265 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
3268 construct_printer_info_1(PRINTER_ENUM_ICON8
, printer
, snum
);
3270 /* check the required size. */
3271 *needed
+= spoolss_size_printer_info_1(printer
);
3273 if (!alloc_buffer_size(buffer
, *needed
)) {
3275 return WERR_INSUFFICIENT_BUFFER
;
3278 /* fill the buffer with the structures */
3279 smb_io_printer_info_1("", buffer
, printer
, 0);
3284 if (*needed
> offered
) {
3285 return WERR_INSUFFICIENT_BUFFER
;
3291 /****************************************************************************
3292 ****************************************************************************/
3293 static WERROR
getprinter_level_2(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3295 PRINTER_INFO_2
*printer
=NULL
;
3297 if((printer
=(PRINTER_INFO_2
*)malloc(sizeof(PRINTER_INFO_2
)))==NULL
)
3300 construct_printer_info_2(printer
, snum
);
3302 /* check the required size. */
3303 *needed
+= spoolss_size_printer_info_2(printer
);
3305 if (!alloc_buffer_size(buffer
, *needed
)) {
3306 free_printer_info_2(printer
);
3307 return WERR_INSUFFICIENT_BUFFER
;
3310 /* fill the buffer with the structures */
3311 if (!smb_io_printer_info_2("", buffer
, printer
, 0)) {
3312 free_printer_info_2(printer
);
3317 free_printer_info_2(printer
);
3319 if (*needed
> offered
) {
3320 return WERR_INSUFFICIENT_BUFFER
;
3326 /****************************************************************************
3327 ****************************************************************************/
3328 static WERROR
getprinter_level_3(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3330 PRINTER_INFO_3
*printer
=NULL
;
3332 if (!construct_printer_info_3(&printer
, snum
))
3335 /* check the required size. */
3336 *needed
+= spoolss_size_printer_info_3(printer
);
3338 if (!alloc_buffer_size(buffer
, *needed
)) {
3339 free_printer_info_3(printer
);
3340 return WERR_INSUFFICIENT_BUFFER
;
3343 /* fill the buffer with the structures */
3344 smb_io_printer_info_3("", buffer
, printer
, 0);
3347 free_printer_info_3(printer
);
3349 if (*needed
> offered
) {
3350 return WERR_INSUFFICIENT_BUFFER
;
3356 /****************************************************************************
3357 ****************************************************************************/
3358 static WERROR
getprinter_level_4(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3360 PRINTER_INFO_4
*printer
=NULL
;
3362 if((printer
=(PRINTER_INFO_4
*)malloc(sizeof(PRINTER_INFO_4
)))==NULL
)
3365 if (!construct_printer_info_4(printer
, snum
))
3368 /* check the required size. */
3369 *needed
+= spoolss_size_printer_info_4(printer
);
3371 if (!alloc_buffer_size(buffer
, *needed
)) {
3372 free_printer_info_4(printer
);
3373 return WERR_INSUFFICIENT_BUFFER
;
3376 /* fill the buffer with the structures */
3377 smb_io_printer_info_4("", buffer
, printer
, 0);
3380 free_printer_info_4(printer
);
3382 if (*needed
> offered
) {
3383 return WERR_INSUFFICIENT_BUFFER
;
3389 /****************************************************************************
3390 ****************************************************************************/
3391 static WERROR
getprinter_level_5(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3393 PRINTER_INFO_5
*printer
=NULL
;
3395 if((printer
=(PRINTER_INFO_5
*)malloc(sizeof(PRINTER_INFO_5
)))==NULL
)
3398 if (!construct_printer_info_5(printer
, snum
))
3401 /* check the required size. */
3402 *needed
+= spoolss_size_printer_info_5(printer
);
3404 if (!alloc_buffer_size(buffer
, *needed
)) {
3405 free_printer_info_5(printer
);
3406 return WERR_INSUFFICIENT_BUFFER
;
3409 /* fill the buffer with the structures */
3410 smb_io_printer_info_5("", buffer
, printer
, 0);
3413 free_printer_info_5(printer
);
3415 if (*needed
> offered
) {
3416 return WERR_INSUFFICIENT_BUFFER
;
3422 /****************************************************************************
3423 ****************************************************************************/
3425 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
3427 POLICY_HND
*handle
= &q_u
->handle
;
3428 uint32 level
= q_u
->level
;
3429 NEW_BUFFER
*buffer
= NULL
;
3430 uint32 offered
= q_u
->offered
;
3431 uint32
*needed
= &r_u
->needed
;
3435 /* that's an [in out] buffer */
3436 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3437 buffer
= r_u
->buffer
;
3441 if (!get_printer_snum(p
, handle
, &snum
))
3446 return getprinter_level_0(snum
, buffer
, offered
, needed
);
3448 return getprinter_level_1(snum
, buffer
, offered
, needed
);
3450 return getprinter_level_2(snum
, buffer
, offered
, needed
);
3452 return getprinter_level_3(snum
, buffer
, offered
, needed
);
3454 return getprinter_level_4(snum
, buffer
, offered
, needed
);
3456 return getprinter_level_5(snum
, buffer
, offered
, needed
);
3458 return WERR_UNKNOWN_LEVEL
;
3461 /********************************************************************
3462 * fill a DRIVER_INFO_1 struct
3463 ********************************************************************/
3464 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
3466 init_unistr( &info
->name
, driver
.info_3
->name
);
3469 /********************************************************************
3470 * construct_printer_driver_info_1
3471 ********************************************************************/
3472 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3474 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3475 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3477 ZERO_STRUCT(driver
);
3479 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3480 return WERR_INVALID_PRINTER_NAME
;
3482 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
3483 return WERR_UNKNOWN_PRINTER_DRIVER
;
3485 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
3487 free_a_printer(&printer
,2);
3492 /********************************************************************
3493 * construct_printer_driver_info_2
3494 * fill a printer_info_2 struct
3495 ********************************************************************/
3496 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3500 info
->version
=driver
.info_3
->cversion
;
3502 init_unistr( &info
->name
, driver
.info_3
->name
);
3503 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3506 if (strlen(driver
.info_3
->driverpath
)) {
3507 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3508 init_unistr( &info
->driverpath
, temp
);
3510 init_unistr( &info
->driverpath
, "" );
3512 if (strlen(driver
.info_3
->datafile
)) {
3513 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3514 init_unistr( &info
->datafile
, temp
);
3516 init_unistr( &info
->datafile
, "" );
3518 if (strlen(driver
.info_3
->configfile
)) {
3519 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3520 init_unistr( &info
->configfile
, temp
);
3522 init_unistr( &info
->configfile
, "" );
3525 /********************************************************************
3526 * construct_printer_driver_info_2
3527 * fill a printer_info_2 struct
3528 ********************************************************************/
3529 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3531 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3532 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3534 ZERO_STRUCT(printer
);
3535 ZERO_STRUCT(driver
);
3537 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3538 return WERR_INVALID_PRINTER_NAME
;
3540 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
3541 return WERR_UNKNOWN_PRINTER_DRIVER
;
3543 fill_printer_driver_info_2(info
, driver
, servername
);
3545 free_a_printer(&printer
,2);
3550 /********************************************************************
3551 * copy a strings array and convert to UNICODE
3553 * convert an array of ascii string to a UNICODE string
3554 ********************************************************************/
3555 static void init_unistr_array(uint16
**uni_array
, fstring
*char_array
, char *servername
)
3563 DEBUG(6,("init_unistr_array\n"));
3567 if (char_array
== NULL
)
3571 if (!v
) v
= ""; /* hack to handle null lists */
3573 if (strlen(v
) == 0) break;
3574 slprintf(line
, sizeof(line
)-1, "\\\\%s%s", servername
, v
);
3575 DEBUGADD(6,("%d:%s:%d\n", i
, line
, strlen(line
)));
3576 if((tuary
=Realloc(*uni_array
, (j
+strlen(line
)+2)*sizeof(uint16
))) == NULL
) {
3577 DEBUG(2,("init_unistr_array: Realloc error\n" ));
3581 j
+= (dos_PutUniCode((char *)(*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
), True
) / sizeof(uint16
) );
3586 (*uni_array
)[j
]=0x0000;
3589 DEBUGADD(6,("last one:done\n"));
3592 /********************************************************************
3593 * construct_printer_info_3
3594 * fill a printer_info_3 struct
3595 ********************************************************************/
3596 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3602 info
->version
=driver
.info_3
->cversion
;
3604 init_unistr( &info
->name
, driver
.info_3
->name
);
3605 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3607 if (strlen(driver
.info_3
->driverpath
)) {
3608 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3609 init_unistr( &info
->driverpath
, temp
);
3611 init_unistr( &info
->driverpath
, "" );
3613 if (strlen(driver
.info_3
->datafile
)) {
3614 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3615 init_unistr( &info
->datafile
, temp
);
3617 init_unistr( &info
->datafile
, "" );
3619 if (strlen(driver
.info_3
->configfile
)) {
3620 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3621 init_unistr( &info
->configfile
, temp
);
3623 init_unistr( &info
->configfile
, "" );
3625 if (strlen(driver
.info_3
->helpfile
)) {
3626 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3627 init_unistr( &info
->helpfile
, temp
);
3629 init_unistr( &info
->helpfile
, "" );
3631 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3632 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3634 info
->dependentfiles
=NULL
;
3635 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3638 /********************************************************************
3639 * construct_printer_info_3
3640 * fill a printer_info_3 struct
3641 ********************************************************************/
3642 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3644 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3645 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3647 ZERO_STRUCT(driver
);
3649 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3650 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status
)));
3651 if (!W_ERROR_IS_OK(status
))
3652 return WERR_INVALID_PRINTER_NAME
;
3654 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3655 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status
)));
3660 * I put this code in during testing. Helpful when commenting out the
3661 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
3662 * as win2k always queries the driver using an infor level of 6.
3663 * I've left it in (but ifdef'd out) because I'll probably
3664 * use it in experimentation again in the future. --jerry 22/01/2002
3667 if (!W_ERROR_IS_OK(status
)) {
3669 * Is this a W2k client ?
3672 /* Yes - try again with a WinNT driver. */
3674 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3675 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status
)));
3679 if (!W_ERROR_IS_OK(status
)) {
3680 free_a_printer(&printer
,2);
3681 return WERR_UNKNOWN_PRINTER_DRIVER
;
3689 fill_printer_driver_info_3(info
, driver
, servername
);
3691 free_a_printer(&printer
,2);
3696 /********************************************************************
3697 * construct_printer_info_6
3698 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
3699 ********************************************************************/
3701 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3707 memset(&nullstr
, '\0', sizeof(fstring
));
3709 info
->version
=driver
.info_3
->cversion
;
3711 init_unistr( &info
->name
, driver
.info_3
->name
);
3712 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3714 if (strlen(driver
.info_3
->driverpath
)) {
3715 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3716 init_unistr( &info
->driverpath
, temp
);
3718 init_unistr( &info
->driverpath
, "" );
3720 if (strlen(driver
.info_3
->datafile
)) {
3721 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3722 init_unistr( &info
->datafile
, temp
);
3724 init_unistr( &info
->datafile
, "" );
3726 if (strlen(driver
.info_3
->configfile
)) {
3727 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3728 init_unistr( &info
->configfile
, temp
);
3730 init_unistr( &info
->configfile
, "" );
3732 if (strlen(driver
.info_3
->helpfile
)) {
3733 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3734 init_unistr( &info
->helpfile
, temp
);
3736 init_unistr( &info
->helpfile
, "" );
3738 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3739 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3741 info
->dependentfiles
=NULL
;
3742 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3744 info
->previousdrivernames
=NULL
;
3745 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
3747 info
->driver_date
.low
=0;
3748 info
->driver_date
.high
=0;
3751 info
->driver_version_low
=0;
3752 info
->driver_version_high
=0;
3754 init_unistr( &info
->mfgname
, "");
3755 init_unistr( &info
->oem_url
, "");
3756 init_unistr( &info
->hardware_id
, "");
3757 init_unistr( &info
->provider
, "");
3760 /********************************************************************
3761 * construct_printer_info_6
3762 * fill a printer_info_6 struct
3763 ********************************************************************/
3764 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3766 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3767 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3769 ZERO_STRUCT(driver
);
3771 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3772 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3773 if (!W_ERROR_IS_OK(status
))
3774 return WERR_INVALID_PRINTER_NAME
;
3776 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3777 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3778 if (!W_ERROR_IS_OK(status
)) {
3780 * Is this a W2k client ?
3784 free_a_printer(&printer
,2);
3785 return WERR_UNKNOWN_PRINTER_DRIVER
;
3788 /* Yes - try again with a WinNT driver. */
3790 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3791 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status
)));
3792 if (!W_ERROR_IS_OK(status
)) {
3793 free_a_printer(&printer
,2);
3794 return WERR_UNKNOWN_PRINTER_DRIVER
;
3798 fill_printer_driver_info_6(info
, driver
, servername
);
3800 free_a_printer(&printer
,2);
3805 /****************************************************************************
3806 ****************************************************************************/
3808 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
3810 SAFE_FREE(info
->dependentfiles
);
3813 /****************************************************************************
3814 ****************************************************************************/
3816 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
3818 SAFE_FREE(info
->dependentfiles
);
3822 /****************************************************************************
3823 ****************************************************************************/
3824 static WERROR
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3826 DRIVER_INFO_1
*info
=NULL
;
3829 if((info
=(DRIVER_INFO_1
*)malloc(sizeof(DRIVER_INFO_1
))) == NULL
)
3832 status
=construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
3833 if (!W_ERROR_IS_OK(status
)) {
3838 /* check the required size. */
3839 *needed
+= spoolss_size_printer_driver_info_1(info
);
3841 if (!alloc_buffer_size(buffer
, *needed
)) {
3843 return WERR_INSUFFICIENT_BUFFER
;
3846 /* fill the buffer with the structures */
3847 smb_io_printer_driver_info_1("", buffer
, info
, 0);
3852 if (*needed
> offered
)
3853 return WERR_INSUFFICIENT_BUFFER
;
3858 /****************************************************************************
3859 ****************************************************************************/
3860 static WERROR
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3862 DRIVER_INFO_2
*info
=NULL
;
3865 if((info
=(DRIVER_INFO_2
*)malloc(sizeof(DRIVER_INFO_2
))) == NULL
)
3868 status
=construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
3869 if (!W_ERROR_IS_OK(status
)) {
3874 /* check the required size. */
3875 *needed
+= spoolss_size_printer_driver_info_2(info
);
3877 if (!alloc_buffer_size(buffer
, *needed
)) {
3879 return WERR_INSUFFICIENT_BUFFER
;
3882 /* fill the buffer with the structures */
3883 smb_io_printer_driver_info_2("", buffer
, info
, 0);
3888 if (*needed
> offered
)
3889 return WERR_INSUFFICIENT_BUFFER
;
3894 /****************************************************************************
3895 ****************************************************************************/
3896 static WERROR
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3903 status
=construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
3904 if (!W_ERROR_IS_OK(status
)) {
3908 /* check the required size. */
3909 *needed
+= spoolss_size_printer_driver_info_3(&info
);
3911 if (!alloc_buffer_size(buffer
, *needed
)) {
3912 free_printer_driver_info_3(&info
);
3913 return WERR_INSUFFICIENT_BUFFER
;
3916 /* fill the buffer with the structures */
3917 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
3919 free_printer_driver_info_3(&info
);
3921 if (*needed
> offered
)
3922 return WERR_INSUFFICIENT_BUFFER
;
3927 /****************************************************************************
3928 ****************************************************************************/
3929 static WERROR
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3936 status
=construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
3937 if (!W_ERROR_IS_OK(status
)) {
3941 /* check the required size. */
3942 *needed
+= spoolss_size_printer_driver_info_6(&info
);
3944 if (!alloc_buffer_size(buffer
, *needed
)) {
3945 free_printer_driver_info_6(&info
);
3946 return WERR_INSUFFICIENT_BUFFER
;
3949 /* fill the buffer with the structures */
3950 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
3952 free_printer_driver_info_6(&info
);
3954 if (*needed
> offered
)
3955 return WERR_INSUFFICIENT_BUFFER
;
3960 /****************************************************************************
3961 ****************************************************************************/
3963 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
3965 POLICY_HND
*handle
= &q_u
->handle
;
3966 UNISTR2
*uni_arch
= &q_u
->architecture
;
3967 uint32 level
= q_u
->level
;
3968 uint32 clientmajorversion
= q_u
->clientmajorversion
;
3969 /* uint32 clientminorversion = q_u->clientminorversion; - notused. */
3970 NEW_BUFFER
*buffer
= NULL
;
3971 uint32 offered
= q_u
->offered
;
3972 uint32
*needed
= &r_u
->needed
;
3973 uint32
*servermajorversion
= &r_u
->servermajorversion
;
3974 uint32
*serverminorversion
= &r_u
->serverminorversion
;
3977 fstring architecture
;
3980 /* that's an [in out] buffer */
3981 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3982 buffer
= r_u
->buffer
;
3984 DEBUG(4,("_spoolss_getprinterdriver2\n"));
3987 *servermajorversion
=0;
3988 *serverminorversion
=0;
3990 pstrcpy(servername
, get_called_name());
3991 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
)-1);
3993 if (!get_printer_snum(p
, handle
, &snum
))
3998 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
4000 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
4002 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
4004 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
4007 return WERR_UNKNOWN_LEVEL
;
4010 /****************************************************************************
4011 ****************************************************************************/
4013 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
4015 POLICY_HND
*handle
= &q_u
->handle
;
4017 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4020 DEBUG(3,("Error in startpageprinter printer handle\n"));
4024 Printer
->page_started
=True
;
4028 /****************************************************************************
4029 ****************************************************************************/
4031 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
4033 POLICY_HND
*handle
= &q_u
->handle
;
4035 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4038 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle
)));
4042 Printer
->page_started
=False
;
4047 /********************************************************************
4048 * api_spoolss_getprinter
4049 * called from the spoolss dispatcher
4051 ********************************************************************/
4053 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
4055 POLICY_HND
*handle
= &q_u
->handle
;
4056 /* uint32 level = q_u->doc_info_container.level; - notused. */
4057 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
4058 uint32
*jobid
= &r_u
->jobid
;
4060 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
4064 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4065 struct current_user user
;
4068 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
4072 get_current_user(&user
, p
);
4075 * a nice thing with NT is it doesn't listen to what you tell it.
4076 * when asked to send _only_ RAW datas, it tries to send datas
4079 * So I add checks like in NT Server ...
4081 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
4082 * there's a bug in NT client-side code, so we'll fix it in the
4083 * server-side code. *nnnnnggggh!*
4086 if (info_1
->p_datatype
!= 0) {
4087 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
4088 if (strcmp(datatype
, "RAW") != 0) {
4090 return WERR_INVALID_DATATYPE
;
4094 /* get the share number of the printer */
4095 if (!get_printer_snum(p
, handle
, &snum
)) {
4099 unistr2_to_ascii(jobname
, &info_1
->docname
, sizeof(jobname
));
4101 Printer
->jobid
= print_job_start(&user
, snum
, jobname
);
4103 /* An error occured in print_job_start() so return an appropriate
4106 if (Printer
->jobid
== -1) {
4107 return map_werror_from_unix(errno
);
4110 Printer
->document_started
=True
;
4111 (*jobid
) = Printer
->jobid
;
4116 /********************************************************************
4117 * api_spoolss_getprinter
4118 * called from the spoolss dispatcher
4120 ********************************************************************/
4122 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
4124 POLICY_HND
*handle
= &q_u
->handle
;
4126 return _spoolss_enddocprinter_internal(p
, handle
);
4129 /****************************************************************************
4130 ****************************************************************************/
4132 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
4134 POLICY_HND
*handle
= &q_u
->handle
;
4135 uint32 buffer_size
= q_u
->buffer_size
;
4136 uint8
*buffer
= q_u
->buffer
;
4137 uint32
*buffer_written
= &q_u
->buffer_size2
;
4139 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4142 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
4143 r_u
->buffer_written
= q_u
->buffer_size2
;
4147 (*buffer_written
) = print_job_write(Printer
->jobid
, (char *)buffer
, buffer_size
);
4150 r_u
->buffer_written
= q_u
->buffer_size2
;
4155 /********************************************************************
4156 * api_spoolss_getprinter
4157 * called from the spoolss dispatcher
4159 ********************************************************************/
4160 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
4163 struct current_user user
;
4165 WERROR errcode
= WERR_BADFUNC
;
4166 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4168 get_current_user(&user
, p
);
4171 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
4175 if (!get_printer_snum(p
, handle
, &snum
))
4179 case PRINTER_CONTROL_PAUSE
:
4180 if (print_queue_pause(&user
, snum
, &errcode
)) {
4184 case PRINTER_CONTROL_RESUME
:
4185 case PRINTER_CONTROL_UNPAUSE
:
4186 if (print_queue_resume(&user
, snum
, &errcode
)) {
4190 case PRINTER_CONTROL_PURGE
:
4191 if (print_queue_purge(&user
, snum
, &errcode
)) {
4196 return WERR_UNKNOWN_LEVEL
;
4202 /********************************************************************
4203 * api_spoolss_abortprinter
4204 ********************************************************************/
4206 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
4208 POLICY_HND
*handle
= &q_u
->handle
;
4210 return control_printer(handle
, PRINTER_CONTROL_PURGE
, p
);
4213 /********************************************************************
4214 * called by spoolss_api_setprinter
4215 * when updating a printer description
4216 ********************************************************************/
4217 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
4218 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4219 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
4221 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
4222 struct current_user user
;
4226 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4228 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
)) {
4229 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
4230 OUR_HANDLE(handle
)));
4232 result
= WERR_BADFID
;
4236 /* NT seems to like setting the security descriptor even though
4237 nothing may have actually changed. This causes annoying
4238 dialog boxes when the user doesn't have permission to change
4239 the security descriptor. */
4241 nt_printing_getsec(p
->mem_ctx
, Printer
->dev
.handlename
, &old_secdesc_ctr
);
4243 if (DEBUGLEVEL
>= 10) {
4247 the_acl
= old_secdesc_ctr
->sec
->dacl
;
4248 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
4249 PRINTERNAME(snum
), the_acl
->num_aces
));
4251 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4254 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
4256 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4257 the_acl
->ace
[i
].info
.mask
));
4260 the_acl
= secdesc_ctr
->sec
->dacl
;
4263 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4264 PRINTERNAME(snum
), the_acl
->num_aces
));
4266 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4269 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
4271 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4272 the_acl
->ace
[i
].info
.mask
));
4275 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
4279 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
4281 if (sec_desc_equal(new_secdesc_ctr
->sec
, old_secdesc_ctr
->sec
)) {
4286 /* Work out which user is performing the operation */
4288 get_current_user(&user
, p
);
4290 /* Check the user has permissions to change the security
4291 descriptor. By experimentation with two NT machines, the user
4292 requires Full Access to the printer to change security
4295 if (!print_access_check(&user
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4296 result
= WERR_ACCESS_DENIED
;
4300 result
= nt_printing_setsec(Printer
->dev
.handlename
, new_secdesc_ctr
);
4307 /********************************************************************
4308 Do Samba sanity checks on a printer info struct.
4309 this has changed purpose: it now "canonicalises" printer
4310 info from a client rather than just checking it is correct
4311 ********************************************************************/
4313 static BOOL
check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
4315 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
4316 info
->servername
, info
->printername
, info
->sharename
, info
->portname
, info
->drivername
, info
->comment
, info
->location
));
4318 /* we force some elements to "correct" values */
4319 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", get_called_name());
4320 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
4321 get_called_name(), lp_servicename(snum
));
4322 fstrcpy(info
->sharename
, lp_servicename(snum
));
4323 info
->attributes
= PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
;
4328 /****************************************************************************
4329 ****************************************************************************/
4330 static BOOL
add_printer_hook(NT_PRINTER_INFO_LEVEL
*printer
)
4332 char *cmd
= lp_addprinter_cmd();
4335 pstring driverlocation
;
4339 fstring remote_machine
= "%m";
4341 /* build driver path... only 9X architecture is needed for legacy reasons */
4342 slprintf(driverlocation
, sizeof(driverlocation
)-1, "\\\\%s\\print$\\WIN40\\0",
4344 /* change \ to \\ for the shell */
4345 all_string_sub(driverlocation
,"\\","\\\\",sizeof(pstring
));
4347 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4348 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
4349 printer
->info_2
->portname
, printer
->info_2
->drivername
,
4350 printer
->info_2
->location
, driverlocation
, remote_machine
);
4352 /* Convert script args to unix-codepage */
4353 dos_to_unix(command
, True
);
4354 DEBUG(10,("Running [%s]\n", command
));
4355 ret
= smbrun(command
, &fd
);
4356 DEBUGADD(10,("returned [%d]\n", ret
));
4365 /* Get lines and convert them back to dos-codepage */
4366 qlines
= fd_lines_load(fd
, &numlines
, True
);
4367 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
4371 /* Set the portname to what the script says the portname should be. */
4372 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
4373 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
4375 /* Send SIGHUP to process group... is there a better way? */
4380 file_lines_free(qlines
);
4386 /* Return true if two devicemodes are equal */
4388 #define DEVMODE_CHECK_INT(field) \
4389 if (d1->field != d2->field) { \
4390 DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
4391 d1->field, d2->field)); \
4395 /************************************************************************
4396 Handy, but currently unused functions
4397 ***********************************************************************/
4399 static BOOL
nt_devicemode_equal(NT_DEVICEMODE
*d1
, NT_DEVICEMODE
*d2
)
4401 if (!d1
&& !d2
) goto equal
; /* if both are NULL they are equal */
4404 DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
4405 return False
; /* if either is exclusively NULL are not equal */
4408 if (!strequal(d1
->devicename
, d2
->devicename
)) {
4409 DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1
->devicename
, d2
->devicename
));
4413 if (!strequal(d1
->formname
, d2
->formname
)) {
4414 DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1
->formname
, d2
->formname
));
4418 DEVMODE_CHECK_INT(specversion
);
4419 DEVMODE_CHECK_INT(driverversion
);
4420 DEVMODE_CHECK_INT(driverextra
);
4421 DEVMODE_CHECK_INT(orientation
);
4422 DEVMODE_CHECK_INT(papersize
);
4423 DEVMODE_CHECK_INT(paperlength
);
4424 DEVMODE_CHECK_INT(paperwidth
);
4425 DEVMODE_CHECK_INT(scale
);
4426 DEVMODE_CHECK_INT(copies
);
4427 DEVMODE_CHECK_INT(defaultsource
);
4428 DEVMODE_CHECK_INT(printquality
);
4429 DEVMODE_CHECK_INT(color
);
4430 DEVMODE_CHECK_INT(duplex
);
4431 DEVMODE_CHECK_INT(yresolution
);
4432 DEVMODE_CHECK_INT(ttoption
);
4433 DEVMODE_CHECK_INT(collate
);
4434 DEVMODE_CHECK_INT(logpixels
);
4436 DEVMODE_CHECK_INT(fields
);
4437 DEVMODE_CHECK_INT(bitsperpel
);
4438 DEVMODE_CHECK_INT(pelswidth
);
4439 DEVMODE_CHECK_INT(pelsheight
);
4440 DEVMODE_CHECK_INT(displayflags
);
4441 DEVMODE_CHECK_INT(displayfrequency
);
4442 DEVMODE_CHECK_INT(icmmethod
);
4443 DEVMODE_CHECK_INT(icmintent
);
4444 DEVMODE_CHECK_INT(mediatype
);
4445 DEVMODE_CHECK_INT(dithertype
);
4446 DEVMODE_CHECK_INT(reserved1
);
4447 DEVMODE_CHECK_INT(reserved2
);
4448 DEVMODE_CHECK_INT(panningwidth
);
4449 DEVMODE_CHECK_INT(panningheight
);
4451 /* compare the private data if it exists */
4452 if (!d1
->driverextra
&& !d2
->driverextra
) goto equal
;
4455 DEVMODE_CHECK_INT(driverextra
);
4457 if (memcmp(d1
->private, d2
->private, d1
->driverextra
)) {
4458 DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
4463 DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
4467 /* Return true if two NT_PRINTER_PARAM structures are equal */
4469 static BOOL
nt_printer_param_equal(NT_PRINTER_PARAM
*p1
,
4470 NT_PRINTER_PARAM
*p2
)
4472 if (!p1
&& !p2
) goto equal
;
4474 if ((!p1
&& p2
) || (p1
&& !p2
)) {
4475 DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
4479 /* Compare lists of printer parameters */
4483 NT_PRINTER_PARAM
*q
= p1
;
4485 /* Find the parameter in the second structure */
4489 if (strequal(p1
->value
, q
->value
)) {
4491 if (p1
->type
!= q
->type
) {
4492 DEBUG(10, ("nt_printer_param_equal():"
4493 "types for %s differ (%d != %d)\n",
4494 p1
->value
, p1
->type
,
4499 if (p1
->data_len
!= q
->data_len
) {
4500 DEBUG(10, ("nt_printer_param_equal():"
4501 "len for %s differs (%d != %d)\n",
4502 p1
->value
, p1
->data_len
,
4507 if (memcmp(p1
->data
, q
->data
, p1
->data_len
) == 0) {
4510 DEBUG(10, ("nt_printer_param_equal():"
4511 "data for %s differs\n", p1
->value
));
4521 DEBUG(10, ("nt_printer_param_equal(): param %s "
4522 "does not exist\n", p1
->value
));
4531 DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
4535 /********************************************************************
4536 * Called by update_printer when trying to work out whether to
4537 * actually update printer info.
4538 ********************************************************************/
4540 #define PI_CHECK_INT(field) \
4541 if (pi1->field != pi2->field) { \
4542 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
4543 pi1->field, pi2->field)); \
4547 #define PI_CHECK_STR(field) \
4548 if (!strequal(pi1->field, pi2->field)) { \
4549 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
4550 pi1->field, pi2->field)); \
4554 static BOOL
nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL
*p1
,
4555 NT_PRINTER_INFO_LEVEL
*p2
)
4557 NT_PRINTER_INFO_LEVEL_2
*pi1
, *pi2
;
4559 /* Trivial conditions */
4561 if ((!p1
&& !p2
) || (!p1
->info_2
&& !p2
->info_2
)) {
4565 if ((!p1
&& p2
) || (p1
&& !p2
) ||
4566 (!p1
->info_2
&& p2
->info_2
) ||
4567 (p1
->info_2
&& !p2
->info_2
)) {
4568 DEBUG(10, ("nt_printer_info_level_equal(): info levels "
4573 /* Compare two nt_printer_info_level structures. Don't compare
4574 status or cjobs as they seem to have something to do with the
4580 /* Don't check the attributes as we stomp on the value in
4581 check_printer_ok() anyway. */
4584 PI_CHECK_INT(attributes
);
4587 PI_CHECK_INT(priority
);
4588 PI_CHECK_INT(default_priority
);
4589 PI_CHECK_INT(starttime
);
4590 PI_CHECK_INT(untiltime
);
4591 PI_CHECK_INT(averageppm
);
4593 /* Yuck - don't check the printername or servername as the
4594 mod_a_printer() code plays games with them. You can't
4595 change the printername or the sharename through this interface
4598 PI_CHECK_STR(sharename
);
4599 PI_CHECK_STR(portname
);
4600 PI_CHECK_STR(drivername
);
4601 PI_CHECK_STR(comment
);
4602 PI_CHECK_STR(location
);
4604 if (!nt_devicemode_equal(pi1
->devmode
, pi2
->devmode
)) {
4608 PI_CHECK_STR(sepfile
);
4609 PI_CHECK_STR(printprocessor
);
4610 PI_CHECK_STR(datatype
);
4611 PI_CHECK_STR(parameters
);
4613 if (!nt_printer_param_equal(pi1
->specific
, pi2
->specific
)) {
4617 if (!sec_desc_equal(pi1
->secdesc_buf
->sec
, pi2
->secdesc_buf
->sec
)) {
4621 PI_CHECK_INT(changeid
);
4622 PI_CHECK_INT(c_setprinter
);
4623 PI_CHECK_INT(setuptime
);
4626 DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
4632 /********************************************************************
4633 * Called by spoolss_api_setprinter
4634 * when updating a printer description.
4635 ********************************************************************/
4637 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
4638 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4639 DEVICEMODE
*devmode
)
4642 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
4643 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4646 DEBUG(8,("update_printer\n"));
4651 DEBUG(0,("update_printer: Send a mail to samba@samba.org\n"));
4652 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
4653 result
= WERR_UNKNOWN_LEVEL
;
4658 result
= WERR_BADFID
;
4662 if (!get_printer_snum(p
, handle
, &snum
)) {
4663 result
= WERR_BADFID
;
4667 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))) ||
4668 (!W_ERROR_IS_OK(get_a_printer(&old_printer
, 2, lp_servicename(snum
))))) {
4669 result
= WERR_BADFID
;
4673 DEBUGADD(8,("Converting info_2 struct\n"));
4676 * convert_printer_info converts the incoming
4677 * info from the client and overwrites the info
4678 * just read from the tdb in the pointer 'printer'.
4681 if (!convert_printer_info(info
, printer
, level
)) {
4682 result
= WERR_NOMEM
;
4686 if (info
->info_2
->devmode_ptr
!= 0) {
4687 /* we have a valid devmode
4688 convert it and link it*/
4690 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
4691 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
4692 &printer
->info_2
->devmode
)) {
4693 result
= WERR_NOMEM
;
4698 /* Do sanity check on the requested changes for Samba */
4700 if (!check_printer_ok(printer
->info_2
, snum
)) {
4701 result
= WERR_INVALID_PARAM
;
4708 * Another one of those historical misunderstandings...
4709 * This is reminisent of a similar call we had in _spoolss_setprinterdata()
4710 * I'm leaving it here as a reminder. --jerry
4713 if (nt_printer_info_level_equal(printer
, old_printer
)) {
4714 DEBUG(3, ("update_printer: printer info has not changed\n"));
4721 /* Check calling user has permission to update printer description */
4723 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4724 DEBUG(3, ("update_printer: printer property change denied by security descriptor\n"));
4725 result
= WERR_ACCESS_DENIED
;
4729 /* Call addprinter hook */
4731 if (*lp_addprinter_cmd()) {
4732 if ( !add_printer_hook(printer
) ) {
4733 result
= WERR_ACCESS_DENIED
;
4739 * Set the DRIVER_INIT info in the tdb; trigger on magic value for the
4740 * DEVMODE.displayfrequency, which is not used for printer drivers. This
4741 * requires Win32 client code (see other notes elsewhere in the code).
4743 if (printer
->info_2
->devmode
&&
4744 printer
->info_2
->devmode
->displayfrequency
== MAGIC_DISPLAY_FREQUENCY
) {
4746 DEBUG(10,("update_printer: Save printer driver init data\n"));
4747 printer
->info_2
->devmode
->displayfrequency
= 0;
4749 if (update_driver_init(*printer
, 2)!=0) {
4750 DEBUG(10,("update_printer: error updating printer driver init DEVMODE\n"));
4751 result
= WERR_ACCESS_DENIED
;
4756 * When a *new* driver is bound to a printer, the drivername is used to
4757 * lookup previously saved driver initialization info, which is then
4758 * bound to the printer, simulating what happens in the Windows arch.
4760 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
4761 set_driver_init(printer
, 2);
4764 /* Update printer info */
4765 result
= mod_a_printer(*printer
, 2);
4768 free_a_printer(&printer
, 2);
4769 free_a_printer(&old_printer
, 2);
4771 srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER
);
4776 /****************************************************************************
4777 ****************************************************************************/
4779 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
4781 POLICY_HND
*handle
= &q_u
->handle
;
4782 uint32 level
= q_u
->level
;
4783 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
4784 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
4785 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
4786 uint32 command
= q_u
->command
;
4788 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4791 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
4795 /* check the level */
4798 return control_printer(handle
, command
, p
);
4800 return update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
4802 return update_printer_sec(handle
, level
, info
, p
,
4805 return WERR_UNKNOWN_LEVEL
;
4809 /****************************************************************************
4810 ****************************************************************************/
4812 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
4814 POLICY_HND
*handle
= &q_u
->handle
;
4816 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4819 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
4823 if (Printer
->notify
.client_connected
==True
)
4824 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
4826 Printer
->notify
.flags
=0;
4827 Printer
->notify
.options
=0;
4828 Printer
->notify
.localmachine
[0]='\0';
4829 Printer
->notify
.printerlocal
=0;
4830 if (Printer
->notify
.option
)
4831 free_spool_notify_option(&Printer
->notify
.option
);
4832 Printer
->notify
.client_connected
=False
;
4837 /****************************************************************************
4838 ****************************************************************************/
4840 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
4842 /* that's an [in out] buffer (despite appearences to the contrary) */
4843 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4846 return WERR_INVALID_PARAM
; /* this is what a NT server
4847 returns for AddJob. AddJob
4848 must fail on non-local
4852 /****************************************************************************
4853 ****************************************************************************/
4854 static void fill_job_info_1(JOB_INFO_1
*job_info
, print_queue_struct
*queue
,
4855 int position
, int snum
)
4861 t
=gmtime(&queue
->time
);
4862 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", get_called_name());
4864 job_info
->jobid
=queue
->job
;
4865 init_unistr(&job_info
->printername
, lp_servicename(snum
));
4866 init_unistr(&job_info
->machinename
, temp_name
);
4867 init_unistr(&job_info
->username
, queue
->user
);
4868 init_unistr(&job_info
->document
, queue
->file
);
4869 init_unistr(&job_info
->datatype
, "RAW");
4870 init_unistr(&job_info
->text_status
, "");
4871 job_info
->status
=nt_printj_status(queue
->status
);
4872 job_info
->priority
=queue
->priority
;
4873 job_info
->position
=position
;
4874 job_info
->totalpages
=0;
4875 job_info
->pagesprinted
=0;
4877 make_systemtime(&job_info
->submitted
, t
);
4880 /****************************************************************************
4881 ****************************************************************************/
4882 static BOOL
fill_job_info_2(JOB_INFO_2
*job_info
, print_queue_struct
*queue
,
4883 int position
, int snum
,
4884 NT_PRINTER_INFO_LEVEL
*ntprinter
)
4890 t
=gmtime(&queue
->time
);
4891 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", get_called_name());
4893 job_info
->jobid
=queue
->job
;
4895 slprintf(chaine
, sizeof(chaine
)-1, "\\\\%s\\%s", get_called_name(), ntprinter
->info_2
->printername
);
4897 init_unistr(&job_info
->printername
, chaine
);
4899 init_unistr(&job_info
->machinename
, temp_name
);
4900 init_unistr(&job_info
->username
, queue
->user
);
4901 init_unistr(&job_info
->document
, queue
->file
);
4902 init_unistr(&job_info
->notifyname
, queue
->user
);
4903 init_unistr(&job_info
->datatype
, "RAW");
4904 init_unistr(&job_info
->printprocessor
, "winprint");
4905 init_unistr(&job_info
->parameters
, "");
4906 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
4907 init_unistr(&job_info
->text_status
, "");
4909 /* and here the security descriptor */
4911 job_info
->status
=nt_printj_status(queue
->status
);
4912 job_info
->priority
=queue
->priority
;
4913 job_info
->position
=position
;
4914 job_info
->starttime
=0;
4915 job_info
->untiltime
=0;
4916 job_info
->totalpages
=0;
4917 job_info
->size
=queue
->size
;
4918 make_systemtime(&(job_info
->submitted
), t
);
4919 job_info
->timeelapsed
=0;
4920 job_info
->pagesprinted
=0;
4922 if((job_info
->devmode
= construct_dev_mode(snum
)) == NULL
) {
4929 /****************************************************************************
4930 Enumjobs at level 1.
4931 ****************************************************************************/
4932 static WERROR
enumjobs_level1(print_queue_struct
*queue
, int snum
,
4933 NEW_BUFFER
*buffer
, uint32 offered
,
4934 uint32
*needed
, uint32
*returned
)
4939 info
=(JOB_INFO_1
*)malloc(*returned
*sizeof(JOB_INFO_1
));
4946 for (i
=0; i
<*returned
; i
++)
4947 fill_job_info_1(&info
[i
], &queue
[i
], i
, snum
);
4951 /* check the required size. */
4952 for (i
=0; i
<*returned
; i
++)
4953 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
4955 if (!alloc_buffer_size(buffer
, *needed
)) {
4957 return WERR_INSUFFICIENT_BUFFER
;
4960 /* fill the buffer with the structures */
4961 for (i
=0; i
<*returned
; i
++)
4962 smb_io_job_info_1("", buffer
, &info
[i
], 0);
4967 if (*needed
> offered
) {
4969 return WERR_INSUFFICIENT_BUFFER
;
4975 /****************************************************************************
4976 Enumjobs at level 2.
4977 ****************************************************************************/
4978 static WERROR
enumjobs_level2(print_queue_struct
*queue
, int snum
,
4979 NEW_BUFFER
*buffer
, uint32 offered
,
4980 uint32
*needed
, uint32
*returned
)
4982 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4987 info
=(JOB_INFO_2
*)malloc(*returned
*sizeof(JOB_INFO_2
));
4993 result
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
4994 if (!W_ERROR_IS_OK(result
)) {
4999 for (i
=0; i
<*returned
; i
++)
5000 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
);
5002 free_a_printer(&ntprinter
, 2);
5005 /* check the required size. */
5006 for (i
=0; i
<*returned
; i
++)
5007 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
5009 if (!alloc_buffer_size(buffer
, *needed
)) {
5011 return WERR_INSUFFICIENT_BUFFER
;
5014 /* fill the buffer with the structures */
5015 for (i
=0; i
<*returned
; i
++)
5016 smb_io_job_info_2("", buffer
, &info
[i
], 0);
5019 for (i
= 0; i
< *returned
; i
++)
5020 free_job_info_2(&info
[i
]);
5024 if (*needed
> offered
) {
5026 return WERR_INSUFFICIENT_BUFFER
;
5032 /****************************************************************************
5034 ****************************************************************************/
5036 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
5038 POLICY_HND
*handle
= &q_u
->handle
;
5039 /* uint32 firstjob = q_u->firstjob; - notused. */
5040 /* uint32 numofjobs = q_u->numofjobs; - notused. */
5041 uint32 level
= q_u
->level
;
5042 NEW_BUFFER
*buffer
= NULL
;
5043 uint32 offered
= q_u
->offered
;
5044 uint32
*needed
= &r_u
->needed
;
5045 uint32
*returned
= &r_u
->returned
;
5048 print_status_struct prt_status
;
5049 print_queue_struct
*queue
=NULL
;
5051 /* that's an [in out] buffer */
5052 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5053 buffer
= r_u
->buffer
;
5055 DEBUG(4,("_spoolss_enumjobs\n"));
5060 if (!get_printer_snum(p
, handle
, &snum
))
5063 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
5064 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
5066 if (*returned
== 0) {
5073 return enumjobs_level1(queue
, snum
, buffer
, offered
, needed
, returned
);
5075 return enumjobs_level2(queue
, snum
, buffer
, offered
, needed
, returned
);
5079 return WERR_UNKNOWN_LEVEL
;
5083 /****************************************************************************
5084 ****************************************************************************/
5086 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
5091 /****************************************************************************
5092 ****************************************************************************/
5094 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
5096 POLICY_HND
*handle
= &q_u
->handle
;
5097 uint32 jobid
= q_u
->jobid
;
5098 /* uint32 level = q_u->level; - notused. */
5099 /* JOB_INFO *ctr = &q_u->ctr; - notused. */
5100 uint32 command
= q_u
->command
;
5102 struct current_user user
;
5104 WERROR errcode
= WERR_BADFUNC
;
5106 if (!get_printer_snum(p
, handle
, &snum
)) {
5110 if (!print_job_exists(jobid
)) {
5111 return WERR_INVALID_PRINTER_NAME
;
5114 get_current_user(&user
, p
);
5117 case JOB_CONTROL_CANCEL
:
5118 case JOB_CONTROL_DELETE
:
5119 if (print_job_delete(&user
, jobid
, &errcode
)) {
5123 case JOB_CONTROL_PAUSE
:
5124 if (print_job_pause(&user
, jobid
, &errcode
)) {
5128 case JOB_CONTROL_RESTART
:
5129 case JOB_CONTROL_RESUME
:
5130 if (print_job_resume(&user
, jobid
, &errcode
)) {
5135 return WERR_UNKNOWN_LEVEL
;
5141 /****************************************************************************
5142 Enumerates all printer drivers at level 1.
5143 ****************************************************************************/
5144 static WERROR
enumprinterdrivers_level1(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5149 fstring
*list
= NULL
;
5151 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5152 DRIVER_INFO_1
*tdi1
, *driver_info_1
=NULL
;
5156 #define MAX_VERSION 4
5158 for (version
=0; version
<MAX_VERSION
; version
++) {
5160 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5161 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5167 if((tdi1
=(DRIVER_INFO_1
*)Realloc(driver_info_1
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_1
))) == NULL
) {
5168 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
5169 SAFE_FREE(driver_info_1
);
5173 else driver_info_1
= tdi1
;
5176 for (i
=0; i
<ndrivers
; i
++) {
5178 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5179 ZERO_STRUCT(driver
);
5180 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5181 architecture
, version
);
5182 if (!W_ERROR_IS_OK(status
)) {
5186 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
5187 free_a_printer_driver(driver
, 3);
5190 *returned
+=ndrivers
;
5194 /* check the required size. */
5195 for (i
=0; i
<*returned
; i
++) {
5196 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5197 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
5200 if (!alloc_buffer_size(buffer
, *needed
)) {
5201 SAFE_FREE(driver_info_1
);
5202 return WERR_INSUFFICIENT_BUFFER
;
5205 /* fill the buffer with the driver structures */
5206 for (i
=0; i
<*returned
; i
++) {
5207 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5208 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
5211 SAFE_FREE(driver_info_1
);
5213 if (*needed
> offered
) {
5215 return WERR_INSUFFICIENT_BUFFER
;
5221 /****************************************************************************
5222 Enumerates all printer drivers at level 2.
5223 ****************************************************************************/
5224 static WERROR
enumprinterdrivers_level2(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5229 fstring
*list
= NULL
;
5231 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5232 DRIVER_INFO_2
*tdi2
, *driver_info_2
=NULL
;
5236 #define MAX_VERSION 4
5238 for (version
=0; version
<MAX_VERSION
; version
++) {
5240 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5241 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5247 if((tdi2
=(DRIVER_INFO_2
*)Realloc(driver_info_2
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_2
))) == NULL
) {
5248 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
5249 SAFE_FREE(driver_info_2
);
5253 else driver_info_2
= tdi2
;
5256 for (i
=0; i
<ndrivers
; i
++) {
5259 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5260 ZERO_STRUCT(driver
);
5261 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5262 architecture
, version
);
5263 if (!W_ERROR_IS_OK(status
)) {
5267 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
5268 free_a_printer_driver(driver
, 3);
5271 *returned
+=ndrivers
;
5275 /* check the required size. */
5276 for (i
=0; i
<*returned
; i
++) {
5277 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5278 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
5281 if (!alloc_buffer_size(buffer
, *needed
)) {
5282 SAFE_FREE(driver_info_2
);
5283 return WERR_INSUFFICIENT_BUFFER
;
5286 /* fill the buffer with the form structures */
5287 for (i
=0; i
<*returned
; i
++) {
5288 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5289 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
5292 SAFE_FREE(driver_info_2
);
5294 if (*needed
> offered
) {
5296 return WERR_INSUFFICIENT_BUFFER
;
5302 /****************************************************************************
5303 Enumerates all printer drivers at level 3.
5304 ****************************************************************************/
5305 static WERROR
enumprinterdrivers_level3(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5310 fstring
*list
= NULL
;
5312 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5313 DRIVER_INFO_3
*tdi3
, *driver_info_3
=NULL
;
5317 #define MAX_VERSION 4
5319 for (version
=0; version
<MAX_VERSION
; version
++) {
5321 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5322 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5328 if((tdi3
=(DRIVER_INFO_3
*)Realloc(driver_info_3
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_3
))) == NULL
) {
5329 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
5330 SAFE_FREE(driver_info_3
);
5334 else driver_info_3
= tdi3
;
5337 for (i
=0; i
<ndrivers
; i
++) {
5340 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5341 ZERO_STRUCT(driver
);
5342 status
= get_a_printer_driver(&driver
, 3, list
[i
],
5343 architecture
, version
);
5344 if (!W_ERROR_IS_OK(status
)) {
5348 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
5349 free_a_printer_driver(driver
, 3);
5352 *returned
+=ndrivers
;
5356 /* check the required size. */
5357 for (i
=0; i
<*returned
; i
++) {
5358 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5359 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
5362 if (!alloc_buffer_size(buffer
, *needed
)) {
5363 SAFE_FREE(driver_info_3
);
5364 return WERR_INSUFFICIENT_BUFFER
;
5367 /* fill the buffer with the driver structures */
5368 for (i
=0; i
<*returned
; i
++) {
5369 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5370 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
5373 for (i
=0; i
<*returned
; i
++)
5374 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
5376 SAFE_FREE(driver_info_3
);
5378 if (*needed
> offered
) {
5380 return WERR_INSUFFICIENT_BUFFER
;
5386 /****************************************************************************
5387 Enumerates all printer drivers.
5388 ****************************************************************************/
5390 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
5392 /* UNISTR2 *name = &q_u->name; - notused. */
5393 UNISTR2
*environment
= &q_u
->environment
;
5394 uint32 level
= q_u
->level
;
5395 NEW_BUFFER
*buffer
= NULL
;
5396 uint32 offered
= q_u
->offered
;
5397 uint32
*needed
= &r_u
->needed
;
5398 uint32
*returned
= &r_u
->returned
;
5400 fstring
*list
= NULL
;
5402 fstring architecture
;
5404 /* that's an [in out] buffer */
5405 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5406 buffer
= r_u
->buffer
;
5408 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
5409 fstrcpy(servername
, get_called_name());
5413 unistr2_to_ascii(architecture
, environment
, sizeof(architecture
)-1);
5417 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
5419 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
5421 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
5425 return WERR_UNKNOWN_LEVEL
;
5429 /****************************************************************************
5430 ****************************************************************************/
5432 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
5434 form
->flag
=list
->flag
;
5435 init_unistr(&form
->name
, list
->name
);
5436 form
->width
=list
->width
;
5437 form
->length
=list
->length
;
5438 form
->left
=list
->left
;
5439 form
->top
=list
->top
;
5440 form
->right
=list
->right
;
5441 form
->bottom
=list
->bottom
;
5444 /****************************************************************************
5445 ****************************************************************************/
5447 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
5449 /* POLICY_HND *handle = &q_u->handle; - notused. */
5450 uint32 level
= q_u
->level
;
5451 NEW_BUFFER
*buffer
= NULL
;
5452 uint32 offered
= q_u
->offered
;
5453 uint32
*needed
= &r_u
->needed
;
5454 uint32
*numofforms
= &r_u
->numofforms
;
5455 uint32 numbuiltinforms
;
5457 nt_forms_struct
*list
=NULL
;
5458 nt_forms_struct
*builtinlist
=NULL
;
5463 /* that's an [in out] buffer */
5464 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5465 buffer
= r_u
->buffer
;
5467 DEBUG(4,("_spoolss_enumforms\n"));
5468 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5469 DEBUGADD(5,("Info level [%d]\n", level
));
5471 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
5472 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
5473 *numofforms
= get_ntforms(&list
);
5474 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
5475 *numofforms
+= numbuiltinforms
;
5477 if (*numofforms
== 0) return WERR_NO_MORE_ITEMS
;
5481 if ((forms_1
=(FORM_1
*)malloc(*numofforms
* sizeof(FORM_1
))) == NULL
) {
5486 /* construct the list of form structures */
5487 for (i
=0; i
<numbuiltinforms
; i
++) {
5488 DEBUGADD(6,("Filling form number [%d]\n",i
));
5489 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
5492 SAFE_FREE(builtinlist
);
5494 for (; i
<*numofforms
; i
++) {
5495 DEBUGADD(6,("Filling form number [%d]\n",i
));
5496 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
5501 /* check the required size. */
5502 for (i
=0; i
<numbuiltinforms
; i
++) {
5503 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5504 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5506 for (; i
<*numofforms
; i
++) {
5507 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5508 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5511 *needed
=buffer_size
;
5513 if (!alloc_buffer_size(buffer
, buffer_size
)){
5515 return WERR_INSUFFICIENT_BUFFER
;
5518 /* fill the buffer with the form structures */
5519 for (i
=0; i
<numbuiltinforms
; i
++) {
5520 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5521 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5523 for (; i
<*numofforms
; i
++) {
5524 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5525 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5530 if (*needed
> offered
) {
5532 return WERR_INSUFFICIENT_BUFFER
;
5539 SAFE_FREE(builtinlist
);
5540 return WERR_UNKNOWN_LEVEL
;
5545 /****************************************************************************
5546 ****************************************************************************/
5548 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
5550 /* POLICY_HND *handle = &q_u->handle; - notused. */
5551 uint32 level
= q_u
->level
;
5552 UNISTR2
*uni_formname
= &q_u
->formname
;
5553 NEW_BUFFER
*buffer
= NULL
;
5554 uint32 offered
= q_u
->offered
;
5555 uint32
*needed
= &r_u
->needed
;
5557 nt_forms_struct
*list
=NULL
;
5558 nt_forms_struct builtin_form
;
5563 int numofforms
=0, i
=0;
5565 /* that's an [in out] buffer */
5566 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5567 buffer
= r_u
->buffer
;
5569 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
)-1);
5571 DEBUG(4,("_spoolss_getform\n"));
5572 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5573 DEBUGADD(5,("Info level [%d]\n", level
));
5575 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
5576 if (!foundBuiltin
) {
5577 numofforms
= get_ntforms(&list
);
5578 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
5580 if (numofforms
== 0)
5587 fill_form_1(&form_1
, &builtin_form
);
5590 /* Check if the requested name is in the list of form structures */
5591 for (i
=0; i
<numofforms
; i
++) {
5593 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
5595 if (strequal(form_name
, list
[i
].name
)) {
5596 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
5597 fill_form_1(&form_1
, &list
[i
]);
5603 if (i
== numofforms
) {
5607 /* check the required size. */
5609 *needed
=spoolss_size_form_1(&form_1
);
5611 if (!alloc_buffer_size(buffer
, buffer_size
)){
5612 return WERR_INSUFFICIENT_BUFFER
;
5615 if (*needed
> offered
) {
5616 return WERR_INSUFFICIENT_BUFFER
;
5619 /* fill the buffer with the form structures */
5620 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
5621 smb_io_form_1("", buffer
, &form_1
, 0);
5627 return WERR_UNKNOWN_LEVEL
;
5631 /****************************************************************************
5632 ****************************************************************************/
5633 static void fill_port_1(PORT_INFO_1
*port
, char *name
)
5635 init_unistr(&port
->port_name
, name
);
5638 /****************************************************************************
5639 ****************************************************************************/
5640 static void fill_port_2(PORT_INFO_2
*port
, char *name
)
5642 init_unistr(&port
->port_name
, name
);
5643 init_unistr(&port
->monitor_name
, "Local Monitor");
5644 init_unistr(&port
->description
, "Local Port");
5645 #define PORT_TYPE_WRITE 1
5646 port
->port_type
=PORT_TYPE_WRITE
;
5650 /****************************************************************************
5652 ****************************************************************************/
5653 static WERROR
enumports_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5655 PORT_INFO_1
*ports
=NULL
;
5658 if (*lp_enumports_cmd()) {
5659 char *cmd
= lp_enumports_cmd();
5666 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 1);
5668 DEBUG(10,("Running [%s]\n", command
));
5669 ret
= smbrun(command
, &fd
);
5670 DEBUG(10,("Returned [%d]\n", ret
));
5674 /* Is this the best error to return here? */
5675 return WERR_ACCESS_DENIED
;
5679 qlines
= fd_lines_load(fd
, &numlines
,True
);
5680 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5684 if((ports
=(PORT_INFO_1
*)malloc( numlines
* sizeof(PORT_INFO_1
) )) == NULL
) {
5685 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
5686 werror_str(WERR_NOMEM
)));
5687 file_lines_free(qlines
);
5691 for (i
=0; i
<numlines
; i
++) {
5692 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5693 fill_port_1(&ports
[i
], qlines
[i
]);
5696 file_lines_free(qlines
);
5699 *returned
= numlines
;
5702 *returned
= 1; /* Sole Samba port returned. */
5704 if((ports
=(PORT_INFO_1
*)malloc( sizeof(PORT_INFO_1
) )) == NULL
)
5707 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5709 fill_port_1(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5712 /* check the required size. */
5713 for (i
=0; i
<*returned
; i
++) {
5714 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5715 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
5718 if (!alloc_buffer_size(buffer
, *needed
)) {
5720 return WERR_INSUFFICIENT_BUFFER
;
5723 /* fill the buffer with the ports structures */
5724 for (i
=0; i
<*returned
; i
++) {
5725 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5726 smb_io_port_1("", buffer
, &ports
[i
], 0);
5731 if (*needed
> offered
) {
5733 return WERR_INSUFFICIENT_BUFFER
;
5739 /****************************************************************************
5741 ****************************************************************************/
5743 static WERROR
enumports_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5745 PORT_INFO_2
*ports
=NULL
;
5748 if (*lp_enumports_cmd()) {
5749 char *cmd
= lp_enumports_cmd();
5758 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME
)))
5759 path
= lp_pathname(lp_servicenumber(PRINTERS_NAME
));
5761 path
= lp_lockdir();
5763 slprintf(tmp_file
, sizeof(tmp_file
)-1, "%s/smbcmd.%u.", path
, (unsigned int)sys_getpid());
5764 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 2);
5767 DEBUG(10,("Running [%s > %s]\n", command
,tmp_file
));
5768 ret
= smbrun(command
, &fd
);
5769 DEBUGADD(10,("returned [%d]\n", ret
));
5773 /* Is this the best error to return here? */
5774 return WERR_ACCESS_DENIED
;
5778 qlines
= fd_lines_load(fd
, &numlines
,True
);
5779 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5783 if((ports
=(PORT_INFO_2
*)malloc( numlines
* sizeof(PORT_INFO_2
) )) == NULL
) {
5784 file_lines_free(qlines
);
5788 for (i
=0; i
<numlines
; i
++) {
5789 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5790 fill_port_2(&(ports
[i
]), qlines
[i
]);
5793 file_lines_free(qlines
);
5796 *returned
= numlines
;
5802 if((ports
=(PORT_INFO_2
*)malloc( sizeof(PORT_INFO_2
) )) == NULL
)
5805 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5807 fill_port_2(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5810 /* check the required size. */
5811 for (i
=0; i
<*returned
; i
++) {
5812 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5813 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
5816 if (!alloc_buffer_size(buffer
, *needed
)) {
5818 return WERR_INSUFFICIENT_BUFFER
;
5821 /* fill the buffer with the ports structures */
5822 for (i
=0; i
<*returned
; i
++) {
5823 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5824 smb_io_port_2("", buffer
, &ports
[i
], 0);
5829 if (*needed
> offered
) {
5831 return WERR_INSUFFICIENT_BUFFER
;
5837 /****************************************************************************
5839 ****************************************************************************/
5841 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
5843 /* UNISTR2 *name = &q_u->name; - notused. */
5844 uint32 level
= q_u
->level
;
5845 NEW_BUFFER
*buffer
= NULL
;
5846 uint32 offered
= q_u
->offered
;
5847 uint32
*needed
= &r_u
->needed
;
5848 uint32
*returned
= &r_u
->returned
;
5850 /* that's an [in out] buffer */
5851 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5852 buffer
= r_u
->buffer
;
5854 DEBUG(4,("_spoolss_enumports\n"));
5861 return enumports_level_1(buffer
, offered
, needed
, returned
);
5863 return enumports_level_2(buffer
, offered
, needed
, returned
);
5865 return WERR_UNKNOWN_LEVEL
;
5869 /****************************************************************************
5870 ****************************************************************************/
5871 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
5872 const SPOOL_PRINTER_INFO_LEVEL
*info
,
5873 DEVICEMODE
*devmode
, SEC_DESC_BUF
*sec_desc_buf
,
5874 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
5877 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5880 WERROR err
= WERR_OK
;
5882 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
5883 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
5887 ZERO_STRUCTP(printer
);
5889 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
5890 if (!convert_printer_info(info
, printer
, 2)) {
5891 free_a_printer(&printer
, 2);
5895 /* check to see if the printer already exists */
5897 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
5898 DEBUG(5, ("_spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed!\n",
5899 printer
->info_2
->sharename
));
5900 free_a_printer(&printer
, 2);
5901 return WERR_PRINTER_ALREADY_EXISTS
;
5904 if (*lp_addprinter_cmd() )
5905 if ( !add_printer_hook(printer
) ) {
5906 free_a_printer(&printer
,2);
5907 return WERR_ACCESS_DENIED
;
5910 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", get_called_name(),
5911 printer
->info_2
->sharename
);
5913 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
5914 free_a_printer(&printer
,2);
5915 return WERR_ACCESS_DENIED
;
5918 /* you must be a printer admin to add a new printer */
5919 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
5920 free_a_printer(&printer
,2);
5921 return WERR_ACCESS_DENIED
;
5925 * Do sanity check on the requested changes for Samba.
5928 if (!check_printer_ok(printer
->info_2
, snum
)) {
5929 free_a_printer(&printer
,2);
5930 return WERR_INVALID_PARAM
;
5934 * When a printer is created, the drivername bound to the printer is used
5935 * to lookup previously saved driver initialization info, which is then
5936 * bound to the new printer, simulating what happens in the Windows arch.
5940 set_driver_init(printer
, 2);
5942 /* A valid devmode was included, convert and link it
5944 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
5946 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
5947 &printer
->info_2
->devmode
))
5951 set_driver_init(printer
, 2);
5953 /* write the ASCII on disk */
5954 err
= mod_a_printer(*printer
, 2);
5955 if (!W_ERROR_IS_OK(err
)) {
5956 free_a_printer(&printer
,2);
5960 if (!open_printer_hnd(p
, handle
, name
)) {
5961 /* Handle open failed - remove addition. */
5962 del_a_printer(printer
->info_2
->sharename
);
5963 free_a_printer(&printer
,2);
5964 return WERR_ACCESS_DENIED
;
5967 free_a_printer(&printer
,2);
5969 update_c_setprinter(False
);
5971 srv_spoolss_sendnotify(0, PRINTER_CHANGE_ADD_PRINTER
);
5976 /****************************************************************************
5977 ****************************************************************************/
5979 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
5981 UNISTR2
*uni_srv_name
= &q_u
->server_name
;
5982 uint32 level
= q_u
->level
;
5983 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
5984 DEVICEMODE
*devmode
= q_u
->devmode_ctr
.devmode
;
5985 SEC_DESC_BUF
*sdb
= q_u
->secdesc_ctr
;
5986 uint32 user_switch
= q_u
->user_switch
;
5987 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
5988 POLICY_HND
*handle
= &r_u
->handle
;
5992 /* we don't handle yet */
5993 /* but I know what to do ... */
5994 return WERR_UNKNOWN_LEVEL
;
5996 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
5998 user_switch
, user
, handle
);
6000 return WERR_UNKNOWN_LEVEL
;
6004 /****************************************************************************
6005 ****************************************************************************/
6007 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
6009 /* UNISTR2 *server_name = &q_u->server_name; - notused. */
6010 uint32 level
= q_u
->level
;
6011 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
6012 WERROR err
= WERR_OK
;
6013 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6014 struct current_user user
;
6016 ZERO_STRUCT(driver
);
6018 get_current_user(&user
, p
);
6020 if (!convert_printer_driver_info(info
, &driver
, level
)) {
6025 DEBUG(5,("Cleaning driver's information\n"));
6026 err
= clean_up_driver_struct(driver
, level
, &user
);
6027 if (!W_ERROR_IS_OK(err
))
6030 DEBUG(5,("Moving driver to final destination\n"));
6031 if(!move_driver_to_download_area(driver
, level
, &user
, &err
)) {
6032 if (W_ERROR_IS_OK(err
))
6033 err
= WERR_ACCESS_DENIED
;
6037 if (add_a_printer_driver(driver
, level
)!=0) {
6038 err
= WERR_ACCESS_DENIED
;
6043 free_a_printer_driver(driver
, level
);
6047 /****************************************************************************
6048 ****************************************************************************/
6049 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
6051 init_unistr(&info
->name
, name
);
6054 /****************************************************************************
6055 ****************************************************************************/
6056 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6060 pstring short_archi
;
6061 DRIVER_DIRECTORY_1
*info
=NULL
;
6063 fstring asc_name
, servername
;
6065 unistr2_to_ascii(long_archi
, uni_environment
, sizeof(long_archi
)-1);
6067 if (get_short_archi(short_archi
, long_archi
)==False
)
6068 return WERR_INVALID_ENVIRONMENT
;
6070 if((info
=(DRIVER_DIRECTORY_1
*)malloc(sizeof(DRIVER_DIRECTORY_1
))) == NULL
)
6074 /* use the name the client sent us */
6076 unistr2_to_ascii(asc_name
, name
, sizeof(asc_name
)-1);
6077 if (asc_name
[0] == '\\' && asc_name
[1] == '\\')
6078 fstrcpy(servername
, asc_name
);
6080 fstrcpy(servername
, "\\\\");
6081 fstrcat(servername
, asc_name
);
6084 slprintf(path
, sizeof(path
)-1, "%s\\print$\\%s", servername
, short_archi
);
6087 slprintf(path
, sizeof(path
)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi
);
6089 DEBUG(4,("printer driver directory: [%s]\n", path
));
6091 fill_driverdir_1(info
, path
);
6093 *needed
+= spoolss_size_driverdir_info_1(info
);
6095 if (!alloc_buffer_size(buffer
, *needed
)) {
6097 return WERR_INSUFFICIENT_BUFFER
;
6100 smb_io_driverdir_1("", buffer
, info
, 0);
6104 if (*needed
> offered
)
6105 return WERR_INSUFFICIENT_BUFFER
;
6110 /****************************************************************************
6111 ****************************************************************************/
6113 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
6115 UNISTR2
*name
= &q_u
->name
;
6116 UNISTR2
*uni_environment
= &q_u
->environment
;
6117 uint32 level
= q_u
->level
;
6118 NEW_BUFFER
*buffer
= NULL
;
6119 uint32 offered
= q_u
->offered
;
6120 uint32
*needed
= &r_u
->needed
;
6122 /* that's an [in out] buffer */
6123 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6124 buffer
= r_u
->buffer
;
6126 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
6132 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
6134 return WERR_UNKNOWN_LEVEL
;
6138 /****************************************************************************
6139 ****************************************************************************/
6141 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
6143 POLICY_HND
*handle
= &q_u
->handle
;
6144 uint32 idx
= q_u
->index
;
6145 uint32 in_value_len
= q_u
->valuesize
;
6146 uint32 in_data_len
= q_u
->datasize
;
6147 uint32
*out_max_value_len
= &r_u
->valuesize
;
6148 uint16
**out_value
= &r_u
->value
;
6149 uint32
*out_value_len
= &r_u
->realvaluesize
;
6150 uint32
*out_type
= &r_u
->type
;
6151 uint32
*out_max_data_len
= &r_u
->datasize
;
6152 uint8
**data_out
= &r_u
->data
;
6153 uint32
*out_data_len
= &r_u
->realdatasize
;
6155 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6160 uint32 biggest_valuesize
;
6161 uint32 biggest_datasize
;
6163 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6169 ZERO_STRUCT(printer
);
6173 *out_max_data_len
=0;
6177 DEBUG(5,("spoolss_enumprinterdata\n"));
6180 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
6184 if (!get_printer_snum(p
,handle
, &snum
))
6187 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6188 if (!W_ERROR_IS_OK(result
))
6192 * The NT machine wants to know the biggest size of value and data
6194 * cf: MSDN EnumPrinterData remark section
6196 if ( (in_value_len
==0) && (in_data_len
==0) ) {
6197 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
6201 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
6202 * if this parameter size doesn't exist.
6203 * Ok - my opinion here is that the client is not asking for the greatest
6204 * possible size of all the parameters, but is asking specifically for the size needed
6205 * for this specific parameter. In that case we can remove the loop below and
6206 * simplify this lookup code considerably. JF - comments welcome. JRA.
6209 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
6211 free_a_printer(&printer
, 2);
6212 return WERR_NO_MORE_ITEMS
;
6219 biggest_valuesize
=0;
6222 while (get_specific_param_by_index(*printer
, 2, param_index
, value
, &data
, &type
, &data_len
)) {
6223 if (strlen(value
) > biggest_valuesize
) biggest_valuesize
=strlen(value
);
6224 if (data_len
> biggest_datasize
) biggest_datasize
=data_len
;
6226 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
, biggest_datasize
));
6232 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
6233 *out_value_len
=2*(1+biggest_valuesize
);
6234 *out_data_len
=biggest_datasize
;
6236 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
6238 free_a_printer(&printer
, 2);
6243 * the value len is wrong in NT sp3
6244 * that's the number of bytes not the number of unicode chars
6247 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
6250 free_a_printer(&printer
, 2);
6252 /* out_value should default to "" or else NT4 has
6253 problems unmarshalling the response */
6255 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
6256 if((*out_value
=(uint16
*)talloc_zero(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
6259 *out_value_len
= (uint32
)dos_PutUniCode((char *)*out_value
, "", in_value_len
, True
);
6261 /* the data is counted in bytes */
6262 *out_max_data_len
= in_data_len
;
6263 *out_data_len
= in_data_len
;
6264 if((*data_out
=(uint8
*)talloc_zero(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
6267 return WERR_NO_MORE_ITEMS
;
6270 free_a_printer(&printer
, 2);
6274 * - counted in bytes in the request
6275 * - counted in UNICODE chars in the max reply
6276 * - counted in bytes in the real size
6278 * take a pause *before* coding not *during* coding
6281 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
6282 if((*out_value
=(uint16
*)talloc_zero(p
->mem_ctx
,in_value_len
*sizeof(uint8
))) == NULL
) {
6287 *out_value_len
= (uint32
)dos_PutUniCode((char *)*out_value
, value
, in_value_len
, True
);
6291 /* the data is counted in bytes */
6292 *out_max_data_len
=in_data_len
;
6293 if((*data_out
=(uint8
*)talloc_zero(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) {
6298 memcpy(*data_out
, data
, (size_t)data_len
);
6299 *out_data_len
=data_len
;
6306 /****************************************************************************
6307 ****************************************************************************/
6309 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
6311 POLICY_HND
*handle
= &q_u
->handle
;
6312 UNISTR2
*value
= &q_u
->value
;
6313 uint32 type
= q_u
->type
;
6314 /* uint32 max_len = q_u->max_len; - notused. */
6315 uint8
*data
= q_u
->data
;
6316 uint32 real_len
= q_u
->real_len
;
6317 /* uint32 numeric_data = q_u->numeric_data; - notused. */
6319 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6320 NT_PRINTER_PARAM
*param
= NULL
, old_param
;
6322 WERROR status
= WERR_OK
;
6323 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6325 DEBUG(5,("spoolss_setprinterdata\n"));
6328 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
6332 if (!get_printer_snum(p
,handle
, &snum
))
6335 ZERO_STRUCT(old_param
);
6338 * Access check : NT returns "access denied" if you make a
6339 * SetPrinterData call without the necessary privildge.
6340 * we were originally returning OK if nothing changed
6341 * which made Win2k issue **a lot** of SetPrinterData
6342 * when connecting to a printer --jerry
6345 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6346 DEBUG(3, ("security descriptor change denied by existing "
6347 "security descriptor\n"));
6348 status
= WERR_ACCESS_DENIED
;
6352 /* Check if we are making any changes or not. Return true if
6353 nothing is actually changing. This is not needed anymore but
6354 has been left in as an optimization to keep from from
6355 writing to disk as often --jerry */
6357 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6358 if (!W_ERROR_IS_OK(status
))
6361 convert_specific_param(¶m
, value
, type
, data
, real_len
);
6364 /* JRA. W2K always changes changeid. */
6366 if (get_specific_param(*printer
, 2, param
->value
, &old_param
.data
,
6367 &old_param
.type
, (uint32
*)&old_param
.data_len
)) {
6369 if (param
->type
== old_param
.type
&&
6370 param
->data_len
== old_param
.data_len
&&
6371 memcmp(param
->data
, old_param
.data
,
6372 old_param
.data_len
) == 0) {
6374 DEBUG(3, ("setprinterdata hasn't changed\n"));
6381 unlink_specific_param_if_exist(printer
->info_2
, param
);
6384 * When client side code sets a magic printer data key, detect it and save
6385 * the current printer data and the magic key's data (its the DEVMODE) for
6386 * future printer/driver initializations.
6388 if (param
->type
==3 && !strcmp( param
->value
, PHANTOM_DEVMODE_KEY
)) {
6390 * Set devmode and printer initialization info
6392 status
= save_driver_init(printer
, 2, param
);
6395 add_a_specific_param(printer
->info_2
, ¶m
);
6396 status
= mod_a_printer(*printer
, 2);
6400 free_a_printer(&printer
, 2);
6402 free_nt_printer_param(¶m
);
6403 SAFE_FREE(old_param
.data
);
6406 /* Is this correct. JRA ? */
6407 srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER
);
6413 /****************************************************************************
6414 ****************************************************************************/
6416 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
6418 POLICY_HND
*handle
= &q_u
->handle
;
6419 UNISTR2
*value
= &q_u
->valuename
;
6421 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6422 NT_PRINTER_PARAM param
;
6424 WERROR status
= WERR_OK
;
6425 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6427 DEBUG(5,("spoolss_deleteprinterdata\n"));
6430 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
6434 if (!get_printer_snum(p
, handle
, &snum
))
6437 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6438 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
6439 "change denied by existing security descriptor\n"));
6440 return WERR_ACCESS_DENIED
;
6443 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6444 if (!W_ERROR_IS_OK(status
))
6447 ZERO_STRUCTP(¶m
);
6448 unistr2_to_ascii(param
.value
, value
, sizeof(param
.value
)-1);
6450 if(!unlink_specific_param_if_exist(printer
->info_2
, ¶m
))
6451 status
= WERR_INVALID_PARAM
;
6453 status
= mod_a_printer(*printer
, 2);
6455 free_a_printer(&printer
, 2);
6459 /****************************************************************************
6460 ****************************************************************************/
6462 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
6464 POLICY_HND
*handle
= &q_u
->handle
;
6465 /* uint32 level = q_u->level; - notused. */
6466 FORM
*form
= &q_u
->form
;
6467 nt_forms_struct tmpForm
;
6469 WERROR status
= WERR_OK
;
6470 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6473 nt_forms_struct
*list
=NULL
;
6474 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6476 DEBUG(5,("spoolss_addform\n"));
6479 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
6483 if (!get_printer_snum(p
,handle
, &snum
))
6486 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6487 DEBUG(3, ("security descriptor change denied by existing "
6488 "security descriptor\n"));
6489 status
= WERR_ACCESS_DENIED
;
6493 /* can't add if builtin */
6494 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6495 return WERR_ALREADY_EXISTS
;
6498 count
=get_ntforms(&list
);
6499 if(!add_a_form(&list
, form
, &count
))
6501 write_ntforms(&list
, count
);
6504 * ChangeID must always be set
6507 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6508 if (!W_ERROR_IS_OK(status
))
6511 status
= mod_a_printer(*printer
, 2);
6512 if (!W_ERROR_IS_OK(status
))
6516 free_a_printer(&printer
, 2);
6522 /****************************************************************************
6523 ****************************************************************************/
6525 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
6527 POLICY_HND
*handle
= &q_u
->handle
;
6528 UNISTR2
*form_name
= &q_u
->name
;
6529 nt_forms_struct tmpForm
;
6531 WERROR ret
= WERR_OK
;
6532 nt_forms_struct
*list
=NULL
;
6533 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6535 WERROR status
= WERR_OK
;
6536 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6538 DEBUG(5,("spoolss_deleteform\n"));
6541 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
6545 if (!get_printer_snum(p
, handle
, &snum
))
6548 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6549 DEBUG(3, ("security descriptor change denied by existing "
6550 "security descriptor\n"));
6551 return WERR_ACCESS_DENIED
;
6554 /* can't delete if builtin */
6555 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
6556 return WERR_INVALID_PARAM
;
6559 count
= get_ntforms(&list
);
6560 if(!delete_a_form(&list
, form_name
, &count
, &ret
))
6561 return WERR_INVALID_PARAM
;
6564 * ChangeID must always be set
6567 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6568 if (!W_ERROR_IS_OK(status
))
6571 status
= mod_a_printer(*printer
, 2);
6572 if (!W_ERROR_IS_OK(status
))
6576 free_a_printer(&printer
, 2);
6582 /****************************************************************************
6583 ****************************************************************************/
6585 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
6587 POLICY_HND
*handle
= &q_u
->handle
;
6588 /* UNISTR2 *uni_name = &q_u->name; - notused. */
6589 /* uint32 level = q_u->level; - notused. */
6590 FORM
*form
= &q_u
->form
;
6591 nt_forms_struct tmpForm
;
6593 WERROR status
= WERR_OK
;
6594 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6597 nt_forms_struct
*list
=NULL
;
6598 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6600 DEBUG(5,("spoolss_setform\n"));
6603 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
6607 if (!get_printer_snum(p
, handle
, &snum
))
6610 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6611 DEBUG(3, ("security descriptor change denied by existing "
6612 "security descriptor\n"));
6613 return WERR_ACCESS_DENIED
;
6616 /* can't set if builtin */
6617 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6618 return WERR_INVALID_PARAM
;
6621 count
=get_ntforms(&list
);
6622 update_a_form(&list
, form
, count
);
6623 write_ntforms(&list
, count
);
6626 * ChangeID must always be set
6629 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6630 if (!W_ERROR_IS_OK(status
))
6633 status
= mod_a_printer(*printer
, 2);
6634 if (!W_ERROR_IS_OK(status
))
6638 free_a_printer(&printer
, 2);
6644 /****************************************************************************
6645 enumprintprocessors level 1.
6646 ****************************************************************************/
6647 static WERROR
enumprintprocessors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6649 PRINTPROCESSOR_1
*info_1
=NULL
;
6651 if((info_1
= (PRINTPROCESSOR_1
*)malloc(sizeof(PRINTPROCESSOR_1
))) == NULL
)
6656 init_unistr(&info_1
->name
, "winprint");
6658 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
6660 if (!alloc_buffer_size(buffer
, *needed
))
6661 return WERR_INSUFFICIENT_BUFFER
;
6663 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
6667 if (*needed
> offered
) {
6669 return WERR_INSUFFICIENT_BUFFER
;
6675 /****************************************************************************
6676 ****************************************************************************/
6678 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
6680 /* UNISTR2 *name = &q_u->name; - notused. */
6681 /* UNISTR2 *environment = &q_u->environment; - notused. */
6682 uint32 level
= q_u
->level
;
6683 NEW_BUFFER
*buffer
= NULL
;
6684 uint32 offered
= q_u
->offered
;
6685 uint32
*needed
= &r_u
->needed
;
6686 uint32
*returned
= &r_u
->returned
;
6688 /* that's an [in out] buffer */
6689 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6690 buffer
= r_u
->buffer
;
6692 DEBUG(5,("spoolss_enumprintprocessors\n"));
6695 * Enumerate the print processors ...
6697 * Just reply with "winprint", to keep NT happy
6698 * and I can use my nice printer checker.
6706 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
6708 return WERR_UNKNOWN_LEVEL
;
6712 /****************************************************************************
6713 enumprintprocdatatypes level 1.
6714 ****************************************************************************/
6715 static WERROR
enumprintprocdatatypes_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6717 PRINTPROCDATATYPE_1
*info_1
=NULL
;
6719 if((info_1
= (PRINTPROCDATATYPE_1
*)malloc(sizeof(PRINTPROCDATATYPE_1
))) == NULL
)
6724 init_unistr(&info_1
->name
, "RAW");
6726 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
6728 if (!alloc_buffer_size(buffer
, *needed
))
6729 return WERR_INSUFFICIENT_BUFFER
;
6731 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
6735 if (*needed
> offered
) {
6737 return WERR_INSUFFICIENT_BUFFER
;
6743 /****************************************************************************
6744 ****************************************************************************/
6746 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
6748 /* UNISTR2 *name = &q_u->name; - notused. */
6749 /* UNISTR2 *processor = &q_u->processor; - notused. */
6750 uint32 level
= q_u
->level
;
6751 NEW_BUFFER
*buffer
= NULL
;
6752 uint32 offered
= q_u
->offered
;
6753 uint32
*needed
= &r_u
->needed
;
6754 uint32
*returned
= &r_u
->returned
;
6756 /* that's an [in out] buffer */
6757 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6758 buffer
= r_u
->buffer
;
6760 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
6767 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
6769 return WERR_UNKNOWN_LEVEL
;
6773 /****************************************************************************
6774 enumprintmonitors level 1.
6775 ****************************************************************************/
6777 static WERROR
enumprintmonitors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6779 PRINTMONITOR_1
*info_1
=NULL
;
6781 if((info_1
= (PRINTMONITOR_1
*)malloc(sizeof(PRINTMONITOR_1
))) == NULL
)
6786 init_unistr(&info_1
->name
, "Local Port");
6788 *needed
+= spoolss_size_printmonitor_info_1(info_1
);
6790 if (!alloc_buffer_size(buffer
, *needed
))
6791 return WERR_INSUFFICIENT_BUFFER
;
6793 smb_io_printmonitor_info_1("", buffer
, info_1
, 0);
6797 if (*needed
> offered
) {
6799 return WERR_INSUFFICIENT_BUFFER
;
6805 /****************************************************************************
6806 enumprintmonitors level 2.
6807 ****************************************************************************/
6808 static WERROR
enumprintmonitors_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6810 PRINTMONITOR_2
*info_2
=NULL
;
6812 if((info_2
= (PRINTMONITOR_2
*)malloc(sizeof(PRINTMONITOR_2
))) == NULL
)
6817 init_unistr(&info_2
->name
, "Local Port");
6818 init_unistr(&info_2
->environment
, "Windows NT X86");
6819 init_unistr(&info_2
->dll_name
, "localmon.dll");
6821 *needed
+= spoolss_size_printmonitor_info_2(info_2
);
6823 if (!alloc_buffer_size(buffer
, *needed
))
6824 return WERR_INSUFFICIENT_BUFFER
;
6826 smb_io_printmonitor_info_2("", buffer
, info_2
, 0);
6830 if (*needed
> offered
) {
6832 return WERR_INSUFFICIENT_BUFFER
;
6838 /****************************************************************************
6839 ****************************************************************************/
6841 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
6843 /* UNISTR2 *name = &q_u->name; - notused. */
6844 uint32 level
= q_u
->level
;
6845 NEW_BUFFER
*buffer
= NULL
;
6846 uint32 offered
= q_u
->offered
;
6847 uint32
*needed
= &r_u
->needed
;
6848 uint32
*returned
= &r_u
->returned
;
6850 /* that's an [in out] buffer */
6851 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6852 buffer
= r_u
->buffer
;
6854 DEBUG(5,("spoolss_enumprintmonitors\n"));
6857 * Enumerate the print monitors ...
6859 * Just reply with "Local Port", to keep NT happy
6860 * and I can use my nice printer checker.
6868 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
6870 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
6872 return WERR_UNKNOWN_LEVEL
;
6876 /****************************************************************************
6877 ****************************************************************************/
6878 static WERROR
getjob_level_1(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6882 JOB_INFO_1
*info_1
=NULL
;
6884 info_1
=(JOB_INFO_1
*)malloc(sizeof(JOB_INFO_1
));
6886 if (info_1
== NULL
) {
6891 for (i
=0; i
<count
&& found
==False
; i
++) {
6892 if (queue
[i
].job
==(int)jobid
)
6899 /* NT treats not found as bad param... yet another bad choice */
6900 return WERR_INVALID_PARAM
;
6903 fill_job_info_1(info_1
, &(queue
[i
-1]), i
, snum
);
6907 *needed
+= spoolss_size_job_info_1(info_1
);
6909 if (!alloc_buffer_size(buffer
, *needed
)) {
6911 return WERR_INSUFFICIENT_BUFFER
;
6914 smb_io_job_info_1("", buffer
, info_1
, 0);
6918 if (*needed
> offered
)
6919 return WERR_INSUFFICIENT_BUFFER
;
6925 /****************************************************************************
6926 ****************************************************************************/
6927 static WERROR
getjob_level_2(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6932 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6935 info_2
=(JOB_INFO_2
*)malloc(sizeof(JOB_INFO_2
));
6937 ZERO_STRUCTP(info_2
);
6939 if (info_2
== NULL
) {
6944 for (i
=0; i
<count
&& found
==False
; i
++) {
6945 if (queue
[i
].job
==(int)jobid
)
6952 /* NT treats not found as bad param... yet another bad choice */
6953 return WERR_INVALID_PARAM
;
6956 ret
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
6957 if (!W_ERROR_IS_OK(ret
)) {
6962 fill_job_info_2(info_2
, &(queue
[i
-1]), i
, snum
, ntprinter
);
6964 free_a_printer(&ntprinter
, 2);
6967 *needed
+= spoolss_size_job_info_2(info_2
);
6969 if (!alloc_buffer_size(buffer
, *needed
)) {
6971 return WERR_INSUFFICIENT_BUFFER
;
6974 smb_io_job_info_2("", buffer
, info_2
, 0);
6976 free_job_info_2(info_2
);
6979 if (*needed
> offered
)
6980 return WERR_INSUFFICIENT_BUFFER
;
6985 /****************************************************************************
6986 ****************************************************************************/
6988 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
6990 POLICY_HND
*handle
= &q_u
->handle
;
6991 uint32 jobid
= q_u
->jobid
;
6992 uint32 level
= q_u
->level
;
6993 NEW_BUFFER
*buffer
= NULL
;
6994 uint32 offered
= q_u
->offered
;
6995 uint32
*needed
= &r_u
->needed
;
6999 print_queue_struct
*queue
=NULL
;
7000 print_status_struct prt_status
;
7002 /* that's an [in out] buffer */
7003 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
7004 buffer
= r_u
->buffer
;
7006 DEBUG(5,("spoolss_getjob\n"));
7010 if (!get_printer_snum(p
, handle
, &snum
))
7013 count
= print_queue_status(snum
, &queue
, &prt_status
);
7015 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
7016 count
, prt_status
.status
, prt_status
.message
));
7020 return getjob_level_1(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
7022 return getjob_level_2(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
7025 return WERR_UNKNOWN_LEVEL
;
7029 /********************************************************************
7030 * spoolss_getprinterdataex
7031 ********************************************************************/
7033 WERROR
_spoolss_getprinterdataex(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATAEX
*q_u
, SPOOL_R_GETPRINTERDATAEX
*r_u
)
7035 POLICY_HND
*handle
= &q_u
->handle
;
7036 uint32 in_size
= q_u
->size
;
7037 uint32
*type
= &r_u
->type
;
7038 uint32
*out_size
= &r_u
->size
;
7039 uint8
**data
= &r_u
->data
;
7040 uint32
*needed
= &r_u
->needed
;
7043 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
7046 DEBUG(4,("_spoolss_getprinterdataex\n"));
7048 unistr2_to_ascii(key
, &q_u
->keyname
, sizeof(key
) - 1);
7049 unistr2_to_ascii(value
, &q_u
->valuename
, sizeof(value
) - 1);
7051 /* in case of problem, return some default values */
7058 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, 4*sizeof(uint8
))) == NULL
)
7060 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7065 /* Is the handle to a printer or to the server? */
7067 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
7069 DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
7070 return WERR_INVALID_PARAM
;
7075 * From MSDN documentation of GetPrinterDataEx: pass request
7076 * to GetPrinterData if key is "PrinterDriverData". This is
7077 * the only key we really support. Other keys to implement:
7083 if (strcmp(key
, "PrinterDriverData") != 0)
7084 return WERR_INVALID_PARAM
;
7086 DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
7087 found
= getprinterdata_printer(p
, p
->mem_ctx
, handle
, value
,
7088 type
, data
, needed
, in_size
);
7093 DEBUG(5, ("value not found, allocating %d\n", *out_size
));
7095 /* reply this param doesn't exist */
7097 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
)
7103 return WERR_INVALID_PARAM
;
7106 if (*needed
> *out_size
)
7107 return WERR_MORE_DATA
;
7112 /********************************************************************
7113 * spoolss_setprinterdata
7114 ********************************************************************/
7116 WERROR
_spoolss_setprinterdataex(pipes_struct
*p
, SPOOL_Q_SETPRINTERDATAEX
*q_u
, SPOOL_R_SETPRINTERDATAEX
*r_u
)
7118 SPOOL_Q_SETPRINTERDATA q_u_local
;
7119 SPOOL_R_SETPRINTERDATA r_u_local
;
7122 DEBUG(4,("_spoolss_setprinterdataex\n"));
7124 /* From MSDN documentation of SetPrinterDataEx: pass request to
7125 SetPrinterData if key is "PrinterDriverData" */
7127 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
) - 1);
7129 if (strcmp(key
, "PrinterDriverData") == 0)
7130 return WERR_INVALID_PARAM
;
7132 ZERO_STRUCT(q_u_local
);
7133 ZERO_STRUCT(r_u_local
);
7135 /* make a copy to call _spoolss_setprinterdata() */
7137 memcpy(&q_u_local
.handle
, &q_u
->handle
, sizeof(POLICY_HND
));
7138 copy_unistr2(&q_u_local
.value
, &q_u
->value
);
7139 q_u_local
.type
= q_u
->type
;
7140 q_u_local
.max_len
= q_u
->max_len
;
7141 q_u_local
.data
= q_u
->data
;
7142 q_u_local
.real_len
= q_u
->real_len
;
7143 q_u_local
.numeric_data
= q_u
->numeric_data
;
7145 return _spoolss_setprinterdata(p
, &q_u_local
, &r_u_local
);
7148 /********************************************************************
7149 * spoolss_enumprinterkey
7150 ********************************************************************/
7152 /* constants for EnumPrinterKey() */
7153 #define ENUMERATED_KEY_SIZE 19
7155 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
7158 uint16 enumkeys
[ENUMERATED_KEY_SIZE
+1];
7161 char *PrinterKey
= "PrinterDriverData";
7163 DEBUG(4,("_spoolss_enumprinterkey\n"));
7165 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
) - 1);
7168 * we only support enumating all keys (key == "")
7169 * Of course, the only key we support is the "PrinterDriverData"
7172 if (strlen(key
) == 0)
7174 r_u
->needed
= ENUMERATED_KEY_SIZE
*2;
7175 if (q_u
->size
< r_u
->needed
)
7176 return WERR_MORE_DATA
;
7179 for (i
=0; i
<ENUMERATED_KEY_SIZE
-2; i
++)
7181 enumkeys
[i
] = (uint16
)(*ptr
);
7185 /* tag of with 2 '\0's */
7186 enumkeys
[i
++] = '\0';
7189 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, ENUMERATED_KEY_SIZE
, enumkeys
))
7190 return WERR_BADFILE
;
7195 /* The "PrinterDriverData" key should have no subkeys */
7196 if (strcmp(key
, PrinterKey
) == 0)
7199 if (q_u
->size
< r_u
->needed
)
7200 return WERR_MORE_DATA
;
7202 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, 1, enumkeys
))
7203 return WERR_BADFILE
;
7209 /* The return value for an unknown key is documented in MSDN
7210 EnumPrinterKey description */
7211 return WERR_BADFILE
;
7214 /********************************************************************
7215 * spoolss_enumprinterdataex
7216 ********************************************************************/
7218 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
7220 POLICY_HND
*handle
= &q_u
->handle
;
7221 uint32 in_size
= q_u
->size
;
7224 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7225 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
7227 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
7236 DEBUG(4,("_spoolss_enumprinterdataex\n"));
7239 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
7245 * The only key we support is "PrinterDriverData". This should return
7246 > an array of all the key/value pairs returned by EnumPrinterDataSee
7247 * _spoolss_getprinterdataex() for details --jerry
7250 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
) - 1);
7251 if (strcmp(key
, "PrinterDriverData") != 0)
7253 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
7254 return WERR_INVALID_PARAM
;
7258 if (!get_printer_snum(p
,handle
, &snum
))
7261 ZERO_STRUCT(printer
);
7262 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7263 if (!W_ERROR_IS_OK(result
))
7268 * loop through all params and build the array to pass
7269 * back to the client
7276 while (get_specific_param_by_index(*printer
, 2, param_index
, value
, &data
, &type
, &data_len
))
7278 PRINTER_ENUM_VALUES
*ptr
;
7281 DEBUG(10,("retrieved value number [%d] [%s]\n", num_entries
, value
));
7283 if ((ptr
=talloc_realloc(p
->mem_ctx
, enum_values
, (num_entries
+1) * sizeof(PRINTER_ENUM_VALUES
))) == NULL
)
7285 DEBUG(0,("talloc_realloc failed to allocate more memory!\n"));
7286 result
= WERR_NOMEM
;
7292 init_unistr(&enum_values
[num_entries
].valuename
, value
);
7293 enum_values
[num_entries
].value_len
= (strlen(value
)+1) * 2;
7294 enum_values
[num_entries
].type
= type
;
7297 * NULL terminate REG_SZ
7298 * FIXME!!! We should not be correctly problems in the way
7299 * we store PrinterData here. Need to investogate
7300 * SetPrinterData[Ex] --jerry
7303 if (type
== REG_SZ
) {
7304 /* fix alignment if the string was stored
7305 in a bizarre fashion */
7306 if ((data_len
% 2) == 0)
7309 add_len
= data_len
% 2;
7312 if (!(enum_values
[num_entries
].data
=talloc_zero(p
->mem_ctx
, data_len
+add_len
))) {
7313 DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n"));
7314 result
= WERR_NOMEM
;
7317 memcpy(enum_values
[num_entries
].data
, data
, data_len
);
7318 enum_values
[num_entries
].data_len
= data_len
+ add_len
;
7320 /* keep track of the size of the array in bytes */
7322 needed
+= spoolss_size_printer_enum_values(&enum_values
[num_entries
]);
7328 r_u
->needed
= needed
;
7329 r_u
->returned
= num_entries
;
7331 if (needed
> in_size
) {
7332 result
= WERR_MORE_DATA
;
7336 /* copy data into the reply */
7338 r_u
->ctr
.size
= r_u
->needed
;
7339 r_u
->ctr
.size_of_array
= r_u
->returned
;
7340 r_u
->ctr
.values
= enum_values
;
7345 free_a_printer(&printer
, 2);
7350 /****************************************************************************
7351 ****************************************************************************/
7353 /* Disabled because it doesn't fix the bug I am looking at but it would be
7354 a shame to throw away the code. -tpot */
7358 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1
*info
, char *name
)
7360 init_unistr(&info
->name
, name
);
7363 static WERROR
getprintprocessordirectory_level_1(UNISTR2
*name
,
7364 UNISTR2
*environment
,
7371 pstring short_archi
;
7372 PRINTPROCESSOR_DIRECTORY_1
*info
=NULL
;
7374 unistr2_to_ascii(long_archi
, environment
, sizeof(long_archi
)-1);
7376 if (get_short_archi(short_archi
, long_archi
)==FALSE
)
7377 return WERR_INVALID_ENVIRONMENT
;
7379 if((info
=(PRINTPROCESSOR_DIRECTORY_1
*)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1
))) == NULL
)
7382 /* Not sure what to return here - are UNC names valid here?.
7383 Windows returns the string: C:\WINNT\System32\spool\PRTPROCS\W32X86
7384 which is pretty bogus for a RPC. */
7386 slprintf(path
, sizeof(path
)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi
);
7388 DEBUG(4,("print processor directory: [%s]\n", path
));
7390 fill_printprocessordirectory_1(info
, path
);
7392 *needed
+= spoolss_size_printprocessordirectory_info_1(info
);
7394 if (!alloc_buffer_size(buffer
, *needed
)) {
7396 return WERR_INSUFFICIENT_BUFFER
;
7399 smb_io_printprocessordirectory_1("", buffer
, info
, 0);
7403 if (*needed
> offered
)
7404 return WERR_INSUFFICIENT_BUFFER
;
7409 WERROR
_spoolss_getprintprocessordirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTPROCESSORDIRECTORY
*q_u
, SPOOL_R_GETPRINTPROCESSORDIRECTORY
*r_u
)
7411 uint32 level
= q_u
->level
;
7412 NEW_BUFFER
*buffer
= NULL
;
7413 uint32 offered
= q_u
->offered
;
7414 uint32
*needed
= &r_u
->needed
;
7416 /* that's an [in out] buffer */
7417 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
7418 buffer
= r_u
->buffer
;
7420 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
7426 return getprintprocessordirectory_level_1
7427 (&q_u
->name
, &q_u
->environment
, buffer
, offered
, needed
);
7429 return WERR_UNKNOWN_LEVEL
;
7432 return WERR_ACCESS_DENIED
;