2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 * Copyright (C) Jean François Micouleau 1998-2000.
8 * Copyright (C) Jeremy Allison 2001.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL
;
28 extern pstring global_myname
;
30 #ifndef MAX_OPEN_PRINTER_EXS
31 #define MAX_OPEN_PRINTER_EXS 50
34 #define PRINTER_HANDLE_IS_PRINTER 0
35 #define PRINTER_HANDLE_IS_PRINTSERVER 1
44 /* structure to store the printer handles */
45 /* and a reference to what it's pointing to */
46 /* and the notify info asked about */
47 /* that's the central struct */
48 typedef struct _Printer
{
49 BOOL document_started
;
51 int jobid
; /* jobid in printing backend */
55 fstring printerservername
;
64 SPOOL_NOTIFY_OPTION
*option
;
65 POLICY_HND client_hnd
;
66 uint32 client_connected
;
74 typedef struct _counter_printer_0
{
82 static ubi_dlList counter_list
;
84 static struct cli_state cli
;
85 static uint32 smb_connections
=0;
87 #define OUR_HANDLE(hnd) ((hnd==NULL)?"NULL":(IVAL(hnd->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER"))
89 /* translate between internal status numbers and NT status numbers */
90 static int nt_printj_status(int v
)
96 return JOB_STATUS_PAUSED
;
98 return JOB_STATUS_SPOOLING
;
100 return JOB_STATUS_PRINTING
;
102 return JOB_STATUS_ERROR
;
104 return JOB_STATUS_DELETING
;
106 return JOB_STATUS_OFFLINE
;
108 return JOB_STATUS_PAPEROUT
;
110 return JOB_STATUS_PRINTED
;
112 return JOB_STATUS_DELETED
;
114 return JOB_STATUS_BLOCKED
;
115 case LPQ_USER_INTERVENTION
:
116 return JOB_STATUS_USER_INTERVENTION
;
121 static int nt_printq_status(int v
)
125 return PRINTER_STATUS_PAUSED
;
134 /****************************************************************************
135 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
136 ****************************************************************************/
138 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION
**pp
)
140 SPOOL_NOTIFY_OPTION
*sp
= *pp
;
148 safe_free(sp
->ctr
.type
);
153 /***************************************************************************
154 Disconnect from the client
155 ****************************************************************************/
157 static void srv_spoolss_replycloseprinter(POLICY_HND
*handle
)
161 /* weird if the test succeds !!! */
162 if (smb_connections
==0) {
163 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
167 if(!cli_spoolss_reply_close_printer(&cli
, handle
, &status
))
168 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n"));
170 /* if it's the last connection, deconnect the IPC$ share */
171 if (smb_connections
==1) {
172 if(!spoolss_disconnect_from_client(&cli
))
175 message_deregister(MSG_PRINTER_NOTIFY
);
181 /****************************************************************************
182 Functions to free a printer entry datastruct.
183 ****************************************************************************/
185 static void free_printer_entry(void *ptr
)
187 Printer_entry
*Printer
= (Printer_entry
*)ptr
;
189 if (Printer
->notify
.client_connected
==True
)
190 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
192 Printer
->notify
.flags
=0;
193 Printer
->notify
.options
=0;
194 Printer
->notify
.localmachine
[0]='\0';
195 Printer
->notify
.printerlocal
=0;
196 free_spool_notify_option(&Printer
->notify
.option
);
197 Printer
->notify
.option
=NULL
;
198 Printer
->notify
.client_connected
=False
;
203 /****************************************************************************
204 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
205 ****************************************************************************/
207 SPOOL_NOTIFY_OPTION
*dup_spool_notify_option(SPOOL_NOTIFY_OPTION
*sp
)
209 SPOOL_NOTIFY_OPTION
*new_sp
= NULL
;
214 new_sp
= (SPOOL_NOTIFY_OPTION
*)malloc(sizeof(SPOOL_NOTIFY_OPTION
));
221 new_sp
->ctr
.type
= (SPOOL_NOTIFY_OPTION_TYPE
*)memdup(sp
->ctr
.type
, sizeof(SPOOL_NOTIFY_OPTION_TYPE
) * sp
->ctr
.count
);
223 if (!new_sp
->ctr
.type
) {
232 /****************************************************************************
233 find printer index by handle
234 ****************************************************************************/
236 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
238 Printer_entry
*find_printer
= NULL
;
240 if(!find_policy_by_hnd(p
,hnd
,(void **)&find_printer
)) {
241 DEBUG(3,("find_printer_index_by_hnd: Printer handle not found: "));
248 /****************************************************************************
249 close printer index by handle
250 ****************************************************************************/
252 static BOOL
close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
254 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
257 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
261 close_policy_hnd(p
, hnd
);
266 /****************************************************************************
267 delete a printer given a handle
268 ****************************************************************************/
269 static uint32
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
271 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
274 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
275 return ERROR_INVALID_HANDLE
;
278 if (del_a_printer(Printer
->dev
.handlename
) != 0) {
279 DEBUG(3,("Error deleting printer %s\n", Printer
->dev
.handlename
));
280 return ERROR_INVALID_HANDLE
;
283 /* Check calling user has permission to delete printer. Note that
284 since we set the snum parameter to -1 only administrators can
285 delete the printer. This stops people with the Full Control
286 permission from deleting the printer. */
288 if (!print_access_check(NULL
, -1, PRINTER_ACCESS_ADMINISTER
)) {
289 DEBUG(3, ("printer delete denied by security descriptor\n"));
290 return ERROR_ACCESS_DENIED
;
293 if (*lp_deleteprinter_cmd()) {
295 char *cmd
= lp_deleteprinter_cmd();
300 /* Printer->dev.handlename equals portname equals sharename */
301 slprintf(command
, sizeof(command
)-1, "%s \"%s\"", cmd
,
302 Printer
->dev
.handlename
);
303 dos_to_unix(command
, True
); /* Convert printername to unix-codepage */
305 DEBUG(10,("Running [%s]\n", command
));
306 ret
= smbrun(command
, NULL
);
308 return ERROR_INVALID_HANDLE
; /* What to return here? */
310 DEBUGADD(10,("returned [%d]\n", ret
));
312 /* Send SIGHUP to process group... is there a better way? */
315 if ( ( i
= lp_servicenumber( Printer
->dev
.handlename
) ) >= 0 ) {
317 return ERROR_SUCCESS
;
319 return ERROR_ACCESS_DENIED
;
322 return ERROR_SUCCESS
;
325 /****************************************************************************
326 return the snum of a printer corresponding to an handle
327 ****************************************************************************/
328 static BOOL
get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
)
330 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
333 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd
)));
337 switch (Printer
->printer_type
) {
338 case PRINTER_HANDLE_IS_PRINTER
:
339 DEBUG(4,("short name:%s\n", Printer
->dev
.handlename
));
340 *number
= print_queue_snum(Printer
->dev
.handlename
);
341 return (*number
!= -1);
342 case PRINTER_HANDLE_IS_PRINTSERVER
:
349 /****************************************************************************
350 set printer handle type.
351 ****************************************************************************/
352 static BOOL
set_printer_hnd_accesstype(pipes_struct
*p
, POLICY_HND
*hnd
, uint32 access_required
)
354 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
357 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd
)));
361 DEBUG(4,("Setting printer access=%x\n", access_required
));
362 Printer
->access
= access_required
;
366 /****************************************************************************
367 Set printer handle type.
368 Check if it's \\server or \\server\printer
369 ****************************************************************************/
371 static BOOL
set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
373 DEBUG(3,("Setting printer type=%s\n", handlename
));
375 if ( strlen(handlename
) < 3 ) {
376 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
380 /* it's a print server */
381 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr(handlename
+2, '\\')) {
382 DEBUGADD(4,("Printer is a print server\n"));
383 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTSERVER
;
387 DEBUGADD(4,("Printer is a printer\n"));
388 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTER
;
394 /****************************************************************************
395 Set printer handle name.
396 ****************************************************************************/
398 static BOOL
set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
400 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
402 int n_services
=lp_numservices();
406 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename
, strlen(handlename
)));
408 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTSERVER
) {
409 ZERO_STRUCT(Printer
->dev
.printerservername
);
410 strncpy(Printer
->dev
.printerservername
, handlename
, strlen(handlename
));
414 if (Printer
->printer_type
!=PRINTER_HANDLE_IS_PRINTER
)
417 if (*handlename
=='\\') {
418 aprinter
=strchr(handlename
+2, '\\');
425 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter
, strlen(aprinter
)));
428 * store the Samba share name in it
429 * in back we have the long printer name
430 * need to iterate all the snum and do a
431 * get_a_printer each time to find the printer
432 * faster to do it here than later.
435 for (snum
=0;snum
<n_services
&& found
==False
;snum
++) {
438 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
441 DEBUGADD(5,("share:%s\n",lp_servicename(snum
)));
443 if (get_a_printer(&printer
, 2, lp_servicename(snum
))!=0)
446 printername
=strchr(printer
->info_2
->printername
+2, '\\');
449 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
450 printer
->info_2
->printername
, aprinter
));
452 if ( strlen(printername
) != strlen(aprinter
) ) {
453 free_a_printer(&printer
, 2);
457 if ( strncasecmp(printername
, aprinter
, strlen(aprinter
))) {
458 free_a_printer(&printer
, 2);
466 * if we haven't found a printer with the given handlename
467 * then it can be a share name as you can open both \\server\printer and
472 * we still check if the printer description file exists as NT won't be happy
473 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
477 DEBUGADD(5,("Printer not found, checking for share now\n"));
479 for (snum
=0;snum
<n_services
&& found
==False
;snum
++) {
481 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
484 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum
)));
486 if (get_a_printer(&printer
, 2, lp_servicename(snum
))!=0)
489 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
490 printer
->info_2
->printername
, aprinter
));
492 if ( strlen(lp_servicename(snum
)) != strlen(aprinter
) ) {
493 free_a_printer(&printer
, 2);
497 if ( strncasecmp(lp_servicename(snum
), aprinter
, strlen(aprinter
))) {
498 free_a_printer(&printer
, 2);
507 DEBUGADD(4,("Printer not found\n"));
512 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
513 printer
->info_2
->printername
, lp_servicename(snum
),snum
));
515 ZERO_STRUCT(Printer
->dev
.handlename
);
516 strncpy(Printer
->dev
.handlename
, lp_servicename(snum
), strlen(lp_servicename(snum
)));
518 free_a_printer(&printer
, 2);
523 /****************************************************************************
524 find first available printer slot. creates a printer handle for you.
525 ****************************************************************************/
527 static BOOL
open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
)
529 Printer_entry
*new_printer
;
531 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
533 if((new_printer
=(Printer_entry
*)malloc(sizeof(Printer_entry
))) == NULL
)
536 ZERO_STRUCTP(new_printer
);
538 new_printer
->notify
.option
=NULL
;
540 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
541 safe_free(new_printer
);
545 if (!set_printer_hnd_printertype(new_printer
, name
)) {
546 close_printer_handle(p
, hnd
);
550 if (!set_printer_hnd_name(new_printer
, name
)) {
551 close_printer_handle(p
, hnd
);
555 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
560 /********************************************************************
561 Return True is the handle is a print server.
562 ********************************************************************/
564 static BOOL
handle_is_printserver(pipes_struct
*p
, POLICY_HND
*handle
)
566 Printer_entry
*Printer
=find_printer_index_by_hnd(p
,handle
);
571 if (Printer
->printer_type
!= PRINTER_HANDLE_IS_PRINTSERVER
)
577 /****************************************************************************
578 allocate more memory for a BUFFER.
579 ****************************************************************************/
580 static BOOL
alloc_buffer_size(NEW_BUFFER
*buffer
, uint32 buffer_size
)
588 /* damn, I'm doing the reverse operation of prs_grow() :) */
589 if (buffer_size
< prs_data_size(ps
))
592 extra_space
= buffer_size
- prs_data_size(ps
);
595 * save the offset and move to the end of the buffer
596 * prs_grow() checks the extra_space against the offset
598 old_offset
=prs_offset(ps
);
599 prs_set_offset(ps
, prs_data_size(ps
));
601 if (!prs_grow(ps
, extra_space
))
604 prs_set_offset(ps
, old_offset
);
606 buffer
->string_at_end
=prs_data_size(ps
);
611 /***************************************************************************
612 receive the notify message
613 ****************************************************************************/
615 static void srv_spoolss_receive_message(int msg_type
, pid_t src
, void *buf
, size_t len
)
619 struct pipes_struct
*p
;
621 struct handle_list
*hl
;
624 fstrcpy(printer
,buf
);
627 DEBUG(0,("srv_spoolss_receive_message: got null message !\n"));
631 DEBUG(10,("srv_spoolss_receive_message: Got message about printer %s\n", printer
));
634 * We need to enumerate all printers. The handle list is shared
635 * across pipes of the same name, so just find the first open
640 for ( p
= get_first_pipe(); p
; get_next_pipe(p
)) {
641 if (strequal(p
->name
, "spoolss")) {
642 hl
= p
->pipe_handles
;
648 DEBUG(0,("srv_spoolss_receive_message: no handle list on spoolss pipe !\n"));
652 /* Iterate the printer list on this pipe. */
653 for (pol
= hl
->Policy
; pol
; pol
= pol
->next
) {
654 Printer_entry
*find_printer
= (Printer_entry
*)pol
->data_ptr
;
660 * if the entry is the given printer or if it's a printerserver
661 * we send the message
664 if (find_printer
->printer_type
==PRINTER_HANDLE_IS_PRINTER
)
665 if (strcmp(find_printer
->dev
.handlename
, printer
))
668 if (find_printer
->notify
.client_connected
==True
)
669 cli_spoolss_reply_rrpcn(&cli
, &find_printer
->notify
.client_hnd
, PRINTER_CHANGE_ALL
, 0x0, &status
);
673 /***************************************************************************
675 ****************************************************************************/
676 static BOOL
srv_spoolss_sendnotify(pipes_struct
*p
, POLICY_HND
*handle
)
680 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
683 DEBUG(0,("srv_spoolss_sendnotify: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
687 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTER
)
688 fstrcpy(printer
, Printer
->dev
.handlename
);
690 fstrcpy(printer
, "");
692 /*srv_spoolss_receive_message(printer);*/
693 DEBUG(10,("srv_spoolss_sendnotify: Sending message about printer %s\n", printer
));
695 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY
, printer
, strlen(printer
) + 1, False
); /* Null terminate... */
700 /********************************************************************
701 * spoolss_open_printer
703 * called from the spoolss dispatcher
704 ********************************************************************/
706 uint32
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
709 uint32 result
= NT_STATUS_NO_PROBLEMO
;
712 UNISTR2
*printername
= NULL
;
713 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
714 /* uint32 user_switch = q_u->user_switch; - notused */
715 /* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
716 POLICY_HND
*handle
= &r_u
->handle
;
720 struct current_user user
;
722 if (q_u
->printername_ptr
!= 0)
723 printername
= &q_u
->printername
;
725 if (printername
== NULL
)
726 return ERROR_INVALID_PRINTER_NAME
;
728 /* some sanity check because you can open a printer or a print server */
729 /* aka: \\server\printer or \\server */
730 unistr2_to_ascii(name
, printername
, sizeof(name
)-1);
732 DEBUGADD(3,("checking name: %s\n",name
));
734 if (!open_printer_hnd(p
, handle
, name
))
735 return ERROR_INVALID_PRINTER_NAME
;
738 if (printer_default->datatype_ptr != NULL)
740 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
741 set_printer_hnd_datatype(handle, datatype);
744 set_printer_hnd_datatype(handle, "");
747 if (!set_printer_hnd_accesstype(p
, handle
, printer_default
->access_required
)) {
748 close_printer_handle(p
, handle
);
749 return ERROR_ACCESS_DENIED
;
753 First case: the user is opening the print server:
755 Disallow MS AddPrinterWizard if parameter disables it. A Win2k
756 client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
758 Then both Win2k and WinNT clients try an OpenPrinterEx with
759 SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
760 or if the user is listed in the smb.conf printer admin parameter.
762 Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
763 client view printer folder, but does not show the MSAPW.
765 Note: this test needs code to check access rights here too. Jeremy
766 could you look at this?
769 Second case: the user is opening a printer:
770 NT doesn't let us connect to a printer if the connecting user
771 doesn't have print permission.
775 get_current_user(&user
, p
);
777 if (handle_is_printserver(p
, handle
)) {
778 if (printer_default
->access_required
== 0) {
779 return NT_STATUS_NO_PROBLEMO
;
781 else if ((printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
) == SERVER_ACCESS_ADMINISTER
) {
783 /* Printserver handles use global struct... */
786 if (!lp_ms_add_printer_wizard()) {
787 close_printer_handle(p
, handle
);
788 return ERROR_ACCESS_DENIED
;
790 else if (user
.uid
== 0 || user_in_list(uidtoname(user
.uid
), lp_printer_admin(snum
))) {
791 return NT_STATUS_NO_PROBLEMO
;
794 close_printer_handle(p
, handle
);
795 return ERROR_ACCESS_DENIED
;
801 /* NT doesn't let us connect to a printer if the connecting user
802 doesn't have print permission. */
804 if (!get_printer_snum(p
, handle
, &snum
))
805 return ERROR_INVALID_HANDLE
;
807 /* map an empty access mask to the minimum access mask */
808 if (printer_default
->access_required
== 0x0)
809 printer_default
->access_required
= PRINTER_ACCESS_USE
;
811 if (!print_access_check(&user
, snum
, printer_default
->access_required
)) {
812 DEBUG(3, ("access DENIED for printer open\n"));
813 close_printer_handle(p
, handle
);
814 return ERROR_ACCESS_DENIED
;
818 * If we have a default device pointer in the
819 * printer_default struct, then we need to get
820 * the printer info from the tdb and if there is
821 * no default devicemode there then we do a *SET*
822 * here ! This is insanity.... JRA.
826 * If the openprinterex rpc call contains a devmode,
827 * it's a per-user one. This per-user devmode is derivated
828 * from the global devmode. Openprinterex() contains a per-user
829 * devmode for when you do EMF printing and spooling.
830 * In the EMF case, the NT workstation is only doing half the job
831 * of rendering the page. The other half is done by running the printer
832 * driver on the server.
833 * The EMF file doesn't contain the page description (paper size, orientation, ...).
834 * The EMF file only contains what is to be printed on the page.
835 * So in order for the server to know how to print, the NT client sends
836 * a devicemode attached to the openprinterex call.
837 * But this devicemode is short lived, it's only valid for the current print job.
839 * If Samba would have supported EMF spooling, this devicemode would
840 * have been attached to the handle, to sent it to the driver to correctly
841 * rasterize the EMF file.
843 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
844 * we just act as a pass-thru between windows and the printer.
846 * In order to know that Samba supports only RAW spooling, NT has to call
847 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
848 * and until NT sends a RAW job, we refuse it.
850 * But to call getprinter() or startdoc(), you first need a valid handle,
851 * and to get an handle you have to call openprintex(). Hence why you have
852 * a devicemode in the openprinterex() call.
855 * Differences between NT4 and NT 2000.
858 * On NT4, you only have a global devicemode. This global devicemode can be changed
859 * by the administrator (or by a user with enough privs). Everytime a user
860 * wants to print, the devicemode is resetted to the default. In Word, everytime
861 * you print, the printer's characteristics are always reset to the global devicemode.
865 * In W2K, there is the notion of per-user devicemode. The first time you use
866 * a printer, a per-user devicemode is build from the global devicemode.
867 * If you change your per-user devicemode, it is saved in the registry, under the
868 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
869 * printer preferences available.
871 * To change the per-user devicemode: it's the "Printing Preferences ..." button
872 * on the General Tab of the printer properties windows.
874 * To change the global devicemode: it's the "Printing Defaults..." button
875 * on the Advanced Tab of the printer properties window.
883 if (printer_default
->devmode_cont
.devmode
!= NULL
) {
884 result
= printer_write_default_dev( snum
, printer_default
);
886 close_printer_handle(p
, handle
);
893 return NT_STATUS_NO_PROBLEMO
;
896 /****************************************************************************
897 ****************************************************************************/
898 static BOOL
convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
899 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
903 uni_2_asc_printer_info_2(uni
->info_2
, &printer
->info_2
);
912 static BOOL
convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
913 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
917 printer
->info_3
=NULL
;
918 uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
);
921 printer
->info_6
=NULL
;
922 uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
);
931 BOOL
convert_devicemode(char *printername
, const DEVICEMODE
*devmode
,
932 NT_DEVICEMODE
**pp_nt_devmode
)
934 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
937 * Ensure nt_devmode is a valid pointer
938 * as we will be overwriting it.
941 if (nt_devmode
== NULL
) {
942 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
943 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
947 unistr_to_dos(nt_devmode
->devicename
, (const char *)devmode
->devicename
.buffer
, 31);
948 unistr_to_dos(nt_devmode
->formname
, (const char *)devmode
->formname
.buffer
, 31);
950 nt_devmode
->specversion
=devmode
->specversion
;
951 nt_devmode
->driverversion
=devmode
->driverversion
;
952 nt_devmode
->size
=devmode
->size
;
953 nt_devmode
->fields
=devmode
->fields
;
954 nt_devmode
->orientation
=devmode
->orientation
;
955 nt_devmode
->papersize
=devmode
->papersize
;
956 nt_devmode
->paperlength
=devmode
->paperlength
;
957 nt_devmode
->paperwidth
=devmode
->paperwidth
;
958 nt_devmode
->scale
=devmode
->scale
;
959 nt_devmode
->copies
=devmode
->copies
;
960 nt_devmode
->defaultsource
=devmode
->defaultsource
;
961 nt_devmode
->printquality
=devmode
->printquality
;
962 nt_devmode
->color
=devmode
->color
;
963 nt_devmode
->duplex
=devmode
->duplex
;
964 nt_devmode
->yresolution
=devmode
->yresolution
;
965 nt_devmode
->ttoption
=devmode
->ttoption
;
966 nt_devmode
->collate
=devmode
->collate
;
968 nt_devmode
->logpixels
=devmode
->logpixels
;
969 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
970 nt_devmode
->pelswidth
=devmode
->pelswidth
;
971 nt_devmode
->pelsheight
=devmode
->pelsheight
;
972 nt_devmode
->displayflags
=devmode
->displayflags
;
973 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
974 nt_devmode
->icmmethod
=devmode
->icmmethod
;
975 nt_devmode
->icmintent
=devmode
->icmintent
;
976 nt_devmode
->mediatype
=devmode
->mediatype
;
977 nt_devmode
->dithertype
=devmode
->dithertype
;
978 nt_devmode
->reserved1
=devmode
->reserved1
;
979 nt_devmode
->reserved2
=devmode
->reserved2
;
980 nt_devmode
->panningwidth
=devmode
->panningwidth
;
981 nt_devmode
->panningheight
=devmode
->panningheight
;
984 * Only change private and driverextra if the incoming devmode
985 * has a new one. JRA.
988 if ((devmode
->driverextra
!= 0) && (devmode
->private != NULL
)) {
989 safe_free(nt_devmode
->private);
990 nt_devmode
->driverextra
=devmode
->driverextra
;
991 if((nt_devmode
->private=(uint8
*)malloc(nt_devmode
->driverextra
* sizeof(uint8
))) == NULL
)
993 memcpy(nt_devmode
->private, devmode
->private, nt_devmode
->driverextra
);
996 *pp_nt_devmode
= nt_devmode
;
1001 /********************************************************************
1002 * _spoolss_enddocprinter_internal.
1003 ********************************************************************/
1005 static uint32
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1007 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1010 DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
1011 return ERROR_INVALID_HANDLE
;
1014 Printer
->document_started
=False
;
1015 print_job_end(Printer
->jobid
,True
);
1016 /* error codes unhandled so far ... */
1021 /********************************************************************
1022 * api_spoolss_closeprinter
1023 ********************************************************************/
1025 uint32
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1027 POLICY_HND
*handle
= &q_u
->handle
;
1029 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1031 if (Printer
&& Printer
->document_started
)
1032 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1034 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1036 if (!close_printer_handle(p
, handle
))
1037 return ERROR_INVALID_HANDLE
;
1039 return NT_STATUS_NO_PROBLEMO
;
1042 /********************************************************************
1043 * api_spoolss_deleteprinter
1045 ********************************************************************/
1047 uint32
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1049 POLICY_HND
*handle
= &q_u
->handle
;
1051 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1054 if (Printer
&& Printer
->document_started
)
1055 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1057 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1059 result
= delete_printer_handle(p
, handle
);
1061 if (result
== ERROR_SUCCESS
) {
1062 srv_spoolss_sendnotify(p
, handle
);
1068 /*******************************************************************
1069 * static function to lookup the version id corresponding to an
1070 * long architecture string
1071 ******************************************************************/
1072 static int get_version_id (char * arch
)
1075 struct table_node archi_table
[]= {
1077 {"Windows 4.0", "WIN40", 0 },
1078 {"Windows NT x86", "W32X86", 2 },
1079 {"Windows NT R4000", "W32MIPS", 2 },
1080 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1081 {"Windows NT PowerPC", "W32PPC", 2 },
1085 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1087 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1088 return (archi_table
[i
].version
);
1094 /********************************************************************
1095 * _spoolss_deleteprinterdriver
1097 * We currently delete the driver for the architecture only.
1098 * This can leave the driver for other archtectures. However,
1099 * since every printer associates a "Windows NT x86" driver name
1100 * and we cannot delete that one while it is in use, **and** since
1101 * it is impossible to assign a driver to a Samba printer without
1102 * having the "Windows NT x86" driver installed,...
1104 * ....we should not get into trouble here.
1107 ********************************************************************/
1109 uint32
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
,
1110 SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
1114 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1117 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
)-1 );
1118 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
)-1 );
1120 /* check that we have a valid driver name first */
1121 if ((version
=get_version_id(arch
)) == -1) {
1122 /* this is what NT returns */
1123 return ERROR_INVALID_ENVIRONMENT
;
1127 if (get_a_printer_driver (&info
, 3, driver
, arch
, version
) != 0) {
1128 /* this is what NT returns */
1129 return ERROR_UNKNOWN_PRINTER_DRIVER
;
1133 if (printer_driver_in_use(arch
, driver
))
1135 /* this is what NT returns */
1136 return ERROR_PRINTER_DRIVER_IN_USE
;
1139 return delete_printer_driver(info
.info_3
);
1143 /********************************************************************
1144 GetPrinterData on a printer server Handle.
1145 ********************************************************************/
1146 static BOOL
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
1150 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
1152 if (!strcmp(value
, "BeepEnabled")) {
1154 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1156 SIVAL(*data
, 0, 0x01);
1161 if (!strcmp(value
, "EventLog")) {
1163 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1165 SIVAL(*data
, 0, 0x1B);
1170 if (!strcmp(value
, "NetPopup")) {
1172 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1174 SIVAL(*data
, 0, 0x01);
1179 if (!strcmp(value
, "MajorVersion")) {
1181 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
1183 SIVAL(*data
, 0, 0x02);
1188 if (!strcmp(value
, "DefaultSpoolDirectory")) {
1189 pstring string
="You are using a Samba server";
1191 *needed
= 2*(strlen(string
)+1);
1192 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1194 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1196 /* it's done by hand ready to go on the wire */
1197 for (i
=0; i
<strlen(string
); i
++) {
1198 (*data
)[2*i
]=string
[i
];
1199 (*data
)[2*i
+1]='\0';
1204 if (!strcmp(value
, "Architecture")) {
1205 pstring string
="Windows NT x86";
1207 *needed
= 2*(strlen(string
)+1);
1208 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
1210 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
1211 for (i
=0; i
<strlen(string
); i
++) {
1212 (*data
)[2*i
]=string
[i
];
1213 (*data
)[2*i
+1]='\0';
1221 /********************************************************************
1222 GetPrinterData on a printer Handle.
1223 ********************************************************************/
1224 static BOOL
getprinterdata_printer(pipes_struct
*p
, TALLOC_CTX
*ctx
, POLICY_HND
*handle
,
1225 fstring value
, uint32
*type
,
1226 uint8
**data
, uint32
*needed
, uint32 in_size
)
1228 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1232 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1234 DEBUG(5,("getprinterdata_printer\n"));
1237 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1241 if(!get_printer_snum(p
, handle
, &snum
))
1244 if(get_a_printer(&printer
, 2, lp_servicename(snum
)) != 0)
1247 if (!get_specific_param(*printer
, 2, value
, &idata
, type
, &len
)) {
1248 free_a_printer(&printer
, 2);
1252 free_a_printer(&printer
, 2);
1254 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size
));
1257 if((*data
= (uint8
*)talloc(ctx
, in_size
*sizeof(uint8
) )) == NULL
) {
1261 memset(*data
, 0, in_size
*sizeof(uint8
));
1262 /* copy the min(in_size, len) */
1263 memcpy(*data
, idata
, (len
>in_size
)?in_size
:len
*sizeof(uint8
));
1270 DEBUG(5,("getprinterdata_printer:copy done\n"));
1277 /********************************************************************
1278 * spoolss_getprinterdata
1279 ********************************************************************/
1281 uint32
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
1283 POLICY_HND
*handle
= &q_u
->handle
;
1284 UNISTR2
*valuename
= &q_u
->valuename
;
1285 uint32 in_size
= q_u
->size
;
1286 uint32
*type
= &r_u
->type
;
1287 uint32
*out_size
= &r_u
->size
;
1288 uint8
**data
= &r_u
->data
;
1289 uint32
*needed
= &r_u
->needed
;
1293 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
1296 * Reminder: when it's a string, the length is in BYTES
1297 * even if UNICODE is negociated.
1304 /* in case of problem, return some default values */
1308 DEBUG(4,("_spoolss_getprinterdata\n"));
1311 if((*data
=(uint8
*)malloc(4*sizeof(uint8
))) == NULL
)
1312 return ERROR_NOT_ENOUGH_MEMORY
;
1313 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1314 return ERROR_INVALID_HANDLE
;
1317 unistr2_to_ascii(value
, valuename
, sizeof(value
)-1);
1319 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
1320 found
=getprinterdata_printer_server(p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
1322 found
= getprinterdata_printer(p
, p
->mem_ctx
, handle
, value
, type
, data
, needed
, *out_size
);
1325 DEBUG(5, ("value not found, allocating %d\n", *out_size
));
1326 /* reply this param doesn't exist */
1328 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
)
1329 return ERROR_NOT_ENOUGH_MEMORY
;
1334 return ERROR_INVALID_PARAMETER
;
1337 if (*needed
> *out_size
)
1338 return ERROR_MORE_DATA
;
1340 return NT_STATUS_NO_PROBLEMO
;
1344 /***************************************************************************
1345 connect to the client
1346 ****************************************************************************/
1347 static BOOL
srv_spoolss_replyopenprinter(char *printer
, uint32 localprinter
, uint32 type
, POLICY_HND
*handle
)
1352 * If it's the first connection, contact the client
1353 * and connect to the IPC$ share anonumously
1355 if (smb_connections
==0) {
1356 fstring unix_printer
;
1358 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
1359 dos_to_unix(unix_printer
, True
);
1361 if(!spoolss_connect_to_client(&cli
, unix_printer
))
1363 message_register(MSG_PRINTER_NOTIFY
, srv_spoolss_receive_message
);
1369 if(!cli_spoolss_reply_open_printer(&cli
, printer
, localprinter
, type
, &status
, handle
))
1375 /********************************************************************
1377 * ReplyFindFirstPrinterChangeNotifyEx
1379 * jfmxxxx: before replying OK: status=0
1380 * should do a rpc call to the workstation asking ReplyOpenPrinter
1381 * have to code it, later.
1383 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
1384 * called from api_spoolss_rffpcnex
1385 ********************************************************************/
1387 uint32
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
1389 POLICY_HND
*handle
= &q_u
->handle
;
1390 uint32 flags
= q_u
->flags
;
1391 uint32 options
= q_u
->options
;
1392 UNISTR2
*localmachine
= &q_u
->localmachine
;
1393 uint32 printerlocal
= q_u
->printerlocal
;
1394 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
1396 /* store the notify value in the printer struct */
1398 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1401 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
1402 return ERROR_INVALID_HANDLE
;
1405 Printer
->notify
.flags
=flags
;
1406 Printer
->notify
.options
=options
;
1407 Printer
->notify
.printerlocal
=printerlocal
;
1409 if (Printer
->notify
.option
)
1410 free_spool_notify_option(&Printer
->notify
.option
);
1412 Printer
->notify
.option
=dup_spool_notify_option(option
);
1414 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
, sizeof(Printer
->notify
.localmachine
)-1);
1416 /* connect to the client machine and send a ReplyOpenPrinter */
1417 if(srv_spoolss_replyopenprinter(Printer
->notify
.localmachine
,
1418 Printer
->notify
.printerlocal
, 1,
1419 &Printer
->notify
.client_hnd
))
1420 Printer
->notify
.client_connected
=True
;
1422 return NT_STATUS_NO_PROBLEMO
;
1425 /*******************************************************************
1426 * fill a notify_info_data with the servername
1427 ********************************************************************/
1429 static void spoolss_notify_server_name(int snum
,
1430 SPOOL_NOTIFY_INFO_DATA
*data
,
1431 print_queue_struct
*queue
,
1432 NT_PRINTER_INFO_LEVEL
*printer
,
1433 TALLOC_CTX
*mem_ctx
)
1435 pstring temp_name
, temp
;
1438 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
1440 len
= (uint32
)dos_PutUniCode(temp
, temp_name
, sizeof(temp
) - 2, True
);
1442 data
->notify_data
.data
.length
= len
/ 2 - 1;
1443 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1445 if (!data
->notify_data
.data
.string
) {
1446 data
->notify_data
.data
.length
= 0;
1450 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1453 /*******************************************************************
1454 * fill a notify_info_data with the printername (not including the servername).
1455 ********************************************************************/
1456 static void spoolss_notify_printer_name(int snum
,
1457 SPOOL_NOTIFY_INFO_DATA
*data
,
1458 print_queue_struct
*queue
,
1459 NT_PRINTER_INFO_LEVEL
*printer
,
1460 TALLOC_CTX
*mem_ctx
)
1465 /* the notify name should not contain the \\server\ part */
1466 char *p
= strrchr(printer
->info_2
->printername
, '\\');
1469 p
= printer
->info_2
->printername
;
1474 len
= (uint32
)dos_PutUniCode(temp
, p
, sizeof(temp
) - 2, True
);
1476 data
->notify_data
.data
.length
= len
/ 2 - 1;
1477 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1479 if (!data
->notify_data
.data
.string
) {
1480 data
->notify_data
.data
.length
= 0;
1484 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1487 /*******************************************************************
1488 * fill a notify_info_data with the servicename
1489 ********************************************************************/
1490 static void spoolss_notify_share_name(int snum
,
1491 SPOOL_NOTIFY_INFO_DATA
*data
,
1492 print_queue_struct
*queue
,
1493 NT_PRINTER_INFO_LEVEL
*printer
,
1494 TALLOC_CTX
*mem_ctx
)
1499 len
= (uint32
)dos_PutUniCode(temp
, lp_servicename(snum
),
1500 sizeof(temp
) - 2, True
);
1502 data
->notify_data
.data
.length
= len
/ 2 - 1;
1503 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1505 if (!data
->notify_data
.data
.string
) {
1506 data
->notify_data
.data
.length
= 0;
1510 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1513 /*******************************************************************
1514 * fill a notify_info_data with the port name
1515 ********************************************************************/
1516 static void spoolss_notify_port_name(int snum
,
1517 SPOOL_NOTIFY_INFO_DATA
*data
,
1518 print_queue_struct
*queue
,
1519 NT_PRINTER_INFO_LEVEL
*printer
,
1520 TALLOC_CTX
*mem_ctx
)
1525 /* even if it's strange, that's consistant in all the code */
1527 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->portname
,
1528 sizeof(temp
) - 2, True
);
1530 data
->notify_data
.data
.length
= len
/ 2 - 1;
1531 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1533 if (!data
->notify_data
.data
.string
) {
1534 data
->notify_data
.data
.length
= 0;
1538 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1541 /*******************************************************************
1542 * fill a notify_info_data with the printername
1543 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
1544 * but it doesn't exist, have to see what to do
1545 ********************************************************************/
1546 static void spoolss_notify_driver_name(int snum
,
1547 SPOOL_NOTIFY_INFO_DATA
*data
,
1548 print_queue_struct
*queue
,
1549 NT_PRINTER_INFO_LEVEL
*printer
,
1550 TALLOC_CTX
*mem_ctx
)
1555 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->drivername
,
1556 sizeof(temp
) - 2, True
);
1558 data
->notify_data
.data
.length
= len
/ 2 - 1;
1559 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1561 if (!data
->notify_data
.data
.string
) {
1562 data
->notify_data
.data
.length
= 0;
1566 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1569 /*******************************************************************
1570 * fill a notify_info_data with the comment
1571 ********************************************************************/
1572 static void spoolss_notify_comment(int snum
,
1573 SPOOL_NOTIFY_INFO_DATA
*data
,
1574 print_queue_struct
*queue
,
1575 NT_PRINTER_INFO_LEVEL
*printer
,
1576 TALLOC_CTX
*mem_ctx
)
1581 if (*printer
->info_2
->comment
== '\0')
1582 len
= (uint32
)dos_PutUniCode(temp
, lp_comment(snum
),
1583 sizeof(temp
) - 2, True
);
1585 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->comment
,
1586 sizeof(temp
) - 2, True
);
1588 data
->notify_data
.data
.length
= len
/ 2 - 1;
1589 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1591 if (!data
->notify_data
.data
.string
) {
1592 data
->notify_data
.data
.length
= 0;
1596 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1599 /*******************************************************************
1600 * fill a notify_info_data with the comment
1601 * jfm:xxxx incorrect, have to create a new smb.conf option
1602 * location = "Room 1, floor 2, building 3"
1603 ********************************************************************/
1604 static void spoolss_notify_location(int snum
,
1605 SPOOL_NOTIFY_INFO_DATA
*data
,
1606 print_queue_struct
*queue
,
1607 NT_PRINTER_INFO_LEVEL
*printer
,
1608 TALLOC_CTX
*mem_ctx
)
1613 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->location
,
1614 sizeof(temp
) - 2, True
);
1616 data
->notify_data
.data
.length
= len
/ 2 - 1;
1617 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1619 if (!data
->notify_data
.data
.string
) {
1620 data
->notify_data
.data
.length
= 0;
1624 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1627 /*******************************************************************
1628 * fill a notify_info_data with the device mode
1629 * jfm:xxxx don't to it for know but that's a real problem !!!
1630 ********************************************************************/
1631 static void spoolss_notify_devmode(int snum
,
1632 SPOOL_NOTIFY_INFO_DATA
*data
,
1633 print_queue_struct
*queue
,
1634 NT_PRINTER_INFO_LEVEL
*printer
,
1635 TALLOC_CTX
*mem_ctx
)
1639 /*******************************************************************
1640 * fill a notify_info_data with the separator file name
1641 * jfm:xxxx just return no file could add an option to smb.conf
1642 * separator file = "separator.txt"
1643 ********************************************************************/
1644 static void spoolss_notify_sepfile(int snum
,
1645 SPOOL_NOTIFY_INFO_DATA
*data
,
1646 print_queue_struct
*queue
,
1647 NT_PRINTER_INFO_LEVEL
*printer
,
1648 TALLOC_CTX
*mem_ctx
)
1653 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->sepfile
,
1654 sizeof(temp
) - 2, True
);
1656 data
->notify_data
.data
.length
= len
/ 2 - 1;
1657 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1659 if (!data
->notify_data
.data
.string
) {
1660 data
->notify_data
.data
.length
= 0;
1664 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1667 /*******************************************************************
1668 * fill a notify_info_data with the print processor
1669 * jfm:xxxx return always winprint to indicate we don't do anything to it
1670 ********************************************************************/
1671 static void spoolss_notify_print_processor(int snum
,
1672 SPOOL_NOTIFY_INFO_DATA
*data
,
1673 print_queue_struct
*queue
,
1674 NT_PRINTER_INFO_LEVEL
*printer
,
1675 TALLOC_CTX
*mem_ctx
)
1680 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->printprocessor
,
1681 sizeof(temp
) - 2, True
);
1683 data
->notify_data
.data
.length
= len
/ 2 - 1;
1684 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1686 if (!data
->notify_data
.data
.string
) {
1687 data
->notify_data
.data
.length
= 0;
1691 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1694 /*******************************************************************
1695 * fill a notify_info_data with the print processor options
1696 * jfm:xxxx send an empty string
1697 ********************************************************************/
1698 static void spoolss_notify_parameters(int snum
,
1699 SPOOL_NOTIFY_INFO_DATA
*data
,
1700 print_queue_struct
*queue
,
1701 NT_PRINTER_INFO_LEVEL
*printer
,
1702 TALLOC_CTX
*mem_ctx
)
1707 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->parameters
,
1708 sizeof(temp
) - 2, True
);
1710 data
->notify_data
.data
.length
= len
/ 2 - 1;
1711 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1713 if (!data
->notify_data
.data
.string
) {
1714 data
->notify_data
.data
.length
= 0;
1718 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1721 /*******************************************************************
1722 * fill a notify_info_data with the data type
1723 * jfm:xxxx always send RAW as data type
1724 ********************************************************************/
1725 static void spoolss_notify_datatype(int snum
,
1726 SPOOL_NOTIFY_INFO_DATA
*data
,
1727 print_queue_struct
*queue
,
1728 NT_PRINTER_INFO_LEVEL
*printer
,
1729 TALLOC_CTX
*mem_ctx
)
1734 len
= (uint32
)dos_PutUniCode(temp
, printer
->info_2
->datatype
,
1735 sizeof(pstring
) - 2, True
);
1737 data
->notify_data
.data
.length
= len
/ 2 - 1;
1738 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1740 if (!data
->notify_data
.data
.string
) {
1741 data
->notify_data
.data
.length
= 0;
1745 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1748 /*******************************************************************
1749 * fill a notify_info_data with the security descriptor
1750 * jfm:xxxx send an null pointer to say no security desc
1751 * have to implement security before !
1752 ********************************************************************/
1753 static void spoolss_notify_security_desc(int snum
,
1754 SPOOL_NOTIFY_INFO_DATA
*data
,
1755 print_queue_struct
*queue
,
1756 NT_PRINTER_INFO_LEVEL
*printer
,
1757 TALLOC_CTX
*mem_ctx
)
1759 data
->notify_data
.data
.length
=0;
1760 data
->notify_data
.data
.string
= NULL
;
1763 /*******************************************************************
1764 * fill a notify_info_data with the attributes
1765 * jfm:xxxx a samba printer is always shared
1766 ********************************************************************/
1767 static void spoolss_notify_attributes(int snum
,
1768 SPOOL_NOTIFY_INFO_DATA
*data
,
1769 print_queue_struct
*queue
,
1770 NT_PRINTER_INFO_LEVEL
*printer
,
1771 TALLOC_CTX
*mem_ctx
)
1773 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
1776 /*******************************************************************
1777 * fill a notify_info_data with the priority
1778 ********************************************************************/
1779 static void spoolss_notify_priority(int snum
,
1780 SPOOL_NOTIFY_INFO_DATA
*data
,
1781 print_queue_struct
*queue
,
1782 NT_PRINTER_INFO_LEVEL
*printer
,
1783 TALLOC_CTX
*mem_ctx
)
1785 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
1788 /*******************************************************************
1789 * fill a notify_info_data with the default priority
1790 ********************************************************************/
1791 static void spoolss_notify_default_priority(int snum
,
1792 SPOOL_NOTIFY_INFO_DATA
*data
,
1793 print_queue_struct
*queue
,
1794 NT_PRINTER_INFO_LEVEL
*printer
,
1795 TALLOC_CTX
*mem_ctx
)
1797 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
1800 /*******************************************************************
1801 * fill a notify_info_data with the start time
1802 ********************************************************************/
1803 static void spoolss_notify_start_time(int snum
,
1804 SPOOL_NOTIFY_INFO_DATA
*data
,
1805 print_queue_struct
*queue
,
1806 NT_PRINTER_INFO_LEVEL
*printer
,
1807 TALLOC_CTX
*mem_ctx
)
1809 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
1812 /*******************************************************************
1813 * fill a notify_info_data with the until time
1814 ********************************************************************/
1815 static void spoolss_notify_until_time(int snum
,
1816 SPOOL_NOTIFY_INFO_DATA
*data
,
1817 print_queue_struct
*queue
,
1818 NT_PRINTER_INFO_LEVEL
*printer
,
1819 TALLOC_CTX
*mem_ctx
)
1821 data
->notify_data
.value
[0] = printer
->info_2
->untiltime
;
1824 /*******************************************************************
1825 * fill a notify_info_data with the status
1826 ********************************************************************/
1827 static void spoolss_notify_status(int snum
,
1828 SPOOL_NOTIFY_INFO_DATA
*data
,
1829 print_queue_struct
*queue
,
1830 NT_PRINTER_INFO_LEVEL
*printer
,
1831 TALLOC_CTX
*mem_ctx
)
1833 print_queue_struct
*q
=NULL
;
1834 print_status_struct status
;
1836 memset(&status
, 0, sizeof(status
));
1837 print_queue_status(snum
, &q
, &status
);
1838 data
->notify_data
.value
[0]=(uint32
) status
.status
;
1842 /*******************************************************************
1843 * fill a notify_info_data with the number of jobs queued
1844 ********************************************************************/
1845 static void spoolss_notify_cjobs(int snum
,
1846 SPOOL_NOTIFY_INFO_DATA
*data
,
1847 print_queue_struct
*queue
,
1848 NT_PRINTER_INFO_LEVEL
*printer
,
1849 TALLOC_CTX
*mem_ctx
)
1851 print_queue_struct
*q
=NULL
;
1852 print_status_struct status
;
1854 memset(&status
, 0, sizeof(status
));
1855 data
->notify_data
.value
[0] = print_queue_status(snum
, &q
, &status
);
1859 /*******************************************************************
1860 * fill a notify_info_data with the average ppm
1861 ********************************************************************/
1862 static void spoolss_notify_average_ppm(int snum
,
1863 SPOOL_NOTIFY_INFO_DATA
*data
,
1864 print_queue_struct
*queue
,
1865 NT_PRINTER_INFO_LEVEL
*printer
,
1866 TALLOC_CTX
*mem_ctx
)
1868 /* always respond 8 pages per minutes */
1869 /* a little hard ! */
1870 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
1873 /*******************************************************************
1874 * fill a notify_info_data with username
1875 ********************************************************************/
1876 static void spoolss_notify_username(int snum
,
1877 SPOOL_NOTIFY_INFO_DATA
*data
,
1878 print_queue_struct
*queue
,
1879 NT_PRINTER_INFO_LEVEL
*printer
,
1880 TALLOC_CTX
*mem_ctx
)
1885 len
= (uint32
)dos_PutUniCode(temp
, queue
->user
,
1886 sizeof(temp
) - 2, True
);
1888 data
->notify_data
.data
.length
= len
/ 2 - 1;
1889 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1891 if (!data
->notify_data
.data
.string
) {
1892 data
->notify_data
.data
.length
= 0;
1896 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1899 /*******************************************************************
1900 * fill a notify_info_data with job status
1901 ********************************************************************/
1902 static void spoolss_notify_job_status(int snum
,
1903 SPOOL_NOTIFY_INFO_DATA
*data
,
1904 print_queue_struct
*queue
,
1905 NT_PRINTER_INFO_LEVEL
*printer
,
1906 TALLOC_CTX
*mem_ctx
)
1908 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
1911 /*******************************************************************
1912 * fill a notify_info_data with job name
1913 ********************************************************************/
1914 static void spoolss_notify_job_name(int snum
,
1915 SPOOL_NOTIFY_INFO_DATA
*data
,
1916 print_queue_struct
*queue
,
1917 NT_PRINTER_INFO_LEVEL
*printer
,
1918 TALLOC_CTX
*mem_ctx
)
1923 len
= (uint32
)dos_PutUniCode(temp
, queue
->file
, sizeof(temp
) - 2,
1926 data
->notify_data
.data
.length
= len
/ 2 - 1;
1927 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1929 if (!data
->notify_data
.data
.string
) {
1930 data
->notify_data
.data
.length
= 0;
1934 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1937 /*******************************************************************
1938 * fill a notify_info_data with job status
1939 ********************************************************************/
1940 static void spoolss_notify_job_status_string(int snum
,
1941 SPOOL_NOTIFY_INFO_DATA
*data
,
1942 print_queue_struct
*queue
,
1943 NT_PRINTER_INFO_LEVEL
*printer
,
1944 TALLOC_CTX
*mem_ctx
)
1947 * Now we're returning job status codes we just return a "" here. JRA.
1954 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
1957 switch (queue
->status
) {
1962 p
= ""; /* NT provides the paused string */
1971 #endif /* NO LONGER NEEDED. */
1973 len
= (uint32
)dos_PutUniCode(temp
, p
, sizeof(temp
) - 2, True
);
1975 data
->notify_data
.data
.length
= len
/ 2 - 1;
1976 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
1978 if (!data
->notify_data
.data
.string
) {
1979 data
->notify_data
.data
.length
= 0;
1983 memcpy(data
->notify_data
.data
.string
, temp
, len
);
1986 /*******************************************************************
1987 * fill a notify_info_data with job time
1988 ********************************************************************/
1989 static void spoolss_notify_job_time(int snum
,
1990 SPOOL_NOTIFY_INFO_DATA
*data
,
1991 print_queue_struct
*queue
,
1992 NT_PRINTER_INFO_LEVEL
*printer
,
1993 TALLOC_CTX
*mem_ctx
)
1995 data
->notify_data
.value
[0]=0x0;
1998 /*******************************************************************
1999 * fill a notify_info_data with job size
2000 ********************************************************************/
2001 static void spoolss_notify_job_size(int snum
,
2002 SPOOL_NOTIFY_INFO_DATA
*data
,
2003 print_queue_struct
*queue
,
2004 NT_PRINTER_INFO_LEVEL
*printer
,
2005 TALLOC_CTX
*mem_ctx
)
2007 data
->notify_data
.value
[0]=queue
->size
;
2010 /*******************************************************************
2011 * fill a notify_info_data with job position
2012 ********************************************************************/
2013 static void spoolss_notify_job_position(int snum
,
2014 SPOOL_NOTIFY_INFO_DATA
*data
,
2015 print_queue_struct
*queue
,
2016 NT_PRINTER_INFO_LEVEL
*printer
,
2017 TALLOC_CTX
*mem_ctx
)
2019 data
->notify_data
.value
[0]=queue
->job
;
2022 /*******************************************************************
2023 * fill a notify_info_data with submitted time
2024 ********************************************************************/
2025 static void spoolss_notify_submitted_time(int snum
,
2026 SPOOL_NOTIFY_INFO_DATA
*data
,
2027 print_queue_struct
*queue
,
2028 NT_PRINTER_INFO_LEVEL
*printer
,
2029 TALLOC_CTX
*mem_ctx
)
2035 t
=gmtime(&queue
->time
);
2037 len
= sizeof(SYSTEMTIME
);
2039 data
->notify_data
.data
.length
= len
/2 - 1;
2040 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2042 if (!data
->notify_data
.data
.string
) {
2043 data
->notify_data
.data
.length
= 0;
2047 make_systemtime(&st
, t
);
2048 memcpy(data
->notify_data
.data
.string
,&st
,len
);
2053 struct s_notify_info_data_table
2059 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
2060 print_queue_struct
*queue
,
2061 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
2064 struct s_notify_info_data_table notify_info_data_table
[] =
2066 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", POINTER
, spoolss_notify_server_name
},
2067 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2068 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", POINTER
, spoolss_notify_share_name
},
2069 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2070 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2071 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", POINTER
, spoolss_notify_comment
},
2072 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", POINTER
, spoolss_notify_location
},
2073 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2074 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", POINTER
, spoolss_notify_sepfile
},
2075 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2076 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2077 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2078 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, spoolss_notify_security_desc
},
2079 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE
, spoolss_notify_attributes
},
2080 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2081 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE
, spoolss_notify_default_priority
},
2082 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2083 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2084 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_status
},
2085 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", POINTER
, NULL
},
2086 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", ONE_VALUE
, spoolss_notify_cjobs
},
2087 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE
, spoolss_notify_average_ppm
},
2088 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER
, NULL
},
2089 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER
, NULL
},
2090 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER
, NULL
},
2091 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER
, NULL
},
2092 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", POINTER
, spoolss_notify_printer_name
},
2093 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", POINTER
, spoolss_notify_server_name
},
2094 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", POINTER
, spoolss_notify_port_name
},
2095 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", POINTER
, spoolss_notify_username
},
2096 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", POINTER
, spoolss_notify_username
},
2097 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", POINTER
, spoolss_notify_datatype
},
2098 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER
, spoolss_notify_print_processor
},
2099 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", POINTER
, spoolss_notify_parameters
},
2100 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", POINTER
, spoolss_notify_driver_name
},
2101 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", POINTER
, spoolss_notify_devmode
},
2102 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", ONE_VALUE
, spoolss_notify_job_status
},
2103 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", POINTER
, spoolss_notify_job_status_string
},
2104 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER
, NULL
},
2105 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", POINTER
, spoolss_notify_job_name
},
2106 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", ONE_VALUE
, spoolss_notify_priority
},
2107 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", ONE_VALUE
, spoolss_notify_job_position
},
2108 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", POINTER
, spoolss_notify_submitted_time
},
2109 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", ONE_VALUE
, spoolss_notify_start_time
},
2110 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE
, spoolss_notify_until_time
},
2111 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", ONE_VALUE
, spoolss_notify_job_time
},
2112 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE
, NULL
},
2113 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE
, NULL
},
2114 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE
, spoolss_notify_job_size
},
2115 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_BYTES_PRINTED
, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE
, NULL
},
2116 { END
, END
, "", END
, NULL
}
2119 /*******************************************************************
2120 return the size of info_data structure
2121 ********************************************************************/
2122 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
2126 while (notify_info_data_table
[i
].type
!= END
)
2128 if ( (notify_info_data_table
[i
].type
== type
) &&
2129 (notify_info_data_table
[i
].field
== field
) )
2131 return (notify_info_data_table
[i
].size
);
2138 /*******************************************************************
2139 return the type of notify_info_data
2140 ********************************************************************/
2141 static BOOL
type_of_notify_info_data(uint16 type
, uint16 field
)
2145 while (notify_info_data_table
[i
].type
!= END
)
2147 if ( (notify_info_data_table
[i
].type
== type
) &&
2148 (notify_info_data_table
[i
].field
== field
) )
2150 if (notify_info_data_table
[i
].size
== POINTER
)
2164 /****************************************************************************
2165 ****************************************************************************/
2166 static int search_notify(uint16 type
, uint16 field
, int *value
)
2171 for (j
=0, found
=False
; found
==False
&& notify_info_data_table
[j
].type
!= END
; j
++)
2173 if ( (notify_info_data_table
[j
].type
== type
) &&
2174 (notify_info_data_table
[j
].field
== field
) )
2179 if ( found
&& (notify_info_data_table
[j
].fn
!= NULL
) )
2185 /****************************************************************************
2186 ****************************************************************************/
2187 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
2189 info_data
->type
= type
;
2190 info_data
->field
= field
;
2191 info_data
->reserved
= 0;
2193 info_data
->size
= size_of_notify_info_data(type
, field
);
2194 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
2198 /*******************************************************************
2200 * fill a notify_info struct with info asked
2202 ********************************************************************/
2203 static BOOL
construct_notify_printer_info(SPOOL_NOTIFY_INFO
*info
, int
2204 snum
, SPOOL_NOTIFY_OPTION_TYPE
2205 *option_type
, uint32 id
,
2206 TALLOC_CTX
*mem_ctx
)
2212 SPOOL_NOTIFY_INFO_DATA
*current_data
;
2213 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2214 print_queue_struct
*queue
=NULL
;
2216 type
=option_type
->type
;
2218 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
2219 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2220 option_type
->count
, lp_servicename(snum
)));
2222 if (get_a_printer(&printer
, 2, lp_servicename(snum
))!=0)
2225 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2226 field
= option_type
->fields
[field_num
];
2227 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
2229 if (!search_notify(type
, field
, &j
) )
2232 if((info
->data
=(SPOOL_NOTIFY_INFO_DATA
*)Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2235 current_data
=&info
->data
[info
->count
];
2237 construct_info_data(current_data
, type
, field
, id
);
2239 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
2240 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
2242 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2248 free_a_printer(&printer
, 2);
2252 /*******************************************************************
2254 * fill a notify_info struct with info asked
2256 ********************************************************************/
2257 static BOOL
construct_notify_jobs_info(print_queue_struct
*queue
,
2258 SPOOL_NOTIFY_INFO
*info
,
2259 NT_PRINTER_INFO_LEVEL
*printer
,
2260 int snum
, SPOOL_NOTIFY_OPTION_TYPE
2261 *option_type
, uint32 id
,
2262 TALLOC_CTX
*mem_ctx
)
2268 SPOOL_NOTIFY_INFO_DATA
*current_data
;
2270 DEBUG(4,("construct_notify_jobs_info\n"));
2272 type
= option_type
->type
;
2274 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
2275 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2276 option_type
->count
));
2278 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
2279 field
= option_type
->fields
[field_num
];
2281 if (!search_notify(type
, field
, &j
) )
2284 if((info
->data
=Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
2288 current_data
=&(info
->data
[info
->count
]);
2290 construct_info_data(current_data
, type
, field
, id
);
2291 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
2300 * JFM: The enumeration is not that simple, it's even non obvious.
2302 * let's take an example: I want to monitor the PRINTER SERVER for
2303 * the printer's name and the number of jobs currently queued.
2304 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
2305 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
2307 * I have 3 printers on the back of my server.
2309 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
2312 * 1 printer 1 name 1
2313 * 2 printer 1 cjob 1
2314 * 3 printer 2 name 2
2315 * 4 printer 2 cjob 2
2316 * 5 printer 3 name 3
2317 * 6 printer 3 name 3
2319 * that's the print server case, the printer case is even worse.
2322 /*******************************************************************
2324 * enumerate all printers on the printserver
2325 * fill a notify_info struct with info asked
2327 ********************************************************************/
2329 static uint32
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
2330 SPOOL_NOTIFY_INFO
*info
,
2331 TALLOC_CTX
*mem_ctx
)
2334 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2335 int n_services
=lp_numservices();
2338 SPOOL_NOTIFY_OPTION
*option
;
2339 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2341 DEBUG(4,("printserver_notify_info\n"));
2343 option
=Printer
->notify
.option
;
2349 for (i
=0; i
<option
->count
; i
++) {
2350 option_type
=&(option
->ctr
.type
[i
]);
2352 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
2355 for (snum
=0; snum
<n_services
; snum
++)
2356 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
2357 if (construct_notify_printer_info
2358 (info
, snum
, option_type
, id
, mem_ctx
))
2363 * Debugging information, don't delete.
2366 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2367 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2368 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2370 for (i=0; i<info->count; i++) {
2371 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2372 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2373 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2377 return NT_STATUS_NO_PROBLEMO
;
2380 /*******************************************************************
2382 * fill a notify_info struct with info asked
2384 ********************************************************************/
2385 static uint32
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
2386 TALLOC_CTX
*mem_ctx
)
2389 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
2392 SPOOL_NOTIFY_OPTION
*option
;
2393 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
2395 print_queue_struct
*queue
=NULL
;
2396 print_status_struct status
;
2398 DEBUG(4,("printer_notify_info\n"));
2400 option
=Printer
->notify
.option
;
2406 get_printer_snum(p
, hnd
, &snum
);
2408 for (i
=0; i
<option
->count
; i
++) {
2409 option_type
=&option
->ctr
.type
[i
];
2411 switch ( option_type
->type
) {
2412 case PRINTER_NOTIFY_TYPE
:
2413 if(construct_notify_printer_info(info
, snum
,
2419 case JOB_NOTIFY_TYPE
: {
2420 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2422 memset(&status
, 0, sizeof(status
));
2423 count
= print_queue_status(snum
, &queue
, &status
);
2425 if (get_a_printer(&printer
, 2,
2426 lp_servicename(snum
)) != 0)
2429 for (j
=0; j
<count
; j
++) {
2430 construct_notify_jobs_info(&queue
[j
], info
,
2437 free_a_printer(&printer
, 2);
2447 * Debugging information, don't delete.
2450 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2451 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2452 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2454 for (i=0; i<info->count; i++) {
2455 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2456 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2457 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2460 return NT_STATUS_NO_PROBLEMO
;
2463 /********************************************************************
2465 ********************************************************************/
2467 uint32
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
2469 POLICY_HND
*handle
= &q_u
->handle
;
2470 /* uint32 change = q_u->change; - notused. */
2471 /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
2472 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
2474 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2475 uint32 result
= ERROR_INVALID_HANDLE
;
2477 /* we always have a NOTIFY_INFO struct */
2481 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",
2482 OUR_HANDLE(handle
)));
2486 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
2488 /* jfm: the change value isn't used right now.
2489 * we will honour it when
2490 * a) we'll be able to send notification to the client
2491 * b) we'll have a way to communicate between the spoolss process.
2493 * same thing for option->flags
2494 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2495 * I don't have a global notification system, I'm sending back all the
2496 * informations even when _NOTHING_ has changed.
2499 /* just ignore the SPOOL_NOTIFY_OPTION */
2501 switch (Printer
->printer_type
) {
2502 case PRINTER_HANDLE_IS_PRINTSERVER
:
2503 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
2506 case PRINTER_HANDLE_IS_PRINTER
:
2507 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
2515 /********************************************************************
2516 * construct_printer_info_0
2517 * fill a printer_info_0 struct
2518 ********************************************************************/
2519 static BOOL
construct_printer_info_0(PRINTER_INFO_0
*printer
, int snum
)
2523 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2524 counter_printer_0
*session_counter
;
2525 uint32 global_counter
;
2529 print_queue_struct
*queue
=NULL
;
2530 print_status_struct status
;
2532 memset(&status
, 0, sizeof(status
));
2534 if (get_a_printer(&ntprinter
, 2, lp_servicename(snum
)) != 0)
2537 count
= print_queue_status(snum
, &queue
, &status
);
2539 /* check if we already have a counter for this printer */
2540 session_counter
= (counter_printer_0
*)ubi_dlFirst(&counter_list
);
2542 for(; session_counter
; session_counter
= (counter_printer_0
*)ubi_dlNext(session_counter
)) {
2543 if (session_counter
->snum
== snum
)
2547 /* it's the first time, add it to the list */
2548 if (session_counter
==NULL
) {
2549 if((session_counter
=(counter_printer_0
*)malloc(sizeof(counter_printer_0
))) == NULL
) {
2550 free_a_printer(&ntprinter
, 2);
2553 ZERO_STRUCTP(session_counter
);
2554 session_counter
->snum
=snum
;
2555 session_counter
->counter
=0;
2556 ubi_dlAddHead( &counter_list
, (ubi_dlNode
*)session_counter
);
2560 session_counter
->counter
++;
2563 * the global_counter should be stored in a TDB as it's common to all the clients
2564 * and should be zeroed on samba startup
2566 global_counter
=session_counter
->counter
;
2568 pstrcpy(chaine
,ntprinter
->info_2
->printername
);
2570 init_unistr(&printer
->printername
, chaine
);
2572 slprintf(chaine
,sizeof(chaine
)-1,"\\\\%s", global_myname
);
2573 init_unistr(&printer
->servername
, chaine
);
2575 printer
->cjobs
= count
;
2576 printer
->total_jobs
= 0;
2577 printer
->total_bytes
= 0;
2579 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
2580 t
=gmtime(&setuptime
);
2582 printer
->year
= t
->tm_year
+1900;
2583 printer
->month
= t
->tm_mon
+1;
2584 printer
->dayofweek
= t
->tm_wday
;
2585 printer
->day
= t
->tm_mday
;
2586 printer
->hour
= t
->tm_hour
;
2587 printer
->minute
= t
->tm_min
;
2588 printer
->second
= t
->tm_sec
;
2589 printer
->milliseconds
= 0;
2591 printer
->global_counter
= global_counter
;
2592 printer
->total_pages
= 0;
2593 printer
->major_version
= 0x0004; /* NT 4 */
2594 printer
->build_version
= 0x0565; /* build 1381 */
2595 printer
->unknown7
= 0x1;
2596 printer
->unknown8
= 0x0;
2597 printer
->unknown9
= 0x0;
2598 printer
->session_counter
= session_counter
->counter
;
2599 printer
->unknown11
= 0x0;
2600 printer
->printer_errors
= 0x0; /* number of print failure */
2601 printer
->unknown13
= 0x0;
2602 printer
->unknown14
= 0x1;
2603 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
2604 printer
->unknown16
= 0x0;
2605 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
2606 printer
->unknown18
= 0x0;
2607 printer
->status
= nt_printq_status(status
.status
);
2608 printer
->unknown20
= 0x0;
2609 printer
->c_setprinter
= ntprinter
->info_2
->c_setprinter
; /* how many times setprinter has been called */
2610 printer
->unknown22
= 0x0;
2611 printer
->unknown23
= 0x6; /* 6 ???*/
2612 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
2613 printer
->unknown25
= 0;
2614 printer
->unknown26
= 0;
2615 printer
->unknown27
= 0;
2616 printer
->unknown28
= 0;
2617 printer
->unknown29
= 0;
2620 free_a_printer(&ntprinter
,2);
2624 /********************************************************************
2625 * construct_printer_info_1
2626 * fill a printer_info_1 struct
2627 ********************************************************************/
2628 static BOOL
construct_printer_info_1(uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
2632 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2634 if (get_a_printer(&ntprinter
, 2, lp_servicename(snum
)) != 0)
2637 printer
->flags
=flags
;
2639 if (*ntprinter
->info_2
->comment
== '\0') {
2640 init_unistr(&printer
->comment
, lp_comment(snum
));
2641 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",global_myname
, ntprinter
->info_2
->printername
,
2642 ntprinter
->info_2
->drivername
, lp_comment(snum
));
2645 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2646 slprintf(chaine
,sizeof(chaine
)-1,"%s%s,%s,%s",global_myname
, ntprinter
->info_2
->printername
,
2647 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
2650 slprintf(chaine2
,sizeof(chaine
)-1,"%s", ntprinter
->info_2
->printername
);
2652 init_unistr(&printer
->description
, chaine
);
2653 init_unistr(&printer
->name
, chaine2
);
2655 free_a_printer(&ntprinter
,2);
2660 /****************************************************************************
2661 Free a DEVMODE struct.
2662 ****************************************************************************/
2664 static void free_dev_mode(DEVICEMODE
*dev
)
2670 safe_free(dev
->private);
2675 /****************************************************************************
2676 Create a DEVMODE struct. Returns malloced memory.
2677 ****************************************************************************/
2679 static DEVICEMODE
*construct_dev_mode(int snum
)
2683 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2684 NT_DEVICEMODE
*ntdevmode
= NULL
;
2685 DEVICEMODE
*devmode
= NULL
;
2687 DEBUG(7,("construct_dev_mode\n"));
2689 DEBUGADD(8,("getting printer characteristics\n"));
2691 if ((devmode
= (DEVICEMODE
*)malloc(sizeof(DEVICEMODE
))) == NULL
) {
2692 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
2696 ZERO_STRUCTP(devmode
);
2698 if(get_a_printer(&printer
, 2, lp_servicename(snum
)) != 0)
2701 if (printer
->info_2
->devmode
)
2702 ntdevmode
= dup_nt_devicemode(printer
->info_2
->devmode
);
2704 if (ntdevmode
== NULL
)
2707 DEBUGADD(8,("loading DEVICEMODE\n"));
2709 slprintf(adevice
, sizeof(adevice
)-1, printer
->info_2
->printername
);
2710 init_unistr(&devmode
->devicename
, adevice
);
2712 slprintf(aform
, sizeof(aform
)-1, ntdevmode
->formname
);
2713 init_unistr(&devmode
->formname
, aform
);
2715 devmode
->specversion
= ntdevmode
->specversion
;
2716 devmode
->driverversion
= ntdevmode
->driverversion
;
2717 devmode
->size
= ntdevmode
->size
;
2718 devmode
->driverextra
= ntdevmode
->driverextra
;
2719 devmode
->fields
= ntdevmode
->fields
;
2721 devmode
->orientation
= ntdevmode
->orientation
;
2722 devmode
->papersize
= ntdevmode
->papersize
;
2723 devmode
->paperlength
= ntdevmode
->paperlength
;
2724 devmode
->paperwidth
= ntdevmode
->paperwidth
;
2725 devmode
->scale
= ntdevmode
->scale
;
2726 devmode
->copies
= ntdevmode
->copies
;
2727 devmode
->defaultsource
= ntdevmode
->defaultsource
;
2728 devmode
->printquality
= ntdevmode
->printquality
;
2729 devmode
->color
= ntdevmode
->color
;
2730 devmode
->duplex
= ntdevmode
->duplex
;
2731 devmode
->yresolution
= ntdevmode
->yresolution
;
2732 devmode
->ttoption
= ntdevmode
->ttoption
;
2733 devmode
->collate
= ntdevmode
->collate
;
2734 devmode
->icmmethod
= ntdevmode
->icmmethod
;
2735 devmode
->icmintent
= ntdevmode
->icmintent
;
2736 devmode
->mediatype
= ntdevmode
->mediatype
;
2737 devmode
->dithertype
= ntdevmode
->dithertype
;
2739 if (ntdevmode
->private != NULL
) {
2740 if ((devmode
->private=(uint8
*)memdup(ntdevmode
->private, ntdevmode
->driverextra
)) == NULL
)
2744 free_nt_devicemode(&ntdevmode
);
2745 free_a_printer(&printer
,2);
2752 free_nt_devicemode(&ntdevmode
);
2754 free_a_printer(&printer
,2);
2755 free_dev_mode(devmode
);
2760 /********************************************************************
2761 * construct_printer_info_2
2762 * fill a printer_info_2 struct
2763 ********************************************************************/
2765 static BOOL
construct_printer_info_2(PRINTER_INFO_2
*printer
, int snum
)
2768 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2770 print_queue_struct
*queue
=NULL
;
2771 print_status_struct status
;
2772 memset(&status
, 0, sizeof(status
));
2774 if (get_a_printer(&ntprinter
, 2, lp_servicename(snum
)) !=0 )
2777 memset(&status
, 0, sizeof(status
));
2778 count
= print_queue_status(snum
, &queue
, &status
);
2780 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
2781 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
2782 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
2783 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
2784 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
2786 if (*ntprinter
->info_2
->comment
== '\0')
2787 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
2789 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
2791 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
2792 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
2793 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
2794 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
2795 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
2797 printer
->attributes
= ntprinter
->info_2
->attributes
;
2799 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
2800 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
2801 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
2802 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
2803 printer
->status
= nt_printq_status(status
.status
); /* status */
2804 printer
->cjobs
= count
; /* jobs */
2805 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
2807 if((printer
->devmode
= construct_dev_mode(snum
)) == NULL
) {
2808 DEBUG(8, ("Returning NULL Devicemode!\n"));
2811 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2812 /* steal the printer info sec_desc structure. [badly done]. */
2813 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2814 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen memory. */
2815 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen memory. */
2816 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen memory. */
2819 printer
->secdesc
= NULL
;
2822 free_a_printer(&ntprinter
, 2);
2827 /********************************************************************
2828 * construct_printer_info_3
2829 * fill a printer_info_3 struct
2830 ********************************************************************/
2831 static BOOL
construct_printer_info_3(PRINTER_INFO_3
**pp_printer
, int snum
)
2833 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
2834 PRINTER_INFO_3
*printer
= NULL
;
2836 if (get_a_printer(&ntprinter
, 2, lp_servicename(snum
)) !=0 )
2840 if ((printer
= (PRINTER_INFO_3
*)malloc(sizeof(PRINTER_INFO_3
))) == NULL
) {
2841 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
2845 ZERO_STRUCTP(printer
);
2847 printer
->flags
= 4; /* These are the components of the SD we are returning. */
2848 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
2849 /* steal the printer info sec_desc structure. [badly done]. */
2850 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
2854 * Set the flags for the components we are returning.
2857 if (printer
->secdesc
->owner_sid
)
2858 printer
->flags
|= OWNER_SECURITY_INFORMATION
;
2860 if (printer
->secdesc
->grp_sid
)
2861 printer
->flags
|= GROUP_SECURITY_INFORMATION
;
2863 if (printer
->secdesc
->dacl
)
2864 printer
->flags
|= DACL_SECURITY_INFORMATION
;
2866 if (printer
->secdesc
->sacl
)
2867 printer
->flags
|= SACL_SECURITY_INFORMATION
;
2870 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen the malloced memory. */
2871 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen the malloced memory. */
2872 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen the malloced memory. */
2875 free_a_printer(&ntprinter
, 2);
2877 *pp_printer
= printer
;
2881 /********************************************************************
2882 Spoolss_enumprinters.
2883 ********************************************************************/
2884 static BOOL
enum_all_printers_info_1(uint32 flags
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2888 int n_services
=lp_numservices();
2889 PRINTER_INFO_1
*printers
=NULL
;
2890 PRINTER_INFO_1 current_prt
;
2892 DEBUG(4,("enum_all_printers_info_1\n"));
2894 for (snum
=0; snum
<n_services
; snum
++) {
2895 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
2896 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
2898 if (construct_printer_info_1(flags
, ¤t_prt
, snum
)) {
2899 if((printers
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_1
))) == NULL
) {
2901 return ERROR_NOT_ENOUGH_MEMORY
;
2903 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
2904 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
2910 /* check the required size. */
2911 for (i
=0; i
<*returned
; i
++)
2912 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
2914 if (!alloc_buffer_size(buffer
, *needed
))
2915 return ERROR_INSUFFICIENT_BUFFER
;
2917 /* fill the buffer with the structures */
2918 for (i
=0; i
<*returned
; i
++)
2919 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
2922 safe_free(printers
);
2924 if (*needed
> offered
) {
2926 return ERROR_INSUFFICIENT_BUFFER
;
2929 return NT_STATUS_NO_PROBLEMO
;
2932 /********************************************************************
2933 enum_all_printers_info_1_local.
2934 *********************************************************************/
2935 static BOOL
enum_all_printers_info_1_local(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2937 DEBUG(4,("enum_all_printers_info_1_local\n"));
2939 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
2942 /********************************************************************
2943 enum_all_printers_info_1_name.
2944 *********************************************************************/
2945 static BOOL
enum_all_printers_info_1_name(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2948 DEBUG(4,("enum_all_printers_info_1_name\n"));
2950 fstrcpy(temp
, "\\\\");
2951 fstrcat(temp
, global_myname
);
2953 if (strequal(name
, temp
)) {
2954 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
2957 return ERROR_INVALID_NAME
;
2960 /********************************************************************
2961 enum_all_printers_info_1_remote.
2962 *********************************************************************/
2963 static BOOL
enum_all_printers_info_1_remote(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
2965 PRINTER_INFO_1
*printer
;
2966 fstring printername
;
2969 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2971 /* JFM: currently it's more a place holder than anything else.
2972 * In the spooler world there is a notion of server registration.
2973 * the print servers are registring (sp ?) on the PDC (in the same domain)
2975 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2978 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
2979 return ERROR_NOT_ENOUGH_MEMORY
;
2983 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", global_myname
);
2984 slprintf(desc
, sizeof(desc
)-1,"%s", global_myname
);
2985 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
2987 init_unistr(&printer
->description
, desc
);
2988 init_unistr(&printer
->name
, printername
);
2989 init_unistr(&printer
->comment
, comment
);
2990 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
2992 /* check the required size. */
2993 *needed
+= spoolss_size_printer_info_1(printer
);
2995 if (!alloc_buffer_size(buffer
, *needed
)) {
2997 return ERROR_INSUFFICIENT_BUFFER
;
3000 /* fill the buffer with the structures */
3001 smb_io_printer_info_1("", buffer
, printer
, 0);
3006 if (*needed
> offered
) {
3008 return ERROR_INSUFFICIENT_BUFFER
;
3011 return NT_STATUS_NO_PROBLEMO
;
3014 /********************************************************************
3015 enum_all_printers_info_1_network.
3016 *********************************************************************/
3018 static BOOL
enum_all_printers_info_1_network(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
3020 DEBUG(4,("enum_all_printers_info_1_network\n"));
3022 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
3025 /********************************************************************
3026 * api_spoolss_enumprinters
3028 * called from api_spoolss_enumprinters (see this to understand)
3029 ********************************************************************/
3031 static BOOL
enum_all_printers_info_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
3035 int n_services
=lp_numservices();
3036 PRINTER_INFO_2
*printers
=NULL
;
3037 PRINTER_INFO_2 current_prt
;
3039 for (snum
=0; snum
<n_services
; snum
++) {
3040 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
3041 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
3043 if (construct_printer_info_2(¤t_prt
, snum
)) {
3044 if((printers
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_2
))) == NULL
)
3045 return ERROR_NOT_ENOUGH_MEMORY
;
3046 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
));
3047 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
3053 /* check the required size. */
3054 for (i
=0; i
<*returned
; i
++)
3055 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
3057 if (!alloc_buffer_size(buffer
, *needed
)) {
3058 for (i
=0; i
<*returned
; i
++) {
3059 free_devmode(printers
[i
].devmode
);
3061 safe_free(printers
);
3062 return ERROR_INSUFFICIENT_BUFFER
;
3065 /* fill the buffer with the structures */
3066 for (i
=0; i
<*returned
; i
++)
3067 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
3070 for (i
=0; i
<*returned
; i
++) {
3071 free_devmode(printers
[i
].devmode
);
3073 safe_free(printers
);
3075 if (*needed
> offered
) {
3077 return ERROR_INSUFFICIENT_BUFFER
;
3080 return NT_STATUS_NO_PROBLEMO
;
3083 /********************************************************************
3084 * handle enumeration of printers at level 1
3085 ********************************************************************/
3086 static uint32
enumprinters_level1( uint32 flags
, fstring name
,
3087 NEW_BUFFER
*buffer
, uint32 offered
,
3088 uint32
*needed
, uint32
*returned
)
3090 /* Not all the flags are equals */
3092 if (flags
& PRINTER_ENUM_LOCAL
)
3093 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
3095 if (flags
& PRINTER_ENUM_NAME
)
3096 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
3098 if (flags
& PRINTER_ENUM_REMOTE
)
3099 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
3101 if (flags
& PRINTER_ENUM_NETWORK
)
3102 return enum_all_printers_info_1_network(buffer
, offered
, needed
, returned
);
3104 return NT_STATUS_NO_PROBLEMO
; /* NT4sp5 does that */
3107 /********************************************************************
3108 * handle enumeration of printers at level 2
3109 ********************************************************************/
3110 static uint32
enumprinters_level2( uint32 flags
, fstring servername
,
3111 NEW_BUFFER
*buffer
, uint32 offered
,
3112 uint32
*needed
, uint32
*returned
)
3116 fstrcpy(temp
, "\\\\");
3117 fstrcat(temp
, global_myname
);
3119 if (flags
& PRINTER_ENUM_LOCAL
) {
3120 if (strequal(servername
, temp
))
3121 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3123 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3126 if (flags
& PRINTER_ENUM_NAME
) {
3127 if (strequal(servername
, temp
))
3128 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
3130 return ERROR_INVALID_NAME
;
3133 if (flags
& PRINTER_ENUM_REMOTE
)
3134 return ERROR_INVALID_LEVEL
;
3136 return NT_STATUS_NO_PROBLEMO
;
3139 /********************************************************************
3140 * handle enumeration of printers at level 5
3141 ********************************************************************/
3142 static uint32
enumprinters_level5( uint32 flags
, fstring servername
,
3143 NEW_BUFFER
*buffer
, uint32 offered
,
3144 uint32
*needed
, uint32
*returned
)
3146 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
3147 return NT_STATUS_NO_PROBLEMO
;
3150 /********************************************************************
3151 * api_spoolss_enumprinters
3153 * called from api_spoolss_enumprinters (see this to understand)
3154 ********************************************************************/
3156 uint32
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
3158 uint32 flags
= q_u
->flags
;
3159 UNISTR2
*servername
= &q_u
->servername
;
3160 uint32 level
= q_u
->level
;
3161 NEW_BUFFER
*buffer
= NULL
;
3162 uint32 offered
= q_u
->offered
;
3163 uint32
*needed
= &r_u
->needed
;
3164 uint32
*returned
= &r_u
->returned
;
3168 /* that's an [in out] buffer */
3169 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3170 buffer
= r_u
->buffer
;
3172 DEBUG(4,("_spoolss_enumprinters\n"));
3179 * flags==PRINTER_ENUM_NAME
3180 * if name=="" then enumerates all printers
3181 * if name!="" then enumerate the printer
3182 * flags==PRINTER_ENUM_REMOTE
3183 * name is NULL, enumerate printers
3184 * Level 2: name!="" enumerates printers, name can't be NULL
3185 * Level 3: doesn't exist
3186 * Level 4: does a local registry lookup
3187 * Level 5: same as Level 2
3190 unistr2_to_ascii(name
, servername
, sizeof(name
)-1);
3195 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
3197 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
3199 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
3203 return ERROR_INVALID_LEVEL
;
3207 /****************************************************************************
3208 ****************************************************************************/
3209 static uint32
getprinter_level_0(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3211 PRINTER_INFO_0
*printer
=NULL
;
3213 if((printer
=(PRINTER_INFO_0
*)malloc(sizeof(PRINTER_INFO_0
))) == NULL
)
3214 return ERROR_NOT_ENOUGH_MEMORY
;
3216 construct_printer_info_0(printer
, snum
);
3218 /* check the required size. */
3219 *needed
+= spoolss_size_printer_info_0(printer
);
3221 if (!alloc_buffer_size(buffer
, *needed
)) {
3223 return ERROR_INSUFFICIENT_BUFFER
;
3226 /* fill the buffer with the structures */
3227 smb_io_printer_info_0("", buffer
, printer
, 0);
3232 if (*needed
> offered
) {
3233 return ERROR_INSUFFICIENT_BUFFER
;
3236 return NT_STATUS_NO_PROBLEMO
;
3239 /****************************************************************************
3240 ****************************************************************************/
3241 static uint32
getprinter_level_1(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3243 PRINTER_INFO_1
*printer
=NULL
;
3245 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
3246 return ERROR_NOT_ENOUGH_MEMORY
;
3248 construct_printer_info_1(PRINTER_ENUM_ICON8
, printer
, snum
);
3250 /* check the required size. */
3251 *needed
+= spoolss_size_printer_info_1(printer
);
3253 if (!alloc_buffer_size(buffer
, *needed
)) {
3255 return ERROR_INSUFFICIENT_BUFFER
;
3258 /* fill the buffer with the structures */
3259 smb_io_printer_info_1("", buffer
, printer
, 0);
3264 if (*needed
> offered
) {
3265 return ERROR_INSUFFICIENT_BUFFER
;
3268 return NT_STATUS_NO_PROBLEMO
;
3271 /****************************************************************************
3272 ****************************************************************************/
3273 static uint32
getprinter_level_2(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3275 PRINTER_INFO_2
*printer
=NULL
;
3277 if((printer
=(PRINTER_INFO_2
*)malloc(sizeof(PRINTER_INFO_2
)))==NULL
)
3278 return ERROR_NOT_ENOUGH_MEMORY
;
3280 construct_printer_info_2(printer
, snum
);
3282 /* check the required size. */
3283 *needed
+= spoolss_size_printer_info_2(printer
);
3285 if (!alloc_buffer_size(buffer
, *needed
)) {
3286 free_printer_info_2(printer
);
3287 return ERROR_INSUFFICIENT_BUFFER
;
3290 /* fill the buffer with the structures */
3291 if (!smb_io_printer_info_2("", buffer
, printer
, 0)) {
3292 free_printer_info_2(printer
);
3293 return ERROR_NOT_ENOUGH_MEMORY
;
3297 free_printer_info_2(printer
);
3299 if (*needed
> offered
) {
3300 return ERROR_INSUFFICIENT_BUFFER
;
3303 return NT_STATUS_NO_PROBLEMO
;
3306 /****************************************************************************
3307 ****************************************************************************/
3308 static uint32
getprinter_level_3(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3310 PRINTER_INFO_3
*printer
=NULL
;
3312 if (!construct_printer_info_3(&printer
, snum
))
3313 return ERROR_NOT_ENOUGH_MEMORY
;
3315 /* check the required size. */
3316 *needed
+= spoolss_size_printer_info_3(printer
);
3318 if (!alloc_buffer_size(buffer
, *needed
)) {
3319 free_printer_info_3(printer
);
3320 return ERROR_INSUFFICIENT_BUFFER
;
3323 /* fill the buffer with the structures */
3324 smb_io_printer_info_3("", buffer
, printer
, 0);
3327 free_printer_info_3(printer
);
3329 if (*needed
> offered
) {
3330 return ERROR_INSUFFICIENT_BUFFER
;
3333 return NT_STATUS_NO_PROBLEMO
;
3336 /****************************************************************************
3337 ****************************************************************************/
3339 uint32
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
3341 POLICY_HND
*handle
= &q_u
->handle
;
3342 uint32 level
= q_u
->level
;
3343 NEW_BUFFER
*buffer
= NULL
;
3344 uint32 offered
= q_u
->offered
;
3345 uint32
*needed
= &r_u
->needed
;
3349 /* that's an [in out] buffer */
3350 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3351 buffer
= r_u
->buffer
;
3355 if (!get_printer_snum(p
, handle
, &snum
))
3356 return ERROR_INVALID_HANDLE
;
3360 return getprinter_level_0(snum
, buffer
, offered
, needed
);
3362 return getprinter_level_1(snum
, buffer
, offered
, needed
);
3364 return getprinter_level_2(snum
, buffer
, offered
, needed
);
3366 return getprinter_level_3(snum
, buffer
, offered
, needed
);
3368 return ERROR_INVALID_LEVEL
;
3372 /********************************************************************
3373 * fill a DRIVER_INFO_1 struct
3374 ********************************************************************/
3375 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
3377 init_unistr( &info
->name
, driver
.info_3
->name
);
3380 /********************************************************************
3381 * construct_printer_driver_info_1
3382 ********************************************************************/
3383 static uint32
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3385 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3386 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3388 ZERO_STRUCT(driver
);
3390 if (get_a_printer(&printer
, 2, lp_servicename(snum
)) != 0)
3391 return ERROR_INVALID_PRINTER_NAME
;
3393 if (get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
) != 0)
3394 return ERROR_UNKNOWN_PRINTER_DRIVER
;
3396 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
3398 free_a_printer(&printer
,2);
3400 return NT_STATUS_NO_PROBLEMO
;
3403 /********************************************************************
3404 * construct_printer_driver_info_2
3405 * fill a printer_info_2 struct
3406 ********************************************************************/
3407 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3411 info
->version
=driver
.info_3
->cversion
;
3413 init_unistr( &info
->name
, driver
.info_3
->name
);
3414 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3417 if (strlen(driver
.info_3
->driverpath
)) {
3418 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3419 init_unistr( &info
->driverpath
, temp
);
3421 init_unistr( &info
->driverpath
, "" );
3423 if (strlen(driver
.info_3
->datafile
)) {
3424 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3425 init_unistr( &info
->datafile
, temp
);
3427 init_unistr( &info
->datafile
, "" );
3429 if (strlen(driver
.info_3
->configfile
)) {
3430 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3431 init_unistr( &info
->configfile
, temp
);
3433 init_unistr( &info
->configfile
, "" );
3436 /********************************************************************
3437 * construct_printer_driver_info_2
3438 * fill a printer_info_2 struct
3439 ********************************************************************/
3440 static uint32
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3442 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3443 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3445 ZERO_STRUCT(printer
);
3446 ZERO_STRUCT(driver
);
3448 if (!get_a_printer(&printer
, 2, lp_servicename(snum
)) != 0)
3449 return ERROR_INVALID_PRINTER_NAME
;
3451 if (!get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
) != 0)
3452 return ERROR_UNKNOWN_PRINTER_DRIVER
;
3454 fill_printer_driver_info_2(info
, driver
, servername
);
3456 free_a_printer(&printer
,2);
3458 return NT_STATUS_NO_PROBLEMO
;
3461 /********************************************************************
3462 * copy a strings array and convert to UNICODE
3464 * convert an array of ascii string to a UNICODE string
3465 ********************************************************************/
3466 static void init_unistr_array(uint16
**uni_array
, fstring
*char_array
, char *servername
)
3473 DEBUG(6,("init_unistr_array\n"));
3477 if (char_array
== NULL
)
3481 if (!v
) v
= ""; /* hack to handle null lists */
3483 if (strlen(v
) == 0) break;
3484 slprintf(line
, sizeof(line
)-1, "\\\\%s%s", servername
, v
);
3485 DEBUGADD(6,("%d:%s:%d\n", i
, line
, strlen(line
)));
3486 if((*uni_array
=Realloc(*uni_array
, (j
+strlen(line
)+2)*sizeof(uint16
))) == NULL
) {
3487 DEBUG(0,("init_unistr_array: Realloc error\n" ));
3490 j
+= (dos_PutUniCode((char *)(*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
), True
) / sizeof(uint16
) );
3495 (*uni_array
)[j
]=0x0000;
3498 DEBUGADD(6,("last one:done\n"));
3501 /********************************************************************
3502 * construct_printer_info_3
3503 * fill a printer_info_3 struct
3504 ********************************************************************/
3505 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3511 info
->version
=driver
.info_3
->cversion
;
3513 init_unistr( &info
->name
, driver
.info_3
->name
);
3514 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3516 if (strlen(driver
.info_3
->driverpath
)) {
3517 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3518 init_unistr( &info
->driverpath
, temp
);
3520 init_unistr( &info
->driverpath
, "" );
3522 if (strlen(driver
.info_3
->datafile
)) {
3523 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3524 init_unistr( &info
->datafile
, temp
);
3526 init_unistr( &info
->datafile
, "" );
3528 if (strlen(driver
.info_3
->configfile
)) {
3529 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3530 init_unistr( &info
->configfile
, temp
);
3532 init_unistr( &info
->configfile
, "" );
3534 if (strlen(driver
.info_3
->helpfile
)) {
3535 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3536 init_unistr( &info
->helpfile
, temp
);
3538 init_unistr( &info
->helpfile
, "" );
3540 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3541 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3543 info
->dependentfiles
=NULL
;
3544 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3547 /********************************************************************
3548 * construct_printer_info_3
3549 * fill a printer_info_3 struct
3550 ********************************************************************/
3551 static uint32
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3553 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3554 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3556 ZERO_STRUCT(driver
);
3558 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3559 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status
));
3561 return ERROR_INVALID_PRINTER_NAME
;
3563 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3564 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status
));
3566 free_a_printer(&printer
,2);
3567 return ERROR_UNKNOWN_PRINTER_DRIVER
;
3570 fill_printer_driver_info_3(info
, driver
, servername
);
3572 free_a_printer(&printer
,2);
3574 return NT_STATUS_NO_PROBLEMO
;
3577 /********************************************************************
3578 * construct_printer_info_6
3579 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
3580 ********************************************************************/
3582 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
3588 memset(&nullstr
, '\0', sizeof(fstring
));
3590 info
->version
=driver
.info_3
->cversion
;
3592 init_unistr( &info
->name
, driver
.info_3
->name
);
3593 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
3595 if (strlen(driver
.info_3
->driverpath
)) {
3596 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
3597 init_unistr( &info
->driverpath
, temp
);
3599 init_unistr( &info
->driverpath
, "" );
3601 if (strlen(driver
.info_3
->datafile
)) {
3602 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
3603 init_unistr( &info
->datafile
, temp
);
3605 init_unistr( &info
->datafile
, "" );
3607 if (strlen(driver
.info_3
->configfile
)) {
3608 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
3609 init_unistr( &info
->configfile
, temp
);
3611 init_unistr( &info
->configfile
, "" );
3613 if (strlen(driver
.info_3
->helpfile
)) {
3614 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
3615 init_unistr( &info
->helpfile
, temp
);
3617 init_unistr( &info
->helpfile
, "" );
3619 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
3620 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
3622 info
->dependentfiles
=NULL
;
3623 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
3625 info
->previousdrivernames
=NULL
;
3626 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
3628 info
->driver_date
.low
=0;
3629 info
->driver_date
.high
=0;
3632 info
->driver_version_low
=0;
3633 info
->driver_version_high
=0;
3635 init_unistr( &info
->mfgname
, "");
3636 init_unistr( &info
->oem_url
, "");
3637 init_unistr( &info
->hardware_id
, "");
3638 init_unistr( &info
->provider
, "");
3641 /********************************************************************
3642 * construct_printer_info_6
3643 * fill a printer_info_6 struct
3644 ********************************************************************/
3645 static uint32
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
3647 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3648 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3650 ZERO_STRUCT(driver
);
3652 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
3653 DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status
));
3655 return ERROR_INVALID_PRINTER_NAME
;
3657 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3658 DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status
));
3661 * Is this a W2k client ?
3665 free_a_printer(&printer
,2);
3666 return ERROR_UNKNOWN_PRINTER_DRIVER
;
3669 /* Yes - try again with a WinNT driver. */
3671 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
3672 DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status
));
3674 free_a_printer(&printer
,2);
3675 return ERROR_UNKNOWN_PRINTER_DRIVER
;
3679 fill_printer_driver_info_6(info
, driver
, servername
);
3681 free_a_printer(&printer
,2);
3683 return NT_STATUS_NO_PROBLEMO
;
3686 /****************************************************************************
3687 ****************************************************************************/
3689 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
3691 safe_free(info
->dependentfiles
);
3694 /****************************************************************************
3695 ****************************************************************************/
3697 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
3699 safe_free(info
->dependentfiles
);
3703 /****************************************************************************
3704 ****************************************************************************/
3705 static uint32
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3707 DRIVER_INFO_1
*info
=NULL
;
3710 if((info
=(DRIVER_INFO_1
*)malloc(sizeof(DRIVER_INFO_1
))) == NULL
)
3711 return ERROR_NOT_ENOUGH_MEMORY
;
3713 status
=construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
3714 if (status
!= NT_STATUS_NO_PROBLEMO
) {
3719 /* check the required size. */
3720 *needed
+= spoolss_size_printer_driver_info_1(info
);
3722 if (!alloc_buffer_size(buffer
, *needed
)) {
3724 return ERROR_INSUFFICIENT_BUFFER
;
3727 /* fill the buffer with the structures */
3728 smb_io_printer_driver_info_1("", buffer
, info
, 0);
3733 if (*needed
> offered
)
3734 return ERROR_INSUFFICIENT_BUFFER
;
3736 return NT_STATUS_NO_PROBLEMO
;
3739 /****************************************************************************
3740 ****************************************************************************/
3741 static uint32
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3743 DRIVER_INFO_2
*info
=NULL
;
3746 if((info
=(DRIVER_INFO_2
*)malloc(sizeof(DRIVER_INFO_2
))) == NULL
)
3747 return ERROR_NOT_ENOUGH_MEMORY
;
3749 status
=construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
3750 if (status
!= NT_STATUS_NO_PROBLEMO
) {
3755 /* check the required size. */
3756 *needed
+= spoolss_size_printer_driver_info_2(info
);
3758 if (!alloc_buffer_size(buffer
, *needed
)) {
3760 return ERROR_INSUFFICIENT_BUFFER
;
3763 /* fill the buffer with the structures */
3764 smb_io_printer_driver_info_2("", buffer
, info
, 0);
3769 if (*needed
> offered
)
3770 return ERROR_INSUFFICIENT_BUFFER
;
3772 return NT_STATUS_NO_PROBLEMO
;
3775 /****************************************************************************
3776 ****************************************************************************/
3777 static uint32
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3784 status
=construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
3785 if (status
!= NT_STATUS_NO_PROBLEMO
) {
3789 /* check the required size. */
3790 *needed
+= spoolss_size_printer_driver_info_3(&info
);
3792 if (!alloc_buffer_size(buffer
, *needed
)) {
3793 free_printer_driver_info_3(&info
);
3794 return ERROR_INSUFFICIENT_BUFFER
;
3797 /* fill the buffer with the structures */
3798 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
3800 free_printer_driver_info_3(&info
);
3802 if (*needed
> offered
)
3803 return ERROR_INSUFFICIENT_BUFFER
;
3805 return NT_STATUS_NO_PROBLEMO
;
3808 /****************************************************************************
3809 ****************************************************************************/
3810 static uint32
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
3817 status
=construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
3818 if (status
!= NT_STATUS_NO_PROBLEMO
) {
3822 /* check the required size. */
3823 *needed
+= spoolss_size_printer_driver_info_6(&info
);
3825 if (!alloc_buffer_size(buffer
, *needed
)) {
3826 free_printer_driver_info_6(&info
);
3827 return ERROR_INSUFFICIENT_BUFFER
;
3830 /* fill the buffer with the structures */
3831 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
3833 free_printer_driver_info_6(&info
);
3835 if (*needed
> offered
)
3836 return ERROR_INSUFFICIENT_BUFFER
;
3838 return NT_STATUS_NO_PROBLEMO
;
3841 /****************************************************************************
3842 ****************************************************************************/
3844 uint32
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
3846 POLICY_HND
*handle
= &q_u
->handle
;
3847 UNISTR2
*uni_arch
= &q_u
->architecture
;
3848 uint32 level
= q_u
->level
;
3849 uint32 clientmajorversion
= q_u
->clientmajorversion
;
3850 /* uint32 clientminorversion = q_u->clientminorversion; - notused. */
3851 NEW_BUFFER
*buffer
= NULL
;
3852 uint32 offered
= q_u
->offered
;
3853 uint32
*needed
= &r_u
->needed
;
3854 uint32
*servermajorversion
= &r_u
->servermajorversion
;
3855 uint32
*serverminorversion
= &r_u
->serverminorversion
;
3858 fstring architecture
;
3861 /* that's an [in out] buffer */
3862 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
3863 buffer
= r_u
->buffer
;
3865 DEBUG(4,("_spoolss_getprinterdriver2\n"));
3868 *servermajorversion
=0;
3869 *serverminorversion
=0;
3871 pstrcpy(servername
, global_myname
);
3872 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
)-1);
3874 if (!get_printer_snum(p
, handle
, &snum
))
3875 return ERROR_INVALID_HANDLE
;
3879 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3881 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3883 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3885 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
3887 return ERROR_INVALID_LEVEL
;
3891 /****************************************************************************
3892 ****************************************************************************/
3894 uint32
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
3896 POLICY_HND
*handle
= &q_u
->handle
;
3898 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3901 Printer
->page_started
=True
;
3905 DEBUG(3,("Error in startpageprinter printer handle\n"));
3906 return ERROR_INVALID_HANDLE
;
3909 /****************************************************************************
3910 ****************************************************************************/
3912 uint32
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
3914 POLICY_HND
*handle
= &q_u
->handle
;
3916 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3919 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle
)));
3920 return ERROR_INVALID_HANDLE
;
3923 Printer
->page_started
=False
;
3925 return NT_STATUS_NO_PROBLEMO
;
3928 /********************************************************************
3929 * api_spoolss_getprinter
3930 * called from the spoolss dispatcher
3932 ********************************************************************/
3934 uint32
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
3936 POLICY_HND
*handle
= &q_u
->handle
;
3937 /* uint32 level = q_u->doc_info_container.level; - notused. */
3938 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
3939 uint32
*jobid
= &r_u
->jobid
;
3941 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
3945 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
3946 struct current_user user
;
3949 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
3950 return ERROR_INVALID_HANDLE
;
3953 get_current_user(&user
, p
);
3956 * a nice thing with NT is it doesn't listen to what you tell it.
3957 * when asked to send _only_ RAW datas, it tries to send datas
3960 * So I add checks like in NT Server ...
3962 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
3963 * there's a bug in NT client-side code, so we'll fix it in the
3964 * server-side code. *nnnnnggggh!*
3967 if (info_1
->p_datatype
!= 0) {
3968 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
3969 if (strcmp(datatype
, "RAW") != 0) {
3971 return ERROR_INVALID_DATATYPE
;
3975 /* get the share number of the printer */
3976 if (!get_printer_snum(p
, handle
, &snum
)) {
3977 return ERROR_INVALID_HANDLE
;
3980 unistr2_to_ascii(jobname
, &info_1
->docname
, sizeof(jobname
));
3982 Printer
->jobid
= print_job_start(&user
, snum
, jobname
);
3984 /* An error occured in print_job_start() so return an appropriate
3987 if (Printer
->jobid
== -1) {
3988 return map_nt_error_from_unix(errno
);
3991 Printer
->document_started
=True
;
3992 (*jobid
) = Printer
->jobid
;
3997 /********************************************************************
3998 * api_spoolss_getprinter
3999 * called from the spoolss dispatcher
4001 ********************************************************************/
4003 uint32
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
4005 POLICY_HND
*handle
= &q_u
->handle
;
4007 return _spoolss_enddocprinter_internal(p
, handle
);
4010 /****************************************************************************
4011 ****************************************************************************/
4013 uint32
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
4015 POLICY_HND
*handle
= &q_u
->handle
;
4016 uint32 buffer_size
= q_u
->buffer_size
;
4017 uint8
*buffer
= q_u
->buffer
;
4018 uint32
*buffer_written
= &q_u
->buffer_size2
;
4020 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4023 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle
)));
4024 r_u
->buffer_written
= q_u
->buffer_size2
;
4025 return ERROR_INVALID_HANDLE
;
4028 (*buffer_written
) = print_job_write(Printer
->jobid
, (char *)buffer
, buffer_size
);
4031 r_u
->buffer_written
= q_u
->buffer_size2
;
4036 /********************************************************************
4037 * api_spoolss_getprinter
4038 * called from the spoolss dispatcher
4040 ********************************************************************/
4041 static uint32
control_printer(POLICY_HND
*handle
, uint32 command
,
4044 struct current_user user
;
4045 int snum
, errcode
= ERROR_INVALID_FUNCTION
;
4046 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4048 get_current_user(&user
, p
);
4051 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4052 return ERROR_INVALID_HANDLE
;
4055 if (!get_printer_snum(p
, handle
, &snum
))
4056 return ERROR_INVALID_HANDLE
;
4059 case PRINTER_CONTROL_PAUSE
:
4060 if (print_queue_pause(&user
, snum
, &errcode
)) {
4064 case PRINTER_CONTROL_RESUME
:
4065 case PRINTER_CONTROL_UNPAUSE
:
4066 if (print_queue_resume(&user
, snum
, &errcode
)) {
4070 case PRINTER_CONTROL_PURGE
:
4071 if (print_queue_purge(&user
, snum
, &errcode
)) {
4076 return ERROR_INVALID_LEVEL
;
4082 /********************************************************************
4083 * api_spoolss_abortprinter
4084 ********************************************************************/
4086 uint32
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
4088 POLICY_HND
*handle
= &q_u
->handle
;
4090 return control_printer(handle
, PRINTER_CONTROL_PURGE
, p
);
4093 /********************************************************************
4094 * called by spoolss_api_setprinter
4095 * when updating a printer description
4096 ********************************************************************/
4097 static uint32
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
4098 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4099 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
4101 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
4102 struct current_user user
;
4106 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4108 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
)) {
4109 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n",
4110 OUR_HANDLE(handle
)));
4112 result
= ERROR_INVALID_HANDLE
;
4116 /* NT seems to like setting the security descriptor even though
4117 nothing may have actually changed. This causes annoying
4118 dialog boxes when the user doesn't have permission to change
4119 the security descriptor. */
4121 nt_printing_getsec(p
->mem_ctx
, Printer
->dev
.handlename
, &old_secdesc_ctr
);
4123 if (DEBUGLEVEL
>= 10) {
4127 the_acl
= old_secdesc_ctr
->sec
->dacl
;
4128 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
4129 PRINTERNAME(snum
), the_acl
->num_aces
));
4131 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4134 sid_to_string(sid_str
, &the_acl
->ace
[i
].sid
);
4136 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4137 the_acl
->ace
[i
].info
.mask
));
4140 the_acl
= secdesc_ctr
->sec
->dacl
;
4143 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4144 PRINTERNAME(snum
), the_acl
->num_aces
));
4146 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4149 sid_to_string(sid_str
, &the_acl
->ace
[i
].sid
);
4151 DEBUG(10, ("%s 0x%08x\n", sid_str
,
4152 the_acl
->ace
[i
].info
.mask
));
4155 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
4159 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
4161 if (sec_desc_equal(new_secdesc_ctr
->sec
, old_secdesc_ctr
->sec
)) {
4162 result
= NT_STATUS_NO_PROBLEMO
;
4166 /* Work out which user is performing the operation */
4168 get_current_user(&user
, p
);
4170 /* Check the user has permissions to change the security
4171 descriptor. By experimentation with two NT machines, the user
4172 requires Full Access to the printer to change security
4175 if (!print_access_check(&user
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4176 result
= ERROR_ACCESS_DENIED
;
4180 result
= nt_printing_setsec(Printer
->dev
.handlename
, new_secdesc_ctr
);
4187 /********************************************************************
4188 Do Samba sanity checks on a printer info struct.
4189 this has changed purpose: it now "canonicalises" printer
4190 info from a client rather than just checking it is correct
4191 ********************************************************************/
4193 static BOOL
check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
4195 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
4196 info
->servername
, info
->printername
, info
->sharename
, info
->portname
, info
->drivername
, info
->comment
, info
->location
));
4198 /* we force some elements to "correct" values */
4199 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname
);
4200 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
4201 global_myname
, lp_servicename(snum
));
4202 fstrcpy(info
->sharename
, lp_servicename(snum
));
4203 info
->attributes
= PRINTER_ATTRIBUTE_SHARED \
4204 | PRINTER_ATTRIBUTE_LOCAL \
4205 | PRINTER_ATTRIBUTE_RAW_ONLY \
4206 | PRINTER_ATTRIBUTE_QUEUED
;
4211 /****************************************************************************
4212 ****************************************************************************/
4213 static BOOL
add_printer_hook(NT_PRINTER_INFO_LEVEL
*printer
)
4215 char *cmd
= lp_addprinter_cmd();
4218 pstring driverlocation
;
4223 /* build driver path... only 9X architecture is needed for legacy reasons */
4224 slprintf(driverlocation
, sizeof(driverlocation
)-1, "\\\\%s\\print$\\WIN40\\0",
4226 /* change \ to \\ for the shell */
4227 all_string_sub(driverlocation
,"\\","\\\\",sizeof(pstring
));
4229 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4230 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
4231 printer
->info_2
->portname
, printer
->info_2
->drivername
,
4232 printer
->info_2
->location
, driverlocation
);
4234 /* Convert script args to unix-codepage */
4235 dos_to_unix(command
, True
);
4236 DEBUG(10,("Running [%s]\n", command
));
4237 ret
= smbrun(command
, &fd
);
4238 DEBUGADD(10,("returned [%d]\n", ret
));
4247 /* Get lines and convert them back to dos-codepage */
4248 qlines
= fd_lines_load(fd
, &numlines
, True
);
4249 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
4253 /* Set the portname to what the script says the portname should be. */
4254 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
4255 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
4257 /* Send SIGHUP to process group... is there a better way? */
4262 file_lines_free(qlines
);
4266 /* Return true if two devicemodes are equal */
4268 #define DEVMODE_CHECK_INT(field) \
4269 if (d1->field != d2->field) { \
4270 DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
4271 d1->field, d2->field)); \
4275 static BOOL
nt_devicemode_equal(NT_DEVICEMODE
*d1
, NT_DEVICEMODE
*d2
)
4277 if (!d1
&& !d2
) goto equal
; /* if both are NULL they are equal */
4280 DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
4281 return False
; /* if either is exclusively NULL are not equal */
4284 if (!strequal(d1
->devicename
, d2
->devicename
)) {
4285 DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1
->devicename
, d2
->devicename
));
4289 if (!strequal(d1
->formname
, d2
->formname
)) {
4290 DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1
->formname
, d2
->formname
));
4294 DEVMODE_CHECK_INT(specversion
);
4295 DEVMODE_CHECK_INT(driverversion
);
4296 DEVMODE_CHECK_INT(driverextra
);
4297 DEVMODE_CHECK_INT(orientation
);
4298 DEVMODE_CHECK_INT(papersize
);
4299 DEVMODE_CHECK_INT(paperlength
);
4300 DEVMODE_CHECK_INT(paperwidth
);
4301 DEVMODE_CHECK_INT(scale
);
4302 DEVMODE_CHECK_INT(copies
);
4303 DEVMODE_CHECK_INT(defaultsource
);
4304 DEVMODE_CHECK_INT(printquality
);
4305 DEVMODE_CHECK_INT(color
);
4306 DEVMODE_CHECK_INT(duplex
);
4307 DEVMODE_CHECK_INT(yresolution
);
4308 DEVMODE_CHECK_INT(ttoption
);
4309 DEVMODE_CHECK_INT(collate
);
4310 DEVMODE_CHECK_INT(logpixels
);
4312 DEVMODE_CHECK_INT(fields
);
4313 DEVMODE_CHECK_INT(bitsperpel
);
4314 DEVMODE_CHECK_INT(pelswidth
);
4315 DEVMODE_CHECK_INT(pelsheight
);
4316 DEVMODE_CHECK_INT(displayflags
);
4317 DEVMODE_CHECK_INT(displayfrequency
);
4318 DEVMODE_CHECK_INT(icmmethod
);
4319 DEVMODE_CHECK_INT(icmintent
);
4320 DEVMODE_CHECK_INT(mediatype
);
4321 DEVMODE_CHECK_INT(dithertype
);
4322 DEVMODE_CHECK_INT(reserved1
);
4323 DEVMODE_CHECK_INT(reserved2
);
4324 DEVMODE_CHECK_INT(panningwidth
);
4325 DEVMODE_CHECK_INT(panningheight
);
4327 /* compare the private data if it exists */
4328 if (!d1
->driverextra
&& !d2
->driverextra
) goto equal
;
4331 DEVMODE_CHECK_INT(driverextra
);
4333 if (memcmp(d1
->private, d2
->private, d1
->driverextra
)) {
4334 DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
4339 DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
4343 /* Return true if two NT_PRINTER_PARAM structures are equal */
4345 static BOOL
nt_printer_param_equal(NT_PRINTER_PARAM
*p1
,
4346 NT_PRINTER_PARAM
*p2
)
4348 if (!p1
&& !p2
) goto equal
;
4350 if ((!p1
&& p2
) || (p1
&& !p2
)) {
4351 DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
4355 /* Compare lists of printer parameters */
4359 NT_PRINTER_PARAM
*q
= p1
;
4361 /* Find the parameter in the second structure */
4365 if (strequal(p1
->value
, q
->value
)) {
4367 if (p1
->type
!= q
->type
) {
4368 DEBUG(10, ("nt_printer_param_equal():"
4369 "types for %s differ (%d != %d)\n",
4370 p1
->value
, p1
->type
,
4375 if (p1
->data_len
!= q
->data_len
) {
4376 DEBUG(10, ("nt_printer_param_equal():"
4377 "len for %s differs (%d != %d)\n",
4378 p1
->value
, p1
->data_len
,
4383 if (memcmp(p1
->data
, q
->data
, p1
->data_len
) == 0) {
4386 DEBUG(10, ("nt_printer_param_equal():"
4387 "data for %s differs\n", p1
->value
));
4397 DEBUG(10, ("nt_printer_param_equal(): param %s "
4398 "does not exist\n", p1
->value
));
4407 DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
4411 /********************************************************************
4412 * Called by update_printer when trying to work out whether to
4413 * actually update printer info.
4414 ********************************************************************/
4416 #define PI_CHECK_INT(field) \
4417 if (pi1->field != pi2->field) { \
4418 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
4419 pi1->field, pi2->field)); \
4423 #define PI_CHECK_STR(field) \
4424 if (!strequal(pi1->field, pi2->field)) { \
4425 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
4426 pi1->field, pi2->field)); \
4430 static BOOL
nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL
*p1
,
4431 NT_PRINTER_INFO_LEVEL
*p2
)
4433 NT_PRINTER_INFO_LEVEL_2
*pi1
, *pi2
;
4435 /* Trivial conditions */
4437 if ((!p1
&& !p2
) || (!p1
->info_2
&& !p2
->info_2
)) {
4441 if ((!p1
&& p2
) || (p1
&& !p2
) ||
4442 (!p1
->info_2
&& p2
->info_2
) ||
4443 (p1
->info_2
&& !p2
->info_2
)) {
4444 DEBUG(10, ("nt_printer_info_level_equal(): info levels "
4449 /* Compare two nt_printer_info_level structures. Don't compare
4450 status or cjobs as they seem to have something to do with the
4456 /* Don't check the attributes as we stomp on the value in
4457 check_printer_ok() anyway. */
4460 PI_CHECK_INT(attributes
);
4463 PI_CHECK_INT(priority
);
4464 PI_CHECK_INT(default_priority
);
4465 PI_CHECK_INT(starttime
);
4466 PI_CHECK_INT(untiltime
);
4467 PI_CHECK_INT(averageppm
);
4469 /* Yuck - don't check the printername or servername as the
4470 add_a_printer() code plays games with them. You can't
4471 change the printername or the sharename through this interface
4474 PI_CHECK_STR(sharename
);
4475 PI_CHECK_STR(portname
);
4476 PI_CHECK_STR(drivername
);
4477 PI_CHECK_STR(comment
);
4478 PI_CHECK_STR(location
);
4480 if (!nt_devicemode_equal(pi1
->devmode
, pi2
->devmode
)) {
4484 PI_CHECK_STR(sepfile
);
4485 PI_CHECK_STR(printprocessor
);
4486 PI_CHECK_STR(datatype
);
4487 PI_CHECK_STR(parameters
);
4489 if (!nt_printer_param_equal(pi1
->specific
, pi2
->specific
)) {
4493 if (!sec_desc_equal(pi1
->secdesc_buf
->sec
, pi2
->secdesc_buf
->sec
)) {
4497 PI_CHECK_INT(changeid
);
4498 PI_CHECK_INT(c_setprinter
);
4499 PI_CHECK_INT(setuptime
);
4502 DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
4506 /********************************************************************
4507 * called by spoolss_api_setprinter
4508 * when updating a printer description
4509 ********************************************************************/
4511 static uint32
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
4512 const SPOOL_PRINTER_INFO_LEVEL
*info
,
4513 DEVICEMODE
*devmode
)
4516 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
4517 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4520 DEBUG(8,("update_printer\n"));
4522 result
= NT_STATUS_NO_PROBLEMO
;
4525 DEBUG(0,("Send a mail to samba@samba.org\n"));
4526 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
4527 result
= ERROR_INVALID_LEVEL
;
4532 result
= ERROR_INVALID_HANDLE
;
4536 if (!get_printer_snum(p
, handle
, &snum
)) {
4537 result
= ERROR_INVALID_HANDLE
;
4541 if((get_a_printer(&printer
, 2, lp_servicename(snum
)) != 0) ||
4542 (get_a_printer(&old_printer
, 2, lp_servicename(snum
)) != 0)) {
4543 result
= ERROR_INVALID_HANDLE
;
4547 DEBUGADD(8,("Converting info_2 struct\n"));
4550 * convert_printer_info converts the incoming
4551 * info from the client and overwrites the info
4552 * just read from the tdb in the pointer 'printer'.
4555 convert_printer_info(info
, printer
, level
);
4557 if (info
->info_2
->devmode_ptr
!= 0) {
4558 /* we have a valid devmode
4559 convert it and link it*/
4561 DEBUGADD(8,("Converting the devicemode struct\n"));
4562 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
4563 &printer
->info_2
->devmode
)) {
4564 result
= ERROR_NOT_ENOUGH_MEMORY
;
4569 /* Do sanity check on the requested changes for Samba */
4571 if (!check_printer_ok(printer
->info_2
, snum
)) {
4572 result
= ERROR_INVALID_PARAMETER
;
4576 /* NT likes to call this function even though nothing has actually
4577 changed. Check this so the user doesn't end up with an
4578 annoying permission denied dialog box. */
4580 if (nt_printer_info_level_equal(printer
, old_printer
)) {
4581 DEBUG(3, ("printer info has not changed\n"));
4582 result
= NT_STATUS_NO_PROBLEMO
;
4586 /* Check calling user has permission to update printer description */
4588 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4589 DEBUG(3, ("printer property change denied by security "
4591 result
= ERROR_ACCESS_DENIED
;
4595 /* Call addprinter hook */
4597 if (*lp_addprinter_cmd() )
4598 if ( !add_printer_hook(printer
) ) {
4599 result
= ERROR_ACCESS_DENIED
;
4603 /* Update printer info */
4605 if (add_a_printer(*printer
, 2)!=0) {
4606 /* I don't really know what to return here !!! */
4607 result
= ERROR_ACCESS_DENIED
;
4612 free_a_printer(&printer
, 2);
4613 free_a_printer(&old_printer
, 2);
4615 srv_spoolss_sendnotify(p
, handle
);
4620 /****************************************************************************
4621 ****************************************************************************/
4623 uint32
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
4625 POLICY_HND
*handle
= &q_u
->handle
;
4626 uint32 level
= q_u
->level
;
4627 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
4628 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
4629 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
4630 uint32 command
= q_u
->command
;
4632 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4635 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4636 return ERROR_INVALID_HANDLE
;
4639 /* check the level */
4642 return control_printer(handle
, command
, p
);
4644 return update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
4646 return update_printer_sec(handle
, level
, info
, p
,
4649 return ERROR_INVALID_LEVEL
;
4653 /****************************************************************************
4654 ****************************************************************************/
4656 uint32
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
4658 POLICY_HND
*handle
= &q_u
->handle
;
4660 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
4663 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle
)));
4664 return ERROR_INVALID_HANDLE
;
4667 if (Printer
->notify
.client_connected
==True
)
4668 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
4670 Printer
->notify
.flags
=0;
4671 Printer
->notify
.options
=0;
4672 Printer
->notify
.localmachine
[0]='\0';
4673 Printer
->notify
.printerlocal
=0;
4674 if (Printer
->notify
.option
)
4675 free_spool_notify_option(&Printer
->notify
.option
);
4676 Printer
->notify
.client_connected
=False
;
4678 return NT_STATUS_NO_PROBLEMO
;
4681 /****************************************************************************
4682 ****************************************************************************/
4684 uint32
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
4686 /* that's an [in out] buffer (despite appearences to the contrary) */
4687 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4690 return ERROR_INVALID_PARAMETER
; /* this is what a NT server
4691 returns for AddJob. AddJob
4692 must fail on non-local
4696 /****************************************************************************
4697 ****************************************************************************/
4698 static void fill_job_info_1(JOB_INFO_1
*job_info
, print_queue_struct
*queue
,
4699 int position
, int snum
)
4705 t
=gmtime(&queue
->time
);
4706 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
4708 job_info
->jobid
=queue
->job
;
4709 init_unistr(&job_info
->printername
, lp_servicename(snum
));
4710 init_unistr(&job_info
->machinename
, temp_name
);
4711 init_unistr(&job_info
->username
, queue
->user
);
4712 init_unistr(&job_info
->document
, queue
->file
);
4713 init_unistr(&job_info
->datatype
, "RAW");
4714 init_unistr(&job_info
->text_status
, "");
4715 job_info
->status
=nt_printj_status(queue
->status
);
4716 job_info
->priority
=queue
->priority
;
4717 job_info
->position
=position
;
4718 job_info
->totalpages
=0;
4719 job_info
->pagesprinted
=0;
4721 make_systemtime(&job_info
->submitted
, t
);
4724 /****************************************************************************
4725 ****************************************************************************/
4726 static BOOL
fill_job_info_2(JOB_INFO_2
*job_info
, print_queue_struct
*queue
,
4727 int position
, int snum
,
4728 NT_PRINTER_INFO_LEVEL
*ntprinter
)
4734 t
=gmtime(&queue
->time
);
4735 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", global_myname
);
4737 job_info
->jobid
=queue
->job
;
4739 slprintf(chaine
, sizeof(chaine
)-1, "\\\\%s\\%s", global_myname
, ntprinter
->info_2
->printername
);
4741 init_unistr(&job_info
->printername
, chaine
);
4743 init_unistr(&job_info
->machinename
, temp_name
);
4744 init_unistr(&job_info
->username
, queue
->user
);
4745 init_unistr(&job_info
->document
, queue
->file
);
4746 init_unistr(&job_info
->notifyname
, queue
->user
);
4747 init_unistr(&job_info
->datatype
, "RAW");
4748 init_unistr(&job_info
->printprocessor
, "winprint");
4749 init_unistr(&job_info
->parameters
, "");
4750 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
4751 init_unistr(&job_info
->text_status
, "");
4753 /* and here the security descriptor */
4755 job_info
->status
=nt_printj_status(queue
->status
);
4756 job_info
->priority
=queue
->priority
;
4757 job_info
->position
=position
;
4758 job_info
->starttime
=0;
4759 job_info
->untiltime
=0;
4760 job_info
->totalpages
=0;
4761 job_info
->size
=queue
->size
;
4762 make_systemtime(&(job_info
->submitted
), t
);
4763 job_info
->timeelapsed
=0;
4764 job_info
->pagesprinted
=0;
4766 if((job_info
->devmode
= construct_dev_mode(snum
)) == NULL
) {
4773 /****************************************************************************
4774 Enumjobs at level 1.
4775 ****************************************************************************/
4776 static uint32
enumjobs_level1(print_queue_struct
*queue
, int snum
,
4777 NEW_BUFFER
*buffer
, uint32 offered
,
4778 uint32
*needed
, uint32
*returned
)
4783 info
=(JOB_INFO_1
*)malloc(*returned
*sizeof(JOB_INFO_1
));
4787 return ERROR_NOT_ENOUGH_MEMORY
;
4790 for (i
=0; i
<*returned
; i
++)
4791 fill_job_info_1(&info
[i
], &queue
[i
], i
, snum
);
4795 /* check the required size. */
4796 for (i
=0; i
<*returned
; i
++)
4797 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
4799 if (!alloc_buffer_size(buffer
, *needed
)) {
4801 return ERROR_INSUFFICIENT_BUFFER
;
4804 /* fill the buffer with the structures */
4805 for (i
=0; i
<*returned
; i
++)
4806 smb_io_job_info_1("", buffer
, &info
[i
], 0);
4811 if (*needed
> offered
) {
4813 return ERROR_INSUFFICIENT_BUFFER
;
4816 return NT_STATUS_NO_PROBLEMO
;
4819 /****************************************************************************
4820 Enumjobs at level 2.
4821 ****************************************************************************/
4822 static uint32
enumjobs_level2(print_queue_struct
*queue
, int snum
,
4823 NEW_BUFFER
*buffer
, uint32 offered
,
4824 uint32
*needed
, uint32
*returned
)
4826 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4830 info
=(JOB_INFO_2
*)malloc(*returned
*sizeof(JOB_INFO_2
));
4833 return ERROR_NOT_ENOUGH_MEMORY
;
4836 if (get_a_printer(&ntprinter
, 2, lp_servicename(snum
)) !=0) {
4838 return ERROR_NOT_ENOUGH_MEMORY
;
4841 for (i
=0; i
<*returned
; i
++)
4842 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
);
4844 free_a_printer(&ntprinter
, 2);
4847 /* check the required size. */
4848 for (i
=0; i
<*returned
; i
++)
4849 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
4851 if (!alloc_buffer_size(buffer
, *needed
)) {
4853 return ERROR_INSUFFICIENT_BUFFER
;
4856 /* fill the buffer with the structures */
4857 for (i
=0; i
<*returned
; i
++)
4858 smb_io_job_info_2("", buffer
, &info
[i
], 0);
4861 for (i
= 0; i
< *returned
; i
++)
4862 free_job_info_2(&info
[i
]);
4866 if (*needed
> offered
) {
4868 return ERROR_INSUFFICIENT_BUFFER
;
4871 return NT_STATUS_NO_PROBLEMO
;
4874 /****************************************************************************
4876 ****************************************************************************/
4878 uint32
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
4880 POLICY_HND
*handle
= &q_u
->handle
;
4881 /* uint32 firstjob = q_u->firstjob; - notused. */
4882 /* uint32 numofjobs = q_u->numofjobs; - notused. */
4883 uint32 level
= q_u
->level
;
4884 NEW_BUFFER
*buffer
= NULL
;
4885 uint32 offered
= q_u
->offered
;
4886 uint32
*needed
= &r_u
->needed
;
4887 uint32
*returned
= &r_u
->returned
;
4890 print_queue_struct
*queue
=NULL
;
4891 print_status_struct prt_status
;
4893 /* that's an [in out] buffer */
4894 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4895 buffer
= r_u
->buffer
;
4897 DEBUG(4,("_spoolss_enumjobs\n"));
4899 ZERO_STRUCT(prt_status
);
4904 if (!get_printer_snum(p
, handle
, &snum
))
4905 return ERROR_INVALID_HANDLE
;
4907 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
4908 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
4910 if (*returned
== 0) {
4912 return NT_STATUS_NO_PROBLEMO
;
4917 return enumjobs_level1(queue
, snum
, buffer
, offered
, needed
, returned
);
4919 return enumjobs_level2(queue
, snum
, buffer
, offered
, needed
, returned
);
4923 return ERROR_INVALID_LEVEL
;
4927 /****************************************************************************
4928 ****************************************************************************/
4930 uint32
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
4935 /****************************************************************************
4936 ****************************************************************************/
4938 uint32
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
4940 POLICY_HND
*handle
= &q_u
->handle
;
4941 uint32 jobid
= q_u
->jobid
;
4942 /* uint32 level = q_u->level; - notused. */
4943 /* JOB_INFO *ctr = &q_u->ctr; - notused. */
4944 uint32 command
= q_u
->command
;
4946 struct current_user user
;
4947 print_status_struct prt_status
;
4948 int snum
, errcode
= ERROR_INVALID_FUNCTION
;
4950 memset(&prt_status
, 0, sizeof(prt_status
));
4952 if (!get_printer_snum(p
, handle
, &snum
)) {
4953 return ERROR_INVALID_HANDLE
;
4956 if (!print_job_exists(jobid
)) {
4957 return ERROR_INVALID_PRINTER_NAME
;
4960 get_current_user(&user
, p
);
4963 case JOB_CONTROL_CANCEL
:
4964 case JOB_CONTROL_DELETE
:
4965 if (print_job_delete(&user
, jobid
, &errcode
)) {
4969 case JOB_CONTROL_PAUSE
:
4970 if (print_job_pause(&user
, jobid
, &errcode
)) {
4974 case JOB_CONTROL_RESTART
:
4975 case JOB_CONTROL_RESUME
:
4976 if (print_job_resume(&user
, jobid
, &errcode
)) {
4981 return ERROR_INVALID_LEVEL
;
4987 /****************************************************************************
4988 Enumerates all printer drivers at level 1.
4989 ****************************************************************************/
4990 static uint32
enumprinterdrivers_level1(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4995 fstring
*list
= NULL
;
4997 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
4998 DRIVER_INFO_1
*driver_info_1
=NULL
;
5002 #define MAX_VERSION 4
5004 for (version
=0; version
<MAX_VERSION
; version
++) {
5006 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5007 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5010 return ERROR_NOT_ENOUGH_MEMORY
;
5013 if((driver_info_1
=(DRIVER_INFO_1
*)Realloc(driver_info_1
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_1
))) == NULL
) {
5015 return ERROR_NOT_ENOUGH_MEMORY
;
5019 for (i
=0; i
<ndrivers
; i
++) {
5021 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5022 ZERO_STRUCT(driver
);
5023 if ((status
= get_a_printer_driver(&driver
, 3, list
[i
], architecture
, version
)) != 0) {
5027 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
5028 free_a_printer_driver(driver
, 3);
5031 *returned
+=ndrivers
;
5035 /* check the required size. */
5036 for (i
=0; i
<*returned
; i
++) {
5037 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5038 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
5041 if (!alloc_buffer_size(buffer
, *needed
)) {
5042 safe_free(driver_info_1
);
5043 return ERROR_INSUFFICIENT_BUFFER
;
5046 /* fill the buffer with the driver structures */
5047 for (i
=0; i
<*returned
; i
++) {
5048 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5049 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
5052 safe_free(driver_info_1
);
5054 if (*needed
> offered
) {
5056 return ERROR_INSUFFICIENT_BUFFER
;
5059 return NT_STATUS_NO_PROBLEMO
;
5062 /****************************************************************************
5063 Enumerates all printer drivers at level 2.
5064 ****************************************************************************/
5065 static uint32
enumprinterdrivers_level2(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5070 fstring
*list
= NULL
;
5072 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5073 DRIVER_INFO_2
*driver_info_2
=NULL
;
5077 #define MAX_VERSION 4
5079 for (version
=0; version
<MAX_VERSION
; version
++) {
5081 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5082 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5085 return ERROR_NOT_ENOUGH_MEMORY
;
5088 if((driver_info_2
=(DRIVER_INFO_2
*)Realloc(driver_info_2
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_2
))) == NULL
) {
5090 return ERROR_NOT_ENOUGH_MEMORY
;
5094 for (i
=0; i
<ndrivers
; i
++) {
5097 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5098 ZERO_STRUCT(driver
);
5099 if ((status
= get_a_printer_driver(&driver
, 3, list
[i
], architecture
, version
)) != 0) {
5103 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
5104 free_a_printer_driver(driver
, 3);
5107 *returned
+=ndrivers
;
5111 /* check the required size. */
5112 for (i
=0; i
<*returned
; i
++) {
5113 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5114 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
5117 if (!alloc_buffer_size(buffer
, *needed
)) {
5118 safe_free(driver_info_2
);
5119 return ERROR_INSUFFICIENT_BUFFER
;
5122 /* fill the buffer with the form structures */
5123 for (i
=0; i
<*returned
; i
++) {
5124 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5125 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
5128 safe_free(driver_info_2
);
5130 if (*needed
> offered
) {
5132 return ERROR_INSUFFICIENT_BUFFER
;
5135 return NT_STATUS_NO_PROBLEMO
;
5138 /****************************************************************************
5139 Enumerates all printer drivers at level 3.
5140 ****************************************************************************/
5141 static uint32
enumprinterdrivers_level3(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5146 fstring
*list
= NULL
;
5148 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5149 DRIVER_INFO_3
*driver_info_3
=NULL
;
5153 #define MAX_VERSION 4
5155 for (version
=0; version
<MAX_VERSION
; version
++) {
5157 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
5158 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
5161 return ERROR_NOT_ENOUGH_MEMORY
;
5164 if((driver_info_3
=(DRIVER_INFO_3
*)Realloc(driver_info_3
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_3
))) == NULL
) {
5166 return ERROR_NOT_ENOUGH_MEMORY
;
5170 for (i
=0; i
<ndrivers
; i
++) {
5173 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
5174 ZERO_STRUCT(driver
);
5175 if ((status
= get_a_printer_driver(&driver
, 3, list
[i
], architecture
, version
)) != 0) {
5179 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
5180 free_a_printer_driver(driver
, 3);
5183 *returned
+=ndrivers
;
5187 /* check the required size. */
5188 for (i
=0; i
<*returned
; i
++) {
5189 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
5190 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
5193 if (!alloc_buffer_size(buffer
, *needed
)) {
5194 safe_free(driver_info_3
);
5195 return ERROR_INSUFFICIENT_BUFFER
;
5198 /* fill the buffer with the driver structures */
5199 for (i
=0; i
<*returned
; i
++) {
5200 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
5201 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
5204 for (i
=0; i
<*returned
; i
++)
5205 safe_free(driver_info_3
[i
].dependentfiles
);
5207 safe_free(driver_info_3
);
5209 if (*needed
> offered
) {
5211 return ERROR_INSUFFICIENT_BUFFER
;
5214 return NT_STATUS_NO_PROBLEMO
;
5217 /****************************************************************************
5218 Enumerates all printer drivers.
5219 ****************************************************************************/
5221 uint32
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
5223 /* UNISTR2 *name = &q_u->name; - notused. */
5224 UNISTR2
*environment
= &q_u
->environment
;
5225 uint32 level
= q_u
->level
;
5226 NEW_BUFFER
*buffer
= NULL
;
5227 uint32 offered
= q_u
->offered
;
5228 uint32
*needed
= &r_u
->needed
;
5229 uint32
*returned
= &r_u
->returned
;
5231 fstring
*list
= NULL
;
5233 fstring architecture
;
5235 /* that's an [in out] buffer */
5236 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5237 buffer
= r_u
->buffer
;
5239 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
5240 fstrcpy(servername
, global_myname
);
5244 unistr2_to_ascii(architecture
, environment
, sizeof(architecture
)-1);
5248 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
5250 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
5252 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
5256 return ERROR_INVALID_LEVEL
;
5260 /****************************************************************************
5261 ****************************************************************************/
5263 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
5265 form
->flag
=list
->flag
;
5266 init_unistr(&form
->name
, list
->name
);
5267 form
->width
=list
->width
;
5268 form
->length
=list
->length
;
5269 form
->left
=list
->left
;
5270 form
->top
=list
->top
;
5271 form
->right
=list
->right
;
5272 form
->bottom
=list
->bottom
;
5275 /****************************************************************************
5276 ****************************************************************************/
5278 uint32
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
5280 /* POLICY_HND *handle = &q_u->handle; - notused. */
5281 uint32 level
= q_u
->level
;
5282 NEW_BUFFER
*buffer
= NULL
;
5283 uint32 offered
= q_u
->offered
;
5284 uint32
*needed
= &r_u
->needed
;
5285 uint32
*numofforms
= &r_u
->numofforms
;
5286 uint32 numbuiltinforms
;
5288 nt_forms_struct
*list
=NULL
;
5289 nt_forms_struct
*builtinlist
=NULL
;
5294 /* that's an [in out] buffer */
5295 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5296 buffer
= r_u
->buffer
;
5298 DEBUG(4,("_spoolss_enumforms\n"));
5299 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5300 DEBUGADD(5,("Info level [%d]\n", level
));
5302 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
5303 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
5304 *numofforms
= get_ntforms(&list
);
5305 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
5306 *numofforms
+= numbuiltinforms
;
5308 if (*numofforms
== 0) return ERROR_NO_MORE_ITEMS
;
5312 if ((forms_1
=(FORM_1
*)malloc(*numofforms
* sizeof(FORM_1
))) == NULL
) {
5314 return ERROR_NOT_ENOUGH_MEMORY
;
5317 /* construct the list of form structures */
5318 for (i
=0; i
<numbuiltinforms
; i
++) {
5319 DEBUGADD(6,("Filling form number [%d]\n",i
));
5320 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
5323 safe_free(builtinlist
);
5325 for (; i
<*numofforms
; i
++) {
5326 DEBUGADD(6,("Filling form number [%d]\n",i
));
5327 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
5332 /* check the required size. */
5333 for (i
=0; i
<numbuiltinforms
; i
++) {
5334 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5335 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5337 for (; i
<*numofforms
; i
++) {
5338 DEBUGADD(6,("adding form [%d]'s size\n",i
));
5339 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
5342 *needed
=buffer_size
;
5344 if (!alloc_buffer_size(buffer
, buffer_size
)){
5346 return ERROR_INSUFFICIENT_BUFFER
;
5349 /* fill the buffer with the form structures */
5350 for (i
=0; i
<numbuiltinforms
; i
++) {
5351 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5352 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5354 for (; i
<*numofforms
; i
++) {
5355 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
5356 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
5361 if (*needed
> offered
) {
5363 return ERROR_INSUFFICIENT_BUFFER
;
5366 return NT_STATUS_NO_PROBLEMO
;
5370 safe_free(builtinlist
);
5371 return ERROR_INVALID_LEVEL
;
5376 /****************************************************************************
5377 ****************************************************************************/
5379 uint32
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
5381 /* POLICY_HND *handle = &q_u->handle; - notused. */
5382 uint32 level
= q_u
->level
;
5383 UNISTR2
*uni_formname
= &q_u
->formname
;
5384 NEW_BUFFER
*buffer
= NULL
;
5385 uint32 offered
= q_u
->offered
;
5386 uint32
*needed
= &r_u
->needed
;
5388 nt_forms_struct
*list
=NULL
;
5389 nt_forms_struct builtin_form
;
5394 int numofforms
=0, i
=0;
5396 /* that's an [in out] buffer */
5397 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5398 buffer
= r_u
->buffer
;
5400 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
)-1);
5402 DEBUG(4,("_spoolss_getform\n"));
5403 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
5404 DEBUGADD(5,("Info level [%d]\n", level
));
5406 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
5407 if (!foundBuiltin
) {
5408 numofforms
= get_ntforms(&list
);
5409 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
5411 if (numofforms
== 0)
5412 return ERROR_INVALID_HANDLE
;
5418 fill_form_1(&form_1
, &builtin_form
);
5421 /* Check if the requested name is in the list of form structures */
5422 for (i
=0; i
<numofforms
; i
++) {
5424 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
5426 if (strequal(form_name
, list
[i
].name
)) {
5427 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
5428 fill_form_1(&form_1
, &list
[i
]);
5434 if (i
== numofforms
) {
5435 return ERROR_INVALID_HANDLE
;
5438 /* check the required size. */
5440 *needed
=spoolss_size_form_1(&form_1
);
5442 if (!alloc_buffer_size(buffer
, buffer_size
)){
5443 return ERROR_INSUFFICIENT_BUFFER
;
5446 if (*needed
> offered
) {
5447 return ERROR_INSUFFICIENT_BUFFER
;
5450 /* fill the buffer with the form structures */
5451 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
5452 smb_io_form_1("", buffer
, &form_1
, 0);
5454 return NT_STATUS_NO_PROBLEMO
;
5458 return ERROR_INVALID_LEVEL
;
5462 /****************************************************************************
5463 ****************************************************************************/
5464 static void fill_port_1(PORT_INFO_1
*port
, char *name
)
5466 init_unistr(&port
->port_name
, name
);
5469 /****************************************************************************
5470 ****************************************************************************/
5471 static void fill_port_2(PORT_INFO_2
*port
, char *name
)
5473 init_unistr(&port
->port_name
, name
);
5474 init_unistr(&port
->monitor_name
, "Local Monitor");
5475 init_unistr(&port
->description
, "Local Port");
5476 #define PORT_TYPE_WRITE 1
5477 port
->port_type
=PORT_TYPE_WRITE
;
5481 /****************************************************************************
5483 ****************************************************************************/
5484 static uint32
enumports_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5486 PORT_INFO_1
*ports
=NULL
;
5489 if (*lp_enumports_cmd()) {
5490 char *cmd
= lp_enumports_cmd();
5497 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 1);
5499 DEBUG(10,("Running [%s]\n", command
));
5500 ret
= smbrun(command
, &fd
);
5501 DEBUG(10,("Returned [%d]\n", ret
));
5505 /* Is this the best error to return here? */
5506 return ERROR_ACCESS_DENIED
;
5510 qlines
= fd_lines_load(fd
, &numlines
,True
);
5511 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5515 if((ports
=(PORT_INFO_1
*)malloc( numlines
* sizeof(PORT_INFO_1
) )) == NULL
) {
5516 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY
));
5517 file_lines_free(qlines
);
5518 return ERROR_NOT_ENOUGH_MEMORY
;
5521 for (i
=0; i
<numlines
; i
++) {
5522 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5523 fill_port_1(&ports
[i
], qlines
[i
]);
5526 file_lines_free(qlines
);
5529 *returned
= numlines
;
5532 *returned
= 1; /* Sole Samba port returned. */
5534 if((ports
=(PORT_INFO_1
*)malloc( sizeof(PORT_INFO_1
) )) == NULL
)
5535 return ERROR_NOT_ENOUGH_MEMORY
;
5537 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5539 fill_port_1(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5542 /* check the required size. */
5543 for (i
=0; i
<*returned
; i
++) {
5544 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5545 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
5548 if (!alloc_buffer_size(buffer
, *needed
)) {
5550 return ERROR_INSUFFICIENT_BUFFER
;
5553 /* fill the buffer with the ports structures */
5554 for (i
=0; i
<*returned
; i
++) {
5555 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5556 smb_io_port_1("", buffer
, &ports
[i
], 0);
5561 if (*needed
> offered
) {
5563 return ERROR_INSUFFICIENT_BUFFER
;
5566 return NT_STATUS_NO_PROBLEMO
;
5569 /****************************************************************************
5571 ****************************************************************************/
5573 static uint32
enumports_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
5575 PORT_INFO_2
*ports
=NULL
;
5578 if (*lp_enumports_cmd()) {
5579 char *cmd
= lp_enumports_cmd();
5588 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME
)))
5589 path
= lp_pathname(lp_servicenumber(PRINTERS_NAME
));
5591 path
= lp_lockdir();
5593 slprintf(tmp_file
, sizeof(tmp_file
)-1, "%s/smbcmd.%u.", path
, (unsigned int)sys_getpid());
5594 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 2);
5597 DEBUG(10,("Running [%s > %s]\n", command
,tmp_file
));
5598 ret
= smbrun(command
, &fd
);
5599 DEBUGADD(10,("returned [%d]\n", ret
));
5603 /* Is this the best error to return here? */
5604 return ERROR_ACCESS_DENIED
;
5608 qlines
= fd_lines_load(fd
, &numlines
,True
);
5609 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5613 if((ports
=(PORT_INFO_2
*)malloc( numlines
* sizeof(PORT_INFO_2
) )) == NULL
) {
5614 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY
));
5615 file_lines_free(qlines
);
5616 return ERROR_NOT_ENOUGH_MEMORY
;
5619 for (i
=0; i
<numlines
; i
++) {
5620 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
5621 fill_port_2(&(ports
[i
]), qlines
[i
]);
5624 file_lines_free(qlines
);
5627 *returned
= numlines
;
5633 if((ports
=(PORT_INFO_2
*)malloc( sizeof(PORT_INFO_2
) )) == NULL
)
5634 return ERROR_NOT_ENOUGH_MEMORY
;
5636 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
5638 fill_port_2(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
5641 /* check the required size. */
5642 for (i
=0; i
<*returned
; i
++) {
5643 DEBUGADD(6,("adding port [%d]'s size\n", i
));
5644 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
5647 if (!alloc_buffer_size(buffer
, *needed
)) {
5649 return ERROR_INSUFFICIENT_BUFFER
;
5652 /* fill the buffer with the ports structures */
5653 for (i
=0; i
<*returned
; i
++) {
5654 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
5655 smb_io_port_2("", buffer
, &ports
[i
], 0);
5660 if (*needed
> offered
) {
5662 return ERROR_INSUFFICIENT_BUFFER
;
5665 return NT_STATUS_NO_PROBLEMO
;
5668 /****************************************************************************
5670 ****************************************************************************/
5672 uint32
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
5674 /* UNISTR2 *name = &q_u->name; - notused. */
5675 uint32 level
= q_u
->level
;
5676 NEW_BUFFER
*buffer
= NULL
;
5677 uint32 offered
= q_u
->offered
;
5678 uint32
*needed
= &r_u
->needed
;
5679 uint32
*returned
= &r_u
->returned
;
5681 /* that's an [in out] buffer */
5682 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5683 buffer
= r_u
->buffer
;
5685 DEBUG(4,("_spoolss_enumports\n"));
5692 return enumports_level_1(buffer
, offered
, needed
, returned
);
5694 return enumports_level_2(buffer
, offered
, needed
, returned
);
5696 return ERROR_INVALID_LEVEL
;
5700 /****************************************************************************
5701 ****************************************************************************/
5702 static uint32
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
5703 const SPOOL_PRINTER_INFO_LEVEL
*info
,
5704 uint32 unk0
, uint32 unk1
, uint32 unk2
, uint32 unk3
,
5705 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
5708 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5712 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
5713 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
5714 return ERROR_NOT_ENOUGH_MEMORY
;
5717 ZERO_STRUCTP(printer
);
5719 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
5720 convert_printer_info(info
, printer
, 2);
5722 if (*lp_addprinter_cmd() )
5723 if ( !add_printer_hook(printer
) ) {
5724 free_a_printer(&printer
,2);
5725 return ERROR_ACCESS_DENIED
;
5728 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname
,
5729 printer
->info_2
->sharename
);
5731 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
5732 free_a_printer(&printer
,2);
5733 return ERROR_ACCESS_DENIED
;
5736 /* you must be a printer admin to add a new printer */
5737 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
5738 free_a_printer(&printer
,2);
5739 return ERROR_ACCESS_DENIED
;
5743 * Do sanity check on the requested changes for Samba.
5746 if (!check_printer_ok(printer
->info_2
, snum
)) {
5747 free_a_printer(&printer
,2);
5748 return ERROR_INVALID_PARAMETER
;
5751 /* write the ASCII on disk */
5752 if (add_a_printer(*printer
, 2) != 0) {
5753 free_a_printer(&printer
,2);
5754 return ERROR_ACCESS_DENIED
;
5757 if (!open_printer_hnd(p
, handle
, name
)) {
5758 /* Handle open failed - remove addition. */
5759 del_a_printer(printer
->info_2
->sharename
);
5760 free_a_printer(&printer
,2);
5761 return ERROR_ACCESS_DENIED
;
5764 free_a_printer(&printer
,2);
5766 srv_spoolss_sendnotify(p
, handle
);
5768 return NT_STATUS_NO_PROBLEMO
;
5771 /****************************************************************************
5772 ****************************************************************************/
5774 uint32
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
5776 UNISTR2
*uni_srv_name
= &q_u
->server_name
;
5777 uint32 level
= q_u
->level
;
5778 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
5779 uint32 unk0
= q_u
->unk0
;
5780 uint32 unk1
= q_u
->unk1
;
5781 uint32 unk2
= q_u
->unk2
;
5782 uint32 unk3
= q_u
->unk3
;
5783 uint32 user_switch
= q_u
->user_switch
;
5784 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
5785 POLICY_HND
*handle
= &r_u
->handle
;
5789 /* we don't handle yet */
5790 /* but I know what to do ... */
5791 return ERROR_INVALID_LEVEL
;
5793 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
5794 unk0
, unk1
, unk2
, unk3
,
5795 user_switch
, user
, handle
);
5797 return ERROR_INVALID_LEVEL
;
5801 /****************************************************************************
5802 ****************************************************************************/
5804 uint32
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
5806 /* UNISTR2 *server_name = &q_u->server_name; - notused. */
5807 uint32 level
= q_u
->level
;
5808 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
5810 uint32 err
= NT_STATUS_NO_PROBLEMO
;
5811 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5812 struct current_user user
;
5814 ZERO_STRUCT(driver
);
5816 get_current_user(&user
, p
);
5818 convert_printer_driver_info(info
, &driver
, level
);
5820 DEBUG(5,("Cleaning driver's information\n"));
5821 if ((err
= clean_up_driver_struct(driver
, level
, &user
)) != NT_STATUS_NO_PROBLEMO
)
5824 DEBUG(5,("Moving driver to final destination\n"));
5825 if(!move_driver_to_download_area(driver
, level
, &user
, &err
)) {
5827 err
= ERROR_ACCESS_DENIED
;
5831 if (add_a_printer_driver(driver
, level
)!=0) {
5832 err
= ERROR_ACCESS_DENIED
;
5837 free_a_printer_driver(driver
, level
);
5841 /****************************************************************************
5842 ****************************************************************************/
5843 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
5845 init_unistr(&info
->name
, name
);
5848 /****************************************************************************
5849 ****************************************************************************/
5850 static uint32
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5854 pstring short_archi
;
5855 DRIVER_DIRECTORY_1
*info
=NULL
;
5857 unistr2_to_ascii(long_archi
, uni_environment
, sizeof(long_archi
)-1);
5859 if (get_short_archi(short_archi
, long_archi
)==FALSE
)
5860 return ERROR_INVALID_ENVIRONMENT
;
5862 if((info
=(DRIVER_DIRECTORY_1
*)malloc(sizeof(DRIVER_DIRECTORY_1
))) == NULL
)
5863 return ERROR_NOT_ENOUGH_MEMORY
;
5865 slprintf(path
, sizeof(path
)-1, "\\\\%s\\print$\\%s", global_myname
, short_archi
);
5867 DEBUG(4,("printer driver directory: [%s]\n", path
));
5869 fill_driverdir_1(info
, path
);
5871 *needed
+= spoolss_size_driverdir_info_1(info
);
5873 if (!alloc_buffer_size(buffer
, *needed
)) {
5875 return ERROR_INSUFFICIENT_BUFFER
;
5878 smb_io_driverdir_1("", buffer
, info
, 0);
5882 if (*needed
> offered
)
5883 return ERROR_INSUFFICIENT_BUFFER
;
5885 return NT_STATUS_NO_PROBLEMO
;
5888 /****************************************************************************
5889 ****************************************************************************/
5891 uint32
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
5893 UNISTR2
*name
= &q_u
->name
;
5894 UNISTR2
*uni_environment
= &q_u
->environment
;
5895 uint32 level
= q_u
->level
;
5896 NEW_BUFFER
*buffer
= NULL
;
5897 uint32 offered
= q_u
->offered
;
5898 uint32
*needed
= &r_u
->needed
;
5900 /* that's an [in out] buffer */
5901 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5902 buffer
= r_u
->buffer
;
5904 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
5910 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
5912 return ERROR_INVALID_LEVEL
;
5916 /****************************************************************************
5917 ****************************************************************************/
5919 uint32
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
5921 POLICY_HND
*handle
= &q_u
->handle
;
5922 uint32 idx
= q_u
->index
;
5923 uint32 in_value_len
= q_u
->valuesize
;
5924 uint32 in_data_len
= q_u
->datasize
;
5925 uint32
*out_max_value_len
= &r_u
->valuesize
;
5926 uint16
**out_value
= &r_u
->value
;
5927 uint32
*out_value_len
= &r_u
->realvaluesize
;
5928 uint32
*out_type
= &r_u
->type
;
5929 uint32
*out_max_data_len
= &r_u
->datasize
;
5930 uint8
**data_out
= &r_u
->data
;
5931 uint32
*out_data_len
= &r_u
->realdatasize
;
5933 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5938 uint32 biggest_valuesize
;
5939 uint32 biggest_datasize
;
5941 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5946 ZERO_STRUCT(printer
);
5948 *out_max_value_len
=0;
5954 *out_max_data_len
=0;
5958 DEBUG(5,("spoolss_enumprinterdata\n"));
5961 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
5962 return ERROR_INVALID_HANDLE
;
5965 if (!get_printer_snum(p
,handle
, &snum
))
5966 return ERROR_INVALID_HANDLE
;
5968 if (get_a_printer(&printer
, 2, lp_servicename(snum
)) != 0)
5969 return ERROR_INVALID_HANDLE
;
5972 * The NT machine wants to know the biggest size of value and data
5974 * cf: MSDN EnumPrinterData remark section
5976 if ( (in_value_len
==0) && (in_data_len
==0) ) {
5977 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
5981 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
5982 * if this parameter size doesn't exist.
5983 * Ok - my opinion here is that the client is not asking for the greatest
5984 * possible size of all the parameters, but is asking specifically for the size needed
5985 * for this specific parameter. In that case we can remove the loop below and
5986 * simplify this lookup code considerably. JF - comments welcome. JRA.
5989 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
5991 free_a_printer(&printer
, 2);
5992 return ERROR_NO_MORE_ITEMS
;
6000 biggest_valuesize
=0;
6003 while (get_specific_param_by_index(*printer
, 2, param_index
, value
, &data
, &type
, &data_len
)) {
6004 if (strlen(value
) > biggest_valuesize
) biggest_valuesize
=strlen(value
);
6005 if (data_len
> biggest_datasize
) biggest_datasize
=data_len
;
6007 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
, biggest_datasize
));
6015 * I think this is correct, it doesn't break APW and
6016 * allows Gerald's Win32 test programs to work correctly,
6017 * but may need altering.... JRA.
6020 if (param_index
== 0) {
6021 /* No parameters found. */
6022 free_a_printer(&printer
, 2);
6023 return ERROR_NO_MORE_ITEMS
;
6026 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
6027 *out_value_len
=2*(1+biggest_valuesize
);
6028 *out_data_len
=biggest_datasize
;
6030 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
6032 free_a_printer(&printer
, 2);
6033 return NT_STATUS_NO_PROBLEMO
;
6037 * the value len is wrong in NT sp3
6038 * that's the number of bytes not the number of unicode chars
6041 if (!get_specific_param_by_index(*printer
, 2, idx
, value
, &data
, &type
, &data_len
)) {
6043 free_a_printer(&printer
, 2);
6044 return ERROR_NO_MORE_ITEMS
;
6047 free_a_printer(&printer
, 2);
6051 * - counted in bytes in the request
6052 * - counted in UNICODE chars in the max reply
6053 * - counted in bytes in the real size
6055 * take a pause *before* coding not *during* coding
6058 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
6059 if((*out_value
=(uint16
*)talloc_zero(p
->mem_ctx
,in_value_len
*sizeof(uint8
))) == NULL
) {
6061 return ERROR_NOT_ENOUGH_MEMORY
;
6064 *out_value_len
= (uint32
)dos_PutUniCode((char *)*out_value
, value
, in_value_len
, True
);
6068 /* the data is counted in bytes */
6069 *out_max_data_len
=in_data_len
;
6070 if((*data_out
=(uint8
*)talloc_zero(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) {
6072 return ERROR_NOT_ENOUGH_MEMORY
;
6075 memcpy(*data_out
, data
, (size_t)data_len
);
6076 *out_data_len
=data_len
;
6080 return NT_STATUS_NO_PROBLEMO
;
6083 /****************************************************************************
6084 ****************************************************************************/
6086 uint32
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
6088 POLICY_HND
*handle
= &q_u
->handle
;
6089 UNISTR2
*value
= &q_u
->value
;
6090 uint32 type
= q_u
->type
;
6091 /* uint32 max_len = q_u->max_len; - notused. */
6092 uint8
*data
= q_u
->data
;
6093 uint32 real_len
= q_u
->real_len
;
6094 /* uint32 numeric_data = q_u->numeric_data; - notused. */
6096 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6097 NT_PRINTER_PARAM
*param
= NULL
, old_param
;
6099 uint32 status
= 0x0;
6100 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6102 DEBUG(5,("spoolss_setprinterdata\n"));
6105 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6106 return ERROR_INVALID_HANDLE
;
6109 if (!get_printer_snum(p
,handle
, &snum
))
6110 return ERROR_INVALID_HANDLE
;
6112 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6114 return ERROR_INVALID_NAME
;
6116 convert_specific_param(¶m
, value
, type
, data
, real_len
);
6118 /* Check if we are making any changes or not. Return true if
6119 nothing is actually changing. */
6121 ZERO_STRUCT(old_param
);
6123 if (get_specific_param(*printer
, 2, param
->value
, &old_param
.data
,
6124 &old_param
.type
, (uint32
*)&old_param
.data_len
)) {
6126 if (param
->type
== old_param
.type
&&
6127 param
->data_len
== old_param
.data_len
&&
6128 memcmp(param
->data
, old_param
.data
,
6129 old_param
.data_len
) == 0) {
6131 DEBUG(3, ("setprinterdata hasn't changed\n"));
6132 status
= NT_STATUS_NO_PROBLEMO
;
6139 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6140 DEBUG(3, ("security descriptor change denied by existing "
6141 "security descriptor\n"));
6142 status
= ERROR_ACCESS_DENIED
;
6146 unlink_specific_param_if_exist(printer
->info_2
, param
);
6148 add_a_specific_param(printer
->info_2
, ¶m
);
6149 status
= mod_a_printer(*printer
, 2);
6152 free_a_printer(&printer
, 2);
6154 free_nt_printer_param(¶m
);
6155 safe_free(old_param
.data
);
6160 /****************************************************************************
6161 ****************************************************************************/
6163 uint32
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
6165 POLICY_HND
*handle
= &q_u
->handle
;
6166 UNISTR2
*value
= &q_u
->valuename
;
6168 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6169 NT_PRINTER_PARAM param
;
6171 uint32 status
= 0x0;
6172 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
6174 DEBUG(5,("spoolss_deleteprinterdata\n"));
6177 DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6178 return ERROR_INVALID_HANDLE
;
6181 if (!get_printer_snum(p
, handle
, &snum
))
6182 return ERROR_INVALID_HANDLE
;
6184 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6185 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
6186 "change denied by existing security descriptor\n"));
6187 return ERROR_ACCESS_DENIED
;
6190 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
6192 return ERROR_INVALID_NAME
;
6194 ZERO_STRUCTP(¶m
);
6195 unistr2_to_ascii(param
.value
, value
, sizeof(param
.value
)-1);
6197 if(!unlink_specific_param_if_exist(printer
->info_2
, ¶m
))
6198 status
= ERROR_INVALID_PARAMETER
;
6200 status
= mod_a_printer(*printer
, 2);
6202 free_a_printer(&printer
, 2);
6206 /****************************************************************************
6207 ****************************************************************************/
6209 uint32
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
6211 POLICY_HND
*handle
= &q_u
->handle
;
6212 /* uint32 level = q_u->level; - notused. */
6213 FORM
*form
= &q_u
->form
;
6214 nt_forms_struct tmpForm
;
6217 nt_forms_struct
*list
=NULL
;
6218 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6220 DEBUG(5,("spoolss_addform\n"));
6223 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6224 return ERROR_INVALID_HANDLE
;
6227 /* can't add if builtin */
6228 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6229 return ERROR_INVALID_PARAMETER
;
6232 count
=get_ntforms(&list
);
6233 if(!add_a_form(&list
, form
, &count
))
6234 return ERROR_NOT_ENOUGH_MEMORY
;
6235 write_ntforms(&list
, count
);
6242 /****************************************************************************
6243 ****************************************************************************/
6245 uint32
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
6247 POLICY_HND
*handle
= &q_u
->handle
;
6248 UNISTR2
*form_name
= &q_u
->name
;
6249 nt_forms_struct tmpForm
;
6252 nt_forms_struct
*list
=NULL
;
6253 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6255 DEBUG(5,("spoolss_deleteform\n"));
6258 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6259 return ERROR_INVALID_HANDLE
;
6262 /* can't delete if builtin */
6263 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
6264 return ERROR_INVALID_PARAMETER
;
6267 count
= get_ntforms(&list
);
6268 if(!delete_a_form(&list
, form_name
, &count
, &ret
))
6269 return ERROR_INVALID_PARAMETER
;
6276 /****************************************************************************
6277 ****************************************************************************/
6279 uint32
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
6281 POLICY_HND
*handle
= &q_u
->handle
;
6282 /* UNISTR2 *uni_name = &q_u->name; - notused. */
6283 /* uint32 level = q_u->level; - notused. */
6284 FORM
*form
= &q_u
->form
;
6285 nt_forms_struct tmpForm
;
6288 nt_forms_struct
*list
=NULL
;
6289 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6291 DEBUG(5,("spoolss_setform\n"));
6294 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle
)));
6295 return ERROR_INVALID_HANDLE
;
6297 /* can't set if builtin */
6298 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
6299 return ERROR_INVALID_PARAMETER
;
6302 count
=get_ntforms(&list
);
6303 update_a_form(&list
, form
, count
);
6304 write_ntforms(&list
, count
);
6311 /****************************************************************************
6312 enumprintprocessors level 1.
6313 ****************************************************************************/
6314 static uint32
enumprintprocessors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6316 PRINTPROCESSOR_1
*info_1
=NULL
;
6318 if((info_1
= (PRINTPROCESSOR_1
*)malloc(sizeof(PRINTPROCESSOR_1
))) == NULL
)
6319 return ERROR_NOT_ENOUGH_MEMORY
;
6323 init_unistr(&info_1
->name
, "winprint");
6325 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
6327 if (!alloc_buffer_size(buffer
, *needed
))
6328 return ERROR_INSUFFICIENT_BUFFER
;
6330 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
6334 if (*needed
> offered
) {
6336 return ERROR_INSUFFICIENT_BUFFER
;
6339 return NT_STATUS_NO_PROBLEMO
;
6342 /****************************************************************************
6343 ****************************************************************************/
6345 uint32
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
6347 /* UNISTR2 *name = &q_u->name; - notused. */
6348 /* UNISTR2 *environment = &q_u->environment; - notused. */
6349 uint32 level
= q_u
->level
;
6350 NEW_BUFFER
*buffer
= NULL
;
6351 uint32 offered
= q_u
->offered
;
6352 uint32
*needed
= &r_u
->needed
;
6353 uint32
*returned
= &r_u
->returned
;
6355 /* that's an [in out] buffer */
6356 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6357 buffer
= r_u
->buffer
;
6359 DEBUG(5,("spoolss_enumprintprocessors\n"));
6362 * Enumerate the print processors ...
6364 * Just reply with "winprint", to keep NT happy
6365 * and I can use my nice printer checker.
6373 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
6375 return ERROR_INVALID_LEVEL
;
6379 /****************************************************************************
6380 enumprintprocdatatypes level 1.
6381 ****************************************************************************/
6382 static uint32
enumprintprocdatatypes_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6384 PRINTPROCDATATYPE_1
*info_1
=NULL
;
6386 if((info_1
= (PRINTPROCDATATYPE_1
*)malloc(sizeof(PRINTPROCDATATYPE_1
))) == NULL
)
6387 return ERROR_NOT_ENOUGH_MEMORY
;
6391 init_unistr(&info_1
->name
, "RAW");
6393 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
6395 if (!alloc_buffer_size(buffer
, *needed
))
6396 return ERROR_INSUFFICIENT_BUFFER
;
6398 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
6402 if (*needed
> offered
) {
6404 return ERROR_INSUFFICIENT_BUFFER
;
6407 return NT_STATUS_NO_PROBLEMO
;
6410 /****************************************************************************
6411 ****************************************************************************/
6413 uint32
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
6415 /* UNISTR2 *name = &q_u->name; - notused. */
6416 /* UNISTR2 *processor = &q_u->processor; - notused. */
6417 uint32 level
= q_u
->level
;
6418 NEW_BUFFER
*buffer
= NULL
;
6419 uint32 offered
= q_u
->offered
;
6420 uint32
*needed
= &r_u
->needed
;
6421 uint32
*returned
= &r_u
->returned
;
6423 /* that's an [in out] buffer */
6424 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6425 buffer
= r_u
->buffer
;
6427 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
6434 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
6436 return ERROR_INVALID_LEVEL
;
6440 /****************************************************************************
6441 enumprintmonitors level 1.
6442 ****************************************************************************/
6444 static uint32
enumprintmonitors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6446 PRINTMONITOR_1
*info_1
=NULL
;
6448 if((info_1
= (PRINTMONITOR_1
*)malloc(sizeof(PRINTMONITOR_1
))) == NULL
)
6449 return ERROR_NOT_ENOUGH_MEMORY
;
6453 init_unistr(&info_1
->name
, "Local Port");
6455 *needed
+= spoolss_size_printmonitor_info_1(info_1
);
6457 if (!alloc_buffer_size(buffer
, *needed
))
6458 return ERROR_INSUFFICIENT_BUFFER
;
6460 smb_io_printmonitor_info_1("", buffer
, info_1
, 0);
6464 if (*needed
> offered
) {
6466 return ERROR_INSUFFICIENT_BUFFER
;
6469 return NT_STATUS_NO_PROBLEMO
;
6472 /****************************************************************************
6473 enumprintmonitors level 2.
6474 ****************************************************************************/
6475 static uint32
enumprintmonitors_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6477 PRINTMONITOR_2
*info_2
=NULL
;
6479 if((info_2
= (PRINTMONITOR_2
*)malloc(sizeof(PRINTMONITOR_2
))) == NULL
)
6480 return ERROR_NOT_ENOUGH_MEMORY
;
6484 init_unistr(&info_2
->name
, "Local Port");
6485 init_unistr(&info_2
->environment
, "Windows NT X86");
6486 init_unistr(&info_2
->dll_name
, "localmon.dll");
6488 *needed
+= spoolss_size_printmonitor_info_2(info_2
);
6490 if (!alloc_buffer_size(buffer
, *needed
))
6491 return ERROR_INSUFFICIENT_BUFFER
;
6493 smb_io_printmonitor_info_2("", buffer
, info_2
, 0);
6497 if (*needed
> offered
) {
6499 return ERROR_INSUFFICIENT_BUFFER
;
6502 return NT_STATUS_NO_PROBLEMO
;
6505 /****************************************************************************
6506 ****************************************************************************/
6508 uint32
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
6510 /* UNISTR2 *name = &q_u->name; - notused. */
6511 uint32 level
= q_u
->level
;
6512 NEW_BUFFER
*buffer
= NULL
;
6513 uint32 offered
= q_u
->offered
;
6514 uint32
*needed
= &r_u
->needed
;
6515 uint32
*returned
= &r_u
->returned
;
6517 /* that's an [in out] buffer */
6518 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6519 buffer
= r_u
->buffer
;
6521 DEBUG(5,("spoolss_enumprintmonitors\n"));
6524 * Enumerate the print monitors ...
6526 * Just reply with "Local Port", to keep NT happy
6527 * and I can use my nice printer checker.
6535 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
6537 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
6539 return ERROR_INVALID_LEVEL
;
6543 /****************************************************************************
6544 ****************************************************************************/
6545 static uint32
getjob_level_1(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6549 JOB_INFO_1
*info_1
=NULL
;
6551 info_1
=(JOB_INFO_1
*)malloc(sizeof(JOB_INFO_1
));
6553 if (info_1
== NULL
) {
6555 return ERROR_NOT_ENOUGH_MEMORY
;
6558 for (i
=0; i
<count
&& found
==False
; i
++) {
6559 if (queue
[i
].job
==(int)jobid
)
6566 /* I shoud reply something else ... I can't find the good one */
6567 return NT_STATUS_NO_PROBLEMO
;
6570 fill_job_info_1(info_1
, &(queue
[i
-1]), i
, snum
);
6574 *needed
+= spoolss_size_job_info_1(info_1
);
6576 if (!alloc_buffer_size(buffer
, *needed
)) {
6578 return ERROR_INSUFFICIENT_BUFFER
;
6581 smb_io_job_info_1("", buffer
, info_1
, 0);
6585 if (*needed
> offered
)
6586 return ERROR_INSUFFICIENT_BUFFER
;
6588 return NT_STATUS_NO_PROBLEMO
;
6592 /****************************************************************************
6593 ****************************************************************************/
6594 static uint32
getjob_level_2(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
6599 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6601 info_2
=(JOB_INFO_2
*)malloc(sizeof(JOB_INFO_2
));
6603 ZERO_STRUCTP(info_2
);
6605 if (info_2
== NULL
) {
6607 return ERROR_NOT_ENOUGH_MEMORY
;
6610 for (i
=0; i
<count
&& found
==False
; i
++) {
6611 if (queue
[i
].job
==(int)jobid
)
6618 /* I shoud reply something else ... I can't find the good one */
6619 return NT_STATUS_NO_PROBLEMO
;
6622 if (get_a_printer(&ntprinter
, 2, lp_servicename(snum
)) !=0) {
6624 return ERROR_NOT_ENOUGH_MEMORY
;
6627 fill_job_info_2(info_2
, &(queue
[i
-1]), i
, snum
, ntprinter
);
6629 free_a_printer(&ntprinter
, 2);
6632 *needed
+= spoolss_size_job_info_2(info_2
);
6634 if (!alloc_buffer_size(buffer
, *needed
)) {
6636 return ERROR_INSUFFICIENT_BUFFER
;
6639 smb_io_job_info_2("", buffer
, info_2
, 0);
6641 free_job_info_2(info_2
);
6644 if (*needed
> offered
)
6645 return ERROR_INSUFFICIENT_BUFFER
;
6647 return NT_STATUS_NO_PROBLEMO
;
6650 /****************************************************************************
6651 ****************************************************************************/
6653 uint32
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
6655 POLICY_HND
*handle
= &q_u
->handle
;
6656 uint32 jobid
= q_u
->jobid
;
6657 uint32 level
= q_u
->level
;
6658 NEW_BUFFER
*buffer
= NULL
;
6659 uint32 offered
= q_u
->offered
;
6660 uint32
*needed
= &r_u
->needed
;
6664 print_queue_struct
*queue
=NULL
;
6665 print_status_struct prt_status
;
6667 /* that's an [in out] buffer */
6668 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6669 buffer
= r_u
->buffer
;
6671 DEBUG(5,("spoolss_getjob\n"));
6673 memset(&prt_status
, 0, sizeof(prt_status
));
6677 if (!get_printer_snum(p
, handle
, &snum
))
6678 return ERROR_INVALID_HANDLE
;
6680 count
= print_queue_status(snum
, &queue
, &prt_status
);
6682 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
6683 count
, prt_status
.status
, prt_status
.message
));
6687 return getjob_level_1(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
6689 return getjob_level_2(queue
, count
, snum
, jobid
, buffer
, offered
, needed
);
6692 return ERROR_INVALID_LEVEL
;