2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001,
8 * Copyright (C) Gerald Carter 2000-2001,
9 * Copyright (C) Tim Potter 2001-2002.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27 up, all the errors returned are DOS errors, not NT status codes. */
31 #ifndef MAX_OPEN_PRINTER_EXS
32 #define MAX_OPEN_PRINTER_EXS 50
35 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
36 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
37 #define PRINTER_HANDLE_IS_PRINTER 0
38 #define PRINTER_HANDLE_IS_PRINTSERVER 1
47 /* structure to store the printer handles */
48 /* and a reference to what it's pointing to */
49 /* and the notify info asked about */
50 /* that's the central struct */
51 typedef struct _Printer{
52 struct _Printer *prev, *next;
53 BOOL document_started;
55 int jobid; /* jobid in printing backend */
59 fstring printerservername;
62 uint32 access_granted;
68 SPOOL_NOTIFY_OPTION *option;
69 POLICY_HND client_hnd;
70 uint32 client_connected;
78 static Printer_entry *printers_list;
80 typedef struct _counter_printer_0 {
88 static ubi_dlList counter_list;
90 static struct cli_state cli;
91 static uint32 smb_connections=0;
94 /* in printing/nt_printing.c */
95 extern STANDARD_MAPPING printer_std_mapping;
97 #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
98 ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
100 /* translate between internal status numbers and NT status numbers */
101 static int nt_printj_status(int v)
107 return JOB_STATUS_PAUSED;
109 return JOB_STATUS_SPOOLING;
111 return JOB_STATUS_PRINTING;
113 return JOB_STATUS_ERROR;
115 return JOB_STATUS_DELETING;
117 return JOB_STATUS_OFFLINE;
119 return JOB_STATUS_PAPEROUT;
121 return JOB_STATUS_PRINTED;
123 return JOB_STATUS_DELETED;
125 return JOB_STATUS_BLOCKED;
126 case LPQ_USER_INTERVENTION:
127 return JOB_STATUS_USER_INTERVENTION;
132 static int nt_printq_status(int v)
136 return PRINTER_STATUS_PAUSED;
145 /****************************************************************************
146 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
147 ****************************************************************************/
149 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
154 SAFE_FREE((*pp)->ctr.type);
158 /***************************************************************************
159 Disconnect from the client
160 ****************************************************************************/
162 static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
166 /* weird if the test succeds !!! */
167 if (smb_connections==0) {
168 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
172 result = cli_spoolss_reply_close_printer(&cli, cli.mem_ctx, handle);
174 if (!NT_STATUS_IS_OK(result))
175 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n"));
177 /* if it's the last connection, deconnect the IPC$ share */
178 if (smb_connections==1) {
179 if(!spoolss_disconnect_from_client(&cli))
182 message_deregister(MSG_PRINTER_NOTIFY);
188 /****************************************************************************
189 Functions to free a printer entry datastruct.
190 ****************************************************************************/
192 static void free_printer_entry(void *ptr)
194 Printer_entry *Printer = (Printer_entry *)ptr;
196 if (Printer->notify.client_connected==True)
197 srv_spoolss_replycloseprinter(&Printer->notify.client_hnd);
199 Printer->notify.flags=0;
200 Printer->notify.options=0;
201 Printer->notify.localmachine[0]='\0';
202 Printer->notify.printerlocal=0;
203 free_spool_notify_option(&Printer->notify.option);
204 Printer->notify.option=NULL;
205 Printer->notify.client_connected=False;
207 /* Remove from the internal list. */
208 DLIST_REMOVE(printers_list, Printer);
213 /****************************************************************************
214 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
215 ****************************************************************************/
217 SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
219 SPOOL_NOTIFY_OPTION *new_sp = NULL;
224 new_sp = (SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
231 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
233 if (!new_sp->ctr.type) {
242 /****************************************************************************
243 find printer index by handle
244 ****************************************************************************/
246 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
248 Printer_entry *find_printer = NULL;
250 if(!find_policy_by_hnd(p,hnd,(void **)&find_printer)) {
251 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
258 /****************************************************************************
259 Close printer index by handle.
260 ****************************************************************************/
262 static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
264 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
267 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
271 close_policy_hnd(p, hnd);
276 /****************************************************************************
277 Delete a printer given a handle.
278 ****************************************************************************/
280 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
282 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
285 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
289 if (del_a_printer(Printer->dev.handlename) != 0) {
290 DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
294 /* Check calling user has permission to delete printer. Note that
295 since we set the snum parameter to -1 only administrators can
296 delete the printer. This stops people with the Full Control
297 permission from deleting the printer. */
299 if (!print_access_check(NULL, -1, PRINTER_ACCESS_ADMINISTER)) {
300 DEBUG(3, ("printer delete denied by security descriptor\n"));
301 return WERR_ACCESS_DENIED;
304 if (*lp_deleteprinter_cmd()) {
306 char *cmd = lp_deleteprinter_cmd();
311 /* Printer->dev.handlename equals portname equals sharename */
312 slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
313 Printer->dev.handlename);
315 DEBUG(10,("Running [%s]\n", command));
316 ret = smbrun(command, NULL);
318 return WERR_BADFID; /* What to return here? */
320 DEBUGADD(10,("returned [%d]\n", ret));
322 /* Send SIGHUP to process group... is there a better way? */
325 if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
329 return WERR_ACCESS_DENIED;
335 /****************************************************************************
336 Return the snum of a printer corresponding to an handle.
337 ****************************************************************************/
339 static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
341 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
344 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
348 switch (Printer->printer_type) {
349 case PRINTER_HANDLE_IS_PRINTER:
350 DEBUG(4,("short name:%s\n", Printer->dev.handlename));
351 *number = print_queue_snum(Printer->dev.handlename);
352 return (*number != -1);
353 case PRINTER_HANDLE_IS_PRINTSERVER:
360 /****************************************************************************
361 Set printer handle type.
362 Check if it's \\server or \\server\printer
363 ****************************************************************************/
365 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
367 DEBUG(3,("Setting printer type=%s\n", handlename));
369 if ( strlen(handlename) < 3 ) {
370 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
374 /* it's a print server */
375 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
376 DEBUGADD(4,("Printer is a print server\n"));
377 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
381 DEBUGADD(4,("Printer is a printer\n"));
382 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
388 /****************************************************************************
389 Set printer handle name.
390 ****************************************************************************/
392 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
395 int n_services=lp_numservices();
400 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
402 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
403 ZERO_STRUCT(Printer->dev.printerservername);
404 strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
408 if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
411 if (*handlename=='\\') {
412 aprinter=strchr_m(handlename+2, '\\');
419 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
422 * The original code allowed smbd to store a printer name that
423 * was different from the share name. This is not possible
424 * anymore, so I've simplified this loop greatly. Here
425 * we are just verifying that the printer name is a valid
426 * printer service defined in smb.conf
427 * --jerry [Fri Feb 15 11:17:46 CST 2002]
430 for (snum=0; snum<n_services; snum++) {
432 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
435 fstrcpy(sname, lp_servicename(snum));
437 DEBUGADD(5,("share:%s\n",sname));
439 if (! StrCaseCmp(sname, aprinter)) {
448 DEBUGADD(4,("Printer not found\n"));
452 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
454 ZERO_STRUCT(Printer->dev.handlename);
455 fstrcpy(Printer->dev.handlename, sname);
460 /****************************************************************************
461 Find first available printer slot. creates a printer handle for you.
462 ****************************************************************************/
464 static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
466 Printer_entry *new_printer;
468 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
470 if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
473 ZERO_STRUCTP(new_printer);
475 new_printer->notify.option=NULL;
477 /* Add to the internal list. */
478 DLIST_ADD(printers_list, new_printer);
480 if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) {
481 SAFE_FREE(new_printer);
485 if (!set_printer_hnd_printertype(new_printer, name)) {
486 close_printer_handle(p, hnd);
490 if (!set_printer_hnd_name(new_printer, name)) {
491 close_printer_handle(p, hnd);
495 new_printer->access_granted = access_granted;
497 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
502 /****************************************************************************
503 Allocate more memory for a BUFFER.
504 ****************************************************************************/
506 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
514 /* damn, I'm doing the reverse operation of prs_grow() :) */
515 if (buffer_size < prs_data_size(ps))
518 extra_space = buffer_size - prs_data_size(ps);
521 * save the offset and move to the end of the buffer
522 * prs_grow() checks the extra_space against the offset
524 old_offset=prs_offset(ps);
525 prs_set_offset(ps, prs_data_size(ps));
527 if (!prs_grow(ps, extra_space))
530 prs_set_offset(ps, old_offset);
532 buffer->string_at_end=prs_data_size(ps);
536 /***************************************************************************
537 Always give preference Printer_entry.notify.option over
538 Printer_entry.notify.flags. Return True if we should send notification
539 events using SPOOLSS_RRPCN. False means that we should use
540 SPOOLSS_ROUTERREPLYPRINTER.
541 **************************************************************************/
542 static BOOL valid_notify_options(Printer_entry *printer)
544 if (printer->notify.option == NULL)
550 /***************************************************************************
551 Simple check to see if the client motify handle is set to watch for events
552 represented by 'flags'
554 FIXME!!!! only a stub right now --jerry
555 **************************************************************************/
557 static BOOL is_client_monitoring_event(Printer_entry *p, uint32 flags)
563 /***************************************************************************
564 Server wrapper for cli_spoolss_routerreplyprinter() since the client
565 function can only send a single change notification at a time.
567 FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER)
569 **************************************************************************/
571 static NTSTATUS srv_spoolss_routerreplyprinter (struct cli_state *cli, TALLOC_CTX *mem_ctx,
572 POLICY_HND *pol, PRINTER_MESSAGE_INFO *info,
573 NT_PRINTER_INFO_LEVEL *printer)
576 uint32 condition = 0x0;
578 if (info->flags & PRINTER_MESSAGE_DRIVER)
579 condition = PRINTER_CHANGE_SET_PRINTER_DRIVER;
581 result = cli_spoolss_routerreplyprinter(cli, mem_ctx, pol, condition,
582 printer->info_2->changeid);
587 /***********************************************************************
588 Wrapper around the decision of which RPC use to in the change
590 **********************************************************************/
592 static NTSTATUS srv_spoolss_send_event_to_client(Printer_entry* Printer,
593 struct cli_state *cli, PRINTER_MESSAGE_INFO *msg,
594 NT_PRINTER_INFO_LEVEL *info)
598 if (valid_notify_options(Printer)) {
599 /* This is a single call that can send information about multiple changes */
600 if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
601 msg->flags |= PRINTER_MESSAGE_ATTRIBUTES;
602 result = cli_spoolss_reply_rrpcn(cli, cli->mem_ctx, &Printer->notify.client_hnd,
606 /* This requires that the server send an individual event notification for each change */
607 result = srv_spoolss_routerreplyprinter(cli, cli->mem_ctx, &Printer->notify.client_hnd,
615 /***********************************************************************
616 Send a change notication message on all handles which have a call
618 **********************************************************************/
620 static void send_spoolss_event_notification(PRINTER_MESSAGE_INFO *msg)
622 Printer_entry *find_printer;
625 NT_PRINTER_INFO_LEVEL *printer = NULL;
628 DEBUG(0,("send_spoolss_event_notification: NULL msg pointer!\n"));
632 for(find_printer = printers_list; find_printer; find_printer = find_printer->next) {
635 * If the entry has a connected client we send the message. There should
636 * only be one of these normally when dealing with the NT/2k spooler.
637 * However, iterate over all to make sure we deal with user applications
638 * in addition to spooler service.
640 * While we are only maintaining a single connection to the client,
641 * the FindFirstPrinterChangeNotification() call is made on a printer
642 * handle, so "client_connected" represents the whether or not the
643 * client asked for change notication on this handle.
648 if (find_printer->notify.client_connected==True) {
650 /* does the client care about what changed? */
652 if (msg->flags && !is_client_monitoring_event(find_printer, msg->flags)) {
653 DEBUG(10,("send_spoolss_event_notification: Client [%s] not monitoring these events\n",
654 find_printer->client.machine));
658 if (find_printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
659 DEBUG(10,("send_spoolss_event_notification: printserver [%s]\n", find_printer->dev.printerservername ));
661 DEBUG(10,("send_spoolss_event_notification: printer [%s]\n", find_printer->dev.handlename));
664 * if handle is a printer, only send if the printer_name matches.
665 * ...else if handle is a printerserver, send to all
668 if (*msg->printer_name && (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
669 && !strequal(msg->printer_name, find_printer->dev.handlename))
671 DEBUG(10,("send_spoolss_event_notification: ignoring message sent to %s [%s]\n",
672 msg->printer_name, find_printer->dev.handlename ));
677 /* lookup the printer if we have a name if we don't already have a
678 valid NT_PRINTER_INFO_LEVEL structure. And yes I'm assuming we
679 will always have a non-empty msg.printer_name */
681 if (!printer || !printer->info_2 || strcmp(msg->printer_name, printer->info_2->printername))
685 free_a_printer(&printer, 2);
689 wresult = get_a_printer(&printer, 2, msg->printer_name);
690 if (! W_ERROR_IS_OK(wresult))
694 /* issue the client call */
696 result = srv_spoolss_send_event_to_client(find_printer, &cli, msg, printer);
698 if (!NT_STATUS_IS_OK(result)) {
699 DEBUG(10,("send_spoolss_event_notification: Event notification failed [%s]\n",
707 /***************************************************************************
708 Receive the notify message and decode the message. Do not send
709 notification if we sent this originally as that would result in
711 ****************************************************************************/
713 static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
715 PRINTER_MESSAGE_INFO msg;
717 if (len < sizeof(msg)) {
718 DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len));
722 memcpy(&msg, buf, sizeof(PRINTER_MESSAGE_INFO));
724 DEBUG(10,("srv_spoolss_receive_message: Got message printer change [queue = %s] low=0x%x high=0x%x flags=0x%x\n",
725 msg.printer_name, (unsigned int)msg.low, (unsigned int)msg.high, msg.flags ));
727 /* Iterate the printer list */
729 send_spoolss_event_notification(&msg);
733 /***************************************************************************
735 ****************************************************************************/
737 static BOOL srv_spoolss_sendnotify(char* printer_name, uint32 high, uint32 low, uint32 flags)
739 char msg[sizeof(PRINTER_MESSAGE_INFO)];
740 PRINTER_MESSAGE_INFO info;
747 fstrcpy(info.printer_name, printer_name);
749 memcpy(msg, &info, sizeof(PRINTER_MESSAGE_INFO));
751 DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x [%s], flags=0x%x\n",
752 low, high, printer_name, flags));
754 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(PRINTER_MESSAGE_INFO),
760 /********************************************************************
761 Copy routines used by convert_to_openprinterex()
762 *******************************************************************/
764 static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
772 DEBUG (8,("dup_devmode\n"));
774 /* bulk copy first */
776 d = talloc_memdup(ctx, devmode, sizeof(DEVICEMODE));
780 /* dup the pointer members separately */
782 len = unistrlen(devmode->devicename.buffer);
784 d->devicename.buffer = talloc(ctx, len*2);
785 if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
790 len = unistrlen(devmode->formname.buffer);
792 d->devicename.buffer = talloc(ctx, len*2);
793 if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
797 d->private = talloc_memdup(ctx, devmode->private, devmode->driverextra);
802 static void copy_devmode_ctr(TALLOC_CTX *ctx, DEVMODE_CTR *new_ctr, DEVMODE_CTR *ctr)
804 if (!new_ctr || !ctr)
807 DEBUG(8,("copy_devmode_ctr\n"));
809 new_ctr->size = ctr->size;
810 new_ctr->devmode_ptr = ctr->devmode_ptr;
813 new_ctr->devmode = dup_devicemode(ctx, ctr->devmode);
816 static void copy_printer_default(TALLOC_CTX *ctx, PRINTER_DEFAULT *new_def, PRINTER_DEFAULT *def)
818 if (!new_def || !def)
821 DEBUG(8,("copy_printer_defaults\n"));
823 new_def->datatype_ptr = def->datatype_ptr;
825 if (def->datatype_ptr)
826 copy_unistr2(&new_def->datatype, &def->datatype);
828 copy_devmode_ctr(ctx, &new_def->devmode_cont, &def->devmode_cont);
830 new_def->access_required = def->access_required;
833 /********************************************************************
834 * Convert a SPOOL_Q_OPEN_PRINTER structure to a
835 * SPOOL_Q_OPEN_PRINTER_EX structure
836 ********************************************************************/
838 static void convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
843 DEBUG(8,("convert_to_openprinterex\n"));
845 q_u_ex->printername_ptr = q_u->printername_ptr;
847 if (q_u->printername_ptr)
848 copy_unistr2(&q_u_ex->printername, &q_u->printername);
850 copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
853 /********************************************************************
854 * spoolss_open_printer
856 * called from the spoolss dispatcher
857 ********************************************************************/
859 WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u)
861 SPOOL_Q_OPEN_PRINTER_EX q_u_ex;
862 SPOOL_R_OPEN_PRINTER_EX r_u_ex;
870 /* convert the OpenPrinter() call to OpenPrinterEx() */
872 convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u);
874 r_u_ex.status = _spoolss_open_printer_ex(p, &q_u_ex, &r_u_ex);
876 /* convert back to OpenPrinter() */
878 memcpy(r_u, &r_u_ex, sizeof(*r_u));
883 /********************************************************************
884 * spoolss_open_printer
886 * called from the spoolss dispatcher
887 ********************************************************************/
889 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
891 UNISTR2 *printername = NULL;
892 PRINTER_DEFAULT *printer_default = &q_u->printer_default;
893 /* uint32 user_switch = q_u->user_switch; - notused */
894 /* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
895 POLICY_HND *handle = &r_u->handle;
899 struct current_user user;
900 Printer_entry *Printer=NULL;
902 if (q_u->printername_ptr != 0)
903 printername = &q_u->printername;
905 if (printername == NULL)
906 return WERR_INVALID_PRINTER_NAME;
908 /* some sanity check because you can open a printer or a print server */
909 /* aka: \\server\printer or \\server */
910 unistr2_to_ascii(name, printername, sizeof(name)-1);
912 DEBUGADD(3,("checking name: %s\n",name));
914 if (!open_printer_hnd(p, handle, name, 0))
915 return WERR_INVALID_PRINTER_NAME;
917 Printer=find_printer_index_by_hnd(p, handle);
919 DEBUG(0,(" _spoolss_open_printer_ex: logic error. \
920 Can't find printer handle we created for priunter %s\n", name ));
921 close_printer_handle(p,handle);
922 return WERR_INVALID_PRINTER_NAME;
926 if (printer_default->datatype_ptr != NULL)
928 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
929 set_printer_hnd_datatype(handle, datatype);
932 set_printer_hnd_datatype(handle, "");
936 First case: the user is opening the print server:
938 Disallow MS AddPrinterWizard if parameter disables it. A Win2k
939 client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
941 Then both Win2k and WinNT clients try an OpenPrinterEx with
942 SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
943 or if the user is listed in the smb.conf printer admin parameter.
945 Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
946 client view printer folder, but does not show the MSAPW.
948 Note: this test needs code to check access rights here too. Jeremy
949 could you look at this?
952 Second case: the user is opening a printer:
953 NT doesn't let us connect to a printer if the connecting user
954 doesn't have print permission.
958 get_current_user(&user, p);
960 if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) {
961 if (printer_default->access_required == 0) {
964 else if ((printer_default->access_required & SERVER_ACCESS_ADMINISTER ) == SERVER_ACCESS_ADMINISTER) {
966 /* Printserver handles use global struct... */
969 if (!lp_ms_add_printer_wizard()) {
970 close_printer_handle(p, handle);
971 return WERR_ACCESS_DENIED;
973 else if (user.uid == 0 || user_in_list(uidtoname(user.uid), lp_printer_admin(snum))) {
977 close_printer_handle(p, handle);
978 return WERR_ACCESS_DENIED;
984 /* NT doesn't let us connect to a printer if the connecting user
985 doesn't have print permission. */
987 if (!get_printer_snum(p, handle, &snum))
990 se_map_standard(&printer_default->access_required, &printer_std_mapping);
992 /* map an empty access mask to the minimum access mask */
993 if (printer_default->access_required == 0x0)
994 printer_default->access_required = PRINTER_ACCESS_USE;
998 * If we are not serving the printer driver for this printer,
999 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1000 * will keep NT clients happy --jerry
1003 if (lp_use_client_driver(snum)
1004 && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
1006 printer_default->access_required = PRINTER_ACCESS_USE;
1009 if (!print_access_check(&user, snum, printer_default->access_required)) {
1010 DEBUG(3, ("access DENIED for printer open\n"));
1011 close_printer_handle(p, handle);
1012 return WERR_ACCESS_DENIED;
1015 if (printer_default->access_required & PRINTER_ACCESS_ADMINISTER)
1016 printer_default->access_required = PRINTER_ACCESS_ADMINISTER;
1018 printer_default->access_required = PRINTER_ACCESS_USE;
1020 DEBUG(4,("Setting printer access=%x\n", printer_default->access_required));
1021 Printer->access_granted = printer_default->access_required;
1024 * If we have a default device pointer in the
1025 * printer_default struct, then we need to get
1026 * the printer info from the tdb and if there is
1027 * no default devicemode there then we do a *SET*
1028 * here ! This is insanity.... JRA.
1032 * If the openprinterex rpc call contains a devmode,
1033 * it's a per-user one. This per-user devmode is derivated
1034 * from the global devmode. Openprinterex() contains a per-user
1035 * devmode for when you do EMF printing and spooling.
1036 * In the EMF case, the NT workstation is only doing half the job
1037 * of rendering the page. The other half is done by running the printer
1038 * driver on the server.
1039 * The EMF file doesn't contain the page description (paper size, orientation, ...).
1040 * The EMF file only contains what is to be printed on the page.
1041 * So in order for the server to know how to print, the NT client sends
1042 * a devicemode attached to the openprinterex call.
1043 * But this devicemode is short lived, it's only valid for the current print job.
1045 * If Samba would have supported EMF spooling, this devicemode would
1046 * have been attached to the handle, to sent it to the driver to correctly
1047 * rasterize the EMF file.
1049 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
1050 * we just act as a pass-thru between windows and the printer.
1052 * In order to know that Samba supports only RAW spooling, NT has to call
1053 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
1054 * and until NT sends a RAW job, we refuse it.
1056 * But to call getprinter() or startdoc(), you first need a valid handle,
1057 * and to get an handle you have to call openprintex(). Hence why you have
1058 * a devicemode in the openprinterex() call.
1061 * Differences between NT4 and NT 2000.
1064 * On NT4, you only have a global devicemode. This global devicemode can be changed
1065 * by the administrator (or by a user with enough privs). Everytime a user
1066 * wants to print, the devicemode is resetted to the default. In Word, everytime
1067 * you print, the printer's characteristics are always reset to the global devicemode.
1071 * In W2K, there is the notion of per-user devicemode. The first time you use
1072 * a printer, a per-user devicemode is build from the global devicemode.
1073 * If you change your per-user devicemode, it is saved in the registry, under the
1074 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
1075 * printer preferences available.
1077 * To change the per-user devicemode: it's the "Printing Preferences ..." button
1078 * on the General Tab of the printer properties windows.
1080 * To change the global devicemode: it's the "Printing Defaults..." button
1081 * on the Advanced Tab of the printer properties window.
1089 if (printer_default->devmode_cont.devmode != NULL) {
1090 result = printer_write_default_dev( snum, printer_default);
1092 close_printer_handle(p, handle);
1102 /****************************************************************************
1103 ****************************************************************************/
1105 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
1106 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
1112 ret = uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
1121 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
1122 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
1128 printer->info_3=NULL;
1129 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
1133 printer->info_6=NULL;
1134 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
1144 BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
1145 NT_DEVICEMODE **pp_nt_devmode)
1147 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1150 * Ensure nt_devmode is a valid pointer
1151 * as we will be overwriting it.
1154 if (nt_devmode == NULL) {
1155 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1156 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1160 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
1161 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
1163 nt_devmode->specversion=devmode->specversion;
1164 nt_devmode->driverversion=devmode->driverversion;
1165 nt_devmode->size=devmode->size;
1166 nt_devmode->fields=devmode->fields;
1167 nt_devmode->orientation=devmode->orientation;
1168 nt_devmode->papersize=devmode->papersize;
1169 nt_devmode->paperlength=devmode->paperlength;
1170 nt_devmode->paperwidth=devmode->paperwidth;
1171 nt_devmode->scale=devmode->scale;
1172 nt_devmode->copies=devmode->copies;
1173 nt_devmode->defaultsource=devmode->defaultsource;
1174 nt_devmode->printquality=devmode->printquality;
1175 nt_devmode->color=devmode->color;
1176 nt_devmode->duplex=devmode->duplex;
1177 nt_devmode->yresolution=devmode->yresolution;
1178 nt_devmode->ttoption=devmode->ttoption;
1179 nt_devmode->collate=devmode->collate;
1181 nt_devmode->logpixels=devmode->logpixels;
1182 nt_devmode->bitsperpel=devmode->bitsperpel;
1183 nt_devmode->pelswidth=devmode->pelswidth;
1184 nt_devmode->pelsheight=devmode->pelsheight;
1185 nt_devmode->displayflags=devmode->displayflags;
1186 nt_devmode->displayfrequency=devmode->displayfrequency;
1187 nt_devmode->icmmethod=devmode->icmmethod;
1188 nt_devmode->icmintent=devmode->icmintent;
1189 nt_devmode->mediatype=devmode->mediatype;
1190 nt_devmode->dithertype=devmode->dithertype;
1191 nt_devmode->reserved1=devmode->reserved1;
1192 nt_devmode->reserved2=devmode->reserved2;
1193 nt_devmode->panningwidth=devmode->panningwidth;
1194 nt_devmode->panningheight=devmode->panningheight;
1197 * Only change private and driverextra if the incoming devmode
1198 * has a new one. JRA.
1201 if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
1202 SAFE_FREE(nt_devmode->private);
1203 nt_devmode->driverextra=devmode->driverextra;
1204 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
1206 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
1209 *pp_nt_devmode = nt_devmode;
1214 /********************************************************************
1215 * _spoolss_enddocprinter_internal.
1216 ********************************************************************/
1218 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1220 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1223 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
1227 Printer->document_started=False;
1228 print_job_end(Printer->jobid,True);
1229 /* error codes unhandled so far ... */
1234 /********************************************************************
1235 * api_spoolss_closeprinter
1236 ********************************************************************/
1238 WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u)
1240 POLICY_HND *handle = &q_u->handle;
1242 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1244 if (Printer && Printer->document_started)
1245 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1247 if (!close_printer_handle(p, handle))
1250 /* clear the returned printer handle. Observed behavior
1251 from Win2k server. Don't think this really matters.
1252 Previous code just copied the value of the closed
1255 memset(&r_u->handle, '\0', sizeof(r_u->handle));
1260 /********************************************************************
1261 * api_spoolss_deleteprinter
1263 ********************************************************************/
1265 WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u)
1267 POLICY_HND *handle = &q_u->handle;
1268 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1271 if (Printer && Printer->document_started)
1272 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1274 memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
1276 result = delete_printer_handle(p, handle);
1278 update_c_setprinter(False);
1280 if (W_ERROR_IS_OK(result)) {
1281 srv_spoolss_sendnotify(Printer->dev.handlename, 0, PRINTER_CHANGE_DELETE_PRINTER, 0x0);
1287 /*******************************************************************
1288 * static function to lookup the version id corresponding to an
1289 * long architecture string
1290 ******************************************************************/
1292 static int get_version_id (char * arch)
1295 struct table_node archi_table[]= {
1297 {"Windows 4.0", "WIN40", 0 },
1298 {"Windows NT x86", "W32X86", 2 },
1299 {"Windows NT R4000", "W32MIPS", 2 },
1300 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1301 {"Windows NT PowerPC", "W32PPC", 2 },
1305 for (i=0; archi_table[i].long_archi != NULL; i++)
1307 if (strcmp(arch, archi_table[i].long_archi) == 0)
1308 return (archi_table[i].version);
1314 /********************************************************************
1315 * _spoolss_deleteprinterdriver
1317 * We currently delete the driver for the architecture only.
1318 * This can leave the driver for other archtectures. However,
1319 * since every printer associates a "Windows NT x86" driver name
1320 * and we cannot delete that one while it is in use, **and** since
1321 * it is impossible to assign a driver to a Samba printer without
1322 * having the "Windows NT x86" driver installed,...
1324 * ....we should not get into trouble here.
1327 ********************************************************************/
1329 WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
1330 SPOOL_R_DELETEPRINTERDRIVER *r_u)
1334 NT_PRINTER_DRIVER_INFO_LEVEL info;
1337 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
1338 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
1340 /* check that we have a valid driver name first */
1341 if ((version=get_version_id(arch)) == -1) {
1342 /* this is what NT returns */
1343 return WERR_INVALID_ENVIRONMENT;
1347 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
1348 return WERR_UNKNOWN_PRINTER_DRIVER;
1352 if (printer_driver_in_use(arch, driver))
1354 return WERR_PRINTER_DRIVER_IN_USE;
1357 return delete_printer_driver(info.info_3);
1360 /********************************************************************
1361 GetPrinterData on a printer server Handle.
1362 ********************************************************************/
1364 static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
1368 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
1370 if (!strcmp(value, "W3SvcInstalled")) {
1372 if((*data = (uint8 *)talloc_zero(ctx, 4*sizeof(uint8) )) == NULL)
1378 if (!strcmp(value, "BeepEnabled")) {
1380 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1382 SIVAL(*data, 0, 0x00);
1387 if (!strcmp(value, "EventLog")) {
1389 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1391 /* formally was 0x1b */
1392 SIVAL(*data, 0, 0x0);
1397 if (!strcmp(value, "NetPopup")) {
1399 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1401 SIVAL(*data, 0, 0x00);
1406 if (!strcmp(value, "MajorVersion")) {
1408 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1410 SIVAL(*data, 0, 0x03);
1415 if (!strcmp(value, "DefaultSpoolDirectory")) {
1418 fstrcpy(string, string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1420 *needed = 2*(strlen(string)+1);
1421 if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
1423 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
1425 /* it's done by hand ready to go on the wire */
1426 for (i=0; i<strlen(string); i++) {
1427 (*data)[2*i]=string[i];
1428 (*data)[2*i+1]='\0';
1433 if (!strcmp(value, "Architecture")) {
1434 pstring string="Windows NT x86";
1436 *needed = 2*(strlen(string)+1);
1437 if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
1439 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
1440 for (i=0; i<strlen(string); i++) {
1441 (*data)[2*i]=string[i];
1442 (*data)[2*i+1]='\0';
1450 /********************************************************************
1451 GetPrinterData on a printer Handle.
1452 ********************************************************************/
1454 static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND *handle,
1455 fstring value, uint32 *type,
1456 uint8 **data, uint32 *needed, uint32 in_size )
1458 NT_PRINTER_INFO_LEVEL *printer = NULL;
1462 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
1464 DEBUG(5,("getprinterdata_printer\n"));
1467 DEBUG(2,("getprinterdata_printer: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
1471 if(!get_printer_snum(p, handle, &snum))
1474 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
1477 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
1478 free_a_printer(&printer, 2);
1482 free_a_printer(&printer, 2);
1484 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
1487 if((*data = (uint8 *)talloc(ctx, in_size *sizeof(uint8) )) == NULL) {
1491 memset(*data, 0, in_size *sizeof(uint8));
1492 /* copy the min(in_size, len) */
1493 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
1500 DEBUG(5,("getprinterdata_printer:copy done\n"));
1507 /********************************************************************
1508 * spoolss_getprinterdata
1509 ********************************************************************/
1511 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
1513 POLICY_HND *handle = &q_u->handle;
1514 UNISTR2 *valuename = &q_u->valuename;
1515 uint32 in_size = q_u->size;
1516 uint32 *type = &r_u->type;
1517 uint32 *out_size = &r_u->size;
1518 uint8 **data = &r_u->data;
1519 uint32 *needed = &r_u->needed;
1523 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
1526 * Reminder: when it's a string, the length is in BYTES
1527 * even if UNICODE is negociated.
1534 /* in case of problem, return some default values */
1538 DEBUG(4,("_spoolss_getprinterdata\n"));
1541 if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL)
1543 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
1547 unistr2_to_ascii(value, valuename, sizeof(value)-1);
1549 if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
1550 found=getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
1552 found= getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
1555 DEBUG(5, ("value not found, allocating %d\n", *out_size));
1556 /* reply this param doesn't exist */
1558 if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
1564 return WERR_INVALID_PARAM;
1567 if (*needed > *out_size)
1568 return WERR_MORE_DATA;
1573 /***************************************************************************
1574 Connect to the client.
1575 ****************************************************************************/
1577 static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle)
1582 * If it's the first connection, contact the client
1583 * and connect to the IPC$ share anonumously
1585 if (smb_connections==0) {
1586 fstring unix_printer;
1588 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
1590 if(!spoolss_connect_to_client(&cli, unix_printer))
1592 message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message);
1598 result = cli_spoolss_reply_open_printer(&cli, cli.mem_ctx, printer, localprinter,
1601 return (NT_STATUS_IS_OK(result));
1604 /********************************************************************
1606 * ReplyFindFirstPrinterChangeNotifyEx
1608 * jfmxxxx: before replying OK: status=0
1609 * should do a rpc call to the workstation asking ReplyOpenPrinter
1610 * have to code it, later.
1612 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
1613 * called from api_spoolss_rffpcnex
1614 ********************************************************************/
1616 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
1618 POLICY_HND *handle = &q_u->handle;
1619 uint32 flags = q_u->flags;
1620 uint32 options = q_u->options;
1621 UNISTR2 *localmachine = &q_u->localmachine;
1622 uint32 printerlocal = q_u->printerlocal;
1623 SPOOL_NOTIFY_OPTION *option = q_u->option;
1625 /* store the notify value in the printer struct */
1627 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1630 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
1634 Printer->notify.flags=flags;
1635 Printer->notify.options=options;
1636 Printer->notify.printerlocal=printerlocal;
1638 if (Printer->notify.option)
1639 free_spool_notify_option(&Printer->notify.option);
1641 Printer->notify.option=dup_spool_notify_option(option);
1643 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
1645 /* connect to the client machine and send a ReplyOpenPrinter */
1646 if(srv_spoolss_replyopenprinter(Printer->notify.localmachine,
1647 Printer->notify.printerlocal, 1,
1648 &Printer->notify.client_hnd))
1650 Printer->notify.client_connected=True;
1656 /*******************************************************************
1657 * fill a notify_info_data with the servername
1658 ********************************************************************/
1660 void spoolss_notify_server_name(int snum,
1661 SPOOL_NOTIFY_INFO_DATA *data,
1662 print_queue_struct *queue,
1663 NT_PRINTER_INFO_LEVEL *printer,
1664 TALLOC_CTX *mem_ctx)
1666 pstring temp_name, temp;
1669 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
1671 len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE);
1673 data->notify_data.data.length = len / 2 - 1;
1674 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1676 if (!data->notify_data.data.string) {
1677 data->notify_data.data.length = 0;
1681 memcpy(data->notify_data.data.string, temp, len);
1684 /*******************************************************************
1685 * fill a notify_info_data with the printername (not including the servername).
1686 ********************************************************************/
1688 void spoolss_notify_printer_name(int snum,
1689 SPOOL_NOTIFY_INFO_DATA *data,
1690 print_queue_struct *queue,
1691 NT_PRINTER_INFO_LEVEL *printer,
1692 TALLOC_CTX *mem_ctx)
1697 /* the notify name should not contain the \\server\ part */
1698 char *p = strrchr(printer->info_2->printername, '\\');
1701 p = printer->info_2->printername;
1706 len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
1708 data->notify_data.data.length = len / 2 - 1;
1709 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1711 if (!data->notify_data.data.string) {
1712 data->notify_data.data.length = 0;
1716 memcpy(data->notify_data.data.string, temp, len);
1719 /*******************************************************************
1720 * fill a notify_info_data with the servicename
1721 ********************************************************************/
1723 void spoolss_notify_share_name(int snum,
1724 SPOOL_NOTIFY_INFO_DATA *data,
1725 print_queue_struct *queue,
1726 NT_PRINTER_INFO_LEVEL *printer,
1727 TALLOC_CTX *mem_ctx)
1732 len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
1734 data->notify_data.data.length = len / 2 - 1;
1735 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1737 if (!data->notify_data.data.string) {
1738 data->notify_data.data.length = 0;
1742 memcpy(data->notify_data.data.string, temp, len);
1745 /*******************************************************************
1746 * fill a notify_info_data with the port name
1747 ********************************************************************/
1749 void spoolss_notify_port_name(int snum,
1750 SPOOL_NOTIFY_INFO_DATA *data,
1751 print_queue_struct *queue,
1752 NT_PRINTER_INFO_LEVEL *printer,
1753 TALLOC_CTX *mem_ctx)
1758 /* even if it's strange, that's consistant in all the code */
1760 len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
1762 data->notify_data.data.length = len / 2 - 1;
1763 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1765 if (!data->notify_data.data.string) {
1766 data->notify_data.data.length = 0;
1770 memcpy(data->notify_data.data.string, temp, len);
1773 /*******************************************************************
1774 * fill a notify_info_data with the printername
1775 * but it doesn't exist, have to see what to do
1776 ********************************************************************/
1778 void spoolss_notify_driver_name(int snum,
1779 SPOOL_NOTIFY_INFO_DATA *data,
1780 print_queue_struct *queue,
1781 NT_PRINTER_INFO_LEVEL *printer,
1782 TALLOC_CTX *mem_ctx)
1787 len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
1788 data->notify_data.data.length = len / 2 - 1;
1789 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1791 if (!data->notify_data.data.string) {
1792 data->notify_data.data.length = 0;
1796 memcpy(data->notify_data.data.string, temp, len);
1799 /*******************************************************************
1800 * fill a notify_info_data with the comment
1801 ********************************************************************/
1803 void spoolss_notify_comment(int snum,
1804 SPOOL_NOTIFY_INFO_DATA *data,
1805 print_queue_struct *queue,
1806 NT_PRINTER_INFO_LEVEL *printer,
1807 TALLOC_CTX *mem_ctx)
1812 if (*printer->info_2->comment == '\0')
1813 len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE);
1815 len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
1817 data->notify_data.data.length = len / 2 - 1;
1818 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1820 if (!data->notify_data.data.string) {
1821 data->notify_data.data.length = 0;
1825 memcpy(data->notify_data.data.string, temp, len);
1828 /*******************************************************************
1829 * fill a notify_info_data with the comment
1830 * location = "Room 1, floor 2, building 3"
1831 ********************************************************************/
1833 void spoolss_notify_location(int snum,
1834 SPOOL_NOTIFY_INFO_DATA *data,
1835 print_queue_struct *queue,
1836 NT_PRINTER_INFO_LEVEL *printer,
1837 TALLOC_CTX *mem_ctx)
1842 len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
1844 data->notify_data.data.length = len / 2 - 1;
1845 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1847 if (!data->notify_data.data.string) {
1848 data->notify_data.data.length = 0;
1852 memcpy(data->notify_data.data.string, temp, len);
1855 /*******************************************************************
1856 * fill a notify_info_data with the device mode
1857 * jfm:xxxx don't to it for know but that's a real problem !!!
1858 ********************************************************************/
1860 static void spoolss_notify_devmode(int snum,
1861 SPOOL_NOTIFY_INFO_DATA *data,
1862 print_queue_struct *queue,
1863 NT_PRINTER_INFO_LEVEL *printer,
1864 TALLOC_CTX *mem_ctx)
1868 /*******************************************************************
1869 * fill a notify_info_data with the separator file name
1870 ********************************************************************/
1872 void spoolss_notify_sepfile(int snum,
1873 SPOOL_NOTIFY_INFO_DATA *data,
1874 print_queue_struct *queue,
1875 NT_PRINTER_INFO_LEVEL *printer,
1876 TALLOC_CTX *mem_ctx)
1881 len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
1883 data->notify_data.data.length = len / 2 - 1;
1884 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1886 if (!data->notify_data.data.string) {
1887 data->notify_data.data.length = 0;
1891 memcpy(data->notify_data.data.string, temp, len);
1894 /*******************************************************************
1895 * fill a notify_info_data with the print processor
1896 * jfm:xxxx return always winprint to indicate we don't do anything to it
1897 ********************************************************************/
1899 void spoolss_notify_print_processor(int snum,
1900 SPOOL_NOTIFY_INFO_DATA *data,
1901 print_queue_struct *queue,
1902 NT_PRINTER_INFO_LEVEL *printer,
1903 TALLOC_CTX *mem_ctx)
1908 len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
1910 data->notify_data.data.length = len / 2 - 1;
1911 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1913 if (!data->notify_data.data.string) {
1914 data->notify_data.data.length = 0;
1918 memcpy(data->notify_data.data.string, temp, len);
1921 /*******************************************************************
1922 * fill a notify_info_data with the print processor options
1923 * jfm:xxxx send an empty string
1924 ********************************************************************/
1926 void spoolss_notify_parameters(int snum,
1927 SPOOL_NOTIFY_INFO_DATA *data,
1928 print_queue_struct *queue,
1929 NT_PRINTER_INFO_LEVEL *printer,
1930 TALLOC_CTX *mem_ctx)
1935 len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
1937 data->notify_data.data.length = len / 2 - 1;
1938 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1940 if (!data->notify_data.data.string) {
1941 data->notify_data.data.length = 0;
1945 memcpy(data->notify_data.data.string, temp, len);
1948 /*******************************************************************
1949 * fill a notify_info_data with the data type
1950 * jfm:xxxx always send RAW as data type
1951 ********************************************************************/
1953 void spoolss_notify_datatype(int snum,
1954 SPOOL_NOTIFY_INFO_DATA *data,
1955 print_queue_struct *queue,
1956 NT_PRINTER_INFO_LEVEL *printer,
1957 TALLOC_CTX *mem_ctx)
1962 len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
1964 data->notify_data.data.length = len / 2 - 1;
1965 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1967 if (!data->notify_data.data.string) {
1968 data->notify_data.data.length = 0;
1972 memcpy(data->notify_data.data.string, temp, len);
1975 /*******************************************************************
1976 * fill a notify_info_data with the security descriptor
1977 * jfm:xxxx send an null pointer to say no security desc
1978 * have to implement security before !
1979 ********************************************************************/
1981 static void spoolss_notify_security_desc(int snum,
1982 SPOOL_NOTIFY_INFO_DATA *data,
1983 print_queue_struct *queue,
1984 NT_PRINTER_INFO_LEVEL *printer,
1985 TALLOC_CTX *mem_ctx)
1987 data->notify_data.data.length=0;
1988 data->notify_data.data.string = NULL;
1991 /*******************************************************************
1992 * fill a notify_info_data with the attributes
1993 * jfm:xxxx a samba printer is always shared
1994 ********************************************************************/
1996 void spoolss_notify_attributes(int snum,
1997 SPOOL_NOTIFY_INFO_DATA *data,
1998 print_queue_struct *queue,
1999 NT_PRINTER_INFO_LEVEL *printer,
2000 TALLOC_CTX *mem_ctx)
2002 data->notify_data.value[0] = printer->info_2->attributes;
2003 data->notify_data.value[1] = 0;
2006 /*******************************************************************
2007 * fill a notify_info_data with the priority
2008 ********************************************************************/
2010 static void spoolss_notify_priority(int snum,
2011 SPOOL_NOTIFY_INFO_DATA *data,
2012 print_queue_struct *queue,
2013 NT_PRINTER_INFO_LEVEL *printer,
2014 TALLOC_CTX *mem_ctx)
2016 data->notify_data.value[0] = printer->info_2->priority;
2017 data->notify_data.value[1] = 0;
2020 /*******************************************************************
2021 * fill a notify_info_data with the default priority
2022 ********************************************************************/
2024 static void spoolss_notify_default_priority(int snum,
2025 SPOOL_NOTIFY_INFO_DATA *data,
2026 print_queue_struct *queue,
2027 NT_PRINTER_INFO_LEVEL *printer,
2028 TALLOC_CTX *mem_ctx)
2030 data->notify_data.value[0] = printer->info_2->default_priority;
2031 data->notify_data.value[1] = 0;
2034 /*******************************************************************
2035 * fill a notify_info_data with the start time
2036 ********************************************************************/
2038 static void spoolss_notify_start_time(int snum,
2039 SPOOL_NOTIFY_INFO_DATA *data,
2040 print_queue_struct *queue,
2041 NT_PRINTER_INFO_LEVEL *printer,
2042 TALLOC_CTX *mem_ctx)
2044 data->notify_data.value[0] = printer->info_2->starttime;
2045 data->notify_data.value[1] = 0;
2048 /*******************************************************************
2049 * fill a notify_info_data with the until time
2050 ********************************************************************/
2052 static void spoolss_notify_until_time(int snum,
2053 SPOOL_NOTIFY_INFO_DATA *data,
2054 print_queue_struct *queue,
2055 NT_PRINTER_INFO_LEVEL *printer,
2056 TALLOC_CTX *mem_ctx)
2058 data->notify_data.value[0] = printer->info_2->untiltime;
2059 data->notify_data.value[1] = 0;
2062 /*******************************************************************
2063 * fill a notify_info_data with the status
2064 ********************************************************************/
2066 static void spoolss_notify_status(int snum,
2067 SPOOL_NOTIFY_INFO_DATA *data,
2068 print_queue_struct *queue,
2069 NT_PRINTER_INFO_LEVEL *printer,
2070 TALLOC_CTX *mem_ctx)
2072 print_status_struct status;
2074 print_queue_length(snum, &status);
2075 data->notify_data.value[0]=(uint32) status.status;
2076 data->notify_data.value[1] = 0;
2079 /*******************************************************************
2080 * fill a notify_info_data with the number of jobs queued
2081 ********************************************************************/
2083 void spoolss_notify_cjobs(int snum,
2084 SPOOL_NOTIFY_INFO_DATA *data,
2085 print_queue_struct *queue,
2086 NT_PRINTER_INFO_LEVEL *printer,
2087 TALLOC_CTX *mem_ctx)
2089 data->notify_data.value[0] = print_queue_length(snum, NULL);
2090 data->notify_data.value[1] = 0;
2093 /*******************************************************************
2094 * fill a notify_info_data with the average ppm
2095 ********************************************************************/
2097 static void spoolss_notify_average_ppm(int snum,
2098 SPOOL_NOTIFY_INFO_DATA *data,
2099 print_queue_struct *queue,
2100 NT_PRINTER_INFO_LEVEL *printer,
2101 TALLOC_CTX *mem_ctx)
2103 /* always respond 8 pages per minutes */
2104 /* a little hard ! */
2105 data->notify_data.value[0] = printer->info_2->averageppm;
2106 data->notify_data.value[1] = 0;
2109 /*******************************************************************
2110 * fill a notify_info_data with username
2111 ********************************************************************/
2113 static void spoolss_notify_username(int snum,
2114 SPOOL_NOTIFY_INFO_DATA *data,
2115 print_queue_struct *queue,
2116 NT_PRINTER_INFO_LEVEL *printer,
2117 TALLOC_CTX *mem_ctx)
2122 len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
2124 data->notify_data.data.length = len / 2 - 1;
2125 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2127 if (!data->notify_data.data.string) {
2128 data->notify_data.data.length = 0;
2132 memcpy(data->notify_data.data.string, temp, len);
2135 /*******************************************************************
2136 * fill a notify_info_data with job status
2137 ********************************************************************/
2139 static void spoolss_notify_job_status(int snum,
2140 SPOOL_NOTIFY_INFO_DATA *data,
2141 print_queue_struct *queue,
2142 NT_PRINTER_INFO_LEVEL *printer,
2143 TALLOC_CTX *mem_ctx)
2145 data->notify_data.value[0]=nt_printj_status(queue->status);
2146 data->notify_data.value[1] = 0;
2149 /*******************************************************************
2150 * fill a notify_info_data with job name
2151 ********************************************************************/
2153 static void spoolss_notify_job_name(int snum,
2154 SPOOL_NOTIFY_INFO_DATA *data,
2155 print_queue_struct *queue,
2156 NT_PRINTER_INFO_LEVEL *printer,
2157 TALLOC_CTX *mem_ctx)
2162 len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
2164 data->notify_data.data.length = len / 2 - 1;
2165 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2167 if (!data->notify_data.data.string) {
2168 data->notify_data.data.length = 0;
2172 memcpy(data->notify_data.data.string, temp, len);
2175 /*******************************************************************
2176 * fill a notify_info_data with job status
2177 ********************************************************************/
2179 static void spoolss_notify_job_status_string(int snum,
2180 SPOOL_NOTIFY_INFO_DATA *data,
2181 print_queue_struct *queue,
2182 NT_PRINTER_INFO_LEVEL *printer,
2183 TALLOC_CTX *mem_ctx)
2186 * Now we're returning job status codes we just return a "" here. JRA.
2193 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2196 switch (queue->status) {
2201 p = ""; /* NT provides the paused string */
2210 #endif /* NO LONGER NEEDED. */
2212 len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
2214 data->notify_data.data.length = len / 2 - 1;
2215 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2217 if (!data->notify_data.data.string) {
2218 data->notify_data.data.length = 0;
2222 memcpy(data->notify_data.data.string, temp, len);
2225 /*******************************************************************
2226 * fill a notify_info_data with job time
2227 ********************************************************************/
2229 static void spoolss_notify_job_time(int snum,
2230 SPOOL_NOTIFY_INFO_DATA *data,
2231 print_queue_struct *queue,
2232 NT_PRINTER_INFO_LEVEL *printer,
2233 TALLOC_CTX *mem_ctx)
2235 data->notify_data.value[0]=0x0;
2236 data->notify_data.value[1]=0;
2239 /*******************************************************************
2240 * fill a notify_info_data with job size
2241 ********************************************************************/
2243 static void spoolss_notify_job_size(int snum,
2244 SPOOL_NOTIFY_INFO_DATA *data,
2245 print_queue_struct *queue,
2246 NT_PRINTER_INFO_LEVEL *printer,
2247 TALLOC_CTX *mem_ctx)
2249 data->notify_data.value[0]=queue->size;
2250 data->notify_data.value[1]=0;
2253 /*******************************************************************
2254 * fill a notify_info_data with page info
2255 ********************************************************************/
2256 static void spoolss_notify_total_pages(int snum,
2257 SPOOL_NOTIFY_INFO_DATA *data,
2258 print_queue_struct *queue,
2259 NT_PRINTER_INFO_LEVEL *printer,
2260 TALLOC_CTX *mem_ctx)
2262 data->notify_data.value[0]=queue->page_count;
2263 data->notify_data.value[1]=0;
2266 /*******************************************************************
2267 * fill a notify_info_data with pages printed info.
2268 ********************************************************************/
2269 static void spoolss_notify_pages_printed(int snum,
2270 SPOOL_NOTIFY_INFO_DATA *data,
2271 print_queue_struct *queue,
2272 NT_PRINTER_INFO_LEVEL *printer,
2273 TALLOC_CTX *mem_ctx)
2275 data->notify_data.value[0]=0; /* Add code when back-end tracks this */
2276 data->notify_data.value[1]=0;
2279 /*******************************************************************
2280 Fill a notify_info_data with job position.
2281 ********************************************************************/
2283 static void spoolss_notify_job_position(int snum,
2284 SPOOL_NOTIFY_INFO_DATA *data,
2285 print_queue_struct *queue,
2286 NT_PRINTER_INFO_LEVEL *printer,
2287 TALLOC_CTX *mem_ctx)
2289 data->notify_data.value[0]=queue->job;
2290 data->notify_data.value[1]=0;
2293 /*******************************************************************
2294 Fill a notify_info_data with submitted time.
2295 ********************************************************************/
2297 static void spoolss_notify_submitted_time(int snum,
2298 SPOOL_NOTIFY_INFO_DATA *data,
2299 print_queue_struct *queue,
2300 NT_PRINTER_INFO_LEVEL *printer,
2301 TALLOC_CTX *mem_ctx)
2308 t=gmtime(&queue->time);
2310 len = sizeof(SYSTEMTIME);
2312 data->notify_data.data.length = len;
2313 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2315 if (!data->notify_data.data.string) {
2316 data->notify_data.data.length = 0;
2320 make_systemtime(&st, t);
2323 * Systemtime must be linearized as a set of UINT16's.
2324 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
2327 p = (char *)data->notify_data.data.string;
2328 SSVAL(p, 0, st.year);
2329 SSVAL(p, 2, st.month);
2330 SSVAL(p, 4, st.dayofweek);
2331 SSVAL(p, 6, st.day);
2332 SSVAL(p, 8, st.hour);
2333 SSVAL(p, 10, st.minute);
2334 SSVAL(p, 12, st.second);
2335 SSVAL(p, 14, st.milliseconds);
2340 struct s_notify_info_data_table
2346 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
2347 print_queue_struct *queue,
2348 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
2351 struct s_notify_info_data_table notify_info_data_table[] =
2353 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
2354 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
2355 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
2356 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
2357 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
2358 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
2359 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
2360 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
2361 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
2362 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
2363 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
2364 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
2365 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
2366 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
2367 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
2368 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
2369 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
2370 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
2371 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
2372 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
2373 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
2374 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
2375 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
2376 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
2377 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
2378 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
2379 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
2380 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
2381 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
2382 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
2383 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
2384 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
2385 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
2386 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
2387 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
2388 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
2389 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
2390 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
2391 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
2392 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
2393 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
2394 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
2395 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, spoolss_notify_submitted_time },
2396 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
2397 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
2398 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
2399 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, spoolss_notify_total_pages },
2400 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, spoolss_notify_pages_printed },
2401 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
2402 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
2403 { END, END, "", END, NULL }
2406 /*******************************************************************
2407 Return the size of info_data structure.
2408 ********************************************************************/
2410 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
2414 while (notify_info_data_table[i].type != END)
2416 if ( (notify_info_data_table[i].type == type ) &&
2417 (notify_info_data_table[i].field == field ) )
2419 return (notify_info_data_table[i].size);
2426 /*******************************************************************
2427 Return the type of notify_info_data.
2428 ********************************************************************/
2430 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
2434 while (notify_info_data_table[i].type != END)
2436 if ( (notify_info_data_table[i].type == type ) &&
2437 (notify_info_data_table[i].field == field ) )
2439 if (notify_info_data_table[i].size == POINTER)
2453 /****************************************************************************
2454 ****************************************************************************/
2456 static int search_notify(uint16 type, uint16 field, int *value)
2461 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
2463 if ( (notify_info_data_table[j].type == type ) &&
2464 (notify_info_data_table[j].field == field ) )
2469 if ( found && (notify_info_data_table[j].fn != NULL) )
2475 /****************************************************************************
2476 ****************************************************************************/
2478 void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
2480 info_data->type = type;
2481 info_data->field = field;
2482 info_data->reserved = 0;
2484 info_data->size = size_of_notify_info_data(type, field);
2485 info_data->enc_type = type_of_notify_info_data(type, field);
2489 /*******************************************************************
2491 * fill a notify_info struct with info asked
2493 ********************************************************************/
2495 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
2496 snum, SPOOL_NOTIFY_OPTION_TYPE
2497 *option_type, uint32 id,
2498 TALLOC_CTX *mem_ctx)
2504 SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
2505 NT_PRINTER_INFO_LEVEL *printer = NULL;
2506 print_queue_struct *queue=NULL;
2508 type=option_type->type;
2510 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
2511 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2512 option_type->count, lp_servicename(snum)));
2514 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2517 for(field_num=0; field_num<option_type->count; field_num++) {
2518 field = option_type->fields[field_num];
2519 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
2521 if (!search_notify(type, field, &j) )
2524 if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
2525 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
2528 else info->data = tid;
2530 current_data=&info->data[info->count];
2532 construct_info_data(current_data, type, field, id);
2534 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
2535 notify_info_data_table[j].name, snum, printer->info_2->printername ));
2537 notify_info_data_table[j].fn(snum, current_data, queue,
2543 free_a_printer(&printer, 2);
2547 /*******************************************************************
2549 * fill a notify_info struct with info asked
2551 ********************************************************************/
2553 static BOOL construct_notify_jobs_info(print_queue_struct *queue,
2554 SPOOL_NOTIFY_INFO *info,
2555 NT_PRINTER_INFO_LEVEL *printer,
2556 int snum, SPOOL_NOTIFY_OPTION_TYPE
2557 *option_type, uint32 id,
2558 TALLOC_CTX *mem_ctx)
2564 SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
2566 DEBUG(4,("construct_notify_jobs_info\n"));
2568 type = option_type->type;
2570 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
2571 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2572 option_type->count));
2574 for(field_num=0; field_num<option_type->count; field_num++) {
2575 field = option_type->fields[field_num];
2577 if (!search_notify(type, field, &j) )
2580 if((tid=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
2581 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
2584 else info->data = tid;
2586 current_data=&(info->data[info->count]);
2588 construct_info_data(current_data, type, field, id);
2589 notify_info_data_table[j].fn(snum, current_data, queue,
2598 * JFM: The enumeration is not that simple, it's even non obvious.
2600 * let's take an example: I want to monitor the PRINTER SERVER for
2601 * the printer's name and the number of jobs currently queued.
2602 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
2603 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
2605 * I have 3 printers on the back of my server.
2607 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
2610 * 1 printer 1 name 1
2611 * 2 printer 1 cjob 1
2612 * 3 printer 2 name 2
2613 * 4 printer 2 cjob 2
2614 * 5 printer 3 name 3
2615 * 6 printer 3 name 3
2617 * that's the print server case, the printer case is even worse.
2620 /*******************************************************************
2622 * enumerate all printers on the printserver
2623 * fill a notify_info struct with info asked
2625 ********************************************************************/
2627 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
2628 SPOOL_NOTIFY_INFO *info,
2629 TALLOC_CTX *mem_ctx)
2632 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
2633 int n_services=lp_numservices();
2636 SPOOL_NOTIFY_OPTION *option;
2637 SPOOL_NOTIFY_OPTION_TYPE *option_type;
2639 DEBUG(4,("printserver_notify_info\n"));
2644 option=Printer->notify.option;
2650 for (i=0; i<option->count; i++) {
2651 option_type=&(option->ctr.type[i]);
2653 if (option_type->type!=PRINTER_NOTIFY_TYPE)
2656 for (snum=0; snum<n_services; snum++)
2657 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
2658 if (construct_notify_printer_info
2659 (info, snum, option_type, id, mem_ctx))
2664 * Debugging information, don't delete.
2667 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2668 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2669 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2671 for (i=0; i<info->count; i++) {
2672 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2673 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2674 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2681 /*******************************************************************
2683 * fill a notify_info struct with info asked
2685 ********************************************************************/
2687 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
2688 TALLOC_CTX *mem_ctx)
2691 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
2694 SPOOL_NOTIFY_OPTION *option;
2695 SPOOL_NOTIFY_OPTION_TYPE *option_type;
2697 print_queue_struct *queue=NULL;
2698 print_status_struct status;
2700 DEBUG(4,("printer_notify_info\n"));
2705 option=Printer->notify.option;
2711 get_printer_snum(p, hnd, &snum);
2713 for (i=0; i<option->count; i++) {
2714 option_type=&option->ctr.type[i];
2716 switch ( option_type->type ) {
2717 case PRINTER_NOTIFY_TYPE:
2718 if(construct_notify_printer_info(info, snum,
2724 case JOB_NOTIFY_TYPE: {
2725 NT_PRINTER_INFO_LEVEL *printer = NULL;
2727 count = print_queue_status(snum, &queue, &status);
2729 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2,
2730 lp_servicename(snum))))
2733 for (j=0; j<count; j++) {
2734 construct_notify_jobs_info(&queue[j], info,
2741 free_a_printer(&printer, 2);
2751 * Debugging information, don't delete.
2754 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2755 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2756 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2758 for (i=0; i<info->count; i++) {
2759 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2760 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2761 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2767 /********************************************************************
2769 ********************************************************************/
2771 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
2773 POLICY_HND *handle = &q_u->handle;
2774 /* uint32 change = q_u->change; - notused. */
2775 /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
2776 SPOOL_NOTIFY_INFO *info = &r_u->info;
2778 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2779 WERROR result = WERR_BADFID;
2781 /* we always have a NOTIFY_INFO struct */
2785 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
2786 OUR_HANDLE(handle)));
2790 DEBUG(4,("Printer type %x\n",Printer->printer_type));
2792 /* jfm: the change value isn't used right now.
2793 * we will honour it when
2794 * a) we'll be able to send notification to the client
2795 * b) we'll have a way to communicate between the spoolss process.
2797 * same thing for option->flags
2798 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2799 * I don't have a global notification system, I'm sending back all the
2800 * informations even when _NOTHING_ has changed.
2803 /* just ignore the SPOOL_NOTIFY_OPTION */
2805 switch (Printer->printer_type) {
2806 case PRINTER_HANDLE_IS_PRINTSERVER:
2807 result = printserver_notify_info(p, handle, info, p->mem_ctx);
2810 case PRINTER_HANDLE_IS_PRINTER:
2811 result = printer_notify_info(p, handle, info, p->mem_ctx);
2819 /********************************************************************
2820 * construct_printer_info_0
2821 * fill a printer_info_0 struct
2822 ********************************************************************/
2824 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
2828 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2829 counter_printer_0 *session_counter;
2830 uint32 global_counter;
2833 print_status_struct status;
2835 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2838 count = print_queue_length(snum, &status);
2840 /* check if we already have a counter for this printer */
2841 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
2843 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
2844 if (session_counter->snum == snum)
2848 /* it's the first time, add it to the list */
2849 if (session_counter==NULL) {
2850 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
2851 free_a_printer(&ntprinter, 2);
2854 ZERO_STRUCTP(session_counter);
2855 session_counter->snum=snum;
2856 session_counter->counter=0;
2857 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
2861 session_counter->counter++;
2864 * the global_counter should be stored in a TDB as it's common to all the clients
2865 * and should be zeroed on samba startup
2867 global_counter=session_counter->counter;
2869 pstrcpy(chaine,ntprinter->info_2->printername);
2871 init_unistr(&printer->printername, chaine);
2873 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_called_name());
2874 init_unistr(&printer->servername, chaine);
2876 printer->cjobs = count;
2877 printer->total_jobs = 0;
2878 printer->total_bytes = 0;
2880 setuptime = (time_t)ntprinter->info_2->setuptime;
2881 t=gmtime(&setuptime);
2883 printer->year = t->tm_year+1900;
2884 printer->month = t->tm_mon+1;
2885 printer->dayofweek = t->tm_wday;
2886 printer->day = t->tm_mday;
2887 printer->hour = t->tm_hour;
2888 printer->minute = t->tm_min;
2889 printer->second = t->tm_sec;
2890 printer->milliseconds = 0;
2892 printer->global_counter = global_counter;
2893 printer->total_pages = 0;
2895 printer->major_version = 0x0004; /* NT 4 */
2896 printer->build_version = 0x0565; /* build 1381 */
2898 printer->major_version = 0x0005; /* NT 5 */
2899 printer->build_version = 0x0893; /* build 2195 */
2901 printer->unknown7 = 0x1;
2902 printer->unknown8 = 0x0;
2903 printer->unknown9 = 0x0;
2904 printer->session_counter = session_counter->counter;
2905 printer->unknown11 = 0x0;
2906 printer->printer_errors = 0x0; /* number of print failure */
2907 printer->unknown13 = 0x0;
2908 printer->unknown14 = 0x1;
2909 printer->unknown15 = 0x024a; /* 586 Pentium ? */
2910 printer->unknown16 = 0x0;
2911 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
2912 printer->unknown18 = 0x0;
2913 printer->status = nt_printq_status(status.status);
2914 printer->unknown20 = 0x0;
2915 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
2916 printer->unknown22 = 0x0;
2917 printer->unknown23 = 0x6; /* 6 ???*/
2918 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
2919 printer->unknown25 = 0;
2920 printer->unknown26 = 0;
2921 printer->unknown27 = 0;
2922 printer->unknown28 = 0;
2923 printer->unknown29 = 0;
2925 free_a_printer(&ntprinter,2);
2929 /********************************************************************
2930 * construct_printer_info_1
2931 * fill a printer_info_1 struct
2932 ********************************************************************/
2934 static BOOL construct_printer_info_1(uint32 flags, PRINTER_INFO_1 *printer, int snum)
2938 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2940 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2943 printer->flags=flags;
2945 if (*ntprinter->info_2->comment == '\0') {
2946 init_unistr(&printer->comment, lp_comment(snum));
2947 slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername,
2948 ntprinter->info_2->drivername, lp_comment(snum));
2951 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
2952 slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername,
2953 ntprinter->info_2->drivername, ntprinter->info_2->comment);
2956 slprintf(chaine2,sizeof(chaine)-1,"%s", ntprinter->info_2->printername);
2958 init_unistr(&printer->description, chaine);
2959 init_unistr(&printer->name, chaine2);
2961 free_a_printer(&ntprinter,2);
2966 /****************************************************************************
2967 Free a DEVMODE struct.
2968 ****************************************************************************/
2970 static void free_dev_mode(DEVICEMODE *dev)
2975 SAFE_FREE(dev->private);
2979 /****************************************************************************
2980 Create a DEVMODE struct. Returns malloced memory.
2981 ****************************************************************************/
2983 static DEVICEMODE *construct_dev_mode(int snum)
2987 NT_PRINTER_INFO_LEVEL *printer = NULL;
2988 NT_DEVICEMODE *ntdevmode = NULL;
2989 DEVICEMODE *devmode = NULL;
2991 DEBUG(7,("construct_dev_mode\n"));
2993 DEBUGADD(8,("getting printer characteristics\n"));
2995 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
2996 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
3000 ZERO_STRUCTP(devmode);
3002 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3005 if (printer->info_2->devmode)
3006 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
3008 if (ntdevmode == NULL)
3011 DEBUGADD(8,("loading DEVICEMODE\n"));
3013 slprintf(adevice, sizeof(adevice)-1, printer->info_2->printername);
3014 init_unistr(&devmode->devicename, adevice);
3016 slprintf(aform, sizeof(aform)-1, ntdevmode->formname);
3017 init_unistr(&devmode->formname, aform);
3019 devmode->specversion = ntdevmode->specversion;
3020 devmode->driverversion = ntdevmode->driverversion;
3021 devmode->size = ntdevmode->size;
3022 devmode->driverextra = ntdevmode->driverextra;
3023 devmode->fields = ntdevmode->fields;
3025 devmode->orientation = ntdevmode->orientation;
3026 devmode->papersize = ntdevmode->papersize;
3027 devmode->paperlength = ntdevmode->paperlength;
3028 devmode->paperwidth = ntdevmode->paperwidth;
3029 devmode->scale = ntdevmode->scale;
3030 devmode->copies = ntdevmode->copies;
3031 devmode->defaultsource = ntdevmode->defaultsource;
3032 devmode->printquality = ntdevmode->printquality;
3033 devmode->color = ntdevmode->color;
3034 devmode->duplex = ntdevmode->duplex;
3035 devmode->yresolution = ntdevmode->yresolution;
3036 devmode->ttoption = ntdevmode->ttoption;
3037 devmode->collate = ntdevmode->collate;
3038 devmode->icmmethod = ntdevmode->icmmethod;
3039 devmode->icmintent = ntdevmode->icmintent;
3040 devmode->mediatype = ntdevmode->mediatype;
3041 devmode->dithertype = ntdevmode->dithertype;
3043 if (ntdevmode->private != NULL) {
3044 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
3048 free_nt_devicemode(&ntdevmode);
3049 free_a_printer(&printer,2);
3056 free_nt_devicemode(&ntdevmode);
3058 free_a_printer(&printer,2);
3059 free_dev_mode(devmode);
3064 /********************************************************************
3065 * construct_printer_info_2
3066 * fill a printer_info_2 struct
3067 ********************************************************************/
3069 static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum)
3072 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3074 print_status_struct status;
3076 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
3079 count = print_queue_length(snum, &status);
3081 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
3082 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
3083 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
3084 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
3085 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
3087 if (*ntprinter->info_2->comment == '\0')
3088 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
3090 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
3092 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
3093 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
3094 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
3095 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
3096 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
3098 printer->attributes = ntprinter->info_2->attributes;
3100 printer->priority = ntprinter->info_2->priority; /* priority */
3101 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
3102 printer->starttime = ntprinter->info_2->starttime; /* starttime */
3103 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
3104 printer->status = nt_printq_status(status.status); /* status */
3105 printer->cjobs = count; /* jobs */
3106 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
3108 if((printer->devmode = construct_dev_mode(snum)) == NULL) {
3109 DEBUG(8, ("Returning NULL Devicemode!\n"));
3112 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
3113 /* steal the printer info sec_desc structure. [badly done]. */
3114 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
3115 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
3116 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
3117 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
3120 printer->secdesc = NULL;
3123 free_a_printer(&ntprinter, 2);
3127 /********************************************************************
3128 * construct_printer_info_3
3129 * fill a printer_info_3 struct
3130 ********************************************************************/
3132 static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum)
3134 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3135 PRINTER_INFO_3 *printer = NULL;
3137 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
3141 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
3142 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
3146 ZERO_STRUCTP(printer);
3148 printer->flags = 4; /* These are the components of the SD we are returning. */
3149 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
3150 /* steal the printer info sec_desc structure. [badly done]. */
3151 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
3155 * Set the flags for the components we are returning.
3158 if (printer->secdesc->owner_sid)
3159 printer->flags |= OWNER_SECURITY_INFORMATION;
3161 if (printer->secdesc->grp_sid)
3162 printer->flags |= GROUP_SECURITY_INFORMATION;
3164 if (printer->secdesc->dacl)
3165 printer->flags |= DACL_SECURITY_INFORMATION;
3167 if (printer->secdesc->sacl)
3168 printer->flags |= SACL_SECURITY_INFORMATION;
3171 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
3172 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
3173 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
3176 free_a_printer(&ntprinter, 2);
3178 *pp_printer = printer;
3182 /********************************************************************
3183 * construct_printer_info_4
3184 * fill a printer_info_4 struct
3185 ********************************************************************/
3187 static BOOL construct_printer_info_4(PRINTER_INFO_4 *printer, int snum)
3189 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3191 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
3194 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
3195 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
3196 printer->attributes = ntprinter->info_2->attributes;
3198 free_a_printer(&ntprinter, 2);
3202 /********************************************************************
3203 * construct_printer_info_5
3204 * fill a printer_info_5 struct
3205 ********************************************************************/
3207 static BOOL construct_printer_info_5(PRINTER_INFO_5 *printer, int snum)
3209 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3211 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
3214 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
3215 init_unistr(&printer->portname, ntprinter->info_2->portname); /* portname */
3216 printer->attributes = ntprinter->info_2->attributes;
3217 printer->device_not_selected_timeout = 0x3a98;
3218 printer->transmission_retry_timeout = 0xafc8;
3220 free_a_printer(&ntprinter, 2);
3224 /********************************************************************
3225 Spoolss_enumprinters.
3226 ********************************************************************/
3228 static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3232 int n_services=lp_numservices();
3233 PRINTER_INFO_1 *tp, *printers=NULL;
3234 PRINTER_INFO_1 current_prt;
3236 DEBUG(4,("enum_all_printers_info_1\n"));
3238 for (snum=0; snum<n_services; snum++) {
3239 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3240 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
3242 if (construct_printer_info_1(flags, ¤t_prt, snum)) {
3243 if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
3244 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
3245 SAFE_FREE(printers);
3250 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
3252 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
3258 /* check the required size. */
3259 for (i=0; i<*returned; i++)
3260 (*needed) += spoolss_size_printer_info_1(&printers[i]);
3262 if (!alloc_buffer_size(buffer, *needed))
3263 return WERR_INSUFFICIENT_BUFFER;
3265 /* fill the buffer with the structures */
3266 for (i=0; i<*returned; i++)
3267 smb_io_printer_info_1("", buffer, &printers[i], 0);
3270 SAFE_FREE(printers);
3272 if (*needed > offered) {
3274 return WERR_INSUFFICIENT_BUFFER;
3280 /********************************************************************
3281 enum_all_printers_info_1_local.
3282 *********************************************************************/
3284 static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3286 DEBUG(4,("enum_all_printers_info_1_local\n"));
3288 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
3291 /********************************************************************
3292 enum_all_printers_info_1_name.
3293 *********************************************************************/
3295 static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3299 DEBUG(4,("enum_all_printers_info_1_name\n"));
3301 if ((name[0] == '\\') && (name[1] == '\\'))
3304 if (is_myname_or_ipaddr(s)) {
3305 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
3308 return WERR_INVALID_NAME;
3311 /********************************************************************
3312 enum_all_printers_info_1_remote.
3313 *********************************************************************/
3315 static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3317 PRINTER_INFO_1 *printer;
3318 fstring printername;
3321 DEBUG(4,("enum_all_printers_info_1_remote\n"));
3323 /* JFM: currently it's more a place holder than anything else.
3324 * In the spooler world there is a notion of server registration.
3325 * the print servers are registring (sp ?) on the PDC (in the same domain)
3327 * We should have a TDB here. The registration is done thru an undocumented RPC call.
3330 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
3335 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name());
3336 slprintf(desc, sizeof(desc)-1,"%s", get_called_name());
3337 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
3339 init_unistr(&printer->description, desc);
3340 init_unistr(&printer->name, printername);
3341 init_unistr(&printer->comment, comment);
3342 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
3344 /* check the required size. */
3345 *needed += spoolss_size_printer_info_1(printer);
3347 if (!alloc_buffer_size(buffer, *needed)) {
3349 return WERR_INSUFFICIENT_BUFFER;
3352 /* fill the buffer with the structures */
3353 smb_io_printer_info_1("", buffer, printer, 0);
3358 if (*needed > offered) {
3360 return WERR_INSUFFICIENT_BUFFER;
3366 /********************************************************************
3367 enum_all_printers_info_1_network.
3368 *********************************************************************/
3370 static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3372 DEBUG(4,("enum_all_printers_info_1_network\n"));
3374 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
3377 /********************************************************************
3378 * api_spoolss_enumprinters
3380 * called from api_spoolss_enumprinters (see this to understand)
3381 ********************************************************************/
3383 static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3387 int n_services=lp_numservices();
3388 PRINTER_INFO_2 *tp, *printers=NULL;
3389 PRINTER_INFO_2 current_prt;
3391 for (snum=0; snum<n_services; snum++) {
3392 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3393 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
3395 if (construct_printer_info_2(¤t_prt, snum)) {
3396 if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) {
3397 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
3398 SAFE_FREE(printers);
3403 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
3404 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
3410 /* check the required size. */
3411 for (i=0; i<*returned; i++)
3412 (*needed) += spoolss_size_printer_info_2(&printers[i]);
3414 if (!alloc_buffer_size(buffer, *needed)) {
3415 for (i=0; i<*returned; i++) {
3416 free_devmode(printers[i].devmode);
3418 SAFE_FREE(printers);
3419 return WERR_INSUFFICIENT_BUFFER;
3422 /* fill the buffer with the structures */
3423 for (i=0; i<*returned; i++)
3424 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
3427 for (i=0; i<*returned; i++) {
3428 free_devmode(printers[i].devmode);
3430 SAFE_FREE(printers);
3432 if (*needed > offered) {
3434 return WERR_INSUFFICIENT_BUFFER;
3440 /********************************************************************
3441 * handle enumeration of printers at level 1
3442 ********************************************************************/
3444 static WERROR enumprinters_level1( uint32 flags, fstring name,
3445 NEW_BUFFER *buffer, uint32 offered,
3446 uint32 *needed, uint32 *returned)
3448 /* Not all the flags are equals */
3450 if (flags & PRINTER_ENUM_LOCAL)
3451 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
3453 if (flags & PRINTER_ENUM_NAME)
3454 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
3456 if (flags & PRINTER_ENUM_REMOTE)
3457 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
3459 if (flags & PRINTER_ENUM_NETWORK)
3460 return enum_all_printers_info_1_network(buffer, offered, needed, returned);
3462 return WERR_OK; /* NT4sp5 does that */
3465 /********************************************************************
3466 * handle enumeration of printers at level 2
3467 ********************************************************************/
3469 static WERROR enumprinters_level2( uint32 flags, fstring servername,
3470 NEW_BUFFER *buffer, uint32 offered,
3471 uint32 *needed, uint32 *returned)
3473 char *s = servername;
3475 if (flags & PRINTER_ENUM_LOCAL) {
3476 return enum_all_printers_info_2(buffer, offered, needed, returned);
3479 if (flags & PRINTER_ENUM_NAME) {
3480 if ((servername[0] == '\\') && (servername[1] == '\\'))
3482 if (is_myname_or_ipaddr(s))
3483 return enum_all_printers_info_2(buffer, offered, needed, returned);
3485 return WERR_INVALID_NAME;
3488 if (flags & PRINTER_ENUM_REMOTE)
3489 return WERR_UNKNOWN_LEVEL;
3494 /********************************************************************
3495 * handle enumeration of printers at level 5
3496 ********************************************************************/
3498 static WERROR enumprinters_level5( uint32 flags, fstring servername,
3499 NEW_BUFFER *buffer, uint32 offered,
3500 uint32 *needed, uint32 *returned)
3502 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
3506 /********************************************************************
3507 * api_spoolss_enumprinters
3509 * called from api_spoolss_enumprinters (see this to understand)
3510 ********************************************************************/
3512 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
3514 uint32 flags = q_u->flags;
3515 UNISTR2 *servername = &q_u->servername;
3516 uint32 level = q_u->level;
3517 NEW_BUFFER *buffer = NULL;
3518 uint32 offered = q_u->offered;
3519 uint32 *needed = &r_u->needed;
3520 uint32 *returned = &r_u->returned;
3524 /* that's an [in out] buffer */
3525 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3526 buffer = r_u->buffer;
3528 DEBUG(4,("_spoolss_enumprinters\n"));
3535 * flags==PRINTER_ENUM_NAME
3536 * if name=="" then enumerates all printers
3537 * if name!="" then enumerate the printer
3538 * flags==PRINTER_ENUM_REMOTE
3539 * name is NULL, enumerate printers
3540 * Level 2: name!="" enumerates printers, name can't be NULL
3541 * Level 3: doesn't exist
3542 * Level 4: does a local registry lookup
3543 * Level 5: same as Level 2
3546 unistr2_to_ascii(name, servername, sizeof(name)-1);
3551 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
3553 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
3555 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
3560 return WERR_UNKNOWN_LEVEL;
3563 /****************************************************************************
3564 ****************************************************************************/
3566 static WERROR getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3568 PRINTER_INFO_0 *printer=NULL;
3570 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
3573 construct_printer_info_0(printer, snum);
3575 /* check the required size. */
3576 *needed += spoolss_size_printer_info_0(printer);
3578 if (!alloc_buffer_size(buffer, *needed)) {
3580 return WERR_INSUFFICIENT_BUFFER;
3583 /* fill the buffer with the structures */
3584 smb_io_printer_info_0("", buffer, printer, 0);
3589 if (*needed > offered) {
3590 return WERR_INSUFFICIENT_BUFFER;
3596 /****************************************************************************
3597 ****************************************************************************/
3599 static WERROR getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3601 PRINTER_INFO_1 *printer=NULL;
3603 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
3606 construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum);
3608 /* check the required size. */
3609 *needed += spoolss_size_printer_info_1(printer);
3611 if (!alloc_buffer_size(buffer, *needed)) {
3613 return WERR_INSUFFICIENT_BUFFER;
3616 /* fill the buffer with the structures */
3617 smb_io_printer_info_1("", buffer, printer, 0);
3622 if (*needed > offered) {
3623 return WERR_INSUFFICIENT_BUFFER;
3629 /****************************************************************************
3630 ****************************************************************************/
3632 static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3634 PRINTER_INFO_2 *printer=NULL;
3636 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
3639 construct_printer_info_2(printer, snum);
3641 /* check the required size. */
3642 *needed += spoolss_size_printer_info_2(printer);
3644 if (!alloc_buffer_size(buffer, *needed)) {
3645 free_printer_info_2(printer);
3646 return WERR_INSUFFICIENT_BUFFER;
3649 /* fill the buffer with the structures */
3650 if (!smb_io_printer_info_2("", buffer, printer, 0)) {
3651 free_printer_info_2(printer);
3656 free_printer_info_2(printer);
3658 if (*needed > offered) {
3659 return WERR_INSUFFICIENT_BUFFER;
3665 /****************************************************************************
3666 ****************************************************************************/
3668 static WERROR getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3670 PRINTER_INFO_3 *printer=NULL;
3672 if (!construct_printer_info_3(&printer, snum))
3675 /* check the required size. */
3676 *needed += spoolss_size_printer_info_3(printer);
3678 if (!alloc_buffer_size(buffer, *needed)) {
3679 free_printer_info_3(printer);
3680 return WERR_INSUFFICIENT_BUFFER;
3683 /* fill the buffer with the structures */
3684 smb_io_printer_info_3("", buffer, printer, 0);
3687 free_printer_info_3(printer);
3689 if (*needed > offered) {
3690 return WERR_INSUFFICIENT_BUFFER;
3696 /****************************************************************************
3697 ****************************************************************************/
3699 static WERROR getprinter_level_4(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3701 PRINTER_INFO_4 *printer=NULL;
3703 if((printer=(PRINTER_INFO_4*)malloc(sizeof(PRINTER_INFO_4)))==NULL)
3706 if (!construct_printer_info_4(printer, snum))
3709 /* check the required size. */
3710 *needed += spoolss_size_printer_info_4(printer);
3712 if (!alloc_buffer_size(buffer, *needed)) {
3713 free_printer_info_4(printer);
3714 return WERR_INSUFFICIENT_BUFFER;
3717 /* fill the buffer with the structures */
3718 smb_io_printer_info_4("", buffer, printer, 0);
3721 free_printer_info_4(printer);
3723 if (*needed > offered) {
3724 return WERR_INSUFFICIENT_BUFFER;
3730 /****************************************************************************
3731 ****************************************************************************/
3733 static WERROR getprinter_level_5(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3735 PRINTER_INFO_5 *printer=NULL;
3737 if((printer=(PRINTER_INFO_5*)malloc(sizeof(PRINTER_INFO_5)))==NULL)
3740 if (!construct_printer_info_5(printer, snum))
3743 /* check the required size. */
3744 *needed += spoolss_size_printer_info_5(printer);
3746 if (!alloc_buffer_size(buffer, *needed)) {
3747 free_printer_info_5(printer);
3748 return WERR_INSUFFICIENT_BUFFER;
3751 /* fill the buffer with the structures */
3752 smb_io_printer_info_5("", buffer, printer, 0);
3755 free_printer_info_5(printer);
3757 if (*needed > offered) {
3758 return WERR_INSUFFICIENT_BUFFER;
3764 /****************************************************************************
3765 ****************************************************************************/
3767 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
3769 POLICY_HND *handle = &q_u->handle;
3770 uint32 level = q_u->level;
3771 NEW_BUFFER *buffer = NULL;
3772 uint32 offered = q_u->offered;
3773 uint32 *needed = &r_u->needed;
3777 /* that's an [in out] buffer */
3778 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3779 buffer = r_u->buffer;
3783 if (!get_printer_snum(p, handle, &snum))
3788 return getprinter_level_0(snum, buffer, offered, needed);
3790 return getprinter_level_1(snum, buffer, offered, needed);
3792 return getprinter_level_2(snum, buffer, offered, needed);
3794 return getprinter_level_3(snum, buffer, offered, needed);
3796 return getprinter_level_4(snum, buffer, offered, needed);
3798 return getprinter_level_5(snum, buffer, offered, needed);
3800 return WERR_UNKNOWN_LEVEL;
3803 /********************************************************************
3804 * fill a DRIVER_INFO_1 struct
3805 ********************************************************************/
3807 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
3809 init_unistr( &info->name, driver.info_3->name);
3812 /********************************************************************
3813 * construct_printer_driver_info_1
3814 ********************************************************************/
3816 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
3818 NT_PRINTER_INFO_LEVEL *printer = NULL;
3819 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3821 ZERO_STRUCT(driver);
3823 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3824 return WERR_INVALID_PRINTER_NAME;
3826 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
3827 return WERR_UNKNOWN_PRINTER_DRIVER;
3829 fill_printer_driver_info_1(info, driver, servername, architecture);
3831 free_a_printer(&printer,2);
3836 /********************************************************************
3837 * construct_printer_driver_info_2
3838 * fill a printer_info_2 struct
3839 ********************************************************************/
3841 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3845 info->version=driver.info_3->cversion;
3847 init_unistr( &info->name, driver.info_3->name );
3848 init_unistr( &info->architecture, driver.info_3->environment );
3851 if (strlen(driver.info_3->driverpath)) {
3852 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3853 init_unistr( &info->driverpath, temp );
3855 init_unistr( &info->driverpath, "" );
3857 if (strlen(driver.info_3->datafile)) {
3858 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3859 init_unistr( &info->datafile, temp );
3861 init_unistr( &info->datafile, "" );
3863 if (strlen(driver.info_3->configfile)) {
3864 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3865 init_unistr( &info->configfile, temp );
3867 init_unistr( &info->configfile, "" );
3870 /********************************************************************
3871 * construct_printer_driver_info_2
3872 * fill a printer_info_2 struct
3873 ********************************************************************/
3875 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
3877 NT_PRINTER_INFO_LEVEL *printer = NULL;
3878 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3880 ZERO_STRUCT(printer);
3881 ZERO_STRUCT(driver);
3883 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3884 return WERR_INVALID_PRINTER_NAME;
3886 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
3887 return WERR_UNKNOWN_PRINTER_DRIVER;
3889 fill_printer_driver_info_2(info, driver, servername);
3891 free_a_printer(&printer,2);
3896 /********************************************************************
3897 * copy a strings array and convert to UNICODE
3899 * convert an array of ascii string to a UNICODE string
3900 ********************************************************************/
3902 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
3910 DEBUG(6,("init_unistr_array\n"));
3914 if (char_array == NULL)
3918 if (!v) v = ""; /* hack to handle null lists */
3920 if (strlen(v) == 0) break;
3921 slprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
3922 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
3923 if((tuary=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
3924 DEBUG(2,("init_unistr_array: Realloc error\n" ));
3928 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, 0)/ sizeof(uint16));
3933 (*uni_array)[j]=0x0000;
3936 DEBUGADD(6,("last one:done\n"));
3939 /********************************************************************
3940 * construct_printer_info_3
3941 * fill a printer_info_3 struct
3942 ********************************************************************/
3944 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3950 info->version=driver.info_3->cversion;
3952 init_unistr( &info->name, driver.info_3->name );
3953 init_unistr( &info->architecture, driver.info_3->environment );
3955 if (strlen(driver.info_3->driverpath)) {
3956 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3957 init_unistr( &info->driverpath, temp );
3959 init_unistr( &info->driverpath, "" );
3961 if (strlen(driver.info_3->datafile)) {
3962 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3963 init_unistr( &info->datafile, temp );
3965 init_unistr( &info->datafile, "" );
3967 if (strlen(driver.info_3->configfile)) {
3968 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3969 init_unistr( &info->configfile, temp );
3971 init_unistr( &info->configfile, "" );
3973 if (strlen(driver.info_3->helpfile)) {
3974 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
3975 init_unistr( &info->helpfile, temp );
3977 init_unistr( &info->helpfile, "" );
3979 init_unistr( &info->monitorname, driver.info_3->monitorname );
3980 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
3982 info->dependentfiles=NULL;
3983 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
3986 /********************************************************************
3987 * construct_printer_info_3
3988 * fill a printer_info_3 struct
3989 ********************************************************************/
3991 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
3993 NT_PRINTER_INFO_LEVEL *printer = NULL;
3994 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3996 ZERO_STRUCT(driver);
3998 status=get_a_printer(&printer, 2, lp_servicename(snum) );
3999 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status)));
4000 if (!W_ERROR_IS_OK(status))
4001 return WERR_INVALID_PRINTER_NAME;
4003 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
4004 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status)));
4009 * I put this code in during testing. Helpful when commenting out the
4010 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
4011 * as win2k always queries the driver using an infor level of 6.
4012 * I've left it in (but ifdef'd out) because I'll probably
4013 * use it in experimentation again in the future. --jerry 22/01/2002
4016 if (!W_ERROR_IS_OK(status)) {
4018 * Is this a W2k client ?
4021 /* Yes - try again with a WinNT driver. */
4023 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
4024 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status)));
4028 if (!W_ERROR_IS_OK(status)) {
4029 free_a_printer(&printer,2);
4030 return WERR_UNKNOWN_PRINTER_DRIVER;
4038 fill_printer_driver_info_3(info, driver, servername);
4040 free_a_printer(&printer,2);
4045 /********************************************************************
4046 * construct_printer_info_6
4047 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
4048 ********************************************************************/
4050 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
4056 memset(&nullstr, '\0', sizeof(fstring));
4058 info->version=driver.info_3->cversion;
4060 init_unistr( &info->name, driver.info_3->name );
4061 init_unistr( &info->architecture, driver.info_3->environment );
4063 if (strlen(driver.info_3->driverpath)) {
4064 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
4065 init_unistr( &info->driverpath, temp );
4067 init_unistr( &info->driverpath, "" );
4069 if (strlen(driver.info_3->datafile)) {
4070 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
4071 init_unistr( &info->datafile, temp );
4073 init_unistr( &info->datafile, "" );
4075 if (strlen(driver.info_3->configfile)) {
4076 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
4077 init_unistr( &info->configfile, temp );
4079 init_unistr( &info->configfile, "" );
4081 if (strlen(driver.info_3->helpfile)) {
4082 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
4083 init_unistr( &info->helpfile, temp );
4085 init_unistr( &info->helpfile, "" );
4087 init_unistr( &info->monitorname, driver.info_3->monitorname );
4088 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
4090 info->dependentfiles=NULL;
4091 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
4093 info->previousdrivernames=NULL;
4094 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
4096 info->driver_date.low=0;
4097 info->driver_date.high=0;
4100 info->driver_version_low=0;
4101 info->driver_version_high=0;
4103 init_unistr( &info->mfgname, "");
4104 init_unistr( &info->oem_url, "");
4105 init_unistr( &info->hardware_id, "");
4106 init_unistr( &info->provider, "");
4109 /********************************************************************
4110 * construct_printer_info_6
4111 * fill a printer_info_6 struct
4112 ********************************************************************/
4114 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
4116 NT_PRINTER_INFO_LEVEL *printer = NULL;
4117 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4119 ZERO_STRUCT(driver);
4121 status=get_a_printer(&printer, 2, lp_servicename(snum) );
4122 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
4123 if (!W_ERROR_IS_OK(status))
4124 return WERR_INVALID_PRINTER_NAME;
4126 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
4127 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
4128 if (!W_ERROR_IS_OK(status)) {
4130 * Is this a W2k client ?
4134 free_a_printer(&printer,2);
4135 return WERR_UNKNOWN_PRINTER_DRIVER;
4138 /* Yes - try again with a WinNT driver. */
4140 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
4141 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
4142 if (!W_ERROR_IS_OK(status)) {
4143 free_a_printer(&printer,2);
4144 return WERR_UNKNOWN_PRINTER_DRIVER;
4148 fill_printer_driver_info_6(info, driver, servername);
4150 free_a_printer(&printer,2);
4155 /****************************************************************************
4156 ****************************************************************************/
4158 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
4160 SAFE_FREE(info->dependentfiles);
4163 /****************************************************************************
4164 ****************************************************************************/
4166 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
4168 SAFE_FREE(info->dependentfiles);
4172 /****************************************************************************
4173 ****************************************************************************/
4175 static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4177 DRIVER_INFO_1 *info=NULL;
4180 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
4183 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
4184 if (!W_ERROR_IS_OK(status)) {
4189 /* check the required size. */
4190 *needed += spoolss_size_printer_driver_info_1(info);
4192 if (!alloc_buffer_size(buffer, *needed)) {
4194 return WERR_INSUFFICIENT_BUFFER;
4197 /* fill the buffer with the structures */
4198 smb_io_printer_driver_info_1("", buffer, info, 0);
4203 if (*needed > offered)
4204 return WERR_INSUFFICIENT_BUFFER;
4209 /****************************************************************************
4210 ****************************************************************************/
4212 static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4214 DRIVER_INFO_2 *info=NULL;
4217 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
4220 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
4221 if (!W_ERROR_IS_OK(status)) {
4226 /* check the required size. */
4227 *needed += spoolss_size_printer_driver_info_2(info);
4229 if (!alloc_buffer_size(buffer, *needed)) {
4231 return WERR_INSUFFICIENT_BUFFER;
4234 /* fill the buffer with the structures */
4235 smb_io_printer_driver_info_2("", buffer, info, 0);
4240 if (*needed > offered)
4241 return WERR_INSUFFICIENT_BUFFER;
4246 /****************************************************************************
4247 ****************************************************************************/
4249 static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4256 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
4257 if (!W_ERROR_IS_OK(status)) {
4261 /* check the required size. */
4262 *needed += spoolss_size_printer_driver_info_3(&info);
4264 if (!alloc_buffer_size(buffer, *needed)) {
4265 free_printer_driver_info_3(&info);
4266 return WERR_INSUFFICIENT_BUFFER;
4269 /* fill the buffer with the structures */
4270 smb_io_printer_driver_info_3("", buffer, &info, 0);
4272 free_printer_driver_info_3(&info);
4274 if (*needed > offered)
4275 return WERR_INSUFFICIENT_BUFFER;
4280 /****************************************************************************
4281 ****************************************************************************/
4283 static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4290 status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
4291 if (!W_ERROR_IS_OK(status)) {
4295 /* check the required size. */
4296 *needed += spoolss_size_printer_driver_info_6(&info);
4298 if (!alloc_buffer_size(buffer, *needed)) {
4299 free_printer_driver_info_6(&info);
4300 return WERR_INSUFFICIENT_BUFFER;
4303 /* fill the buffer with the structures */
4304 smb_io_printer_driver_info_6("", buffer, &info, 0);
4306 free_printer_driver_info_6(&info);
4308 if (*needed > offered)
4309 return WERR_INSUFFICIENT_BUFFER;
4314 /****************************************************************************
4315 ****************************************************************************/
4317 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
4319 POLICY_HND *handle = &q_u->handle;
4320 UNISTR2 *uni_arch = &q_u->architecture;
4321 uint32 level = q_u->level;
4322 uint32 clientmajorversion = q_u->clientmajorversion;
4323 /* uint32 clientminorversion = q_u->clientminorversion; - notused. */
4324 NEW_BUFFER *buffer = NULL;
4325 uint32 offered = q_u->offered;
4326 uint32 *needed = &r_u->needed;
4327 uint32 *servermajorversion = &r_u->servermajorversion;
4328 uint32 *serverminorversion = &r_u->serverminorversion;
4331 fstring architecture;
4334 /* that's an [in out] buffer */
4335 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
4336 buffer = r_u->buffer;
4338 DEBUG(4,("_spoolss_getprinterdriver2\n"));
4341 *servermajorversion=0;
4342 *serverminorversion=0;
4344 pstrcpy(servername, get_called_name());
4345 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
4347 if (!get_printer_snum(p, handle, &snum))
4352 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
4354 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
4356 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
4358 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
4361 return WERR_UNKNOWN_LEVEL;
4364 /****************************************************************************
4365 ****************************************************************************/
4367 WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u)
4369 POLICY_HND *handle = &q_u->handle;
4371 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4374 DEBUG(3,("Error in startpageprinter printer handle\n"));
4378 Printer->page_started=True;
4382 /****************************************************************************
4383 ****************************************************************************/
4385 WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u)
4387 POLICY_HND *handle = &q_u->handle;
4389 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4392 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle)));
4396 Printer->page_started=False;
4397 print_job_endpage(Printer->jobid);
4402 /********************************************************************
4403 * api_spoolss_getprinter
4404 * called from the spoolss dispatcher
4406 ********************************************************************/
4408 WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
4410 POLICY_HND *handle = &q_u->handle;
4411 /* uint32 level = q_u->doc_info_container.level; - notused. */
4412 DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
4413 uint32 *jobid = &r_u->jobid;
4415 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
4419 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4420 struct current_user user;
4423 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
4427 get_current_user(&user, p);
4430 * a nice thing with NT is it doesn't listen to what you tell it.
4431 * when asked to send _only_ RAW datas, it tries to send datas
4434 * So I add checks like in NT Server ...
4436 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
4437 * there's a bug in NT client-side code, so we'll fix it in the
4438 * server-side code. *nnnnnggggh!*
4441 if (info_1->p_datatype != 0) {
4442 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
4443 if (strcmp(datatype, "RAW") != 0) {
4445 return WERR_INVALID_DATATYPE;
4449 /* get the share number of the printer */
4450 if (!get_printer_snum(p, handle, &snum)) {
4454 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
4456 Printer->jobid = print_job_start(&user, snum, jobname);
4458 /* An error occured in print_job_start() so return an appropriate
4461 if (Printer->jobid == -1) {
4462 return map_werror_from_unix(errno);
4465 Printer->document_started=True;
4466 (*jobid) = Printer->jobid;
4471 /********************************************************************
4472 * api_spoolss_getprinter
4473 * called from the spoolss dispatcher
4475 ********************************************************************/
4477 WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u)
4479 POLICY_HND *handle = &q_u->handle;
4481 return _spoolss_enddocprinter_internal(p, handle);
4484 /****************************************************************************
4485 ****************************************************************************/
4487 WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u)
4489 POLICY_HND *handle = &q_u->handle;
4490 uint32 buffer_size = q_u->buffer_size;
4491 uint8 *buffer = q_u->buffer;
4492 uint32 *buffer_written = &q_u->buffer_size2;
4494 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4497 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle)));
4498 r_u->buffer_written = q_u->buffer_size2;
4502 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer, buffer_size);
4505 r_u->buffer_written = q_u->buffer_size2;
4510 /********************************************************************
4511 * api_spoolss_getprinter
4512 * called from the spoolss dispatcher
4514 ********************************************************************/
4516 static WERROR control_printer(POLICY_HND *handle, uint32 command,
4519 struct current_user user;
4521 WERROR errcode = WERR_BADFUNC;
4522 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4524 get_current_user(&user, p);
4527 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
4531 if (!get_printer_snum(p, handle, &snum))
4535 case PRINTER_CONTROL_PAUSE:
4536 if (print_queue_pause(&user, snum, &errcode)) {
4540 case PRINTER_CONTROL_RESUME:
4541 case PRINTER_CONTROL_UNPAUSE:
4542 if (print_queue_resume(&user, snum, &errcode)) {
4546 case PRINTER_CONTROL_PURGE:
4547 if (print_queue_purge(&user, snum, &errcode)) {
4552 return WERR_UNKNOWN_LEVEL;
4558 /********************************************************************
4559 * api_spoolss_abortprinter
4560 ********************************************************************/
4562 WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u)
4564 POLICY_HND *handle = &q_u->handle;
4566 return control_printer(handle, PRINTER_CONTROL_PURGE, p);
4569 /********************************************************************
4570 * called by spoolss_api_setprinter
4571 * when updating a printer description
4572 ********************************************************************/
4574 static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
4575 const SPOOL_PRINTER_INFO_LEVEL *info,
4576 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
4578 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
4579 struct current_user user;
4583 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4585 if (!Printer || !get_printer_snum(p, handle, &snum)) {
4586 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
4587 OUR_HANDLE(handle)));
4589 result = WERR_BADFID;
4593 /* NT seems to like setting the security descriptor even though
4594 nothing may have actually changed. This causes annoying
4595 dialog boxes when the user doesn't have permission to change
4596 the security descriptor. */
4598 nt_printing_getsec(p->mem_ctx, Printer->dev.handlename, &old_secdesc_ctr);
4600 if (DEBUGLEVEL >= 10) {
4604 the_acl = old_secdesc_ctr->sec->dacl;
4605 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
4606 PRINTERNAME(snum), the_acl->num_aces));
4608 for (i = 0; i < the_acl->num_aces; i++) {
4611 sid_to_string(sid_str, &the_acl->ace[i].trustee);
4613 DEBUG(10, ("%s 0x%08x\n", sid_str,
4614 the_acl->ace[i].info.mask));
4617 the_acl = secdesc_ctr->sec->dacl;
4620 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4621 PRINTERNAME(snum), the_acl->num_aces));
4623 for (i = 0; i < the_acl->num_aces; i++) {
4626 sid_to_string(sid_str, &the_acl->ace[i].trustee);
4628 DEBUG(10, ("%s 0x%08x\n", sid_str,
4629 the_acl->ace[i].info.mask));
4632 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
4636 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
4638 if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
4643 /* Work out which user is performing the operation */
4645 get_current_user(&user, p);
4647 /* Check the user has permissions to change the security
4648 descriptor. By experimentation with two NT machines, the user
4649 requires Full Access to the printer to change security
4652 if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
4653 result = WERR_ACCESS_DENIED;
4657 result = nt_printing_setsec(Printer->dev.handlename, new_secdesc_ctr);
4664 /********************************************************************
4665 Do Samba sanity checks on a printer info struct.
4666 this has changed purpose: it now "canonicalises" printer
4667 info from a client rather than just checking it is correct
4668 ********************************************************************/
4670 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
4672 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
4673 info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
4675 /* we force some elements to "correct" values */
4676 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
4677 fstrcpy(info->sharename, lp_servicename(snum));
4678 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
4679 get_called_name(), info->sharename);
4680 info->attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK;
4685 /****************************************************************************
4686 ****************************************************************************/
4688 static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
4690 char *cmd = lp_addprinter_cmd();
4693 pstring driverlocation;
4697 fstring remote_machine = "%m";
4699 /* build driver path... only 9X architecture is needed for legacy reasons */
4700 slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
4702 /* change \ to \\ for the shell */
4703 all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
4705 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4706 cmd, printer->info_2->printername, printer->info_2->sharename,
4707 printer->info_2->portname, printer->info_2->drivername,
4708 printer->info_2->location, driverlocation, remote_machine);
4710 /* Convert script args to unix-codepage */
4711 DEBUG(10,("Running [%s]\n", command));
4712 ret = smbrun(command, &fd);
4713 DEBUGADD(10,("returned [%d]\n", ret));
4722 /* Get lines and convert them back to dos-codepage */
4723 qlines = fd_lines_load(fd, &numlines);
4724 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4728 /* Set the portname to what the script says the portname should be. */
4729 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
4730 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
4732 /* Send SIGHUP to process group... is there a better way? */
4737 file_lines_free(qlines);
4743 /* Return true if two devicemodes are equal */
4745 #define DEVMODE_CHECK_INT(field) \
4746 if (d1->field != d2->field) { \
4747 DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
4748 d1->field, d2->field)); \
4752 /************************************************************************
4753 Handy, but currently unused functions
4754 ***********************************************************************/
4756 static BOOL nt_devicemode_equal(NT_DEVICEMODE *d1, NT_DEVICEMODE *d2)
4758 if (!d1 && !d2) goto equal; /* if both are NULL they are equal */
4761 DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
4762 return False; /* if either is exclusively NULL are not equal */
4765 if (!strequal(d1->devicename, d2->devicename)) {
4766 DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1->devicename, d2->devicename));
4770 if (!strequal(d1->formname, d2->formname)) {
4771 DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1->formname, d2->formname));
4775 DEVMODE_CHECK_INT(specversion);
4776 DEVMODE_CHECK_INT(driverversion);
4777 DEVMODE_CHECK_INT(driverextra);
4778 DEVMODE_CHECK_INT(orientation);
4779 DEVMODE_CHECK_INT(papersize);
4780 DEVMODE_CHECK_INT(paperlength);
4781 DEVMODE_CHECK_INT(paperwidth);
4782 DEVMODE_CHECK_INT(scale);
4783 DEVMODE_CHECK_INT(copies);
4784 DEVMODE_CHECK_INT(defaultsource);
4785 DEVMODE_CHECK_INT(printquality);
4786 DEVMODE_CHECK_INT(color);
4787 DEVMODE_CHECK_INT(duplex);
4788 DEVMODE_CHECK_INT(yresolution);
4789 DEVMODE_CHECK_INT(ttoption);
4790 DEVMODE_CHECK_INT(collate);
4791 DEVMODE_CHECK_INT(logpixels);
4793 DEVMODE_CHECK_INT(fields);
4794 DEVMODE_CHECK_INT(bitsperpel);
4795 DEVMODE_CHECK_INT(pelswidth);
4796 DEVMODE_CHECK_INT(pelsheight);
4797 DEVMODE_CHECK_INT(displayflags);
4798 DEVMODE_CHECK_INT(displayfrequency);
4799 DEVMODE_CHECK_INT(icmmethod);
4800 DEVMODE_CHECK_INT(icmintent);
4801 DEVMODE_CHECK_INT(mediatype);
4802 DEVMODE_CHECK_INT(dithertype);
4803 DEVMODE_CHECK_INT(reserved1);
4804 DEVMODE_CHECK_INT(reserved2);
4805 DEVMODE_CHECK_INT(panningwidth);
4806 DEVMODE_CHECK_INT(panningheight);
4808 /* compare the private data if it exists */
4809 if (!d1->driverextra && !d2->driverextra) goto equal;
4812 DEVMODE_CHECK_INT(driverextra);
4814 if (memcmp(d1->private, d2->private, d1->driverextra)) {
4815 DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
4820 DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
4824 /* Return true if two NT_PRINTER_PARAM structures are equal */
4826 static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
4827 NT_PRINTER_PARAM *p2)
4829 if (!p1 && !p2) goto equal;
4831 if ((!p1 && p2) || (p1 && !p2)) {
4832 DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
4836 /* Compare lists of printer parameters */
4840 NT_PRINTER_PARAM *q = p1;
4842 /* Find the parameter in the second structure */
4846 if (strequal(p1->value, q->value)) {
4848 if (p1->type != q->type) {
4849 DEBUG(10, ("nt_printer_param_equal():"
4850 "types for %s differ (%d != %d)\n",
4851 p1->value, p1->type,
4856 if (p1->data_len != q->data_len) {
4857 DEBUG(10, ("nt_printer_param_equal():"
4858 "len for %s differs (%d != %d)\n",
4859 p1->value, p1->data_len,
4864 if (memcmp(p1->data, q->data, p1->data_len) == 0) {
4867 DEBUG(10, ("nt_printer_param_equal():"
4868 "data for %s differs\n", p1->value));
4878 DEBUG(10, ("nt_printer_param_equal(): param %s "
4879 "does not exist\n", p1->value));
4888 DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
4892 /********************************************************************
4893 * Called by update_printer when trying to work out whether to
4894 * actually update printer info.
4895 ********************************************************************/
4897 #define PI_CHECK_INT(field) \
4898 if (pi1->field != pi2->field) { \
4899 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
4900 pi1->field, pi2->field)); \
4904 #define PI_CHECK_STR(field) \
4905 if (!strequal(pi1->field, pi2->field)) { \
4906 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
4907 pi1->field, pi2->field)); \
4911 static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
4912 NT_PRINTER_INFO_LEVEL *p2)
4914 NT_PRINTER_INFO_LEVEL_2 *pi1, *pi2;
4916 /* Trivial conditions */
4918 if ((!p1 && !p2) || (!p1->info_2 && !p2->info_2)) {
4922 if ((!p1 && p2) || (p1 && !p2) ||
4923 (!p1->info_2 && p2->info_2) ||
4924 (p1->info_2 && !p2->info_2)) {
4925 DEBUG(10, ("nt_printer_info_level_equal(): info levels "
4930 /* Compare two nt_printer_info_level structures. Don't compare
4931 status or cjobs as they seem to have something to do with the
4937 /* Don't check the attributes as we stomp on the value in
4938 check_printer_ok() anyway. */
4941 PI_CHECK_INT(attributes);
4944 PI_CHECK_INT(priority);
4945 PI_CHECK_INT(default_priority);
4946 PI_CHECK_INT(starttime);
4947 PI_CHECK_INT(untiltime);
4948 PI_CHECK_INT(averageppm);
4950 /* Yuck - don't check the printername or servername as the
4951 mod_a_printer() code plays games with them. You can't
4952 change the printername or the sharename through this interface
4955 PI_CHECK_STR(sharename);
4956 PI_CHECK_STR(portname);
4957 PI_CHECK_STR(drivername);
4958 PI_CHECK_STR(comment);
4959 PI_CHECK_STR(location);
4961 if (!nt_devicemode_equal(pi1->devmode, pi2->devmode)) {
4965 PI_CHECK_STR(sepfile);
4966 PI_CHECK_STR(printprocessor);
4967 PI_CHECK_STR(datatype);
4968 PI_CHECK_STR(parameters);
4970 if (!nt_printer_param_equal(pi1->specific, pi2->specific)) {
4974 if (!sec_desc_equal(pi1->secdesc_buf->sec, pi2->secdesc_buf->sec)) {
4978 PI_CHECK_INT(changeid);
4979 PI_CHECK_INT(c_setprinter);
4980 PI_CHECK_INT(setuptime);
4983 DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
4989 /********************************************************************
4990 * Called by spoolss_api_setprinter
4991 * when updating a printer description.
4992 ********************************************************************/
4994 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
4995 const SPOOL_PRINTER_INFO_LEVEL *info,
4996 DEVICEMODE *devmode)
4999 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
5000 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5001 PRINTER_MESSAGE_INFO msg;
5004 DEBUG(8,("update_printer\n"));
5011 DEBUG(0,("update_printer: Send a mail to samba@samba.org\n"));
5012 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
5013 result = WERR_UNKNOWN_LEVEL;
5018 result = WERR_BADFID;
5022 if (!get_printer_snum(p, handle, &snum)) {
5023 result = WERR_BADFID;
5027 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) ||
5028 (!W_ERROR_IS_OK(get_a_printer(&old_printer, 2, lp_servicename(snum))))) {
5029 result = WERR_BADFID;
5033 DEBUGADD(8,("Converting info_2 struct\n"));
5036 * convert_printer_info converts the incoming
5037 * info from the client and overwrites the info
5038 * just read from the tdb in the pointer 'printer'.
5041 if (!convert_printer_info(info, printer, level)) {
5042 result = WERR_NOMEM;
5046 if (info->info_2->devmode_ptr != 0) {
5047 /* we have a valid devmode
5048 convert it and link it*/
5050 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5051 if (!convert_devicemode(printer->info_2->printername, devmode,
5052 &printer->info_2->devmode)) {
5053 result = WERR_NOMEM;
5058 /* Do sanity check on the requested changes for Samba */
5060 if (!check_printer_ok(printer->info_2, snum)) {
5061 result = WERR_INVALID_PARAM;
5068 * Another one of those historical misunderstandings...
5069 * This is reminisent of a similar call we had in _spoolss_setprinterdata()
5070 * I'm leaving it here as a reminder. --jerry
5073 if (nt_printer_info_level_equal(printer, old_printer)) {
5074 DEBUG(3, ("update_printer: printer info has not changed\n"));
5081 /* Check calling user has permission to update printer description */
5083 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5084 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5085 result = WERR_ACCESS_DENIED;
5089 /* Call addprinter hook */
5091 if (*lp_addprinter_cmd()) {
5092 if ( !add_printer_hook(printer) ) {
5093 result = WERR_ACCESS_DENIED;
5099 * Set the DRIVER_INIT info in the tdb; trigger on magic value for the
5100 * DEVMODE.displayfrequency, which is not used for printer drivers. This
5101 * requires Win32 client code (see other notes elsewhere in the code).
5103 if (printer->info_2->devmode &&
5104 printer->info_2->devmode->displayfrequency == MAGIC_DISPLAY_FREQUENCY) {
5106 DEBUG(10,("update_printer: Save printer driver init data\n"));
5107 printer->info_2->devmode->displayfrequency = 0;
5109 if (update_driver_init(*printer, 2)!=0) {
5110 DEBUG(10,("update_printer: error updating printer driver init DEVMODE\n"));
5111 result = WERR_ACCESS_DENIED;
5116 * When a *new* driver is bound to a printer, the drivername is used to
5117 * lookup previously saved driver initialization info, which is then
5118 * bound to the printer, simulating what happens in the Windows arch.
5120 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){
5121 set_driver_init(printer, 2);
5122 msg.flags |= PRINTER_MESSAGE_DRIVER;
5126 /* Update printer info */
5127 result = mod_a_printer(*printer, 2);
5129 /* flag which changes actually occured. This is a small subset of
5130 all the possible changes */
5132 if (!strequal(printer->info_2->comment, old_printer->info_2->comment))
5133 msg.flags |= PRINTER_MESSAGE_COMMENT;
5135 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename))
5136 msg.flags |= PRINTER_MESSAGE_SHARENAME;
5138 if (!strequal(printer->info_2->portname, old_printer->info_2->portname))
5139 msg.flags |= PRINTER_MESSAGE_PORT;
5141 if (!strequal(printer->info_2->location, old_printer->info_2->location))
5142 msg.flags |= PRINTER_MESSAGE_LOCATION;
5146 msg.low = PRINTER_CHANGE_ADD_PRINTER;
5147 fstrcpy(msg.printer_name, printer->info_2->printername);
5149 /* only send a notify if something changed */
5151 srv_spoolss_sendnotify(msg.printer_name, 0, PRINTER_CHANGE_ADD_PRINTER, msg.flags);
5155 free_a_printer(&printer, 2);
5156 free_a_printer(&old_printer, 2);
5162 /****************************************************************************
5163 ****************************************************************************/
5165 WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
5167 POLICY_HND *handle = &q_u->handle;
5168 uint32 level = q_u->level;
5169 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
5170 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
5171 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
5172 uint32 command = q_u->command;
5174 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5177 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5181 /* check the level */
5184 return control_printer(handle, command, p);
5186 return update_printer(p, handle, level, info, devmode_ctr.devmode);
5188 return update_printer_sec(handle, level, info, p,
5191 return WERR_UNKNOWN_LEVEL;
5195 /****************************************************************************
5196 ****************************************************************************/
5198 WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
5200 POLICY_HND *handle = &q_u->handle;
5202 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
5205 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5209 if (Printer->notify.client_connected==True)
5210 srv_spoolss_replycloseprinter(&Printer->notify.client_hnd);
5212 Printer->notify.flags=0;
5213 Printer->notify.options=0;
5214 Printer->notify.localmachine[0]='\0';
5215 Printer->notify.printerlocal=0;
5216 if (Printer->notify.option)
5217 free_spool_notify_option(&Printer->notify.option);
5218 Printer->notify.client_connected=False;
5223 /****************************************************************************
5224 ****************************************************************************/
5226 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
5228 /* that's an [in out] buffer (despite appearences to the contrary) */
5229 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5232 return WERR_INVALID_PARAM; /* this is what a NT server
5233 returns for AddJob. AddJob
5234 must fail on non-local
5238 /****************************************************************************
5239 ****************************************************************************/
5241 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
5242 int position, int snum)
5248 t=gmtime(&queue->time);
5249 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
5251 job_info->jobid=queue->job;
5252 init_unistr(&job_info->printername, lp_servicename(snum));
5253 init_unistr(&job_info->machinename, temp_name);
5254 init_unistr(&job_info->username, queue->fs_user);
5255 init_unistr(&job_info->document, queue->fs_file);
5256 init_unistr(&job_info->datatype, "RAW");
5257 init_unistr(&job_info->text_status, "");
5258 job_info->status=nt_printj_status(queue->status);
5259 job_info->priority=queue->priority;
5260 job_info->position=position;
5261 job_info->totalpages=queue->page_count;
5262 job_info->pagesprinted=0;
5264 make_systemtime(&job_info->submitted, t);
5267 /****************************************************************************
5268 ****************************************************************************/
5270 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
5271 int position, int snum,
5272 NT_PRINTER_INFO_LEVEL *ntprinter,
5273 DEVICEMODE *devmode)
5279 t=gmtime(&queue->time);
5280 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
5282 job_info->jobid=queue->job;
5284 slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", get_called_name(), ntprinter->info_2->printername);
5286 init_unistr(&job_info->printername, chaine);
5288 init_unistr(&job_info->machinename, temp_name);
5289 init_unistr(&job_info->username, queue->fs_user);
5290 init_unistr(&job_info->document, queue->fs_file);
5291 init_unistr(&job_info->notifyname, queue->fs_user);
5292 init_unistr(&job_info->datatype, "RAW");
5293 init_unistr(&job_info->printprocessor, "winprint");
5294 init_unistr(&job_info->parameters, "");
5295 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
5296 init_unistr(&job_info->text_status, "");
5298 /* and here the security descriptor */
5300 job_info->status=nt_printj_status(queue->status);
5301 job_info->priority=queue->priority;
5302 job_info->position=position;
5303 job_info->starttime=0;
5304 job_info->untiltime=0;
5305 job_info->totalpages=queue->page_count;
5306 job_info->size=queue->size;
5307 make_systemtime(&(job_info->submitted), t);
5308 job_info->timeelapsed=0;
5309 job_info->pagesprinted=0;
5311 job_info->devmode = devmode;
5316 /****************************************************************************
5317 Enumjobs at level 1.
5318 ****************************************************************************/
5320 static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
5321 NEW_BUFFER *buffer, uint32 offered,
5322 uint32 *needed, uint32 *returned)
5327 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
5334 for (i=0; i<*returned; i++)
5335 fill_job_info_1(&info[i], &queue[i], i, snum);
5339 /* check the required size. */
5340 for (i=0; i<*returned; i++)
5341 (*needed) += spoolss_size_job_info_1(&info[i]);
5343 if (!alloc_buffer_size(buffer, *needed)) {
5345 return WERR_INSUFFICIENT_BUFFER;
5348 /* fill the buffer with the structures */
5349 for (i=0; i<*returned; i++)
5350 smb_io_job_info_1("", buffer, &info[i], 0);
5355 if (*needed > offered) {
5357 return WERR_INSUFFICIENT_BUFFER;
5363 /****************************************************************************
5364 Enumjobs at level 2.
5365 ****************************************************************************/
5367 static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
5368 NEW_BUFFER *buffer, uint32 offered,
5369 uint32 *needed, uint32 *returned)
5371 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
5372 JOB_INFO_2 *info = NULL;
5375 DEVICEMODE *devmode = NULL;
5377 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
5380 result = WERR_NOMEM;
5384 result = get_a_printer(&ntprinter, 2, lp_servicename(snum));
5385 if (!W_ERROR_IS_OK(result)) {
5390 if (!(devmode = construct_dev_mode(snum))) {
5392 result = WERR_NOMEM;
5396 for (i=0; i<*returned; i++)
5397 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter,
5400 free_a_printer(&ntprinter, 2);
5403 /* check the required size. */
5404 for (i=0; i<*returned; i++)
5405 (*needed) += spoolss_size_job_info_2(&info[i]);
5407 if (*needed > offered) {
5409 result = WERR_INSUFFICIENT_BUFFER;
5413 if (!alloc_buffer_size(buffer, *needed)) {
5415 result = WERR_INSUFFICIENT_BUFFER;
5419 /* fill the buffer with the structures */
5420 for (i=0; i<*returned; i++)
5421 smb_io_job_info_2("", buffer, &info[i], 0);
5426 free_a_printer(&ntprinter, 2);
5427 free_devmode(devmode);
5434 /****************************************************************************
5436 ****************************************************************************/
5438 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
5440 POLICY_HND *handle = &q_u->handle;
5441 /* uint32 firstjob = q_u->firstjob; - notused. */
5442 /* uint32 numofjobs = q_u->numofjobs; - notused. */
5443 uint32 level = q_u->level;
5444 NEW_BUFFER *buffer = NULL;
5445 uint32 offered = q_u->offered;
5446 uint32 *needed = &r_u->needed;
5447 uint32 *returned = &r_u->returned;
5450 print_status_struct prt_status;
5451 print_queue_struct *queue=NULL;
5453 /* that's an [in out] buffer */
5454 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5455 buffer = r_u->buffer;
5457 DEBUG(4,("_spoolss_enumjobs\n"));
5462 if (!get_printer_snum(p, handle, &snum))
5465 *returned = print_queue_status(snum, &queue, &prt_status);
5466 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
5468 if (*returned == 0) {
5475 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
5477 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
5481 return WERR_UNKNOWN_LEVEL;
5485 /****************************************************************************
5486 ****************************************************************************/
5488 WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
5493 /****************************************************************************
5494 ****************************************************************************/
5496 WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
5498 POLICY_HND *handle = &q_u->handle;
5499 uint32 jobid = q_u->jobid;
5500 /* uint32 level = q_u->level; - notused. */
5501 /* JOB_INFO *ctr = &q_u->ctr; - notused. */
5502 uint32 command = q_u->command;
5504 struct current_user user;
5506 WERROR errcode = WERR_BADFUNC;
5508 if (!get_printer_snum(p, handle, &snum)) {
5512 if (!print_job_exists(jobid)) {
5513 return WERR_INVALID_PRINTER_NAME;
5516 get_current_user(&user, p);
5519 case JOB_CONTROL_CANCEL:
5520 case JOB_CONTROL_DELETE:
5521 if (print_job_delete(&user, jobid, &errcode)) {
5525 case JOB_CONTROL_PAUSE:
5526 if (print_job_pause(&user, jobid, &errcode)) {
5530 case JOB_CONTROL_RESTART:
5531 case JOB_CONTROL_RESUME:
5532 if (print_job_resume(&user, jobid, &errcode)) {
5537 return WERR_UNKNOWN_LEVEL;
5543 /****************************************************************************
5544 Enumerates all printer drivers at level 1.
5545 ****************************************************************************/
5547 static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5552 fstring *list = NULL;
5554 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5555 DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
5559 #define MAX_VERSION 4
5561 for (version=0; version<MAX_VERSION; version++) {
5563 ndrivers=get_ntdrivers(&list, architecture, version);
5564 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5570 if((tdi1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
5571 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
5572 SAFE_FREE(driver_info_1);
5576 else driver_info_1 = tdi1;
5579 for (i=0; i<ndrivers; i++) {
5581 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5582 ZERO_STRUCT(driver);
5583 status = get_a_printer_driver(&driver, 3, list[i],
5584 architecture, version);
5585 if (!W_ERROR_IS_OK(status)) {
5589 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
5590 free_a_printer_driver(driver, 3);
5593 *returned+=ndrivers;
5597 /* check the required size. */
5598 for (i=0; i<*returned; i++) {
5599 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5600 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
5603 if (!alloc_buffer_size(buffer, *needed)) {
5604 SAFE_FREE(driver_info_1);
5605 return WERR_INSUFFICIENT_BUFFER;
5608 /* fill the buffer with the driver structures */
5609 for (i=0; i<*returned; i++) {
5610 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5611 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
5614 SAFE_FREE(driver_info_1);
5616 if (*needed > offered) {
5618 return WERR_INSUFFICIENT_BUFFER;
5624 /****************************************************************************
5625 Enumerates all printer drivers at level 2.
5626 ****************************************************************************/
5628 static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5633 fstring *list = NULL;
5635 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5636 DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
5640 #define MAX_VERSION 4
5642 for (version=0; version<MAX_VERSION; version++) {
5644 ndrivers=get_ntdrivers(&list, architecture, version);
5645 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5651 if((tdi2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
5652 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
5653 SAFE_FREE(driver_info_2);
5657 else driver_info_2 = tdi2;
5660 for (i=0; i<ndrivers; i++) {
5663 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5664 ZERO_STRUCT(driver);
5665 status = get_a_printer_driver(&driver, 3, list[i],
5666 architecture, version);
5667 if (!W_ERROR_IS_OK(status)) {
5671 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
5672 free_a_printer_driver(driver, 3);
5675 *returned+=ndrivers;
5679 /* check the required size. */
5680 for (i=0; i<*returned; i++) {
5681 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5682 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
5685 if (!alloc_buffer_size(buffer, *needed)) {
5686 SAFE_FREE(driver_info_2);
5687 return WERR_INSUFFICIENT_BUFFER;
5690 /* fill the buffer with the form structures */
5691 for (i=0; i<*returned; i++) {
5692 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5693 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
5696 SAFE_FREE(driver_info_2);
5698 if (*needed > offered) {
5700 return WERR_INSUFFICIENT_BUFFER;
5706 /****************************************************************************
5707 Enumerates all printer drivers at level 3.
5708 ****************************************************************************/
5710 static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5715 fstring *list = NULL;
5717 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5718 DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
5722 #define MAX_VERSION 4
5724 for (version=0; version<MAX_VERSION; version++) {
5726 ndrivers=get_ntdrivers(&list, architecture, version);
5727 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5733 if((tdi3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
5734 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
5735 SAFE_FREE(driver_info_3);
5739 else driver_info_3 = tdi3;
5742 for (i=0; i<ndrivers; i++) {
5745 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5746 ZERO_STRUCT(driver);
5747 status = get_a_printer_driver(&driver, 3, list[i],
5748 architecture, version);
5749 if (!W_ERROR_IS_OK(status)) {
5753 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
5754 free_a_printer_driver(driver, 3);
5757 *returned+=ndrivers;
5761 /* check the required size. */
5762 for (i=0; i<*returned; i++) {
5763 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5764 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
5767 if (!alloc_buffer_size(buffer, *needed)) {
5768 SAFE_FREE(driver_info_3);
5769 return WERR_INSUFFICIENT_BUFFER;
5772 /* fill the buffer with the driver structures */
5773 for (i=0; i<*returned; i++) {
5774 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5775 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
5778 for (i=0; i<*returned; i++)
5779 SAFE_FREE(driver_info_3[i].dependentfiles);
5781 SAFE_FREE(driver_info_3);
5783 if (*needed > offered) {
5785 return WERR_INSUFFICIENT_BUFFER;
5791 /****************************************************************************
5792 Enumerates all printer drivers.
5793 ****************************************************************************/
5795 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
5797 /* UNISTR2 *name = &q_u->name; - notused. */
5798 UNISTR2 *environment = &q_u->environment;
5799 uint32 level = q_u->level;
5800 NEW_BUFFER *buffer = NULL;
5801 uint32 offered = q_u->offered;
5802 uint32 *needed = &r_u->needed;
5803 uint32 *returned = &r_u->returned;
5805 fstring *list = NULL;
5807 fstring architecture;
5809 /* that's an [in out] buffer */
5810 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5811 buffer = r_u->buffer;
5813 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
5814 fstrcpy(servername, get_called_name());
5818 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
5822 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
5824 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
5826 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
5830 return WERR_UNKNOWN_LEVEL;
5834 /****************************************************************************
5835 ****************************************************************************/
5837 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
5839 form->flag=list->flag;
5840 init_unistr(&form->name, list->name);
5841 form->width=list->width;
5842 form->length=list->length;
5843 form->left=list->left;
5844 form->top=list->top;
5845 form->right=list->right;
5846 form->bottom=list->bottom;
5849 /****************************************************************************
5850 ****************************************************************************/
5852 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
5854 /* POLICY_HND *handle = &q_u->handle; - notused. */
5855 uint32 level = q_u->level;
5856 NEW_BUFFER *buffer = NULL;
5857 uint32 offered = q_u->offered;
5858 uint32 *needed = &r_u->needed;
5859 uint32 *numofforms = &r_u->numofforms;
5860 uint32 numbuiltinforms;
5862 nt_forms_struct *list=NULL;
5863 nt_forms_struct *builtinlist=NULL;
5868 /* that's an [in out] buffer */
5869 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5870 buffer = r_u->buffer;
5872 DEBUG(4,("_spoolss_enumforms\n"));
5873 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
5874 DEBUGADD(5,("Info level [%d]\n", level));
5876 numbuiltinforms = get_builtin_ntforms(&builtinlist);
5877 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
5878 *numofforms = get_ntforms(&list);
5879 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
5880 *numofforms += numbuiltinforms;
5882 if (*numofforms == 0) return WERR_NO_MORE_ITEMS;
5886 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
5891 /* construct the list of form structures */
5892 for (i=0; i<numbuiltinforms; i++) {
5893 DEBUGADD(6,("Filling form number [%d]\n",i));
5894 fill_form_1(&forms_1[i], &builtinlist[i]);
5897 SAFE_FREE(builtinlist);
5899 for (; i<*numofforms; i++) {
5900 DEBUGADD(6,("Filling form number [%d]\n",i));
5901 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
5906 /* check the required size. */
5907 for (i=0; i<numbuiltinforms; i++) {
5908 DEBUGADD(6,("adding form [%d]'s size\n",i));
5909 buffer_size += spoolss_size_form_1(&forms_1[i]);
5911 for (; i<*numofforms; i++) {
5912 DEBUGADD(6,("adding form [%d]'s size\n",i));
5913 buffer_size += spoolss_size_form_1(&forms_1[i]);
5916 *needed=buffer_size;
5918 if (!alloc_buffer_size(buffer, buffer_size)){
5920 return WERR_INSUFFICIENT_BUFFER;
5923 /* fill the buffer with the form structures */
5924 for (i=0; i<numbuiltinforms; i++) {
5925 DEBUGADD(6,("adding form [%d] to buffer\n",i));
5926 smb_io_form_1("", buffer, &forms_1[i], 0);
5928 for (; i<*numofforms; i++) {
5929 DEBUGADD(6,("adding form [%d] to buffer\n",i));
5930 smb_io_form_1("", buffer, &forms_1[i], 0);
5935 if (*needed > offered) {
5937 return WERR_INSUFFICIENT_BUFFER;
5944 SAFE_FREE(builtinlist);
5945 return WERR_UNKNOWN_LEVEL;
5950 /****************************************************************************
5951 ****************************************************************************/
5953 WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u)
5955 /* POLICY_HND *handle = &q_u->handle; - notused. */
5956 uint32 level = q_u->level;
5957 UNISTR2 *uni_formname = &q_u->formname;
5958 NEW_BUFFER *buffer = NULL;
5959 uint32 offered = q_u->offered;
5960 uint32 *needed = &r_u->needed;
5962 nt_forms_struct *list=NULL;
5963 nt_forms_struct builtin_form;
5968 int numofforms=0, i=0;
5970 /* that's an [in out] buffer */
5971 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5972 buffer = r_u->buffer;
5974 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
5976 DEBUG(4,("_spoolss_getform\n"));
5977 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
5978 DEBUGADD(5,("Info level [%d]\n", level));
5980 foundBuiltin = get_a_builtin_ntform(uni_formname,&builtin_form);
5981 if (!foundBuiltin) {
5982 numofforms = get_ntforms(&list);
5983 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
5985 if (numofforms == 0)
5992 fill_form_1(&form_1, &builtin_form);
5995 /* Check if the requested name is in the list of form structures */
5996 for (i=0; i<numofforms; i++) {
5998 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
6000 if (strequal(form_name, list[i].name)) {
6001 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
6002 fill_form_1(&form_1, &list[i]);
6008 if (i == numofforms) {
6012 /* check the required size. */
6014 *needed=spoolss_size_form_1(&form_1);
6016 if (!alloc_buffer_size(buffer, buffer_size)){
6017 return WERR_INSUFFICIENT_BUFFER;
6020 if (*needed > offered) {
6021 return WERR_INSUFFICIENT_BUFFER;
6024 /* fill the buffer with the form structures */
6025 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
6026 smb_io_form_1("", buffer, &form_1, 0);
6032 return WERR_UNKNOWN_LEVEL;
6036 /****************************************************************************
6037 ****************************************************************************/
6039 static void fill_port_1(PORT_INFO_1 *port, char *name)
6041 init_unistr(&port->port_name, name);
6044 /****************************************************************************
6045 ****************************************************************************/
6047 static void fill_port_2(PORT_INFO_2 *port, char *name)
6049 init_unistr(&port->port_name, name);
6050 init_unistr(&port->monitor_name, "Local Monitor");
6051 init_unistr(&port->description, "Local Port");
6052 #define PORT_TYPE_WRITE 1
6053 port->port_type=PORT_TYPE_WRITE;
6057 /****************************************************************************
6059 ****************************************************************************/
6061 static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6063 PORT_INFO_1 *ports=NULL;
6066 if (*lp_enumports_cmd()) {
6067 char *cmd = lp_enumports_cmd();
6074 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1);
6076 DEBUG(10,("Running [%s]\n", command));
6077 ret = smbrun(command, &fd);
6078 DEBUG(10,("Returned [%d]\n", ret));
6082 /* Is this the best error to return here? */
6083 return WERR_ACCESS_DENIED;
6087 qlines = fd_lines_load(fd, &numlines);
6088 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6092 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
6093 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
6094 dos_errstr(WERR_NOMEM)));
6095 file_lines_free(qlines);
6099 for (i=0; i<numlines; i++) {
6100 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
6101 fill_port_1(&ports[i], qlines[i]);
6104 file_lines_free(qlines);
6107 *returned = numlines;
6110 *returned = 1; /* Sole Samba port returned. */
6112 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
6115 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
6117 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
6120 /* check the required size. */
6121 for (i=0; i<*returned; i++) {
6122 DEBUGADD(6,("adding port [%d]'s size\n", i));
6123 *needed += spoolss_size_port_info_1(&ports[i]);
6126 if (!alloc_buffer_size(buffer, *needed)) {
6128 return WERR_INSUFFICIENT_BUFFER;
6131 /* fill the buffer with the ports structures */
6132 for (i=0; i<*returned; i++) {
6133 DEBUGADD(6,("adding port [%d] to buffer\n", i));
6134 smb_io_port_1("", buffer, &ports[i], 0);
6139 if (*needed > offered) {
6141 return WERR_INSUFFICIENT_BUFFER;
6147 /****************************************************************************
6149 ****************************************************************************/
6151 static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6153 PORT_INFO_2 *ports=NULL;
6156 if (*lp_enumports_cmd()) {
6157 char *cmd = lp_enumports_cmd();
6166 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
6167 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
6169 path = lp_lockdir();
6171 slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%u.", path, (unsigned int)sys_getpid());
6172 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 2);
6175 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
6176 ret = smbrun(command, &fd);
6177 DEBUGADD(10,("returned [%d]\n", ret));
6181 /* Is this the best error to return here? */
6182 return WERR_ACCESS_DENIED;
6186 qlines = fd_lines_load(fd, &numlines);
6187 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6191 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
6192 file_lines_free(qlines);
6196 for (i=0; i<numlines; i++) {
6197 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
6198 fill_port_2(&(ports[i]), qlines[i]);
6201 file_lines_free(qlines);
6204 *returned = numlines;
6210 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
6213 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
6215 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
6218 /* check the required size. */
6219 for (i=0; i<*returned; i++) {
6220 DEBUGADD(6,("adding port [%d]'s size\n", i));
6221 *needed += spoolss_size_port_info_2(&ports[i]);
6224 if (!alloc_buffer_size(buffer, *needed)) {
6226 return WERR_INSUFFICIENT_BUFFER;
6229 /* fill the buffer with the ports structures */
6230 for (i=0; i<*returned; i++) {
6231 DEBUGADD(6,("adding port [%d] to buffer\n", i));
6232 smb_io_port_2("", buffer, &ports[i], 0);
6237 if (*needed > offered) {
6239 return WERR_INSUFFICIENT_BUFFER;
6245 /****************************************************************************
6247 ****************************************************************************/
6249 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
6251 /* UNISTR2 *name = &q_u->name; - notused. */
6252 uint32 level = q_u->level;
6253 NEW_BUFFER *buffer = NULL;
6254 uint32 offered = q_u->offered;
6255 uint32 *needed = &r_u->needed;
6256 uint32 *returned = &r_u->returned;
6258 /* that's an [in out] buffer */
6259 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6260 buffer = r_u->buffer;
6262 DEBUG(4,("_spoolss_enumports\n"));
6269 return enumports_level_1(buffer, offered, needed, returned);
6271 return enumports_level_2(buffer, offered, needed, returned);
6273 return WERR_UNKNOWN_LEVEL;
6277 /****************************************************************************
6278 ****************************************************************************/
6280 static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
6281 const SPOOL_PRINTER_INFO_LEVEL *info,
6282 DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf,
6283 uint32 user_switch, const SPOOL_USER_CTR *user,
6286 NT_PRINTER_INFO_LEVEL *printer = NULL;
6289 WERROR err = WERR_OK;
6291 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
6292 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
6296 ZERO_STRUCTP(printer);
6298 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
6299 if (!convert_printer_info(info, printer, 2)) {
6300 free_a_printer(&printer, 2);
6304 /* check to see if the printer already exists */
6306 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
6307 DEBUG(5, ("_spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed!\n",
6308 printer->info_2->sharename));
6309 free_a_printer(&printer, 2);
6310 return WERR_PRINTER_ALREADY_EXISTS;
6313 if (*lp_addprinter_cmd() )
6314 if ( !add_printer_hook(printer) ) {
6315 free_a_printer(&printer,2);
6316 return WERR_ACCESS_DENIED;
6319 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", get_called_name(),
6320 printer->info_2->sharename);
6322 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
6323 free_a_printer(&printer,2);
6324 return WERR_ACCESS_DENIED;
6327 /* you must be a printer admin to add a new printer */
6328 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
6329 free_a_printer(&printer,2);
6330 return WERR_ACCESS_DENIED;
6334 * Do sanity check on the requested changes for Samba.
6337 if (!check_printer_ok(printer->info_2, snum)) {
6338 free_a_printer(&printer,2);
6339 return WERR_INVALID_PARAM;
6343 * When a printer is created, the drivername bound to the printer is used
6344 * to lookup previously saved driver initialization info, which is then
6345 * bound to the new printer, simulating what happens in the Windows arch.
6349 set_driver_init(printer, 2);
6351 /* A valid devmode was included, convert and link it
6353 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
6355 if (!convert_devicemode(printer->info_2->printername, devmode,
6356 &printer->info_2->devmode))
6360 set_driver_init(printer, 2);
6362 /* write the ASCII on disk */
6363 err = mod_a_printer(*printer, 2);
6364 if (!W_ERROR_IS_OK(err)) {
6365 free_a_printer(&printer,2);
6369 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
6370 /* Handle open failed - remove addition. */
6371 del_a_printer(printer->info_2->sharename);
6372 free_a_printer(&printer,2);
6373 return WERR_ACCESS_DENIED;
6376 update_c_setprinter(False);
6378 srv_spoolss_sendnotify(printer->info_2->printername, 0, PRINTER_CHANGE_ADD_PRINTER, 0x0);
6380 free_a_printer(&printer,2);
6385 /****************************************************************************
6386 ****************************************************************************/
6388 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
6390 UNISTR2 *uni_srv_name = &q_u->server_name;
6391 uint32 level = q_u->level;
6392 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
6393 DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
6394 SEC_DESC_BUF *sdb = q_u->secdesc_ctr;
6395 uint32 user_switch = q_u->user_switch;
6396 SPOOL_USER_CTR *user = &q_u->user_ctr;
6397 POLICY_HND *handle = &r_u->handle;
6401 /* we don't handle yet */
6402 /* but I know what to do ... */
6403 return WERR_UNKNOWN_LEVEL;
6405 return spoolss_addprinterex_level_2(p, uni_srv_name, info,
6407 user_switch, user, handle);
6409 return WERR_UNKNOWN_LEVEL;
6413 /****************************************************************************
6414 ****************************************************************************/
6416 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
6418 /* UNISTR2 *server_name = &q_u->server_name; - notused. */
6419 uint32 level = q_u->level;
6420 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
6421 WERROR err = WERR_OK;
6422 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6423 struct current_user user;
6425 ZERO_STRUCT(driver);
6427 get_current_user(&user, p);
6429 if (!convert_printer_driver_info(info, &driver, level)) {
6434 DEBUG(5,("Cleaning driver's information\n"));
6435 err = clean_up_driver_struct(driver, level, &user);
6436 if (!W_ERROR_IS_OK(err))
6439 DEBUG(5,("Moving driver to final destination\n"));
6440 if(!move_driver_to_download_area(driver, level, &user, &err)) {
6441 if (W_ERROR_IS_OK(err))
6442 err = WERR_ACCESS_DENIED;
6446 if (add_a_printer_driver(driver, level)!=0) {
6447 err = WERR_ACCESS_DENIED;
6452 free_a_printer_driver(driver, level);
6456 /****************************************************************************
6457 ****************************************************************************/
6459 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
6461 init_unistr(&info->name, name);
6464 /****************************************************************************
6465 ****************************************************************************/
6467 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
6471 pstring short_archi;
6472 DRIVER_DIRECTORY_1 *info=NULL;
6474 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
6476 if (get_short_archi(short_archi, long_archi)==False)
6477 return WERR_INVALID_ENVIRONMENT;
6479 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
6482 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
6484 DEBUG(4,("printer driver directory: [%s]\n", path));
6486 fill_driverdir_1(info, path);
6488 *needed += spoolss_size_driverdir_info_1(info);
6490 if (!alloc_buffer_size(buffer, *needed)) {
6492 return WERR_INSUFFICIENT_BUFFER;
6495 smb_io_driverdir_1("", buffer, info, 0);
6499 if (*needed > offered)
6500 return WERR_INSUFFICIENT_BUFFER;
6505 /****************************************************************************
6506 ****************************************************************************/
6508 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
6510 UNISTR2 *name = &q_u->name;
6511 UNISTR2 *uni_environment = &q_u->environment;
6512 uint32 level = q_u->level;
6513 NEW_BUFFER *buffer = NULL;
6514 uint32 offered = q_u->offered;
6515 uint32 *needed = &r_u->needed;
6517 /* that's an [in out] buffer */
6518 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6519 buffer = r_u->buffer;
6521 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
6527 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
6529 return WERR_UNKNOWN_LEVEL;
6533 /****************************************************************************
6534 ****************************************************************************/
6536 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
6538 POLICY_HND *handle = &q_u->handle;
6539 uint32 idx = q_u->index;
6540 uint32 in_value_len = q_u->valuesize;
6541 uint32 in_data_len = q_u->datasize;
6542 uint32 *out_max_value_len = &r_u->valuesize;
6543 uint16 **out_value = &r_u->value;
6544 uint32 *out_value_len = &r_u->realvaluesize;
6545 uint32 *out_type = &r_u->type;
6546 uint32 *out_max_data_len = &r_u->datasize;
6547 uint8 **data_out = &r_u->data;
6548 uint32 *out_data_len = &r_u->realdatasize;
6550 NT_PRINTER_INFO_LEVEL *printer = NULL;
6555 uint32 biggest_valuesize;
6556 uint32 biggest_datasize;
6558 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6564 ZERO_STRUCT(printer);
6568 *out_max_data_len=0;
6572 DEBUG(5,("spoolss_enumprinterdata\n"));
6575 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
6579 if (!get_printer_snum(p,handle, &snum))
6582 result = get_a_printer(&printer, 2, lp_servicename(snum));
6583 if (!W_ERROR_IS_OK(result))
6587 * The NT machine wants to know the biggest size of value and data
6589 * cf: MSDN EnumPrinterData remark section
6591 if ( (in_value_len==0) && (in_data_len==0) ) {
6592 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
6596 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
6597 * if this parameter size doesn't exist.
6598 * Ok - my opinion here is that the client is not asking for the greatest
6599 * possible size of all the parameters, but is asking specifically for the size needed
6600 * for this specific parameter. In that case we can remove the loop below and
6601 * simplify this lookup code considerably. JF - comments welcome. JRA.
6604 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
6606 free_a_printer(&printer, 2);
6607 return WERR_NO_MORE_ITEMS;
6614 biggest_valuesize=0;
6617 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
6618 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
6619 if (data_len > biggest_datasize) biggest_datasize=data_len;
6621 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
6627 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
6628 *out_value_len=2*(1+biggest_valuesize);
6629 *out_data_len=biggest_datasize;
6631 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
6633 free_a_printer(&printer, 2);
6638 * the value len is wrong in NT sp3
6639 * that's the number of bytes not the number of unicode chars
6642 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
6645 free_a_printer(&printer, 2);
6647 /* out_value should default to "" or else NT4 has
6648 problems unmarshalling the response */
6650 *out_max_value_len=(in_value_len/sizeof(uint16));
6651 if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
6654 *out_value_len = rpcstr_push((char *)*out_value, "", in_value_len, 0);
6656 /* the data is counted in bytes */
6657 *out_max_data_len = in_data_len;
6658 *out_data_len = in_data_len;
6659 if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
6662 return WERR_NO_MORE_ITEMS;
6665 free_a_printer(&printer, 2);
6669 * - counted in bytes in the request
6670 * - counted in UNICODE chars in the max reply
6671 * - counted in bytes in the real size
6673 * take a pause *before* coding not *during* coding
6676 *out_max_value_len=(in_value_len/sizeof(uint16));
6677 if((*out_value=(uint16 *)talloc_zero(p->mem_ctx,in_value_len*sizeof(uint8))) == NULL) {
6682 *out_value_len = rpcstr_push((char *)*out_value,value, in_value_len, 0);
6686 /* the data is counted in bytes */
6687 *out_max_data_len=in_data_len;
6688 if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) {
6693 memcpy(*data_out, data, (size_t)data_len);
6694 *out_data_len=data_len;
6701 /****************************************************************************
6702 ****************************************************************************/
6704 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
6706 POLICY_HND *handle = &q_u->handle;
6707 UNISTR2 *value = &q_u->value;
6708 uint32 type = q_u->type;
6709 /* uint32 max_len = q_u->max_len; - notused. */
6710 uint8 *data = q_u->data;
6711 uint32 real_len = q_u->real_len;
6712 /* uint32 numeric_data = q_u->numeric_data; - notused. */
6714 NT_PRINTER_INFO_LEVEL *printer = NULL;
6715 NT_PRINTER_PARAM *param = NULL, old_param;
6717 WERROR status = WERR_OK;
6718 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
6720 DEBUG(5,("spoolss_setprinterdata\n"));
6723 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
6727 if (!get_printer_snum(p,handle, &snum))
6730 ZERO_STRUCT(old_param);
6733 * Access check : NT returns "access denied" if you make a
6734 * SetPrinterData call without the necessary privildge.
6735 * we were originally returning OK if nothing changed
6736 * which made Win2k issue **a lot** of SetPrinterData
6737 * when connecting to a printer --jerry
6740 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6741 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
6742 status = WERR_ACCESS_DENIED;
6746 /* Check if we are making any changes or not. Return true if
6747 nothing is actually changing. This is not needed anymore but
6748 has been left in as an optimization to keep from from
6749 writing to disk as often --jerry */
6751 status = get_a_printer(&printer, 2, lp_servicename(snum));
6752 if (!W_ERROR_IS_OK(status))
6755 convert_specific_param(¶m, value , type, data, real_len);
6757 unlink_specific_param_if_exist(printer->info_2, param);
6760 * When client side code sets a magic printer data key, detect it and save
6761 * the current printer data and the magic key's data (its the DEVMODE) for
6762 * future printer/driver initializations.
6764 if (param->type==3 && !strcmp( param->value, PHANTOM_DEVMODE_KEY)) {
6766 * Set devmode and printer initialization info
6768 status = save_driver_init(printer, 2, param);
6771 add_a_specific_param(printer->info_2, ¶m);
6772 status = mod_a_printer(*printer, 2);
6776 free_a_printer(&printer, 2);
6778 free_nt_printer_param(¶m);
6779 SAFE_FREE(old_param.data);
6784 /****************************************************************************
6785 ****************************************************************************/
6787 WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
6789 POLICY_HND *handle = &q_u->handle;
6790 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
6793 DEBUG(5,("_spoolss_resetprinter\n"));
6796 * All we do is to check to see if the handle and queue is valid.
6797 * This call really doesn't mean anything to us because we only
6798 * support RAW printing. --jerry
6802 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
6806 if (!get_printer_snum(p,handle, &snum))
6810 /* blindly return success */
6815 WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
6817 POLICY_HND *handle = &q_u->handle;
6818 UNISTR2 *value = &q_u->valuename;
6820 NT_PRINTER_INFO_LEVEL *printer = NULL;
6821 NT_PRINTER_PARAM param;
6823 WERROR status = WERR_OK;
6824 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
6826 DEBUG(5,("spoolss_deleteprinterdata\n"));
6829 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
6833 if (!get_printer_snum(p, handle, &snum))
6836 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6837 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n"));
6838 return WERR_ACCESS_DENIED;
6841 status = get_a_printer(&printer, 2, lp_servicename(snum));
6842 if (!W_ERROR_IS_OK(status))
6845 ZERO_STRUCTP(¶m);
6846 unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
6848 if(!unlink_specific_param_if_exist(printer->info_2, ¶m))
6849 status = WERR_INVALID_PARAM;
6851 status = mod_a_printer(*printer, 2);
6853 free_a_printer(&printer, 2);
6857 /****************************************************************************
6858 ****************************************************************************/
6860 WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
6862 POLICY_HND *handle = &q_u->handle;
6863 /* uint32 level = q_u->level; - notused. */
6864 FORM *form = &q_u->form;
6865 nt_forms_struct tmpForm;
6867 WERROR status = WERR_OK;
6868 NT_PRINTER_INFO_LEVEL *printer = NULL;
6871 nt_forms_struct *list=NULL;
6872 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6874 DEBUG(5,("spoolss_addform\n"));
6877 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
6881 if (!get_printer_snum(p,handle, &snum))
6884 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6885 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
6886 status = WERR_ACCESS_DENIED;
6890 /* can't add if builtin */
6891 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
6892 return WERR_ALREADY_EXISTS;
6895 count=get_ntforms(&list);
6896 if(!add_a_form(&list, form, &count))
6898 write_ntforms(&list, count);
6901 * ChangeID must always be set
6904 status = get_a_printer(&printer, 2, lp_servicename(snum));
6905 if (!W_ERROR_IS_OK(status))
6908 status = mod_a_printer(*printer, 2);
6909 if (!W_ERROR_IS_OK(status))
6913 free_a_printer(&printer, 2);
6919 /****************************************************************************
6920 ****************************************************************************/
6922 WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u)
6924 POLICY_HND *handle = &q_u->handle;
6925 UNISTR2 *form_name = &q_u->name;
6926 nt_forms_struct tmpForm;
6928 WERROR ret = WERR_OK;
6929 nt_forms_struct *list=NULL;
6930 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6932 WERROR status = WERR_OK;
6933 NT_PRINTER_INFO_LEVEL *printer = NULL;
6935 DEBUG(5,("spoolss_deleteform\n"));
6938 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
6942 if (!get_printer_snum(p, handle, &snum))
6945 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6946 DEBUG(2,("_spoolss_deleteform: denied by handle permissions\n"));
6947 return WERR_ACCESS_DENIED;
6950 /* can't delete if builtin */
6951 if (get_a_builtin_ntform(form_name,&tmpForm)) {
6952 return WERR_INVALID_PARAM;
6955 count = get_ntforms(&list);
6956 if(!delete_a_form(&list, form_name, &count, &ret))
6957 return WERR_INVALID_PARAM;
6960 * ChangeID must always be set
6963 status = get_a_printer(&printer, 2, lp_servicename(snum));
6964 if (!W_ERROR_IS_OK(status))
6967 status = mod_a_printer(*printer, 2);
6968 if (!W_ERROR_IS_OK(status))
6972 free_a_printer(&printer, 2);
6978 /****************************************************************************
6979 ****************************************************************************/
6981 WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
6983 POLICY_HND *handle = &q_u->handle;
6984 /* UNISTR2 *uni_name = &q_u->name; - notused. */
6985 /* uint32 level = q_u->level; - notused. */
6986 FORM *form = &q_u->form;
6987 nt_forms_struct tmpForm;
6989 WERROR status = WERR_OK;
6990 NT_PRINTER_INFO_LEVEL *printer = NULL;
6993 nt_forms_struct *list=NULL;
6994 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6996 DEBUG(5,("spoolss_setform\n"));
6999 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
7003 if (!get_printer_snum(p, handle, &snum))
7006 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
7007 DEBUG(2,("_spoolss_setform: denied by handle permissions\n"));
7008 return WERR_ACCESS_DENIED;
7011 /* can't set if builtin */
7012 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
7013 return WERR_INVALID_PARAM;
7016 count=get_ntforms(&list);
7017 update_a_form(&list, form, count);
7018 write_ntforms(&list, count);
7021 * ChangeID must always be set
7024 status = get_a_printer(&printer, 2, lp_servicename(snum));
7025 if (!W_ERROR_IS_OK(status))
7028 status = mod_a_printer(*printer, 2);
7029 if (!W_ERROR_IS_OK(status))
7033 free_a_printer(&printer, 2);
7039 /****************************************************************************
7040 enumprintprocessors level 1.
7041 ****************************************************************************/
7043 static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7045 PRINTPROCESSOR_1 *info_1=NULL;
7047 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
7052 init_unistr(&info_1->name, "winprint");
7054 *needed += spoolss_size_printprocessor_info_1(info_1);
7056 if (!alloc_buffer_size(buffer, *needed))
7057 return WERR_INSUFFICIENT_BUFFER;
7059 smb_io_printprocessor_info_1("", buffer, info_1, 0);
7063 if (*needed > offered) {
7065 return WERR_INSUFFICIENT_BUFFER;
7071 /****************************************************************************
7072 ****************************************************************************/
7074 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
7076 /* UNISTR2 *name = &q_u->name; - notused. */
7077 /* UNISTR2 *environment = &q_u->environment; - notused. */
7078 uint32 level = q_u->level;
7079 NEW_BUFFER *buffer = NULL;
7080 uint32 offered = q_u->offered;
7081 uint32 *needed = &r_u->needed;
7082 uint32 *returned = &r_u->returned;
7084 /* that's an [in out] buffer */
7085 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
7086 buffer = r_u->buffer;
7088 DEBUG(5,("spoolss_enumprintprocessors\n"));
7091 * Enumerate the print processors ...
7093 * Just reply with "winprint", to keep NT happy
7094 * and I can use my nice printer checker.
7102 return enumprintprocessors_level_1(buffer, offered, needed, returned);
7104 return WERR_UNKNOWN_LEVEL;
7108 /****************************************************************************
7109 enumprintprocdatatypes level 1.
7110 ****************************************************************************/
7112 static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7114 PRINTPROCDATATYPE_1 *info_1=NULL;
7116 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
7121 init_unistr(&info_1->name, "RAW");
7123 *needed += spoolss_size_printprocdatatype_info_1(info_1);
7125 if (!alloc_buffer_size(buffer, *needed))
7126 return WERR_INSUFFICIENT_BUFFER;
7128 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
7132 if (*needed > offered) {
7134 return WERR_INSUFFICIENT_BUFFER;
7140 /****************************************************************************
7141 ****************************************************************************/
7143 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
7145 /* UNISTR2 *name = &q_u->name; - notused. */
7146 /* UNISTR2 *processor = &q_u->processor; - notused. */
7147 uint32 level = q_u->level;
7148 NEW_BUFFER *buffer = NULL;
7149 uint32 offered = q_u->offered;
7150 uint32 *needed = &r_u->needed;
7151 uint32 *returned = &r_u->returned;
7153 /* that's an [in out] buffer */
7154 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
7155 buffer = r_u->buffer;
7157 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
7164 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
7166 return WERR_UNKNOWN_LEVEL;
7170 /****************************************************************************
7171 enumprintmonitors level 1.
7172 ****************************************************************************/
7174 static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7176 PRINTMONITOR_1 *info_1=NULL;
7178 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
7183 init_unistr(&info_1->name, "Local Port");
7185 *needed += spoolss_size_printmonitor_info_1(info_1);
7187 if (!alloc_buffer_size(buffer, *needed))
7188 return WERR_INSUFFICIENT_BUFFER;
7190 smb_io_printmonitor_info_1("", buffer, info_1, 0);
7194 if (*needed > offered) {
7196 return WERR_INSUFFICIENT_BUFFER;
7202 /****************************************************************************
7203 enumprintmonitors level 2.
7204 ****************************************************************************/
7206 static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7208 PRINTMONITOR_2 *info_2=NULL;
7210 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
7215 init_unistr(&info_2->name, "Local Port");
7216 init_unistr(&info_2->environment, "Windows NT X86");
7217 init_unistr(&info_2->dll_name, "localmon.dll");
7219 *needed += spoolss_size_printmonitor_info_2(info_2);
7221 if (!alloc_buffer_size(buffer, *needed))
7222 return WERR_INSUFFICIENT_BUFFER;
7224 smb_io_printmonitor_info_2("", buffer, info_2, 0);
7228 if (*needed > offered) {
7230 return WERR_INSUFFICIENT_BUFFER;
7236 /****************************************************************************
7237 ****************************************************************************/
7239 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
7241 /* UNISTR2 *name = &q_u->name; - notused. */
7242 uint32 level = q_u->level;
7243 NEW_BUFFER *buffer = NULL;
7244 uint32 offered = q_u->offered;
7245 uint32 *needed = &r_u->needed;
7246 uint32 *returned = &r_u->returned;
7248 /* that's an [in out] buffer */
7249 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
7250 buffer = r_u->buffer;
7252 DEBUG(5,("spoolss_enumprintmonitors\n"));
7255 * Enumerate the print monitors ...
7257 * Just reply with "Local Port", to keep NT happy
7258 * and I can use my nice printer checker.
7266 return enumprintmonitors_level_1(buffer, offered, needed, returned);
7268 return enumprintmonitors_level_2(buffer, offered, needed, returned);
7270 return WERR_UNKNOWN_LEVEL;
7274 /****************************************************************************
7275 ****************************************************************************/
7277 static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
7281 JOB_INFO_1 *info_1=NULL;
7283 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
7285 if (info_1 == NULL) {
7290 for (i=0; i<count && found==False; i++) {
7291 if (queue[i].job==(int)jobid)
7298 /* NT treats not found as bad param... yet another bad choice */
7299 return WERR_INVALID_PARAM;
7302 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
7306 *needed += spoolss_size_job_info_1(info_1);
7308 if (!alloc_buffer_size(buffer, *needed)) {
7310 return WERR_INSUFFICIENT_BUFFER;
7313 smb_io_job_info_1("", buffer, info_1, 0);
7317 if (*needed > offered)
7318 return WERR_INSUFFICIENT_BUFFER;
7323 /****************************************************************************
7324 ****************************************************************************/
7326 static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
7331 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
7333 DEVICEMODE *devmode = NULL;
7335 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
7337 ZERO_STRUCTP(info_2);
7339 if (info_2 == NULL) {
7344 for (i=0; i<count && found==False; i++) {
7345 if (queue[i].job==(int)jobid)
7350 /* NT treats not found as bad param... yet another bad
7352 ret = WERR_INVALID_PARAM;
7356 ret = get_a_printer(&ntprinter, 2, lp_servicename(snum));
7357 if (!W_ERROR_IS_OK(ret))
7359 if (construct_dev_mode(snum) == NULL) {
7364 fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter, devmode);
7366 *needed += spoolss_size_job_info_2(info_2);
7368 if (!alloc_buffer_size(buffer, *needed)) {
7369 ret = WERR_INSUFFICIENT_BUFFER;
7373 smb_io_job_info_2("", buffer, info_2, 0);
7375 if (*needed > offered) {
7376 ret = WERR_INSUFFICIENT_BUFFER;
7383 /* Cleanup allocated memory */
7386 free_job_info_2(info_2); /* Also frees devmode */
7388 free_a_printer(&ntprinter, 2);
7393 /****************************************************************************
7394 ****************************************************************************/
7396 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
7398 POLICY_HND *handle = &q_u->handle;
7399 uint32 jobid = q_u->jobid;
7400 uint32 level = q_u->level;
7401 NEW_BUFFER *buffer = NULL;
7402 uint32 offered = q_u->offered;
7403 uint32 *needed = &r_u->needed;
7407 print_queue_struct *queue=NULL;
7408 print_status_struct prt_status;
7410 /* that's an [in out] buffer */
7411 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
7412 buffer = r_u->buffer;
7414 DEBUG(5,("spoolss_getjob\n"));
7418 if (!get_printer_snum(p, handle, &snum))
7421 count = print_queue_status(snum, &queue, &prt_status);
7423 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
7424 count, prt_status.status, prt_status.message));
7428 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
7430 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
7433 return WERR_UNKNOWN_LEVEL;
7437 /********************************************************************
7438 * spoolss_getprinterdataex
7439 ********************************************************************/
7441 WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
7443 POLICY_HND *handle = &q_u->handle;
7444 uint32 in_size = q_u->size;
7445 uint32 *type = &r_u->type;
7446 uint32 *out_size = &r_u->size;
7447 uint8 **data = &r_u->data;
7448 uint32 *needed = &r_u->needed;
7451 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
7454 DEBUG(4,("_spoolss_getprinterdataex\n"));
7456 unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
7457 unistr2_to_ascii(value, &q_u->valuename, sizeof(value) - 1);
7459 /* in case of problem, return some default values */
7466 if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL)
7468 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
7473 /* Is the handle to a printer or to the server? */
7475 if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
7477 DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
7478 return WERR_INVALID_PARAM;
7483 * From MSDN documentation of GetPrinterDataEx: pass request
7484 * to GetPrinterData if key is "PrinterDriverData". This is
7485 * the only key we really support. Other keys to implement:
7491 if (strcmp(key, "PrinterDriverData") != 0)
7492 return WERR_BADFILE;
7494 DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
7495 found = getprinterdata_printer(p, p->mem_ctx, handle, value,
7496 type, data, needed, in_size);
7501 DEBUG(5, ("value not found, allocating %d\n", *out_size));
7503 /* reply this param doesn't exist */
7505 if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
7511 return WERR_INVALID_PARAM;
7514 if (*needed > *out_size)
7515 return WERR_MORE_DATA;
7520 /********************************************************************
7521 * spoolss_setprinterdata
7522 ********************************************************************/
7524 WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
7526 SPOOL_Q_SETPRINTERDATA q_u_local;
7527 SPOOL_R_SETPRINTERDATA r_u_local;
7530 DEBUG(4,("_spoolss_setprinterdataex\n"));
7532 /* From MSDN documentation of SetPrinterDataEx: pass request to
7533 SetPrinterData if key is "PrinterDriverData" */
7535 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
7537 if (strcmp(key, "PrinterDriverData") != 0)
7538 return WERR_INVALID_PARAM;
7540 ZERO_STRUCT(q_u_local);
7541 ZERO_STRUCT(r_u_local);
7543 /* make a copy to call _spoolss_setprinterdata() */
7545 memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND));
7546 copy_unistr2(&q_u_local.value, &q_u->value);
7547 q_u_local.type = q_u->type;
7548 q_u_local.max_len = q_u->max_len;
7549 q_u_local.data = q_u->data;
7550 q_u_local.real_len = q_u->real_len;
7551 q_u_local.numeric_data = q_u->numeric_data;
7553 return _spoolss_setprinterdata(p, &q_u_local, &r_u_local);
7556 /********************************************************************
7557 * spoolss_enumprinterkey
7558 ********************************************************************/
7560 /* constants for EnumPrinterKey() */
7561 #define ENUMERATED_KEY_SIZE 19
7563 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
7566 uint16 enumkeys[ENUMERATED_KEY_SIZE+1];
7569 char *PrinterKey = "PrinterDriverData";
7571 DEBUG(4,("_spoolss_enumprinterkey\n"));
7573 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
7576 * we only support enumating all keys (key == "")
7577 * Of course, the only key we support is the "PrinterDriverData"
7580 if (strlen(key) == 0)
7582 r_u->needed = ENUMERATED_KEY_SIZE *2;
7583 if (q_u->size < r_u->needed)
7584 return WERR_MORE_DATA;
7587 for (i=0; i<ENUMERATED_KEY_SIZE-2; i++)
7589 enumkeys[i] = (uint16)(*ptr);
7593 /* tag of with 2 '\0's */
7594 enumkeys[i++] = '\0';
7597 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, ENUMERATED_KEY_SIZE, enumkeys))
7598 return WERR_BADFILE;
7603 /* The "PrinterDriverData" key should have no subkeys */
7604 if (strcmp(key, PrinterKey) == 0)
7607 if (q_u->size < r_u->needed)
7608 return WERR_MORE_DATA;
7610 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, enumkeys))
7611 return WERR_BADFILE;
7617 /* The return value for an unknown key is documented in MSDN
7618 EnumPrinterKey description */
7619 return WERR_BADFILE;
7622 /********************************************************************
7623 * spoolss_enumprinterdataex
7624 ********************************************************************/
7626 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
7628 POLICY_HND *handle = &q_u->handle;
7629 uint32 in_size = q_u->size;
7632 NT_PRINTER_INFO_LEVEL *printer = NULL;
7633 PRINTER_ENUM_VALUES *enum_values = NULL;
7635 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
7644 DEBUG(4,("_spoolss_enumprinterdataex\n"));
7647 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
7653 * The only key we support is "PrinterDriverData". This should return
7654 > an array of all the key/value pairs returned by EnumPrinterDataSee
7655 * _spoolss_getprinterdataex() for details --jerry
7658 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
7659 if (strcmp(key, "PrinterDriverData") != 0)
7661 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
7662 return WERR_INVALID_PARAM;
7666 if (!get_printer_snum(p,handle, &snum))
7669 ZERO_STRUCT(printer);
7670 result = get_a_printer(&printer, 2, lp_servicename(snum));
7671 if (!W_ERROR_IS_OK(result))
7676 * loop through all params and build the array to pass
7677 * back to the client
7684 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len))
7686 PRINTER_ENUM_VALUES *ptr;
7689 DEBUG(10,("retrieved value number [%d] [%s]\n", num_entries, value));
7691 if ((ptr=talloc_realloc(p->mem_ctx, enum_values, (num_entries+1) * sizeof(PRINTER_ENUM_VALUES))) == NULL)
7693 DEBUG(0,("talloc_realloc failed to allocate more memory!\n"));
7694 result = WERR_NOMEM;
7700 init_unistr(&enum_values[num_entries].valuename, value);
7701 enum_values[num_entries].value_len = (strlen(value)+1) * 2;
7702 enum_values[num_entries].type = type;
7704 if (!(enum_values[num_entries].data=talloc_zero(p->mem_ctx, data_len+add_len))) {
7705 DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n"));
7706 result = WERR_NOMEM;
7709 memcpy(enum_values[num_entries].data, data, data_len);
7710 enum_values[num_entries].data_len = data_len + add_len;
7712 /* keep track of the size of the array in bytes */
7714 needed += spoolss_size_printer_enum_values(&enum_values[num_entries]);
7720 r_u->needed = needed;
7721 r_u->returned = num_entries;
7723 if (needed > in_size) {
7724 result = WERR_MORE_DATA;
7728 /* copy data into the reply */
7730 r_u->ctr.size = r_u->needed;
7731 r_u->ctr.size_of_array = r_u->returned;
7732 r_u->ctr.values = enum_values;
7737 free_a_printer(&printer, 2);
7742 /****************************************************************************
7743 ****************************************************************************/
7745 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name)
7747 init_unistr(&info->name, name);
7750 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
7751 UNISTR2 *environment,
7758 pstring short_archi;
7759 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
7761 unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
7763 if (get_short_archi(short_archi, long_archi)==FALSE)
7764 return WERR_INVALID_ENVIRONMENT;
7766 if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
7769 /* Not sure what to return here - are UNC names valid here?.
7770 Windows returns the string: C:\WINNT\System32\spool\PRTPROCS\W32X86
7771 which is pretty bogus for a RPC. */
7773 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
7775 DEBUG(4,("print processor directory: [%s]\n", path));
7777 fill_printprocessordirectory_1(info, path);
7779 *needed += spoolss_size_printprocessordirectory_info_1(info);
7781 if (!alloc_buffer_size(buffer, *needed)) {
7783 return WERR_INSUFFICIENT_BUFFER;
7786 smb_io_printprocessordirectory_1("", buffer, info, 0);
7790 if (*needed > offered)
7791 return WERR_INSUFFICIENT_BUFFER;
7796 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
7798 uint32 level = q_u->level;
7799 NEW_BUFFER *buffer = NULL;
7800 uint32 offered = q_u->offered;
7801 uint32 *needed = &r_u->needed;
7803 /* that's an [in out] buffer */
7804 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
7805 buffer = r_u->buffer;
7807 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
7813 return getprintprocessordirectory_level_1
7814 (&q_u->name, &q_u->environment, buffer, offered, needed);
7816 return WERR_UNKNOWN_LEVEL;
7819 return WERR_ACCESS_DENIED;