2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 * Copyright (C) Jean François Micouleau 1998-2000.
8 * Copyright (C) Jeremy Allison 2001.
9 * Copyright (C) Gerald Carter 2000-2001.
10 * Copyright (C) Tim Potter 2001.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28 up, all the errors returned are DOS errors, not NT status codes. */
32 #ifndef MAX_OPEN_PRINTER_EXS
33 #define MAX_OPEN_PRINTER_EXS 50
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 BOOL document_started;
54 int jobid; /* jobid in printing backend */
58 fstring printerservername;
67 SPOOL_NOTIFY_OPTION *option;
68 POLICY_HND client_hnd;
69 uint32 client_connected;
77 typedef struct _counter_printer_0 {
85 static ubi_dlList counter_list;
87 static struct cli_state cli;
88 static uint32 smb_connections=0;
90 #define OUR_HANDLE(hnd) ((hnd==NULL)?"NULL":(IVAL(hnd->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER"))
92 /* translate between internal status numbers and NT status numbers */
93 static int nt_printj_status(int v)
99 return JOB_STATUS_PAUSED;
101 return JOB_STATUS_SPOOLING;
103 return JOB_STATUS_PRINTING;
105 return JOB_STATUS_ERROR;
107 return JOB_STATUS_DELETING;
109 return JOB_STATUS_OFFLINE;
111 return JOB_STATUS_PAPEROUT;
113 return JOB_STATUS_PRINTED;
115 return JOB_STATUS_DELETED;
117 return JOB_STATUS_BLOCKED;
118 case LPQ_USER_INTERVENTION:
119 return JOB_STATUS_USER_INTERVENTION;
124 static int nt_printq_status(int v)
128 return PRINTER_STATUS_PAUSED;
137 /****************************************************************************
138 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
139 ****************************************************************************/
141 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
146 SAFE_FREE((*pp)->ctr.type);
150 /***************************************************************************
151 Disconnect from the client
152 ****************************************************************************/
154 static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
158 /* weird if the test succeds !!! */
159 if (smb_connections==0) {
160 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
164 if(!cli_spoolss_reply_close_printer(&cli, handle, &status))
165 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n"));
167 /* if it's the last connection, deconnect the IPC$ share */
168 if (smb_connections==1) {
169 if(!spoolss_disconnect_from_client(&cli))
172 message_deregister(MSG_PRINTER_NOTIFY);
178 /****************************************************************************
179 Functions to free a printer entry datastruct.
180 ****************************************************************************/
182 static void free_printer_entry(void *ptr)
184 Printer_entry *Printer = (Printer_entry *)ptr;
186 if (Printer->notify.client_connected==True)
187 srv_spoolss_replycloseprinter(&Printer->notify.client_hnd);
189 Printer->notify.flags=0;
190 Printer->notify.options=0;
191 Printer->notify.localmachine[0]='\0';
192 Printer->notify.printerlocal=0;
193 free_spool_notify_option(&Printer->notify.option);
194 Printer->notify.option=NULL;
195 Printer->notify.client_connected=False;
200 /****************************************************************************
201 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
202 ****************************************************************************/
204 SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
206 SPOOL_NOTIFY_OPTION *new_sp = NULL;
211 new_sp = (SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
218 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
220 if (!new_sp->ctr.type) {
229 /****************************************************************************
230 find printer index by handle
231 ****************************************************************************/
233 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
235 Printer_entry *find_printer = NULL;
237 if(!find_policy_by_hnd(p,hnd,(void **)&find_printer)) {
238 DEBUG(3,("find_printer_index_by_hnd: Printer handle not found: "));
245 /****************************************************************************
246 close printer index by handle
247 ****************************************************************************/
249 static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
251 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
254 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
258 close_policy_hnd(p, hnd);
263 /****************************************************************************
264 delete a printer given a handle
265 ****************************************************************************/
266 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
268 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
271 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
275 if (del_a_printer(Printer->dev.handlename) != 0) {
276 DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
280 /* Check calling user has permission to delete printer. Note that
281 since we set the snum parameter to -1 only administrators can
282 delete the printer. This stops people with the Full Control
283 permission from deleting the printer. */
285 if (!print_access_check(NULL, -1, PRINTER_ACCESS_ADMINISTER)) {
286 DEBUG(3, ("printer delete denied by security descriptor\n"));
287 return WERR_ACCESS_DENIED;
290 if (*lp_deleteprinter_cmd()) {
292 char *cmd = lp_deleteprinter_cmd();
297 /* Printer->dev.handlename equals portname equals sharename */
298 slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
299 Printer->dev.handlename);
301 DEBUG(10,("Running [%s]\n", command));
302 ret = smbrun(command, NULL);
304 return WERR_BADFID; /* What to return here? */
306 DEBUGADD(10,("returned [%d]\n", ret));
308 /* Send SIGHUP to process group... is there a better way? */
311 if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
315 return WERR_ACCESS_DENIED;
321 /****************************************************************************
322 return the snum of a printer corresponding to an handle
323 ****************************************************************************/
324 static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
326 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
329 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
333 switch (Printer->printer_type) {
334 case PRINTER_HANDLE_IS_PRINTER:
335 DEBUG(4,("short name:%s\n", Printer->dev.handlename));
336 *number = print_queue_snum(Printer->dev.handlename);
337 return (*number != -1);
338 case PRINTER_HANDLE_IS_PRINTSERVER:
345 /****************************************************************************
346 set printer handle type.
347 ****************************************************************************/
348 static BOOL set_printer_hnd_accesstype(pipes_struct *p, POLICY_HND *hnd, uint32 access_required)
350 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
353 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd)));
357 DEBUG(4,("Setting printer access=%x\n", access_required));
358 Printer->access = access_required;
362 /****************************************************************************
363 Set printer handle type.
364 Check if it's \\server or \\server\printer
365 ****************************************************************************/
367 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
369 DEBUG(3,("Setting printer type=%s\n", handlename));
371 if ( strlen(handlename) < 3 ) {
372 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
376 /* it's a print server */
377 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
378 DEBUGADD(4,("Printer is a print server\n"));
379 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
383 DEBUGADD(4,("Printer is a printer\n"));
384 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
390 /****************************************************************************
391 Set printer handle name.
392 ****************************************************************************/
394 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
396 NT_PRINTER_INFO_LEVEL *printer = NULL;
398 int n_services=lp_numservices();
402 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
404 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
405 ZERO_STRUCT(Printer->dev.printerservername);
406 strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
410 if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
413 if (*handlename=='\\') {
414 aprinter=strchr_m(handlename+2, '\\');
421 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
424 * store the Samba share name in it
425 * in back we have the long printer name
426 * need to iterate all the snum and do a
427 * get_a_printer each time to find the printer
428 * faster to do it here than later.
431 for (snum=0;snum<n_services && found==False;snum++) {
434 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
437 DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
439 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
442 printername=strchr_m(printer->info_2->printername+2, '\\');
445 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
446 printer->info_2->printername, aprinter ));
448 if ( strlen(printername) != strlen(aprinter) ) {
449 free_a_printer(&printer, 2);
453 if ( strncasecmp(printername, aprinter, strlen(aprinter))) {
454 free_a_printer(&printer, 2);
462 * if we haven't found a printer with the given handlename
463 * then it can be a share name as you can open both \\server\printer and
468 * we still check if the printer description file exists as NT won't be happy
469 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
473 DEBUGADD(5,("Printer not found, checking for share now\n"));
475 for (snum=0;snum<n_services && found==False;snum++) {
477 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
480 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum)));
482 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
485 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
486 printer->info_2->printername, aprinter ));
488 if ( strlen(lp_servicename(snum)) != strlen(aprinter) ) {
489 free_a_printer(&printer, 2);
493 if ( strncasecmp(lp_servicename(snum), aprinter, strlen(aprinter))) {
494 free_a_printer(&printer, 2);
503 DEBUGADD(4,("Printer not found\n"));
508 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
509 printer->info_2->printername, lp_servicename(snum),snum));
511 ZERO_STRUCT(Printer->dev.handlename);
512 strncpy(Printer->dev.handlename, lp_servicename(snum), strlen(lp_servicename(snum)));
514 free_a_printer(&printer, 2);
519 /****************************************************************************
520 find first available printer slot. creates a printer handle for you.
521 ****************************************************************************/
523 static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name)
525 Printer_entry *new_printer;
527 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
529 if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
532 ZERO_STRUCTP(new_printer);
534 new_printer->notify.option=NULL;
536 if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) {
537 SAFE_FREE(new_printer);
541 if (!set_printer_hnd_printertype(new_printer, name)) {
542 close_printer_handle(p, hnd);
546 if (!set_printer_hnd_name(new_printer, name)) {
547 close_printer_handle(p, hnd);
551 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
556 /********************************************************************
557 Return True is the handle is a print server.
558 ********************************************************************/
560 static BOOL handle_is_printserver(pipes_struct *p, POLICY_HND *handle)
562 Printer_entry *Printer=find_printer_index_by_hnd(p,handle);
567 if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
573 /****************************************************************************
574 allocate more memory for a BUFFER.
575 ****************************************************************************/
576 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
584 /* damn, I'm doing the reverse operation of prs_grow() :) */
585 if (buffer_size < prs_data_size(ps))
588 extra_space = buffer_size - prs_data_size(ps);
591 * save the offset and move to the end of the buffer
592 * prs_grow() checks the extra_space against the offset
594 old_offset=prs_offset(ps);
595 prs_set_offset(ps, prs_data_size(ps));
597 if (!prs_grow(ps, extra_space))
600 prs_set_offset(ps, old_offset);
602 buffer->string_at_end=prs_data_size(ps);
607 /***************************************************************************
608 receive the notify message
609 ****************************************************************************/
611 static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
615 struct pipes_struct *p;
617 struct handle_list *hl;
620 fstrcpy(printer,buf);
623 DEBUG(0,("srv_spoolss_receive_message: got null message !\n"));
627 DEBUG(10,("srv_spoolss_receive_message: Got message about printer %s\n", printer ));
630 * We need to enumerate all printers. The handle list is shared
631 * across pipes of the same name, so just find the first open
636 for ( p = get_first_pipe(); p; get_next_pipe(p)) {
637 if (strequal(p->name, "spoolss")) {
638 hl = p->pipe_handles;
644 DEBUG(0,("srv_spoolss_receive_message: no handle list on spoolss pipe !\n"));
648 /* Iterate the printer list on this pipe. */
649 for (pol = hl->Policy; pol; pol = pol->next ) {
650 Printer_entry *find_printer = (Printer_entry *)pol->data_ptr;
656 * if the entry is the given printer or if it's a printerserver
657 * we send the message
660 if (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
661 if (strcmp(find_printer->dev.handlename, printer))
664 if (find_printer->notify.client_connected==True)
665 cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, PRINTER_CHANGE_ALL, 0x0, &status);
669 /***************************************************************************
671 ****************************************************************************/
672 static BOOL srv_spoolss_sendnotify(pipes_struct *p, POLICY_HND *handle)
676 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
679 DEBUG(0,("srv_spoolss_sendnotify: Invalid handle (%s).\n", OUR_HANDLE(handle)));
683 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
684 fstrcpy(printer, Printer->dev.handlename);
686 fstrcpy(printer, "");
688 /*srv_spoolss_receive_message(printer);*/
689 DEBUG(10,("srv_spoolss_sendnotify: Sending message about printer %s\n", printer ));
691 broadcast_printer_notify(printer);
696 /********************************************************************
697 * spoolss_open_printer
699 * called from the spoolss dispatcher
700 ********************************************************************/
702 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
705 WERROR result = WERR_OK;
708 UNISTR2 *printername = NULL;
709 PRINTER_DEFAULT *printer_default = &q_u->printer_default;
710 /* uint32 user_switch = q_u->user_switch; - notused */
711 /* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
712 POLICY_HND *handle = &r_u->handle;
716 struct current_user user;
718 if (q_u->printername_ptr != 0)
719 printername = &q_u->printername;
721 if (printername == NULL)
722 return WERR_INVALID_PRINTER_NAME;
724 /* some sanity check because you can open a printer or a print server */
725 /* aka: \\server\printer or \\server */
726 unistr2_to_ascii(name, printername, sizeof(name)-1);
728 DEBUGADD(3,("checking name: %s\n",name));
730 if (!open_printer_hnd(p, handle, name))
731 return WERR_INVALID_PRINTER_NAME;
734 if (printer_default->datatype_ptr != NULL)
736 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
737 set_printer_hnd_datatype(handle, datatype);
740 set_printer_hnd_datatype(handle, "");
743 if (!set_printer_hnd_accesstype(p, handle, printer_default->access_required)) {
744 close_printer_handle(p, handle);
745 return WERR_ACCESS_DENIED;
749 First case: the user is opening the print server:
751 Disallow MS AddPrinterWizard if parameter disables it. A Win2k
752 client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
754 Then both Win2k and WinNT clients try an OpenPrinterEx with
755 SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
756 or if the user is listed in the smb.conf printer admin parameter.
758 Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
759 client view printer folder, but does not show the MSAPW.
761 Note: this test needs code to check access rights here too. Jeremy
762 could you look at this?
765 Second case: the user is opening a printer:
766 NT doesn't let us connect to a printer if the connecting user
767 doesn't have print permission.
771 get_current_user(&user, p);
773 if (handle_is_printserver(p, handle)) {
774 if (printer_default->access_required == 0) {
777 else if ((printer_default->access_required & SERVER_ACCESS_ADMINISTER ) == SERVER_ACCESS_ADMINISTER) {
779 /* Printserver handles use global struct... */
782 if (!lp_ms_add_printer_wizard()) {
783 close_printer_handle(p, handle);
784 return WERR_ACCESS_DENIED;
786 else if (user.uid == 0 || user_in_list(uidtoname(user.uid), lp_printer_admin(snum))) {
790 close_printer_handle(p, handle);
791 return WERR_ACCESS_DENIED;
797 /* NT doesn't let us connect to a printer if the connecting user
798 doesn't have print permission. */
800 if (!get_printer_snum(p, handle, &snum))
803 /* map an empty access mask to the minimum access mask */
804 if (printer_default->access_required == 0x0)
805 printer_default->access_required = PRINTER_ACCESS_USE;
809 * If we are not serving the printer driver for this printer,
810 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
811 * will keep NT clients happy --jerry
814 if (lp_use_client_driver(snum)
815 && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
817 printer_default->access_required = PRINTER_ACCESS_USE;
820 if (!print_access_check(&user, snum, printer_default->access_required)) {
821 DEBUG(3, ("access DENIED for printer open\n"));
822 close_printer_handle(p, handle);
823 return WERR_ACCESS_DENIED;
827 * If we have a default device pointer in the
828 * printer_default struct, then we need to get
829 * the printer info from the tdb and if there is
830 * no default devicemode there then we do a *SET*
831 * here ! This is insanity.... JRA.
835 * If the openprinterex rpc call contains a devmode,
836 * it's a per-user one. This per-user devmode is derivated
837 * from the global devmode. Openprinterex() contains a per-user
838 * devmode for when you do EMF printing and spooling.
839 * In the EMF case, the NT workstation is only doing half the job
840 * of rendering the page. The other half is done by running the printer
841 * driver on the server.
842 * The EMF file doesn't contain the page description (paper size, orientation, ...).
843 * The EMF file only contains what is to be printed on the page.
844 * So in order for the server to know how to print, the NT client sends
845 * a devicemode attached to the openprinterex call.
846 * But this devicemode is short lived, it's only valid for the current print job.
848 * If Samba would have supported EMF spooling, this devicemode would
849 * have been attached to the handle, to sent it to the driver to correctly
850 * rasterize the EMF file.
852 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
853 * we just act as a pass-thru between windows and the printer.
855 * In order to know that Samba supports only RAW spooling, NT has to call
856 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
857 * and until NT sends a RAW job, we refuse it.
859 * But to call getprinter() or startdoc(), you first need a valid handle,
860 * and to get an handle you have to call openprintex(). Hence why you have
861 * a devicemode in the openprinterex() call.
864 * Differences between NT4 and NT 2000.
867 * On NT4, you only have a global devicemode. This global devicemode can be changed
868 * by the administrator (or by a user with enough privs). Everytime a user
869 * wants to print, the devicemode is resetted to the default. In Word, everytime
870 * you print, the printer's characteristics are always reset to the global devicemode.
874 * In W2K, there is the notion of per-user devicemode. The first time you use
875 * a printer, a per-user devicemode is build from the global devicemode.
876 * If you change your per-user devicemode, it is saved in the registry, under the
877 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
878 * printer preferences available.
880 * To change the per-user devicemode: it's the "Printing Preferences ..." button
881 * on the General Tab of the printer properties windows.
883 * To change the global devicemode: it's the "Printing Defaults..." button
884 * on the Advanced Tab of the printer properties window.
892 if (printer_default->devmode_cont.devmode != NULL) {
893 result = printer_write_default_dev( snum, printer_default);
895 close_printer_handle(p, handle);
905 /****************************************************************************
906 ****************************************************************************/
907 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
908 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
914 ret = uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
923 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
924 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
930 printer->info_3=NULL;
931 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
935 printer->info_6=NULL;
936 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
946 BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
947 NT_DEVICEMODE **pp_nt_devmode)
949 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
952 * Ensure nt_devmode is a valid pointer
953 * as we will be overwriting it.
956 if (nt_devmode == NULL) {
957 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
958 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
962 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
963 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
965 nt_devmode->specversion=devmode->specversion;
966 nt_devmode->driverversion=devmode->driverversion;
967 nt_devmode->size=devmode->size;
968 nt_devmode->fields=devmode->fields;
969 nt_devmode->orientation=devmode->orientation;
970 nt_devmode->papersize=devmode->papersize;
971 nt_devmode->paperlength=devmode->paperlength;
972 nt_devmode->paperwidth=devmode->paperwidth;
973 nt_devmode->scale=devmode->scale;
974 nt_devmode->copies=devmode->copies;
975 nt_devmode->defaultsource=devmode->defaultsource;
976 nt_devmode->printquality=devmode->printquality;
977 nt_devmode->color=devmode->color;
978 nt_devmode->duplex=devmode->duplex;
979 nt_devmode->yresolution=devmode->yresolution;
980 nt_devmode->ttoption=devmode->ttoption;
981 nt_devmode->collate=devmode->collate;
983 nt_devmode->logpixels=devmode->logpixels;
984 nt_devmode->bitsperpel=devmode->bitsperpel;
985 nt_devmode->pelswidth=devmode->pelswidth;
986 nt_devmode->pelsheight=devmode->pelsheight;
987 nt_devmode->displayflags=devmode->displayflags;
988 nt_devmode->displayfrequency=devmode->displayfrequency;
989 nt_devmode->icmmethod=devmode->icmmethod;
990 nt_devmode->icmintent=devmode->icmintent;
991 nt_devmode->mediatype=devmode->mediatype;
992 nt_devmode->dithertype=devmode->dithertype;
993 nt_devmode->reserved1=devmode->reserved1;
994 nt_devmode->reserved2=devmode->reserved2;
995 nt_devmode->panningwidth=devmode->panningwidth;
996 nt_devmode->panningheight=devmode->panningheight;
999 * Only change private and driverextra if the incoming devmode
1000 * has a new one. JRA.
1003 if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
1004 SAFE_FREE(nt_devmode->private);
1005 nt_devmode->driverextra=devmode->driverextra;
1006 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
1008 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
1011 *pp_nt_devmode = nt_devmode;
1016 /********************************************************************
1017 * _spoolss_enddocprinter_internal.
1018 ********************************************************************/
1020 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1022 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1025 DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle)));
1029 Printer->document_started=False;
1030 print_job_end(Printer->jobid,True);
1031 /* error codes unhandled so far ... */
1036 /********************************************************************
1037 * api_spoolss_closeprinter
1038 ********************************************************************/
1040 WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u)
1042 POLICY_HND *handle = &q_u->handle;
1044 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1046 if (Printer && Printer->document_started)
1047 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1049 memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
1051 if (!close_printer_handle(p, handle))
1057 /********************************************************************
1058 * api_spoolss_deleteprinter
1060 ********************************************************************/
1062 WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u)
1064 POLICY_HND *handle = &q_u->handle;
1065 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1068 if (Printer && Printer->document_started)
1069 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1071 memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
1073 result = delete_printer_handle(p, handle);
1075 if (W_ERROR_IS_OK(result)) {
1076 srv_spoolss_sendnotify(p, handle);
1082 /*******************************************************************
1083 * static function to lookup the version id corresponding to an
1084 * long architecture string
1085 ******************************************************************/
1086 static int get_version_id (char * arch)
1089 struct table_node archi_table[]= {
1091 {"Windows 4.0", "WIN40", 0 },
1092 {"Windows NT x86", "W32X86", 2 },
1093 {"Windows NT R4000", "W32MIPS", 2 },
1094 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1095 {"Windows NT PowerPC", "W32PPC", 2 },
1099 for (i=0; archi_table[i].long_archi != NULL; i++)
1101 if (strcmp(arch, archi_table[i].long_archi) == 0)
1102 return (archi_table[i].version);
1108 /********************************************************************
1109 * _spoolss_deleteprinterdriver
1111 * We currently delete the driver for the architecture only.
1112 * This can leave the driver for other archtectures. However,
1113 * since every printer associates a "Windows NT x86" driver name
1114 * and we cannot delete that one while it is in use, **and** since
1115 * it is impossible to assign a driver to a Samba printer without
1116 * having the "Windows NT x86" driver installed,...
1118 * ....we should not get into trouble here.
1121 ********************************************************************/
1123 WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
1124 SPOOL_R_DELETEPRINTERDRIVER *r_u)
1128 NT_PRINTER_DRIVER_INFO_LEVEL info;
1131 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
1132 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
1134 /* check that we have a valid driver name first */
1135 if ((version=get_version_id(arch)) == -1) {
1136 /* this is what NT returns */
1137 return WERR_INVALID_ENVIRONMENT;
1141 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
1142 return WERR_UNKNOWN_PRINTER_DRIVER;
1146 if (printer_driver_in_use(arch, driver))
1148 return WERR_PRINTER_DRIVER_IN_USE;
1151 return delete_printer_driver(info.info_3);
1155 /********************************************************************
1156 GetPrinterData on a printer server Handle.
1157 ********************************************************************/
1158 static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
1162 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
1164 if (!strcmp(value, "BeepEnabled")) {
1166 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1168 SIVAL(*data, 0, 0x01);
1173 if (!strcmp(value, "EventLog")) {
1175 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1177 SIVAL(*data, 0, 0x1B);
1182 if (!strcmp(value, "NetPopup")) {
1184 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1186 SIVAL(*data, 0, 0x01);
1191 if (!strcmp(value, "MajorVersion")) {
1193 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1195 SIVAL(*data, 0, 0x02);
1200 if (!strcmp(value, "DefaultSpoolDirectory")) {
1201 pstring string="You are using a Samba server";
1203 *needed = 2*(strlen(string)+1);
1204 if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
1206 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
1208 /* it's done by hand ready to go on the wire */
1209 for (i=0; i<strlen(string); i++) {
1210 (*data)[2*i]=string[i];
1211 (*data)[2*i+1]='\0';
1216 if (!strcmp(value, "Architecture")) {
1217 pstring string="Windows NT x86";
1219 *needed = 2*(strlen(string)+1);
1220 if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
1222 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
1223 for (i=0; i<strlen(string); i++) {
1224 (*data)[2*i]=string[i];
1225 (*data)[2*i+1]='\0';
1233 /********************************************************************
1234 GetPrinterData on a printer Handle.
1235 ********************************************************************/
1236 static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND *handle,
1237 fstring value, uint32 *type,
1238 uint8 **data, uint32 *needed, uint32 in_size )
1240 NT_PRINTER_INFO_LEVEL *printer = NULL;
1244 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
1246 DEBUG(5,("getprinterdata_printer\n"));
1249 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
1253 if(!get_printer_snum(p, handle, &snum))
1256 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
1259 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
1260 free_a_printer(&printer, 2);
1264 free_a_printer(&printer, 2);
1266 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
1269 if((*data = (uint8 *)talloc(ctx, in_size *sizeof(uint8) )) == NULL) {
1273 memset(*data, 0, in_size *sizeof(uint8));
1274 /* copy the min(in_size, len) */
1275 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
1282 DEBUG(5,("getprinterdata_printer:copy done\n"));
1289 /********************************************************************
1290 * spoolss_getprinterdata
1291 ********************************************************************/
1293 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
1295 POLICY_HND *handle = &q_u->handle;
1296 UNISTR2 *valuename = &q_u->valuename;
1297 uint32 in_size = q_u->size;
1298 uint32 *type = &r_u->type;
1299 uint32 *out_size = &r_u->size;
1300 uint8 **data = &r_u->data;
1301 uint32 *needed = &r_u->needed;
1305 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
1308 * Reminder: when it's a string, the length is in BYTES
1309 * even if UNICODE is negociated.
1316 /* in case of problem, return some default values */
1320 DEBUG(4,("_spoolss_getprinterdata\n"));
1323 if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL)
1325 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
1329 unistr2_to_ascii(value, valuename, sizeof(value)-1);
1331 if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
1332 found=getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
1334 found= getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
1337 DEBUG(5, ("value not found, allocating %d\n", *out_size));
1338 /* reply this param doesn't exist */
1340 if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
1346 return WERR_INVALID_PARAM;
1349 if (*needed > *out_size)
1350 return WERR_STATUS_MORE_ENTRIES;
1355 /***************************************************************************
1356 connect to the client
1357 ****************************************************************************/
1358 static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle)
1363 * If it's the first connection, contact the client
1364 * and connect to the IPC$ share anonumously
1366 if (smb_connections==0) {
1367 fstring unix_printer;
1369 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
1371 if(!spoolss_connect_to_client(&cli, unix_printer))
1373 message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message);
1379 if(!cli_spoolss_reply_open_printer(&cli, printer, localprinter, type, &status, handle))
1385 /********************************************************************
1387 * ReplyFindFirstPrinterChangeNotifyEx
1389 * jfmxxxx: before replying OK: status=0
1390 * should do a rpc call to the workstation asking ReplyOpenPrinter
1391 * have to code it, later.
1393 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
1394 * called from api_spoolss_rffpcnex
1395 ********************************************************************/
1397 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
1399 POLICY_HND *handle = &q_u->handle;
1400 uint32 flags = q_u->flags;
1401 uint32 options = q_u->options;
1402 UNISTR2 *localmachine = &q_u->localmachine;
1403 uint32 printerlocal = q_u->printerlocal;
1404 SPOOL_NOTIFY_OPTION *option = q_u->option;
1406 /* store the notify value in the printer struct */
1408 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1411 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
1415 Printer->notify.flags=flags;
1416 Printer->notify.options=options;
1417 Printer->notify.printerlocal=printerlocal;
1419 if (Printer->notify.option)
1420 free_spool_notify_option(&Printer->notify.option);
1422 Printer->notify.option=dup_spool_notify_option(option);
1424 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
1426 /* connect to the client machine and send a ReplyOpenPrinter */
1427 if(srv_spoolss_replyopenprinter(Printer->notify.localmachine,
1428 Printer->notify.printerlocal, 1,
1429 &Printer->notify.client_hnd))
1430 Printer->notify.client_connected=True;
1435 /*******************************************************************
1436 * fill a notify_info_data with the servername
1437 ********************************************************************/
1439 static void spoolss_notify_server_name(int snum,
1440 SPOOL_NOTIFY_INFO_DATA *data,
1441 print_queue_struct *queue,
1442 NT_PRINTER_INFO_LEVEL *printer,
1443 TALLOC_CTX *mem_ctx)
1445 pstring temp_name, temp;
1448 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
1450 len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE);
1452 data->notify_data.data.length = len / 2;
1453 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1455 if (!data->notify_data.data.string) {
1456 data->notify_data.data.length = 0;
1460 memcpy(data->notify_data.data.string, temp, len);
1463 /*******************************************************************
1464 * fill a notify_info_data with the printername (not including the servername).
1465 ********************************************************************/
1466 static void spoolss_notify_printer_name(int snum,
1467 SPOOL_NOTIFY_INFO_DATA *data,
1468 print_queue_struct *queue,
1469 NT_PRINTER_INFO_LEVEL *printer,
1470 TALLOC_CTX *mem_ctx)
1475 /* the notify name should not contain the \\server\ part */
1476 char *p = strrchr_m(printer->info_2->printername, '\\');
1479 p = printer->info_2->printername;
1484 len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
1485 data->notify_data.data.length = len / 2;
1486 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1488 if (!data->notify_data.data.string) {
1489 data->notify_data.data.length = 0;
1493 memcpy(data->notify_data.data.string, temp, len);
1496 /*******************************************************************
1497 * fill a notify_info_data with the servicename
1498 ********************************************************************/
1499 static void spoolss_notify_share_name(int snum,
1500 SPOOL_NOTIFY_INFO_DATA *data,
1501 print_queue_struct *queue,
1502 NT_PRINTER_INFO_LEVEL *printer,
1503 TALLOC_CTX *mem_ctx)
1508 len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
1510 data->notify_data.data.length = len / 2;
1511 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1513 if (!data->notify_data.data.string) {
1514 data->notify_data.data.length = 0;
1518 memcpy(data->notify_data.data.string, temp, len);
1521 /*******************************************************************
1522 * fill a notify_info_data with the port name
1523 ********************************************************************/
1524 static void spoolss_notify_port_name(int snum,
1525 SPOOL_NOTIFY_INFO_DATA *data,
1526 print_queue_struct *queue,
1527 NT_PRINTER_INFO_LEVEL *printer,
1528 TALLOC_CTX *mem_ctx)
1533 /* even if it's strange, that's consistant in all the code */
1535 len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
1537 data->notify_data.data.length = len / 2;
1538 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1540 if (!data->notify_data.data.string) {
1541 data->notify_data.data.length = 0;
1545 memcpy(data->notify_data.data.string, temp, len);
1548 /*******************************************************************
1549 * fill a notify_info_data with the printername
1550 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
1551 * but it doesn't exist, have to see what to do
1552 ********************************************************************/
1553 static void spoolss_notify_driver_name(int snum,
1554 SPOOL_NOTIFY_INFO_DATA *data,
1555 print_queue_struct *queue,
1556 NT_PRINTER_INFO_LEVEL *printer,
1557 TALLOC_CTX *mem_ctx)
1562 len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
1563 data->notify_data.data.length = len / 2;
1564 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1566 if (!data->notify_data.data.string) {
1567 data->notify_data.data.length = 0;
1571 memcpy(data->notify_data.data.string, temp, len);
1574 /*******************************************************************
1575 * fill a notify_info_data with the comment
1576 ********************************************************************/
1577 static void spoolss_notify_comment(int snum,
1578 SPOOL_NOTIFY_INFO_DATA *data,
1579 print_queue_struct *queue,
1580 NT_PRINTER_INFO_LEVEL *printer,
1581 TALLOC_CTX *mem_ctx)
1586 if (*printer->info_2->comment == '\0')
1587 len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE);
1590 len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
1592 data->notify_data.data.length = len / 2;
1593 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1595 if (!data->notify_data.data.string) {
1596 data->notify_data.data.length = 0;
1600 memcpy(data->notify_data.data.string, temp, len);
1603 /*******************************************************************
1604 * fill a notify_info_data with the comment
1605 * jfm:xxxx incorrect, have to create a new smb.conf option
1606 * location = "Room 1, floor 2, building 3"
1607 ********************************************************************/
1608 static void spoolss_notify_location(int snum,
1609 SPOOL_NOTIFY_INFO_DATA *data,
1610 print_queue_struct *queue,
1611 NT_PRINTER_INFO_LEVEL *printer,
1612 TALLOC_CTX *mem_ctx)
1617 len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
1619 data->notify_data.data.length = len / 2;
1620 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1622 if (!data->notify_data.data.string) {
1623 data->notify_data.data.length = 0;
1627 memcpy(data->notify_data.data.string, temp, len);
1630 /*******************************************************************
1631 * fill a notify_info_data with the device mode
1632 * jfm:xxxx don't to it for know but that's a real problem !!!
1633 ********************************************************************/
1634 static void spoolss_notify_devmode(int snum,
1635 SPOOL_NOTIFY_INFO_DATA *data,
1636 print_queue_struct *queue,
1637 NT_PRINTER_INFO_LEVEL *printer,
1638 TALLOC_CTX *mem_ctx)
1642 /*******************************************************************
1643 * fill a notify_info_data with the separator file name
1644 * jfm:xxxx just return no file could add an option to smb.conf
1645 * separator file = "separator.txt"
1646 ********************************************************************/
1647 static void spoolss_notify_sepfile(int snum,
1648 SPOOL_NOTIFY_INFO_DATA *data,
1649 print_queue_struct *queue,
1650 NT_PRINTER_INFO_LEVEL *printer,
1651 TALLOC_CTX *mem_ctx)
1656 len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
1658 data->notify_data.data.length = len / 2;
1659 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1661 if (!data->notify_data.data.string) {
1662 data->notify_data.data.length = 0;
1666 memcpy(data->notify_data.data.string, temp, len);
1669 /*******************************************************************
1670 * fill a notify_info_data with the print processor
1671 * jfm:xxxx return always winprint to indicate we don't do anything to it
1672 ********************************************************************/
1673 static void spoolss_notify_print_processor(int snum,
1674 SPOOL_NOTIFY_INFO_DATA *data,
1675 print_queue_struct *queue,
1676 NT_PRINTER_INFO_LEVEL *printer,
1677 TALLOC_CTX *mem_ctx)
1682 len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
1684 data->notify_data.data.length = len / 2;
1685 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1687 if (!data->notify_data.data.string) {
1688 data->notify_data.data.length = 0;
1692 memcpy(data->notify_data.data.string, temp, len);
1695 /*******************************************************************
1696 * fill a notify_info_data with the print processor options
1697 * jfm:xxxx send an empty string
1698 ********************************************************************/
1699 static void spoolss_notify_parameters(int snum,
1700 SPOOL_NOTIFY_INFO_DATA *data,
1701 print_queue_struct *queue,
1702 NT_PRINTER_INFO_LEVEL *printer,
1703 TALLOC_CTX *mem_ctx)
1708 len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
1710 data->notify_data.data.length = len / 2;
1711 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1713 if (!data->notify_data.data.string) {
1714 data->notify_data.data.length = 0;
1718 memcpy(data->notify_data.data.string, temp, len);
1721 /*******************************************************************
1722 * fill a notify_info_data with the data type
1723 * jfm:xxxx always send RAW as data type
1724 ********************************************************************/
1725 static void spoolss_notify_datatype(int snum,
1726 SPOOL_NOTIFY_INFO_DATA *data,
1727 print_queue_struct *queue,
1728 NT_PRINTER_INFO_LEVEL *printer,
1729 TALLOC_CTX *mem_ctx)
1734 len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
1736 data->notify_data.data.length = len / 2;
1737 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1739 if (!data->notify_data.data.string) {
1740 data->notify_data.data.length = 0;
1744 memcpy(data->notify_data.data.string, temp, len);
1747 /*******************************************************************
1748 * fill a notify_info_data with the security descriptor
1749 * jfm:xxxx send an null pointer to say no security desc
1750 * have to implement security before !
1751 ********************************************************************/
1752 static void spoolss_notify_security_desc(int snum,
1753 SPOOL_NOTIFY_INFO_DATA *data,
1754 print_queue_struct *queue,
1755 NT_PRINTER_INFO_LEVEL *printer,
1756 TALLOC_CTX *mem_ctx)
1758 data->notify_data.data.length=0;
1759 data->notify_data.data.string = NULL;
1762 /*******************************************************************
1763 * fill a notify_info_data with the attributes
1764 * jfm:xxxx a samba printer is always shared
1765 ********************************************************************/
1766 static void spoolss_notify_attributes(int snum,
1767 SPOOL_NOTIFY_INFO_DATA *data,
1768 print_queue_struct *queue,
1769 NT_PRINTER_INFO_LEVEL *printer,
1770 TALLOC_CTX *mem_ctx)
1772 data->notify_data.value[0] = printer->info_2->attributes;
1773 data->notify_data.value[1] = 0;
1776 /*******************************************************************
1777 * fill a notify_info_data with the priority
1778 ********************************************************************/
1779 static void spoolss_notify_priority(int snum,
1780 SPOOL_NOTIFY_INFO_DATA *data,
1781 print_queue_struct *queue,
1782 NT_PRINTER_INFO_LEVEL *printer,
1783 TALLOC_CTX *mem_ctx)
1785 data->notify_data.value[0] = printer->info_2->priority;
1786 data->notify_data.value[1] = 0;
1789 /*******************************************************************
1790 * fill a notify_info_data with the default priority
1791 ********************************************************************/
1792 static void spoolss_notify_default_priority(int snum,
1793 SPOOL_NOTIFY_INFO_DATA *data,
1794 print_queue_struct *queue,
1795 NT_PRINTER_INFO_LEVEL *printer,
1796 TALLOC_CTX *mem_ctx)
1798 data->notify_data.value[0] = printer->info_2->default_priority;
1799 data->notify_data.value[1] = 0;
1802 /*******************************************************************
1803 * fill a notify_info_data with the start time
1804 ********************************************************************/
1805 static void spoolss_notify_start_time(int snum,
1806 SPOOL_NOTIFY_INFO_DATA *data,
1807 print_queue_struct *queue,
1808 NT_PRINTER_INFO_LEVEL *printer,
1809 TALLOC_CTX *mem_ctx)
1811 data->notify_data.value[0] = printer->info_2->starttime;
1812 data->notify_data.value[1] = 0;
1815 /*******************************************************************
1816 * fill a notify_info_data with the until time
1817 ********************************************************************/
1818 static void spoolss_notify_until_time(int snum,
1819 SPOOL_NOTIFY_INFO_DATA *data,
1820 print_queue_struct *queue,
1821 NT_PRINTER_INFO_LEVEL *printer,
1822 TALLOC_CTX *mem_ctx)
1824 data->notify_data.value[0] = printer->info_2->untiltime;
1825 data->notify_data.value[1] = 0;
1828 /*******************************************************************
1829 * fill a notify_info_data with the status
1830 ********************************************************************/
1831 static void spoolss_notify_status(int snum,
1832 SPOOL_NOTIFY_INFO_DATA *data,
1833 print_queue_struct *queue,
1834 NT_PRINTER_INFO_LEVEL *printer,
1835 TALLOC_CTX *mem_ctx)
1837 print_status_struct status;
1839 print_queue_length(snum, &status);
1840 data->notify_data.value[0]=(uint32) status.status;
1841 data->notify_data.value[1] = 0;
1844 /*******************************************************************
1845 * fill a notify_info_data with the number of jobs queued
1846 ********************************************************************/
1847 static void spoolss_notify_cjobs(int snum,
1848 SPOOL_NOTIFY_INFO_DATA *data,
1849 print_queue_struct *queue,
1850 NT_PRINTER_INFO_LEVEL *printer,
1851 TALLOC_CTX *mem_ctx)
1853 data->notify_data.value[0] = print_queue_length(snum, NULL);
1854 data->notify_data.value[1] = 0;
1857 /*******************************************************************
1858 * fill a notify_info_data with the average ppm
1859 ********************************************************************/
1860 static void spoolss_notify_average_ppm(int snum,
1861 SPOOL_NOTIFY_INFO_DATA *data,
1862 print_queue_struct *queue,
1863 NT_PRINTER_INFO_LEVEL *printer,
1864 TALLOC_CTX *mem_ctx)
1866 /* always respond 8 pages per minutes */
1867 /* a little hard ! */
1868 data->notify_data.value[0] = printer->info_2->averageppm;
1869 data->notify_data.value[1] = 0;
1872 /*******************************************************************
1873 * fill a notify_info_data with username
1874 ********************************************************************/
1875 static void spoolss_notify_username(int snum,
1876 SPOOL_NOTIFY_INFO_DATA *data,
1877 print_queue_struct *queue,
1878 NT_PRINTER_INFO_LEVEL *printer,
1879 TALLOC_CTX *mem_ctx)
1884 len = rpcstr_push(temp, queue->user, sizeof(temp)-2, STR_TERMINATE);
1887 data->notify_data.data.length = len / 2;
1888 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1890 if (!data->notify_data.data.string) {
1891 data->notify_data.data.length = 0;
1895 memcpy(data->notify_data.data.string, temp, len);
1898 /*******************************************************************
1899 * fill a notify_info_data with job status
1900 ********************************************************************/
1901 static void spoolss_notify_job_status(int snum,
1902 SPOOL_NOTIFY_INFO_DATA *data,
1903 print_queue_struct *queue,
1904 NT_PRINTER_INFO_LEVEL *printer,
1905 TALLOC_CTX *mem_ctx)
1907 data->notify_data.value[0]=nt_printj_status(queue->status);
1908 data->notify_data.value[1] = 0;
1911 /*******************************************************************
1912 * fill a notify_info_data with job name
1913 ********************************************************************/
1914 static void spoolss_notify_job_name(int snum,
1915 SPOOL_NOTIFY_INFO_DATA *data,
1916 print_queue_struct *queue,
1917 NT_PRINTER_INFO_LEVEL *printer,
1918 TALLOC_CTX *mem_ctx)
1923 len = rpcstr_push(temp, queue->file, sizeof(temp)-2, STR_TERMINATE);
1925 data->notify_data.data.length = len / 2;
1926 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1928 if (!data->notify_data.data.string) {
1929 data->notify_data.data.length = 0;
1933 memcpy(data->notify_data.data.string, temp, len);
1936 /*******************************************************************
1937 * fill a notify_info_data with job status
1938 ********************************************************************/
1939 static void spoolss_notify_job_status_string(int snum,
1940 SPOOL_NOTIFY_INFO_DATA *data,
1941 print_queue_struct *queue,
1942 NT_PRINTER_INFO_LEVEL *printer,
1943 TALLOC_CTX *mem_ctx)
1946 * Now we're returning job status codes we just return a "" here. JRA.
1953 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
1956 switch (queue->status) {
1961 p = ""; /* NT provides the paused string */
1970 #endif /* NO LONGER NEEDED. */
1972 len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
1974 data->notify_data.data.length = len / 2;
1975 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1977 if (!data->notify_data.data.string) {
1978 data->notify_data.data.length = 0;
1982 memcpy(data->notify_data.data.string, temp, len);
1985 /*******************************************************************
1986 * fill a notify_info_data with job time
1987 ********************************************************************/
1988 static void spoolss_notify_job_time(int snum,
1989 SPOOL_NOTIFY_INFO_DATA *data,
1990 print_queue_struct *queue,
1991 NT_PRINTER_INFO_LEVEL *printer,
1992 TALLOC_CTX *mem_ctx)
1994 data->notify_data.value[0]=0x0;
1995 data->notify_data.value[1]=0;
1998 /*******************************************************************
1999 * fill a notify_info_data with job size
2000 ********************************************************************/
2001 static void spoolss_notify_job_size(int snum,
2002 SPOOL_NOTIFY_INFO_DATA *data,
2003 print_queue_struct *queue,
2004 NT_PRINTER_INFO_LEVEL *printer,
2005 TALLOC_CTX *mem_ctx)
2007 data->notify_data.value[0]=queue->size;
2008 data->notify_data.value[1]=0;
2011 /*******************************************************************
2012 * fill a notify_info_data with job position
2013 ********************************************************************/
2014 static void spoolss_notify_job_position(int snum,
2015 SPOOL_NOTIFY_INFO_DATA *data,
2016 print_queue_struct *queue,
2017 NT_PRINTER_INFO_LEVEL *printer,
2018 TALLOC_CTX *mem_ctx)
2020 data->notify_data.value[0]=queue->job;
2021 data->notify_data.value[1]=0;
2024 /*******************************************************************
2025 * fill a notify_info_data with submitted time
2026 ********************************************************************/
2027 static void spoolss_notify_submitted_time(int snum,
2028 SPOOL_NOTIFY_INFO_DATA *data,
2029 print_queue_struct *queue,
2030 NT_PRINTER_INFO_LEVEL *printer,
2031 TALLOC_CTX *mem_ctx)
2037 t=gmtime(&queue->time);
2039 len = sizeof(SYSTEMTIME);
2041 data->notify_data.data.length = len;
2042 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2044 if (!data->notify_data.data.string) {
2045 data->notify_data.data.length = 0;
2049 make_systemtime(&st, t);
2050 memcpy(data->notify_data.data.string,&st,len);
2055 struct s_notify_info_data_table
2061 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
2062 print_queue_struct *queue,
2063 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
2066 struct s_notify_info_data_table notify_info_data_table[] =
2068 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
2069 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
2070 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
2071 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
2072 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
2073 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
2074 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
2075 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
2076 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
2077 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
2078 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
2079 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
2080 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
2081 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
2082 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
2083 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
2084 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
2085 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
2086 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
2087 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
2088 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
2089 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
2090 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
2091 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
2092 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
2093 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
2094 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
2095 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
2096 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
2097 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
2098 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
2099 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
2100 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
2101 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
2102 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
2103 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
2104 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
2105 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
2106 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
2107 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
2108 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
2109 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
2110 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, spoolss_notify_submitted_time },
2111 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
2112 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
2113 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
2114 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
2115 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
2116 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
2117 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
2118 { END, END, "", END, NULL }
2121 /*******************************************************************
2122 return the size of info_data structure
2123 ********************************************************************/
2124 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
2128 while (notify_info_data_table[i].type != END)
2130 if ( (notify_info_data_table[i].type == type ) &&
2131 (notify_info_data_table[i].field == field ) )
2133 return (notify_info_data_table[i].size);
2140 /*******************************************************************
2141 return the type of notify_info_data
2142 ********************************************************************/
2143 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
2147 while (notify_info_data_table[i].type != END)
2149 if ( (notify_info_data_table[i].type == type ) &&
2150 (notify_info_data_table[i].field == field ) )
2152 if (notify_info_data_table[i].size == POINTER)
2166 /****************************************************************************
2167 ****************************************************************************/
2168 static int search_notify(uint16 type, uint16 field, int *value)
2173 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
2175 if ( (notify_info_data_table[j].type == type ) &&
2176 (notify_info_data_table[j].field == field ) )
2181 if ( found && (notify_info_data_table[j].fn != NULL) )
2187 /****************************************************************************
2188 ****************************************************************************/
2189 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
2191 info_data->type = type;
2192 info_data->field = field;
2193 info_data->reserved = 0;
2195 info_data->size = size_of_notify_info_data(type, field);
2196 info_data->enc_type = type_of_notify_info_data(type, field);
2200 /*******************************************************************
2202 * fill a notify_info struct with info asked
2204 ********************************************************************/
2205 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
2206 snum, SPOOL_NOTIFY_OPTION_TYPE
2207 *option_type, uint32 id,
2208 TALLOC_CTX *mem_ctx)
2214 SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
2215 NT_PRINTER_INFO_LEVEL *printer = NULL;
2216 print_queue_struct *queue=NULL;
2218 type=option_type->type;
2220 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
2221 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2222 option_type->count, lp_servicename(snum)));
2224 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2227 for(field_num=0; field_num<option_type->count; field_num++) {
2228 field = option_type->fields[field_num];
2229 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
2231 if (!search_notify(type, field, &j) )
2234 if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
2235 DEBUG(0,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
2238 else info->data = tid;
2240 current_data=&info->data[info->count];
2242 construct_info_data(current_data, type, field, id);
2244 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
2245 notify_info_data_table[j].name, snum, printer->info_2->printername ));
2247 notify_info_data_table[j].fn(snum, current_data, queue,
2253 free_a_printer(&printer, 2);
2257 /*******************************************************************
2259 * fill a notify_info struct with info asked
2261 ********************************************************************/
2262 static BOOL construct_notify_jobs_info(print_queue_struct *queue,
2263 SPOOL_NOTIFY_INFO *info,
2264 NT_PRINTER_INFO_LEVEL *printer,
2265 int snum, SPOOL_NOTIFY_OPTION_TYPE
2266 *option_type, uint32 id,
2267 TALLOC_CTX *mem_ctx)
2273 SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
2275 DEBUG(4,("construct_notify_jobs_info\n"));
2277 type = option_type->type;
2279 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
2280 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2281 option_type->count));
2283 for(field_num=0; field_num<option_type->count; field_num++) {
2284 field = option_type->fields[field_num];
2286 if (!search_notify(type, field, &j) )
2289 if((tid=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
2290 DEBUG(0,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
2293 else info->data = tid;
2295 current_data=&(info->data[info->count]);
2297 construct_info_data(current_data, type, field, id);
2298 notify_info_data_table[j].fn(snum, current_data, queue,
2307 * JFM: The enumeration is not that simple, it's even non obvious.
2309 * let's take an example: I want to monitor the PRINTER SERVER for
2310 * the printer's name and the number of jobs currently queued.
2311 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
2312 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
2314 * I have 3 printers on the back of my server.
2316 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
2319 * 1 printer 1 name 1
2320 * 2 printer 1 cjob 1
2321 * 3 printer 2 name 2
2322 * 4 printer 2 cjob 2
2323 * 5 printer 3 name 3
2324 * 6 printer 3 name 3
2326 * that's the print server case, the printer case is even worse.
2329 /*******************************************************************
2331 * enumerate all printers on the printserver
2332 * fill a notify_info struct with info asked
2334 ********************************************************************/
2336 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
2337 SPOOL_NOTIFY_INFO *info,
2338 TALLOC_CTX *mem_ctx)
2341 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
2342 int n_services=lp_numservices();
2345 SPOOL_NOTIFY_OPTION *option;
2346 SPOOL_NOTIFY_OPTION_TYPE *option_type;
2348 DEBUG(4,("printserver_notify_info\n"));
2350 option=Printer->notify.option;
2356 for (i=0; i<option->count; i++) {
2357 option_type=&(option->ctr.type[i]);
2359 if (option_type->type!=PRINTER_NOTIFY_TYPE)
2362 for (snum=0; snum<n_services; snum++)
2363 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
2364 if (construct_notify_printer_info
2365 (info, snum, option_type, id, mem_ctx))
2370 * Debugging information, don't delete.
2373 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2374 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2375 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2377 for (i=0; i<info->count; i++) {
2378 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2379 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2380 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2387 /*******************************************************************
2389 * fill a notify_info struct with info asked
2391 ********************************************************************/
2392 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
2393 TALLOC_CTX *mem_ctx)
2396 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
2399 SPOOL_NOTIFY_OPTION *option;
2400 SPOOL_NOTIFY_OPTION_TYPE *option_type;
2402 print_queue_struct *queue=NULL;
2403 print_status_struct status;
2405 DEBUG(4,("printer_notify_info\n"));
2407 option=Printer->notify.option;
2413 get_printer_snum(p, hnd, &snum);
2415 for (i=0; i<option->count; i++) {
2416 option_type=&option->ctr.type[i];
2418 switch ( option_type->type ) {
2419 case PRINTER_NOTIFY_TYPE:
2420 if(construct_notify_printer_info(info, snum,
2426 case JOB_NOTIFY_TYPE: {
2427 NT_PRINTER_INFO_LEVEL *printer = NULL;
2429 count = print_queue_status(snum, &queue, &status);
2431 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2,
2432 lp_servicename(snum))))
2435 for (j=0; j<count; j++) {
2436 construct_notify_jobs_info(&queue[j], info,
2443 free_a_printer(&printer, 2);
2453 * Debugging information, don't delete.
2456 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2457 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2458 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2460 for (i=0; i<info->count; i++) {
2461 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2462 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2463 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2469 /********************************************************************
2471 ********************************************************************/
2473 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
2475 POLICY_HND *handle = &q_u->handle;
2476 /* uint32 change = q_u->change; - notused. */
2477 /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
2478 SPOOL_NOTIFY_INFO *info = &r_u->info;
2480 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2481 WERROR result = WERR_BADFID;
2483 /* we always have a NOTIFY_INFO struct */
2487 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",
2488 OUR_HANDLE(handle)));
2492 DEBUG(4,("Printer type %x\n",Printer->printer_type));
2494 /* jfm: the change value isn't used right now.
2495 * we will honour it when
2496 * a) we'll be able to send notification to the client
2497 * b) we'll have a way to communicate between the spoolss process.
2499 * same thing for option->flags
2500 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2501 * I don't have a global notification system, I'm sending back all the
2502 * informations even when _NOTHING_ has changed.
2505 /* just ignore the SPOOL_NOTIFY_OPTION */
2507 switch (Printer->printer_type) {
2508 case PRINTER_HANDLE_IS_PRINTSERVER:
2509 result = printserver_notify_info(p, handle, info, p->mem_ctx);
2512 case PRINTER_HANDLE_IS_PRINTER:
2513 result = printer_notify_info(p, handle, info, p->mem_ctx);
2521 /********************************************************************
2522 * construct_printer_info_0
2523 * fill a printer_info_0 struct
2524 ********************************************************************/
2525 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
2529 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2530 counter_printer_0 *session_counter;
2531 uint32 global_counter;
2534 print_status_struct status;
2536 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2539 count = print_queue_length(snum, &status);
2541 /* check if we already have a counter for this printer */
2542 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
2544 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
2545 if (session_counter->snum == snum)
2549 /* it's the first time, add it to the list */
2550 if (session_counter==NULL) {
2551 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
2552 free_a_printer(&ntprinter, 2);
2555 ZERO_STRUCTP(session_counter);
2556 session_counter->snum=snum;
2557 session_counter->counter=0;
2558 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
2562 session_counter->counter++;
2565 * the global_counter should be stored in a TDB as it's common to all the clients
2566 * and should be zeroed on samba startup
2568 global_counter=session_counter->counter;
2570 pstrcpy(chaine,ntprinter->info_2->printername);
2572 init_unistr(&printer->printername, chaine);
2574 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_called_name());
2575 init_unistr(&printer->servername, chaine);
2577 printer->cjobs = count;
2578 printer->total_jobs = 0;
2579 printer->total_bytes = 0;
2581 setuptime = (time_t)ntprinter->info_2->setuptime;
2582 t=gmtime(&setuptime);
2584 printer->year = t->tm_year+1900;
2585 printer->month = t->tm_mon+1;
2586 printer->dayofweek = t->tm_wday;
2587 printer->day = t->tm_mday;
2588 printer->hour = t->tm_hour;
2589 printer->minute = t->tm_min;
2590 printer->second = t->tm_sec;
2591 printer->milliseconds = 0;
2593 printer->global_counter = global_counter;
2594 printer->total_pages = 0;
2595 printer->major_version = 0x0004; /* NT 4 */
2596 printer->build_version = 0x0565; /* build 1381 */
2597 printer->unknown7 = 0x1;
2598 printer->unknown8 = 0x0;
2599 printer->unknown9 = 0x0;
2600 printer->session_counter = session_counter->counter;
2601 printer->unknown11 = 0x0;
2602 printer->printer_errors = 0x0; /* number of print failure */
2603 printer->unknown13 = 0x0;
2604 printer->unknown14 = 0x1;
2605 printer->unknown15 = 0x024a; /* 586 Pentium ? */
2606 printer->unknown16 = 0x0;
2607 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
2608 printer->unknown18 = 0x0;
2609 printer->status = nt_printq_status(status.status);
2610 printer->unknown20 = 0x0;
2611 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
2612 printer->unknown22 = 0x0;
2613 printer->unknown23 = 0x6; /* 6 ???*/
2614 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
2615 printer->unknown25 = 0;
2616 printer->unknown26 = 0;
2617 printer->unknown27 = 0;
2618 printer->unknown28 = 0;
2619 printer->unknown29 = 0;
2621 free_a_printer(&ntprinter,2);
2625 /********************************************************************
2626 * construct_printer_info_1
2627 * fill a printer_info_1 struct
2628 ********************************************************************/
2629 static BOOL construct_printer_info_1(uint32 flags, PRINTER_INFO_1 *printer, int snum)
2633 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2635 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2638 printer->flags=flags;
2640 if (*ntprinter->info_2->comment == '\0') {
2641 init_unistr(&printer->comment, lp_comment(snum));
2642 slprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",get_called_name(), ntprinter->info_2->printername,
2643 ntprinter->info_2->drivername, lp_comment(snum));
2646 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
2647 slprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",get_called_name(), ntprinter->info_2->printername,
2648 ntprinter->info_2->drivername, ntprinter->info_2->comment);
2651 slprintf(chaine2,sizeof(chaine)-1,"%s", ntprinter->info_2->printername);
2653 init_unistr(&printer->description, chaine);
2654 init_unistr(&printer->name, chaine2);
2656 free_a_printer(&ntprinter,2);
2661 /****************************************************************************
2662 Free a DEVMODE struct.
2663 ****************************************************************************/
2665 static void free_dev_mode(DEVICEMODE *dev)
2670 SAFE_FREE(dev->private);
2674 /****************************************************************************
2675 Create a DEVMODE struct. Returns malloced memory.
2676 ****************************************************************************/
2678 static DEVICEMODE *construct_dev_mode(int snum)
2682 NT_PRINTER_INFO_LEVEL *printer = NULL;
2683 NT_DEVICEMODE *ntdevmode = NULL;
2684 DEVICEMODE *devmode = NULL;
2686 DEBUG(7,("construct_dev_mode\n"));
2688 DEBUGADD(8,("getting printer characteristics\n"));
2690 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
2691 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
2695 ZERO_STRUCTP(devmode);
2697 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2700 if (printer->info_2->devmode)
2701 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
2703 if (ntdevmode == NULL)
2706 DEBUGADD(8,("loading DEVICEMODE\n"));
2708 slprintf(adevice, sizeof(adevice)-1, printer->info_2->printername);
2709 init_unistr(&devmode->devicename, adevice);
2711 slprintf(aform, sizeof(aform)-1, ntdevmode->formname);
2712 init_unistr(&devmode->formname, aform);
2714 devmode->specversion = ntdevmode->specversion;
2715 devmode->driverversion = ntdevmode->driverversion;
2716 devmode->size = ntdevmode->size;
2717 devmode->driverextra = ntdevmode->driverextra;
2718 devmode->fields = ntdevmode->fields;
2720 devmode->orientation = ntdevmode->orientation;
2721 devmode->papersize = ntdevmode->papersize;
2722 devmode->paperlength = ntdevmode->paperlength;
2723 devmode->paperwidth = ntdevmode->paperwidth;
2724 devmode->scale = ntdevmode->scale;
2725 devmode->copies = ntdevmode->copies;
2726 devmode->defaultsource = ntdevmode->defaultsource;
2727 devmode->printquality = ntdevmode->printquality;
2728 devmode->color = ntdevmode->color;
2729 devmode->duplex = ntdevmode->duplex;
2730 devmode->yresolution = ntdevmode->yresolution;
2731 devmode->ttoption = ntdevmode->ttoption;
2732 devmode->collate = ntdevmode->collate;
2733 devmode->icmmethod = ntdevmode->icmmethod;
2734 devmode->icmintent = ntdevmode->icmintent;
2735 devmode->mediatype = ntdevmode->mediatype;
2736 devmode->dithertype = ntdevmode->dithertype;
2738 if (ntdevmode->private != NULL) {
2739 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
2743 free_nt_devicemode(&ntdevmode);
2744 free_a_printer(&printer,2);
2751 free_nt_devicemode(&ntdevmode);
2753 free_a_printer(&printer,2);
2754 free_dev_mode(devmode);
2759 /********************************************************************
2760 * construct_printer_info_2
2761 * fill a printer_info_2 struct
2762 ********************************************************************/
2764 static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum)
2767 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2769 print_status_struct status;
2771 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2774 count = print_queue_length(snum, &status);
2776 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
2777 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
2778 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
2779 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
2780 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
2782 if (*ntprinter->info_2->comment == '\0')
2783 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
2785 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
2787 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
2788 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
2789 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
2790 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
2791 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
2793 printer->attributes = ntprinter->info_2->attributes;
2795 printer->priority = ntprinter->info_2->priority; /* priority */
2796 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
2797 printer->starttime = ntprinter->info_2->starttime; /* starttime */
2798 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
2799 printer->status = nt_printq_status(status.status); /* status */
2800 printer->cjobs = count; /* jobs */
2801 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
2803 if((printer->devmode = construct_dev_mode(snum)) == NULL) {
2804 DEBUG(8, ("Returning NULL Devicemode!\n"));
2807 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
2808 /* steal the printer info sec_desc structure. [badly done]. */
2809 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2810 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
2811 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
2812 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
2815 printer->secdesc = NULL;
2818 free_a_printer(&ntprinter, 2);
2822 /********************************************************************
2823 * construct_printer_info_3
2824 * fill a printer_info_3 struct
2825 ********************************************************************/
2826 static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum)
2828 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2829 PRINTER_INFO_3 *printer = NULL;
2831 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2835 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
2836 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
2840 ZERO_STRUCTP(printer);
2842 printer->flags = 4; /* These are the components of the SD we are returning. */
2843 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
2844 /* steal the printer info sec_desc structure. [badly done]. */
2845 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2849 * Set the flags for the components we are returning.
2852 if (printer->secdesc->owner_sid)
2853 printer->flags |= OWNER_SECURITY_INFORMATION;
2855 if (printer->secdesc->grp_sid)
2856 printer->flags |= GROUP_SECURITY_INFORMATION;
2858 if (printer->secdesc->dacl)
2859 printer->flags |= DACL_SECURITY_INFORMATION;
2861 if (printer->secdesc->sacl)
2862 printer->flags |= SACL_SECURITY_INFORMATION;
2865 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
2866 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
2867 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
2870 free_a_printer(&ntprinter, 2);
2872 *pp_printer = printer;
2876 /********************************************************************
2877 Spoolss_enumprinters.
2878 ********************************************************************/
2879 static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2883 int n_services=lp_numservices();
2884 PRINTER_INFO_1 *tp, *printers=NULL;
2885 PRINTER_INFO_1 current_prt;
2887 DEBUG(4,("enum_all_printers_info_1\n"));
2889 for (snum=0; snum<n_services; snum++) {
2890 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2891 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2893 if (construct_printer_info_1(flags, ¤t_prt, snum)) {
2894 if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
2895 DEBUG(0,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
2896 SAFE_FREE(printers);
2901 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2902 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
2908 /* check the required size. */
2909 for (i=0; i<*returned; i++)
2910 (*needed) += spoolss_size_printer_info_1(&printers[i]);
2912 if (!alloc_buffer_size(buffer, *needed))
2913 return WERR_INSUFFICIENT_BUFFER;
2915 /* fill the buffer with the structures */
2916 for (i=0; i<*returned; i++)
2917 smb_io_printer_info_1("", buffer, &printers[i], 0);
2920 SAFE_FREE(printers);
2922 if (*needed > offered) {
2924 return WERR_INSUFFICIENT_BUFFER;
2930 /********************************************************************
2931 enum_all_printers_info_1_local.
2932 *********************************************************************/
2933 static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2935 DEBUG(4,("enum_all_printers_info_1_local\n"));
2937 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2940 /********************************************************************
2941 enum_all_printers_info_1_name.
2942 *********************************************************************/
2943 static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2947 DEBUG(4,("enum_all_printers_info_1_name\n"));
2949 if ((name[0] == '\\') && (name[1] == '\\'))
2952 if (is_myname_or_ipaddr(s)) {
2953 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2956 return WERR_INVALID_NAME;
2959 /********************************************************************
2960 enum_all_printers_info_1_remote.
2961 *********************************************************************/
2962 static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2964 PRINTER_INFO_1 *printer;
2965 fstring printername;
2968 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2970 /* JFM: currently it's more a place holder than anything else.
2971 * In the spooler world there is a notion of server registration.
2972 * the print servers are registring (sp ?) on the PDC (in the same domain)
2974 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2977 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2982 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name());
2983 slprintf(desc, sizeof(desc)-1,"%s", get_called_name());
2984 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
2986 init_unistr(&printer->description, desc);
2987 init_unistr(&printer->name, printername);
2988 init_unistr(&printer->comment, comment);
2989 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2991 /* check the required size. */
2992 *needed += spoolss_size_printer_info_1(printer);
2994 if (!alloc_buffer_size(buffer, *needed)) {
2996 return WERR_INSUFFICIENT_BUFFER;
2999 /* fill the buffer with the structures */
3000 smb_io_printer_info_1("", buffer, printer, 0);
3005 if (*needed > offered) {
3007 return WERR_INSUFFICIENT_BUFFER;
3013 /********************************************************************
3014 enum_all_printers_info_1_network.
3015 *********************************************************************/
3017 static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3019 DEBUG(4,("enum_all_printers_info_1_network\n"));
3021 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
3024 /********************************************************************
3025 * api_spoolss_enumprinters
3027 * called from api_spoolss_enumprinters (see this to understand)
3028 ********************************************************************/
3030 static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3034 int n_services=lp_numservices();
3035 PRINTER_INFO_2 *tp, *printers=NULL;
3036 PRINTER_INFO_2 current_prt;
3038 for (snum=0; snum<n_services; snum++) {
3039 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3040 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
3042 if (construct_printer_info_2(¤t_prt, snum)) {
3043 if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) {
3044 DEBUG(0,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
3045 SAFE_FREE(printers);
3050 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
3051 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
3057 /* check the required size. */
3058 for (i=0; i<*returned; i++)
3059 (*needed) += spoolss_size_printer_info_2(&printers[i]);
3061 if (!alloc_buffer_size(buffer, *needed)) {
3062 for (i=0; i<*returned; i++) {
3063 free_devmode(printers[i].devmode);
3065 SAFE_FREE(printers);
3066 return WERR_INSUFFICIENT_BUFFER;
3069 /* fill the buffer with the structures */
3070 for (i=0; i<*returned; i++)
3071 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
3074 for (i=0; i<*returned; i++) {
3075 free_devmode(printers[i].devmode);
3077 SAFE_FREE(printers);
3079 if (*needed > offered) {
3081 return WERR_INSUFFICIENT_BUFFER;
3087 /********************************************************************
3088 * handle enumeration of printers at level 1
3089 ********************************************************************/
3090 static WERROR enumprinters_level1( uint32 flags, fstring name,
3091 NEW_BUFFER *buffer, uint32 offered,
3092 uint32 *needed, uint32 *returned)
3094 /* Not all the flags are equals */
3096 if (flags & PRINTER_ENUM_LOCAL)
3097 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
3099 if (flags & PRINTER_ENUM_NAME)
3100 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
3102 if (flags & PRINTER_ENUM_REMOTE)
3103 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
3105 if (flags & PRINTER_ENUM_NETWORK)
3106 return enum_all_printers_info_1_network(buffer, offered, needed, returned);
3108 return WERR_OK; /* NT4sp5 does that */
3111 /********************************************************************
3112 * handle enumeration of printers at level 2
3113 ********************************************************************/
3114 static WERROR enumprinters_level2( uint32 flags, fstring servername,
3115 NEW_BUFFER *buffer, uint32 offered,
3116 uint32 *needed, uint32 *returned)
3118 char *s = servername;
3120 if (flags & PRINTER_ENUM_LOCAL) {
3121 return enum_all_printers_info_2(buffer, offered, needed, returned);
3124 if (flags & PRINTER_ENUM_NAME) {
3125 if ((servername[0] == '\\') && (servername[1] == '\\'))
3127 if (is_myname_or_ipaddr(s))
3128 return enum_all_printers_info_2(buffer, offered, needed, returned);
3130 return WERR_INVALID_NAME;
3133 if (flags & PRINTER_ENUM_REMOTE)
3134 return WERR_UNKNOWN_LEVEL;
3139 /********************************************************************
3140 * handle enumeration of printers at level 5
3141 ********************************************************************/
3142 static WERROR enumprinters_level5( uint32 flags, fstring servername,
3143 NEW_BUFFER *buffer, uint32 offered,
3144 uint32 *needed, uint32 *returned)
3146 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
3150 /********************************************************************
3151 * api_spoolss_enumprinters
3153 * called from api_spoolss_enumprinters (see this to understand)
3154 ********************************************************************/
3156 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
3158 uint32 flags = q_u->flags;
3159 UNISTR2 *servername = &q_u->servername;
3160 uint32 level = q_u->level;
3161 NEW_BUFFER *buffer = NULL;
3162 uint32 offered = q_u->offered;
3163 uint32 *needed = &r_u->needed;
3164 uint32 *returned = &r_u->returned;
3168 /* that's an [in out] buffer */
3169 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3170 buffer = r_u->buffer;
3172 DEBUG(4,("_spoolss_enumprinters\n"));
3179 * flags==PRINTER_ENUM_NAME
3180 * if name=="" then enumerates all printers
3181 * if name!="" then enumerate the printer
3182 * flags==PRINTER_ENUM_REMOTE
3183 * name is NULL, enumerate printers
3184 * Level 2: name!="" enumerates printers, name can't be NULL
3185 * Level 3: doesn't exist
3186 * Level 4: does a local registry lookup
3187 * Level 5: same as Level 2
3190 unistr2_to_ascii(name, servername, sizeof(name)-1);
3195 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
3197 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
3199 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
3204 return WERR_UNKNOWN_LEVEL;
3207 /****************************************************************************
3208 ****************************************************************************/
3209 static WERROR getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3211 PRINTER_INFO_0 *printer=NULL;
3213 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
3216 construct_printer_info_0(printer, snum);
3218 /* check the required size. */
3219 *needed += spoolss_size_printer_info_0(printer);
3221 if (!alloc_buffer_size(buffer, *needed)) {
3223 return WERR_INSUFFICIENT_BUFFER;
3226 /* fill the buffer with the structures */
3227 smb_io_printer_info_0("", buffer, printer, 0);
3232 if (*needed > offered) {
3233 return WERR_INSUFFICIENT_BUFFER;
3239 /****************************************************************************
3240 ****************************************************************************/
3241 static WERROR getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3243 PRINTER_INFO_1 *printer=NULL;
3245 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
3248 construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum);
3250 /* check the required size. */
3251 *needed += spoolss_size_printer_info_1(printer);
3253 if (!alloc_buffer_size(buffer, *needed)) {
3255 return WERR_INSUFFICIENT_BUFFER;
3258 /* fill the buffer with the structures */
3259 smb_io_printer_info_1("", buffer, printer, 0);
3264 if (*needed > offered) {
3265 return WERR_INSUFFICIENT_BUFFER;
3271 /****************************************************************************
3272 ****************************************************************************/
3273 static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3275 PRINTER_INFO_2 *printer=NULL;
3277 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
3280 construct_printer_info_2(printer, snum);
3282 /* check the required size. */
3283 *needed += spoolss_size_printer_info_2(printer);
3285 if (!alloc_buffer_size(buffer, *needed)) {
3286 free_printer_info_2(printer);
3287 return WERR_INSUFFICIENT_BUFFER;
3290 /* fill the buffer with the structures */
3291 if (!smb_io_printer_info_2("", buffer, printer, 0)) {
3292 free_printer_info_2(printer);
3297 free_printer_info_2(printer);
3299 if (*needed > offered) {
3300 return WERR_INSUFFICIENT_BUFFER;
3306 /****************************************************************************
3307 ****************************************************************************/
3308 static WERROR getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3310 PRINTER_INFO_3 *printer=NULL;
3312 if (!construct_printer_info_3(&printer, snum))
3315 /* check the required size. */
3316 *needed += spoolss_size_printer_info_3(printer);
3318 if (!alloc_buffer_size(buffer, *needed)) {
3319 free_printer_info_3(printer);
3320 return WERR_INSUFFICIENT_BUFFER;
3323 /* fill the buffer with the structures */
3324 smb_io_printer_info_3("", buffer, printer, 0);
3327 free_printer_info_3(printer);
3329 if (*needed > offered) {
3330 return WERR_INSUFFICIENT_BUFFER;
3336 /****************************************************************************
3337 ****************************************************************************/
3339 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
3341 POLICY_HND *handle = &q_u->handle;
3342 uint32 level = q_u->level;
3343 NEW_BUFFER *buffer = NULL;
3344 uint32 offered = q_u->offered;
3345 uint32 *needed = &r_u->needed;
3349 /* that's an [in out] buffer */
3350 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3351 buffer = r_u->buffer;
3355 if (!get_printer_snum(p, handle, &snum))
3360 return getprinter_level_0(snum, buffer, offered, needed);
3362 return getprinter_level_1(snum, buffer, offered, needed);
3364 return getprinter_level_2(snum, buffer, offered, needed);
3366 return getprinter_level_3(snum, buffer, offered, needed);
3368 return WERR_UNKNOWN_LEVEL;
3371 /********************************************************************
3372 * fill a DRIVER_INFO_1 struct
3373 ********************************************************************/
3374 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
3376 init_unistr( &info->name, driver.info_3->name);
3379 /********************************************************************
3380 * construct_printer_driver_info_1
3381 ********************************************************************/
3382 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
3384 NT_PRINTER_INFO_LEVEL *printer = NULL;
3385 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3387 ZERO_STRUCT(driver);
3389 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3390 return WERR_INVALID_PRINTER_NAME;
3392 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
3393 return WERR_UNKNOWN_PRINTER_DRIVER;
3395 fill_printer_driver_info_1(info, driver, servername, architecture);
3397 free_a_printer(&printer,2);
3402 /********************************************************************
3403 * construct_printer_driver_info_2
3404 * fill a printer_info_2 struct
3405 ********************************************************************/
3406 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3410 info->version=driver.info_3->cversion;
3412 init_unistr( &info->name, driver.info_3->name );
3413 init_unistr( &info->architecture, driver.info_3->environment );
3416 if (strlen(driver.info_3->driverpath)) {
3417 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3418 init_unistr( &info->driverpath, temp );
3420 init_unistr( &info->driverpath, "" );
3422 if (strlen(driver.info_3->datafile)) {
3423 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3424 init_unistr( &info->datafile, temp );
3426 init_unistr( &info->datafile, "" );
3428 if (strlen(driver.info_3->configfile)) {
3429 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3430 init_unistr( &info->configfile, temp );
3432 init_unistr( &info->configfile, "" );
3435 /********************************************************************
3436 * construct_printer_driver_info_2
3437 * fill a printer_info_2 struct
3438 ********************************************************************/
3439 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
3441 NT_PRINTER_INFO_LEVEL *printer = NULL;
3442 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3444 ZERO_STRUCT(printer);
3445 ZERO_STRUCT(driver);
3447 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3448 return WERR_INVALID_PRINTER_NAME;
3450 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
3451 return WERR_UNKNOWN_PRINTER_DRIVER;
3453 fill_printer_driver_info_2(info, driver, servername);
3455 free_a_printer(&printer,2);
3460 /********************************************************************
3461 * copy a strings array and convert to UNICODE
3463 * convert an array of ascii string to a UNICODE string
3464 ********************************************************************/
3465 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
3473 DEBUG(6,("init_unistr_array\n"));
3477 if (char_array == NULL)
3481 if (!v) v = ""; /* hack to handle null lists */
3483 if (strlen(v) == 0) break;
3484 slprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
3485 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
3486 if((tuary=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
3487 DEBUG(0,("init_unistr_array: Realloc error\n" ));
3490 else *uni_array = tuary;
3491 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, 0)/ sizeof(uint16));
3496 (*uni_array)[j]=0x0000;
3499 DEBUGADD(6,("last one:done\n"));
3502 /********************************************************************
3503 * construct_printer_info_3
3504 * fill a printer_info_3 struct
3505 ********************************************************************/
3506 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3512 info->version=driver.info_3->cversion;
3514 init_unistr( &info->name, driver.info_3->name );
3515 init_unistr( &info->architecture, driver.info_3->environment );
3517 if (strlen(driver.info_3->driverpath)) {
3518 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3519 init_unistr( &info->driverpath, temp );
3521 init_unistr( &info->driverpath, "" );
3523 if (strlen(driver.info_3->datafile)) {
3524 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3525 init_unistr( &info->datafile, temp );
3527 init_unistr( &info->datafile, "" );
3529 if (strlen(driver.info_3->configfile)) {
3530 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3531 init_unistr( &info->configfile, temp );
3533 init_unistr( &info->configfile, "" );
3535 if (strlen(driver.info_3->helpfile)) {
3536 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
3537 init_unistr( &info->helpfile, temp );
3539 init_unistr( &info->helpfile, "" );
3541 init_unistr( &info->monitorname, driver.info_3->monitorname );
3542 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
3544 info->dependentfiles=NULL;
3545 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
3548 /********************************************************************
3549 * construct_printer_info_3
3550 * fill a printer_info_3 struct
3551 ********************************************************************/
3552 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
3554 NT_PRINTER_INFO_LEVEL *printer = NULL;
3555 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3557 ZERO_STRUCT(driver);
3559 status=get_a_printer(&printer, 2, lp_servicename(snum) );
3560 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status)));
3561 if (!W_ERROR_IS_OK(status))
3562 return WERR_INVALID_PRINTER_NAME;
3564 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
3565 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status)));
3566 if (!W_ERROR_IS_OK(status)) {
3567 free_a_printer(&printer,2);
3568 return WERR_UNKNOWN_PRINTER_DRIVER;
3571 fill_printer_driver_info_3(info, driver, servername);
3573 free_a_printer(&printer,2);
3578 /********************************************************************
3579 * construct_printer_info_6
3580 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
3581 ********************************************************************/
3583 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3589 memset(&nullstr, '\0', sizeof(fstring));
3591 info->version=driver.info_3->cversion;
3593 init_unistr( &info->name, driver.info_3->name );
3594 init_unistr( &info->architecture, driver.info_3->environment );
3596 if (strlen(driver.info_3->driverpath)) {
3597 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3598 init_unistr( &info->driverpath, temp );
3600 init_unistr( &info->driverpath, "" );
3602 if (strlen(driver.info_3->datafile)) {
3603 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3604 init_unistr( &info->datafile, temp );
3606 init_unistr( &info->datafile, "" );
3608 if (strlen(driver.info_3->configfile)) {
3609 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3610 init_unistr( &info->configfile, temp );
3612 init_unistr( &info->configfile, "" );
3614 if (strlen(driver.info_3->helpfile)) {
3615 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
3616 init_unistr( &info->helpfile, temp );
3618 init_unistr( &info->helpfile, "" );
3620 init_unistr( &info->monitorname, driver.info_3->monitorname );
3621 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
3623 info->dependentfiles=NULL;
3624 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
3626 info->previousdrivernames=NULL;
3627 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
3629 info->driver_date.low=0;
3630 info->driver_date.high=0;
3633 info->driver_version_low=0;
3634 info->driver_version_high=0;
3636 init_unistr( &info->mfgname, "");
3637 init_unistr( &info->oem_url, "");
3638 init_unistr( &info->hardware_id, "");
3639 init_unistr( &info->provider, "");
3642 /********************************************************************
3643 * construct_printer_info_6
3644 * fill a printer_info_6 struct
3645 ********************************************************************/
3646 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
3648 NT_PRINTER_INFO_LEVEL *printer = NULL;
3649 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3651 ZERO_STRUCT(driver);
3653 status=get_a_printer(&printer, 2, lp_servicename(snum) );
3654 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
3655 if (!W_ERROR_IS_OK(status))
3656 return WERR_INVALID_PRINTER_NAME;
3658 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
3659 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
3660 if (!W_ERROR_IS_OK(status)) {
3662 * Is this a W2k client ?
3666 free_a_printer(&printer,2);
3667 return WERR_UNKNOWN_PRINTER_DRIVER;
3670 /* Yes - try again with a WinNT driver. */
3672 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
3673 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
3674 if (!W_ERROR_IS_OK(status)) {
3675 free_a_printer(&printer,2);
3676 return WERR_UNKNOWN_PRINTER_DRIVER;
3680 fill_printer_driver_info_6(info, driver, servername);
3682 free_a_printer(&printer,2);
3687 /****************************************************************************
3688 ****************************************************************************/
3690 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
3692 SAFE_FREE(info->dependentfiles);
3695 /****************************************************************************
3696 ****************************************************************************/
3698 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
3700 SAFE_FREE(info->dependentfiles);
3704 /****************************************************************************
3705 ****************************************************************************/
3706 static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3708 DRIVER_INFO_1 *info=NULL;
3711 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
3714 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
3715 if (!W_ERROR_IS_OK(status)) {
3720 /* check the required size. */
3721 *needed += spoolss_size_printer_driver_info_1(info);
3723 if (!alloc_buffer_size(buffer, *needed)) {
3725 return WERR_INSUFFICIENT_BUFFER;
3728 /* fill the buffer with the structures */
3729 smb_io_printer_driver_info_1("", buffer, info, 0);
3734 if (*needed > offered)
3735 return WERR_INSUFFICIENT_BUFFER;
3740 /****************************************************************************
3741 ****************************************************************************/
3742 static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3744 DRIVER_INFO_2 *info=NULL;
3747 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
3750 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
3751 if (!W_ERROR_IS_OK(status)) {
3756 /* check the required size. */
3757 *needed += spoolss_size_printer_driver_info_2(info);
3759 if (!alloc_buffer_size(buffer, *needed)) {
3761 return WERR_INSUFFICIENT_BUFFER;
3764 /* fill the buffer with the structures */
3765 smb_io_printer_driver_info_2("", buffer, info, 0);
3770 if (*needed > offered)
3771 return WERR_INSUFFICIENT_BUFFER;
3776 /****************************************************************************
3777 ****************************************************************************/
3778 static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3785 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
3786 if (!W_ERROR_IS_OK(status)) {
3790 /* check the required size. */
3791 *needed += spoolss_size_printer_driver_info_3(&info);
3793 if (!alloc_buffer_size(buffer, *needed)) {
3794 free_printer_driver_info_3(&info);
3795 return WERR_INSUFFICIENT_BUFFER;
3798 /* fill the buffer with the structures */
3799 smb_io_printer_driver_info_3("", buffer, &info, 0);
3801 free_printer_driver_info_3(&info);
3803 if (*needed > offered)
3804 return WERR_INSUFFICIENT_BUFFER;
3809 /****************************************************************************
3810 ****************************************************************************/
3811 static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3818 status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
3819 if (!W_ERROR_IS_OK(status)) {
3823 /* check the required size. */
3824 *needed += spoolss_size_printer_driver_info_6(&info);
3826 if (!alloc_buffer_size(buffer, *needed)) {
3827 free_printer_driver_info_6(&info);
3828 return WERR_INSUFFICIENT_BUFFER;
3831 /* fill the buffer with the structures */
3832 smb_io_printer_driver_info_6("", buffer, &info, 0);
3834 free_printer_driver_info_6(&info);
3836 if (*needed > offered)
3837 return WERR_INSUFFICIENT_BUFFER;
3842 /****************************************************************************
3843 ****************************************************************************/
3845 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
3847 POLICY_HND *handle = &q_u->handle;
3848 UNISTR2 *uni_arch = &q_u->architecture;
3849 uint32 level = q_u->level;
3850 uint32 clientmajorversion = q_u->clientmajorversion;
3851 /* uint32 clientminorversion = q_u->clientminorversion; - notused. */
3852 NEW_BUFFER *buffer = NULL;
3853 uint32 offered = q_u->offered;
3854 uint32 *needed = &r_u->needed;
3855 uint32 *servermajorversion = &r_u->servermajorversion;
3856 uint32 *serverminorversion = &r_u->serverminorversion;
3859 fstring architecture;
3862 /* that's an [in out] buffer */
3863 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3864 buffer = r_u->buffer;
3866 DEBUG(4,("_spoolss_getprinterdriver2\n"));
3869 *servermajorversion=0;
3870 *serverminorversion=0;
3872 pstrcpy(servername, get_called_name());
3873 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
3875 if (!get_printer_snum(p, handle, &snum))
3880 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3882 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3884 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3886 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3889 return WERR_UNKNOWN_LEVEL;
3892 /****************************************************************************
3893 ****************************************************************************/
3895 WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u)
3897 POLICY_HND *handle = &q_u->handle;
3899 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
3902 Printer->page_started=True;
3906 DEBUG(3,("Error in startpageprinter printer handle\n"));
3910 /****************************************************************************
3911 ****************************************************************************/
3913 WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u)
3915 POLICY_HND *handle = &q_u->handle;
3917 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
3920 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
3924 Printer->page_started=False;
3929 /********************************************************************
3930 * api_spoolss_getprinter
3931 * called from the spoolss dispatcher
3933 ********************************************************************/
3935 WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
3937 POLICY_HND *handle = &q_u->handle;
3938 /* uint32 level = q_u->doc_info_container.level; - notused. */
3939 DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
3940 uint32 *jobid = &r_u->jobid;
3942 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
3946 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
3947 struct current_user user;
3950 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3954 get_current_user(&user, p);
3957 * a nice thing with NT is it doesn't listen to what you tell it.
3958 * when asked to send _only_ RAW datas, it tries to send datas
3961 * So I add checks like in NT Server ...
3963 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
3964 * there's a bug in NT client-side code, so we'll fix it in the
3965 * server-side code. *nnnnnggggh!*
3968 if (info_1->p_datatype != 0) {
3969 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
3970 if (strcmp(datatype, "RAW") != 0) {
3972 return WERR_INVALID_DATATYPE;
3976 /* get the share number of the printer */
3977 if (!get_printer_snum(p, handle, &snum)) {
3981 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
3983 Printer->jobid = print_job_start(&user, snum, jobname);
3985 /* An error occured in print_job_start() so return an appropriate
3988 if (Printer->jobid == -1) {
3989 return map_werror_from_unix(errno);
3992 Printer->document_started=True;
3993 (*jobid) = Printer->jobid;
3998 /********************************************************************
3999 * api_spoolss_getprinter
4000 * called from the spoolss dispatcher
4002 ********************************************************************/
4004 WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u)
4006 POLICY_HND *handle = &q_u->handle;
4008 return _spoolss_enddocprinter_internal(p, handle);
4011 /****************************************************************************
4012 ****************************************************************************/
4014 WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u)
4016 POLICY_HND *handle = &q_u->handle;
4017 uint32 buffer_size = q_u->buffer_size;
4018 uint8 *buffer = q_u->buffer;
4019 uint32 *buffer_written = &q_u->buffer_size2;
4021 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4024 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
4025 r_u->buffer_written = q_u->buffer_size2;
4029 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer, buffer_size);
4032 r_u->buffer_written = q_u->buffer_size2;
4037 /********************************************************************
4038 * api_spoolss_getprinter
4039 * called from the spoolss dispatcher
4041 ********************************************************************/
4042 static WERROR control_printer(POLICY_HND *handle, uint32 command,
4045 struct current_user user;
4047 WERROR errcode = WERR_BADFUNC;
4048 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4050 get_current_user(&user, p);
4053 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
4057 if (!get_printer_snum(p, handle, &snum))
4061 case PRINTER_CONTROL_PAUSE:
4062 if (print_queue_pause(&user, snum, &errcode)) {
4066 case PRINTER_CONTROL_RESUME:
4067 case PRINTER_CONTROL_UNPAUSE:
4068 if (print_queue_resume(&user, snum, &errcode)) {
4072 case PRINTER_CONTROL_PURGE:
4073 if (print_queue_purge(&user, snum, &errcode)) {
4078 return WERR_UNKNOWN_LEVEL;
4084 /********************************************************************
4085 * api_spoolss_abortprinter
4086 ********************************************************************/
4088 WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u)
4090 POLICY_HND *handle = &q_u->handle;
4092 return control_printer(handle, PRINTER_CONTROL_PURGE, p);
4095 /********************************************************************
4096 * called by spoolss_api_setprinter
4097 * when updating a printer description
4098 ********************************************************************/
4099 static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
4100 const SPOOL_PRINTER_INFO_LEVEL *info,
4101 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
4103 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
4104 struct current_user user;
4108 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4110 if (!Printer || !get_printer_snum(p, handle, &snum)) {
4111 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n",
4112 OUR_HANDLE(handle)));
4114 result = WERR_BADFID;
4118 /* NT seems to like setting the security descriptor even though
4119 nothing may have actually changed. This causes annoying
4120 dialog boxes when the user doesn't have permission to change
4121 the security descriptor. */
4123 nt_printing_getsec(p->mem_ctx, Printer->dev.handlename, &old_secdesc_ctr);
4125 if (DEBUGLEVEL >= 10) {
4129 the_acl = old_secdesc_ctr->sec->dacl;
4130 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
4131 PRINTERNAME(snum), the_acl->num_aces));
4133 for (i = 0; i < the_acl->num_aces; i++) {
4136 sid_to_string(sid_str, &the_acl->ace[i].trustee);
4138 DEBUG(10, ("%s 0x%08x\n", sid_str,
4139 the_acl->ace[i].info.mask));
4142 the_acl = secdesc_ctr->sec->dacl;
4145 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4146 PRINTERNAME(snum), the_acl->num_aces));
4148 for (i = 0; i < the_acl->num_aces; i++) {
4151 sid_to_string(sid_str, &the_acl->ace[i].trustee);
4153 DEBUG(10, ("%s 0x%08x\n", sid_str,
4154 the_acl->ace[i].info.mask));
4157 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
4161 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
4163 if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
4168 /* Work out which user is performing the operation */
4170 get_current_user(&user, p);
4172 /* Check the user has permissions to change the security
4173 descriptor. By experimentation with two NT machines, the user
4174 requires Full Access to the printer to change security
4177 if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
4178 result = WERR_ACCESS_DENIED;
4182 result = nt_printing_setsec(Printer->dev.handlename, new_secdesc_ctr);
4189 /********************************************************************
4190 Do Samba sanity checks on a printer info struct.
4191 this has changed purpose: it now "canonicalises" printer
4192 info from a client rather than just checking it is correct
4193 ********************************************************************/
4195 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
4197 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
4198 info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
4200 /* we force some elements to "correct" values */
4201 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
4202 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
4203 get_called_name(), lp_servicename(snum));
4204 fstrcpy(info->sharename, lp_servicename(snum));
4205 info->attributes = PRINTER_ATTRIBUTE_SHARED \
4206 | PRINTER_ATTRIBUTE_LOCAL \
4207 | PRINTER_ATTRIBUTE_RAW_ONLY \
4208 | PRINTER_ATTRIBUTE_QUEUED ;
4213 /****************************************************************************
4214 ****************************************************************************/
4215 static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
4217 char *cmd = lp_addprinter_cmd();
4220 pstring driverlocation;
4225 /* build driver path... only 9X architecture is needed for legacy reasons */
4226 slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
4228 /* change \ to \\ for the shell */
4229 all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
4231 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4232 cmd, printer->info_2->printername, printer->info_2->sharename,
4233 printer->info_2->portname, printer->info_2->drivername,
4234 printer->info_2->location, driverlocation);
4236 DEBUG(10,("Running [%s]\n", command));
4237 ret = smbrun(command, &fd);
4238 DEBUGADD(10,("returned [%d]\n", ret));
4247 /* Get lines and convert them back to dos-codepage */
4248 qlines = fd_lines_load(fd, &numlines);
4249 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4253 /* Set the portname to what the script says the portname should be. */
4254 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
4255 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
4257 /* Send SIGHUP to process group... is there a better way? */
4262 file_lines_free(qlines);
4266 /* Return true if two devicemodes are equal */
4268 #define DEVMODE_CHECK_INT(field) \
4269 if (d1->field != d2->field) { \
4270 DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
4271 d1->field, d2->field)); \
4275 static BOOL nt_devicemode_equal(NT_DEVICEMODE *d1, NT_DEVICEMODE *d2)
4277 if (!d1 && !d2) goto equal; /* if both are NULL they are equal */
4280 DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
4281 return False; /* if either is exclusively NULL are not equal */
4284 if (!strequal(d1->devicename, d2->devicename)) {
4285 DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1->devicename, d2->devicename));
4289 if (!strequal(d1->formname, d2->formname)) {
4290 DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1->formname, d2->formname));
4294 DEVMODE_CHECK_INT(specversion);
4295 DEVMODE_CHECK_INT(driverversion);
4296 DEVMODE_CHECK_INT(driverextra);
4297 DEVMODE_CHECK_INT(orientation);
4298 DEVMODE_CHECK_INT(papersize);
4299 DEVMODE_CHECK_INT(paperlength);
4300 DEVMODE_CHECK_INT(paperwidth);
4301 DEVMODE_CHECK_INT(scale);
4302 DEVMODE_CHECK_INT(copies);
4303 DEVMODE_CHECK_INT(defaultsource);
4304 DEVMODE_CHECK_INT(printquality);
4305 DEVMODE_CHECK_INT(color);
4306 DEVMODE_CHECK_INT(duplex);
4307 DEVMODE_CHECK_INT(yresolution);
4308 DEVMODE_CHECK_INT(ttoption);
4309 DEVMODE_CHECK_INT(collate);
4310 DEVMODE_CHECK_INT(logpixels);
4312 DEVMODE_CHECK_INT(fields);
4313 DEVMODE_CHECK_INT(bitsperpel);
4314 DEVMODE_CHECK_INT(pelswidth);
4315 DEVMODE_CHECK_INT(pelsheight);
4316 DEVMODE_CHECK_INT(displayflags);
4317 DEVMODE_CHECK_INT(displayfrequency);
4318 DEVMODE_CHECK_INT(icmmethod);
4319 DEVMODE_CHECK_INT(icmintent);
4320 DEVMODE_CHECK_INT(mediatype);
4321 DEVMODE_CHECK_INT(dithertype);
4322 DEVMODE_CHECK_INT(reserved1);
4323 DEVMODE_CHECK_INT(reserved2);
4324 DEVMODE_CHECK_INT(panningwidth);
4325 DEVMODE_CHECK_INT(panningheight);
4327 /* compare the private data if it exists */
4328 if (!d1->driverextra && !d2->driverextra) goto equal;
4331 DEVMODE_CHECK_INT(driverextra);
4333 if (memcmp(d1->private, d2->private, d1->driverextra)) {
4334 DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
4339 DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
4343 /* Return true if two NT_PRINTER_PARAM structures are equal */
4345 static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
4346 NT_PRINTER_PARAM *p2)
4348 if (!p1 && !p2) goto equal;
4350 if ((!p1 && p2) || (p1 && !p2)) {
4351 DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
4355 /* Compare lists of printer parameters */
4359 NT_PRINTER_PARAM *q = p1;
4361 /* Find the parameter in the second structure */
4365 if (strequal(p1->value, q->value)) {
4367 if (p1->type != q->type) {
4368 DEBUG(10, ("nt_printer_param_equal():"
4369 "types for %s differ (%d != %d)\n",
4370 p1->value, p1->type,
4375 if (p1->data_len != q->data_len) {
4376 DEBUG(10, ("nt_printer_param_equal():"
4377 "len for %s differs (%d != %d)\n",
4378 p1->value, p1->data_len,
4383 if (memcmp(p1->data, q->data, p1->data_len) == 0) {
4386 DEBUG(10, ("nt_printer_param_equal():"
4387 "data for %s differs\n", p1->value));
4397 DEBUG(10, ("nt_printer_param_equal(): param %s "
4398 "does not exist\n", p1->value));
4407 DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
4411 /********************************************************************
4412 * Called by update_printer when trying to work out whether to
4413 * actually update printer info.
4414 ********************************************************************/
4416 #define PI_CHECK_INT(field) \
4417 if (pi1->field != pi2->field) { \
4418 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
4419 pi1->field, pi2->field)); \
4423 #define PI_CHECK_STR(field) \
4424 if (!strequal(pi1->field, pi2->field)) { \
4425 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
4426 pi1->field, pi2->field)); \
4430 static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
4431 NT_PRINTER_INFO_LEVEL *p2)
4433 NT_PRINTER_INFO_LEVEL_2 *pi1, *pi2;
4435 /* Trivial conditions */
4437 if ((!p1 && !p2) || (!p1->info_2 && !p2->info_2)) {
4441 if ((!p1 && p2) || (p1 && !p2) ||
4442 (!p1->info_2 && p2->info_2) ||
4443 (p1->info_2 && !p2->info_2)) {
4444 DEBUG(10, ("nt_printer_info_level_equal(): info levels "
4449 /* Compare two nt_printer_info_level structures. Don't compare
4450 status or cjobs as they seem to have something to do with the
4456 /* Don't check the attributes as we stomp on the value in
4457 check_printer_ok() anyway. */
4460 PI_CHECK_INT(attributes);
4463 PI_CHECK_INT(priority);
4464 PI_CHECK_INT(default_priority);
4465 PI_CHECK_INT(starttime);
4466 PI_CHECK_INT(untiltime);
4467 PI_CHECK_INT(averageppm);
4469 /* Yuck - don't check the printername or servername as the
4470 add_a_printer() code plays games with them. You can't
4471 change the printername or the sharename through this interface
4474 PI_CHECK_STR(sharename);
4475 PI_CHECK_STR(portname);
4476 PI_CHECK_STR(drivername);
4477 PI_CHECK_STR(comment);
4478 PI_CHECK_STR(location);
4480 if (!nt_devicemode_equal(pi1->devmode, pi2->devmode)) {
4484 PI_CHECK_STR(sepfile);
4485 PI_CHECK_STR(printprocessor);
4486 PI_CHECK_STR(datatype);
4487 PI_CHECK_STR(parameters);
4489 if (!nt_printer_param_equal(pi1->specific, pi2->specific)) {
4493 if (!sec_desc_equal(pi1->secdesc_buf->sec, pi2->secdesc_buf->sec)) {
4497 PI_CHECK_INT(changeid);
4498 PI_CHECK_INT(c_setprinter);
4499 PI_CHECK_INT(setuptime);
4502 DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
4506 /********************************************************************
4507 * called by spoolss_api_setprinter
4508 * when updating a printer description
4509 ********************************************************************/
4511 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
4512 const SPOOL_PRINTER_INFO_LEVEL *info,
4513 DEVICEMODE *devmode)
4516 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
4517 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4520 DEBUG(8,("update_printer\n"));
4525 DEBUG(0,("Send a mail to samba@samba.org\n"));
4526 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
4527 result = WERR_UNKNOWN_LEVEL;
4532 result = WERR_BADFID;
4536 if (!get_printer_snum(p, handle, &snum)) {
4537 result = WERR_BADFID;
4541 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) ||
4542 (!W_ERROR_IS_OK(get_a_printer(&old_printer, 2, lp_servicename(snum))))) {
4543 result = WERR_BADFID;
4547 DEBUGADD(8,("Converting info_2 struct\n"));
4550 * convert_printer_info converts the incoming
4551 * info from the client and overwrites the info
4552 * just read from the tdb in the pointer 'printer'.
4555 if (!convert_printer_info(info, printer, level)) {
4556 result = WERR_NOMEM;
4560 if (info->info_2->devmode_ptr != 0) {
4561 /* we have a valid devmode
4562 convert it and link it*/
4564 DEBUGADD(8,("Converting the devicemode struct\n"));
4565 if (!convert_devicemode(printer->info_2->printername, devmode,
4566 &printer->info_2->devmode)) {
4567 result = WERR_NOMEM;
4572 /* Do sanity check on the requested changes for Samba */
4574 if (!check_printer_ok(printer->info_2, snum)) {
4575 result = WERR_INVALID_PARAM;
4579 /* NT likes to call this function even though nothing has actually
4580 changed. Check this so the user doesn't end up with an
4581 annoying permission denied dialog box. */
4583 if (nt_printer_info_level_equal(printer, old_printer)) {
4584 DEBUG(3, ("printer info has not changed\n"));
4589 /* Check calling user has permission to update printer description */
4591 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4592 DEBUG(3, ("printer property change denied by security "
4594 result = WERR_ACCESS_DENIED;
4598 /* Call addprinter hook */
4600 if (*lp_addprinter_cmd()) {
4601 if (!add_printer_hook(printer)) {
4602 result = WERR_ACCESS_DENIED;
4607 /* Update printer info */
4608 result = add_a_printer(*printer, 2);
4611 free_a_printer(&printer, 2);
4612 free_a_printer(&old_printer, 2);
4614 srv_spoolss_sendnotify(p, handle);
4619 /****************************************************************************
4620 ****************************************************************************/
4622 WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
4624 POLICY_HND *handle = &q_u->handle;
4625 uint32 level = q_u->level;
4626 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
4627 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
4628 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
4629 uint32 command = q_u->command;
4631 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4634 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
4638 /* check the level */
4641 return control_printer(handle, command, p);
4643 return update_printer(p, handle, level, info, devmode_ctr.devmode);
4645 return update_printer_sec(handle, level, info, p,
4648 return WERR_UNKNOWN_LEVEL;
4652 /****************************************************************************
4653 ****************************************************************************/
4655 WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
4657 POLICY_HND *handle = &q_u->handle;
4659 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
4662 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
4666 if (Printer->notify.client_connected==True)
4667 srv_spoolss_replycloseprinter(&Printer->notify.client_hnd);
4669 Printer->notify.flags=0;
4670 Printer->notify.options=0;
4671 Printer->notify.localmachine[0]='\0';
4672 Printer->notify.printerlocal=0;
4673 if (Printer->notify.option)
4674 free_spool_notify_option(&Printer->notify.option);
4675 Printer->notify.client_connected=False;
4680 /****************************************************************************
4681 ****************************************************************************/
4683 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
4685 /* that's an [in out] buffer (despite appearences to the contrary) */
4686 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
4689 return WERR_INVALID_PARAM; /* this is what a NT server
4690 returns for AddJob. AddJob
4691 must fail on non-local
4695 /****************************************************************************
4696 ****************************************************************************/
4697 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
4698 int position, int snum)
4704 t=gmtime(&queue->time);
4705 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
4707 job_info->jobid=queue->job;
4708 init_unistr(&job_info->printername, lp_servicename(snum));
4709 init_unistr(&job_info->machinename, temp_name);
4710 init_unistr(&job_info->username, queue->user);
4711 init_unistr(&job_info->document, queue->file);
4712 init_unistr(&job_info->datatype, "RAW");
4713 init_unistr(&job_info->text_status, "");
4714 job_info->status=nt_printj_status(queue->status);
4715 job_info->priority=queue->priority;
4716 job_info->position=position;
4717 job_info->totalpages=0;
4718 job_info->pagesprinted=0;
4720 make_systemtime(&job_info->submitted, t);
4723 /****************************************************************************
4724 ****************************************************************************/
4725 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
4726 int position, int snum,
4727 NT_PRINTER_INFO_LEVEL *ntprinter)
4733 t=gmtime(&queue->time);
4734 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
4736 job_info->jobid=queue->job;
4738 slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", get_called_name(), ntprinter->info_2->printername);
4740 init_unistr(&job_info->printername, chaine);
4742 init_unistr(&job_info->machinename, temp_name);
4743 init_unistr(&job_info->username, queue->user);
4744 init_unistr(&job_info->document, queue->file);
4745 init_unistr(&job_info->notifyname, queue->user);
4746 init_unistr(&job_info->datatype, "RAW");
4747 init_unistr(&job_info->printprocessor, "winprint");
4748 init_unistr(&job_info->parameters, "");
4749 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
4750 init_unistr(&job_info->text_status, "");
4752 /* and here the security descriptor */
4754 job_info->status=nt_printj_status(queue->status);
4755 job_info->priority=queue->priority;
4756 job_info->position=position;
4757 job_info->starttime=0;
4758 job_info->untiltime=0;
4759 job_info->totalpages=0;
4760 job_info->size=queue->size;
4761 make_systemtime(&(job_info->submitted), t);
4762 job_info->timeelapsed=0;
4763 job_info->pagesprinted=0;
4765 if((job_info->devmode = construct_dev_mode(snum)) == NULL) {
4772 /****************************************************************************
4773 Enumjobs at level 1.
4774 ****************************************************************************/
4775 static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
4776 NEW_BUFFER *buffer, uint32 offered,
4777 uint32 *needed, uint32 *returned)
4782 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
4789 for (i=0; i<*returned; i++)
4790 fill_job_info_1(&info[i], &queue[i], i, snum);
4794 /* check the required size. */
4795 for (i=0; i<*returned; i++)
4796 (*needed) += spoolss_size_job_info_1(&info[i]);
4798 if (!alloc_buffer_size(buffer, *needed)) {
4800 return WERR_INSUFFICIENT_BUFFER;
4803 /* fill the buffer with the structures */
4804 for (i=0; i<*returned; i++)
4805 smb_io_job_info_1("", buffer, &info[i], 0);
4810 if (*needed > offered) {
4812 return WERR_INSUFFICIENT_BUFFER;
4818 /****************************************************************************
4819 Enumjobs at level 2.
4820 ****************************************************************************/
4821 static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
4822 NEW_BUFFER *buffer, uint32 offered,
4823 uint32 *needed, uint32 *returned)
4825 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4830 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
4836 result = get_a_printer(&ntprinter, 2, lp_servicename(snum));
4837 if (!W_ERROR_IS_OK(result)) {
4842 for (i=0; i<*returned; i++)
4843 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter);
4845 free_a_printer(&ntprinter, 2);
4848 /* check the required size. */
4849 for (i=0; i<*returned; i++)
4850 (*needed) += spoolss_size_job_info_2(&info[i]);
4852 if (!alloc_buffer_size(buffer, *needed)) {
4854 return WERR_INSUFFICIENT_BUFFER;
4857 /* fill the buffer with the structures */
4858 for (i=0; i<*returned; i++)
4859 smb_io_job_info_2("", buffer, &info[i], 0);
4862 for (i = 0; i < *returned; i++)
4863 free_job_info_2(&info[i]);
4867 if (*needed > offered) {
4869 return WERR_INSUFFICIENT_BUFFER;
4875 /****************************************************************************
4877 ****************************************************************************/
4879 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
4881 POLICY_HND *handle = &q_u->handle;
4882 /* uint32 firstjob = q_u->firstjob; - notused. */
4883 /* uint32 numofjobs = q_u->numofjobs; - notused. */
4884 uint32 level = q_u->level;
4885 NEW_BUFFER *buffer = NULL;
4886 uint32 offered = q_u->offered;
4887 uint32 *needed = &r_u->needed;
4888 uint32 *returned = &r_u->returned;
4891 print_status_struct prt_status;
4892 print_queue_struct *queue=NULL;
4894 /* that's an [in out] buffer */
4895 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
4896 buffer = r_u->buffer;
4898 DEBUG(4,("_spoolss_enumjobs\n"));
4903 if (!get_printer_snum(p, handle, &snum))
4906 *returned = print_queue_status(snum, &queue, &prt_status);
4907 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
4909 if (*returned == 0) {
4916 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
4918 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
4922 return WERR_UNKNOWN_LEVEL;
4926 /****************************************************************************
4927 ****************************************************************************/
4929 WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
4934 /****************************************************************************
4935 ****************************************************************************/
4937 WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
4939 POLICY_HND *handle = &q_u->handle;
4940 uint32 jobid = q_u->jobid;
4941 /* uint32 level = q_u->level; - notused. */
4942 /* JOB_INFO *ctr = &q_u->ctr; - notused. */
4943 uint32 command = q_u->command;
4945 struct current_user user;
4947 WERROR errcode = WERR_BADFUNC;
4949 if (!get_printer_snum(p, handle, &snum)) {
4953 if (!print_job_exists(jobid)) {
4954 return WERR_INVALID_PRINTER_NAME;
4957 get_current_user(&user, p);
4960 case JOB_CONTROL_CANCEL:
4961 case JOB_CONTROL_DELETE:
4962 if (print_job_delete(&user, jobid, &errcode)) {
4966 case JOB_CONTROL_PAUSE:
4967 if (print_job_pause(&user, jobid, &errcode)) {
4971 case JOB_CONTROL_RESTART:
4972 case JOB_CONTROL_RESUME:
4973 if (print_job_resume(&user, jobid, &errcode)) {
4978 return WERR_UNKNOWN_LEVEL;
4984 /****************************************************************************
4985 Enumerates all printer drivers at level 1.
4986 ****************************************************************************/
4987 static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4992 fstring *list = NULL;
4994 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4995 DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
4999 #define MAX_VERSION 4
5001 for (version=0; version<MAX_VERSION; version++) {
5003 ndrivers=get_ntdrivers(&list, architecture, version);
5004 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5010 if((tdi1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
5011 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
5012 SAFE_FREE(driver_info_1);
5016 else driver_info_1 = tdi1;
5019 for (i=0; i<ndrivers; i++) {
5021 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5022 ZERO_STRUCT(driver);
5023 status = get_a_printer_driver(&driver, 3, list[i],
5024 architecture, version);
5025 if (!W_ERROR_IS_OK(status)) {
5029 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
5030 free_a_printer_driver(driver, 3);
5033 *returned+=ndrivers;
5037 /* check the required size. */
5038 for (i=0; i<*returned; i++) {
5039 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5040 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
5043 if (!alloc_buffer_size(buffer, *needed)) {
5044 SAFE_FREE(driver_info_1);
5045 return WERR_INSUFFICIENT_BUFFER;
5048 /* fill the buffer with the driver structures */
5049 for (i=0; i<*returned; i++) {
5050 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5051 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
5054 SAFE_FREE(driver_info_1);
5056 if (*needed > offered) {
5058 return WERR_INSUFFICIENT_BUFFER;
5064 /****************************************************************************
5065 Enumerates all printer drivers at level 2.
5066 ****************************************************************************/
5067 static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5072 fstring *list = NULL;
5074 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5075 DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
5079 #define MAX_VERSION 4
5081 for (version=0; version<MAX_VERSION; version++) {
5083 ndrivers=get_ntdrivers(&list, architecture, version);
5084 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5090 if((tdi2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
5091 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
5092 SAFE_FREE(driver_info_2);
5096 else driver_info_2 = tdi2;
5099 for (i=0; i<ndrivers; i++) {
5102 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5103 ZERO_STRUCT(driver);
5104 status = get_a_printer_driver(&driver, 3, list[i],
5105 architecture, version);
5106 if (!W_ERROR_IS_OK(status)) {
5110 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
5111 free_a_printer_driver(driver, 3);
5114 *returned+=ndrivers;
5118 /* check the required size. */
5119 for (i=0; i<*returned; i++) {
5120 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5121 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
5124 if (!alloc_buffer_size(buffer, *needed)) {
5125 SAFE_FREE(driver_info_2);
5126 return WERR_INSUFFICIENT_BUFFER;
5129 /* fill the buffer with the form structures */
5130 for (i=0; i<*returned; i++) {
5131 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5132 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
5135 SAFE_FREE(driver_info_2);
5137 if (*needed > offered) {
5139 return WERR_INSUFFICIENT_BUFFER;
5145 /****************************************************************************
5146 Enumerates all printer drivers at level 3.
5147 ****************************************************************************/
5148 static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5153 fstring *list = NULL;
5155 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5156 DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
5160 #define MAX_VERSION 4
5162 for (version=0; version<MAX_VERSION; version++) {
5164 ndrivers=get_ntdrivers(&list, architecture, version);
5165 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5171 if((tdi3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
5172 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
5173 SAFE_FREE(driver_info_3);
5177 else driver_info_3 = tdi3;
5180 for (i=0; i<ndrivers; i++) {
5183 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5184 ZERO_STRUCT(driver);
5185 status = get_a_printer_driver(&driver, 3, list[i],
5186 architecture, version);
5187 if (!W_ERROR_IS_OK(status)) {
5191 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
5192 free_a_printer_driver(driver, 3);
5195 *returned+=ndrivers;
5199 /* check the required size. */
5200 for (i=0; i<*returned; i++) {
5201 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5202 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
5205 if (!alloc_buffer_size(buffer, *needed)) {
5206 SAFE_FREE(driver_info_3);
5207 return WERR_INSUFFICIENT_BUFFER;
5210 /* fill the buffer with the driver structures */
5211 for (i=0; i<*returned; i++) {
5212 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5213 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
5216 for (i=0; i<*returned; i++)
5217 SAFE_FREE(driver_info_3[i].dependentfiles);
5219 SAFE_FREE(driver_info_3);
5221 if (*needed > offered) {
5223 return WERR_INSUFFICIENT_BUFFER;
5229 /****************************************************************************
5230 Enumerates all printer drivers.
5231 ****************************************************************************/
5233 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
5235 /* UNISTR2 *name = &q_u->name; - notused. */
5236 UNISTR2 *environment = &q_u->environment;
5237 uint32 level = q_u->level;
5238 NEW_BUFFER *buffer = NULL;
5239 uint32 offered = q_u->offered;
5240 uint32 *needed = &r_u->needed;
5241 uint32 *returned = &r_u->returned;
5243 fstring *list = NULL;
5245 fstring architecture;
5247 /* that's an [in out] buffer */
5248 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5249 buffer = r_u->buffer;
5251 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
5252 fstrcpy(servername, get_called_name());
5256 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
5260 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
5262 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
5264 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
5268 return WERR_UNKNOWN_LEVEL;
5272 /****************************************************************************
5273 ****************************************************************************/
5275 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
5277 form->flag=list->flag;
5278 init_unistr(&form->name, list->name);
5279 form->width=list->width;
5280 form->length=list->length;
5281 form->left=list->left;
5282 form->top=list->top;
5283 form->right=list->right;
5284 form->bottom=list->bottom;
5287 /****************************************************************************
5288 ****************************************************************************/
5290 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
5292 /* POLICY_HND *handle = &q_u->handle; - notused. */
5293 uint32 level = q_u->level;
5294 NEW_BUFFER *buffer = NULL;
5295 uint32 offered = q_u->offered;
5296 uint32 *needed = &r_u->needed;
5297 uint32 *numofforms = &r_u->numofforms;
5298 uint32 numbuiltinforms;
5300 nt_forms_struct *list=NULL;
5301 nt_forms_struct *builtinlist=NULL;
5306 /* that's an [in out] buffer */
5307 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5308 buffer = r_u->buffer;
5310 DEBUG(4,("_spoolss_enumforms\n"));
5311 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
5312 DEBUGADD(5,("Info level [%d]\n", level));
5314 numbuiltinforms = get_builtin_ntforms(&builtinlist);
5315 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
5316 *numofforms = get_ntforms(&list);
5317 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
5318 *numofforms += numbuiltinforms;
5320 if (*numofforms == 0) return WERR_NO_MORE_ITEMS;
5324 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
5329 /* construct the list of form structures */
5330 for (i=0; i<numbuiltinforms; i++) {
5331 DEBUGADD(6,("Filling form number [%d]\n",i));
5332 fill_form_1(&forms_1[i], &builtinlist[i]);
5335 SAFE_FREE(builtinlist);
5337 for (; i<*numofforms; i++) {
5338 DEBUGADD(6,("Filling form number [%d]\n",i));
5339 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
5344 /* check the required size. */
5345 for (i=0; i<numbuiltinforms; i++) {
5346 DEBUGADD(6,("adding form [%d]'s size\n",i));
5347 buffer_size += spoolss_size_form_1(&forms_1[i]);
5349 for (; i<*numofforms; i++) {
5350 DEBUGADD(6,("adding form [%d]'s size\n",i));
5351 buffer_size += spoolss_size_form_1(&forms_1[i]);
5354 *needed=buffer_size;
5356 if (!alloc_buffer_size(buffer, buffer_size)){
5358 return WERR_INSUFFICIENT_BUFFER;
5361 /* fill the buffer with the form structures */
5362 for (i=0; i<numbuiltinforms; i++) {
5363 DEBUGADD(6,("adding form [%d] to buffer\n",i));
5364 smb_io_form_1("", buffer, &forms_1[i], 0);
5366 for (; i<*numofforms; i++) {
5367 DEBUGADD(6,("adding form [%d] to buffer\n",i));
5368 smb_io_form_1("", buffer, &forms_1[i], 0);
5373 if (*needed > offered) {
5375 return WERR_INSUFFICIENT_BUFFER;
5382 SAFE_FREE(builtinlist);
5383 return WERR_UNKNOWN_LEVEL;
5388 /****************************************************************************
5389 ****************************************************************************/
5391 WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u)
5393 /* POLICY_HND *handle = &q_u->handle; - notused. */
5394 uint32 level = q_u->level;
5395 UNISTR2 *uni_formname = &q_u->formname;
5396 NEW_BUFFER *buffer = NULL;
5397 uint32 offered = q_u->offered;
5398 uint32 *needed = &r_u->needed;
5400 nt_forms_struct *list=NULL;
5401 nt_forms_struct builtin_form;
5406 int numofforms=0, i=0;
5408 /* that's an [in out] buffer */
5409 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5410 buffer = r_u->buffer;
5412 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
5414 DEBUG(4,("_spoolss_getform\n"));
5415 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
5416 DEBUGADD(5,("Info level [%d]\n", level));
5418 foundBuiltin = get_a_builtin_ntform(uni_formname,&builtin_form);
5419 if (!foundBuiltin) {
5420 numofforms = get_ntforms(&list);
5421 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
5423 if (numofforms == 0)
5430 fill_form_1(&form_1, &builtin_form);
5433 /* Check if the requested name is in the list of form structures */
5434 for (i=0; i<numofforms; i++) {
5436 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
5438 if (strequal(form_name, list[i].name)) {
5439 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
5440 fill_form_1(&form_1, &list[i]);
5446 if (i == numofforms) {
5450 /* check the required size. */
5452 *needed=spoolss_size_form_1(&form_1);
5454 if (!alloc_buffer_size(buffer, buffer_size)){
5455 return WERR_INSUFFICIENT_BUFFER;
5458 if (*needed > offered) {
5459 return WERR_INSUFFICIENT_BUFFER;
5462 /* fill the buffer with the form structures */
5463 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
5464 smb_io_form_1("", buffer, &form_1, 0);
5470 return WERR_UNKNOWN_LEVEL;
5474 /****************************************************************************
5475 ****************************************************************************/
5476 static void fill_port_1(PORT_INFO_1 *port, char *name)
5478 init_unistr(&port->port_name, name);
5481 /****************************************************************************
5482 ****************************************************************************/
5483 static void fill_port_2(PORT_INFO_2 *port, char *name)
5485 init_unistr(&port->port_name, name);
5486 init_unistr(&port->monitor_name, "Local Monitor");
5487 init_unistr(&port->description, "Local Port");
5488 #define PORT_TYPE_WRITE 1
5489 port->port_type=PORT_TYPE_WRITE;
5493 /****************************************************************************
5495 ****************************************************************************/
5496 static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5498 PORT_INFO_1 *ports=NULL;
5501 if (*lp_enumports_cmd()) {
5502 char *cmd = lp_enumports_cmd();
5509 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1);
5511 DEBUG(10,("Running [%s]\n", command));
5512 ret = smbrun(command, &fd);
5513 DEBUG(10,("Returned [%d]\n", ret));
5517 /* Is this the best error to return here? */
5518 return WERR_ACCESS_DENIED;
5522 qlines = fd_lines_load(fd, &numlines);
5523 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5527 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
5528 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
5529 werror_str(WERR_NOMEM)));
5530 file_lines_free(qlines);
5534 for (i=0; i<numlines; i++) {
5535 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
5536 fill_port_1(&ports[i], qlines[i]);
5539 file_lines_free(qlines);
5542 *returned = numlines;
5545 *returned = 1; /* Sole Samba port returned. */
5547 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
5550 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
5552 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
5555 /* check the required size. */
5556 for (i=0; i<*returned; i++) {
5557 DEBUGADD(6,("adding port [%d]'s size\n", i));
5558 *needed += spoolss_size_port_info_1(&ports[i]);
5561 if (!alloc_buffer_size(buffer, *needed)) {
5563 return WERR_INSUFFICIENT_BUFFER;
5566 /* fill the buffer with the ports structures */
5567 for (i=0; i<*returned; i++) {
5568 DEBUGADD(6,("adding port [%d] to buffer\n", i));
5569 smb_io_port_1("", buffer, &ports[i], 0);
5574 if (*needed > offered) {
5576 return WERR_INSUFFICIENT_BUFFER;
5582 /****************************************************************************
5584 ****************************************************************************/
5586 static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5588 PORT_INFO_2 *ports=NULL;
5591 if (*lp_enumports_cmd()) {
5592 char *cmd = lp_enumports_cmd();
5601 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
5602 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
5604 path = lp_lockdir();
5606 slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%u.", path, (unsigned int)sys_getpid());
5607 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 2);
5610 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
5611 ret = smbrun(command, &fd);
5612 DEBUGADD(10,("returned [%d]\n", ret));
5616 /* Is this the best error to return here? */
5617 return WERR_ACCESS_DENIED;
5621 qlines = fd_lines_load(fd, &numlines);
5622 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5626 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
5627 file_lines_free(qlines);
5631 for (i=0; i<numlines; i++) {
5632 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
5633 fill_port_2(&(ports[i]), qlines[i]);
5636 file_lines_free(qlines);
5639 *returned = numlines;
5645 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
5648 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
5650 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
5653 /* check the required size. */
5654 for (i=0; i<*returned; i++) {
5655 DEBUGADD(6,("adding port [%d]'s size\n", i));
5656 *needed += spoolss_size_port_info_2(&ports[i]);
5659 if (!alloc_buffer_size(buffer, *needed)) {
5661 return WERR_INSUFFICIENT_BUFFER;
5664 /* fill the buffer with the ports structures */
5665 for (i=0; i<*returned; i++) {
5666 DEBUGADD(6,("adding port [%d] to buffer\n", i));
5667 smb_io_port_2("", buffer, &ports[i], 0);
5672 if (*needed > offered) {
5674 return WERR_INSUFFICIENT_BUFFER;
5680 /****************************************************************************
5682 ****************************************************************************/
5684 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
5686 /* UNISTR2 *name = &q_u->name; - notused. */
5687 uint32 level = q_u->level;
5688 NEW_BUFFER *buffer = NULL;
5689 uint32 offered = q_u->offered;
5690 uint32 *needed = &r_u->needed;
5691 uint32 *returned = &r_u->returned;
5693 /* that's an [in out] buffer */
5694 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5695 buffer = r_u->buffer;
5697 DEBUG(4,("_spoolss_enumports\n"));
5704 return enumports_level_1(buffer, offered, needed, returned);
5706 return enumports_level_2(buffer, offered, needed, returned);
5708 return WERR_UNKNOWN_LEVEL;
5712 /****************************************************************************
5713 ****************************************************************************/
5714 static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
5715 const SPOOL_PRINTER_INFO_LEVEL *info,
5716 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
5717 uint32 user_switch, const SPOOL_USER_CTR *user,
5720 NT_PRINTER_INFO_LEVEL *printer = NULL;
5723 WERROR err = WERR_OK;
5725 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
5726 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
5730 ZERO_STRUCTP(printer);
5732 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
5733 if (!convert_printer_info(info, printer, 2)) {
5734 free_a_printer(&printer, 2);
5738 /* check to see if the printer already exists */
5740 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
5741 DEBUG(5, ("_spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed!\n",
5742 printer->info_2->sharename));
5743 free_a_printer(&printer, 2);
5744 return WERR_PRINTER_ALREADY_EXISTS;
5747 if (*lp_addprinter_cmd() )
5748 if ( !add_printer_hook(printer) ) {
5749 free_a_printer(&printer,2);
5750 return WERR_ACCESS_DENIED;
5753 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", get_called_name(),
5754 printer->info_2->sharename);
5756 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
5757 free_a_printer(&printer,2);
5758 return WERR_ACCESS_DENIED;
5761 /* you must be a printer admin to add a new printer */
5762 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
5763 free_a_printer(&printer,2);
5764 return WERR_ACCESS_DENIED;
5768 * Do sanity check on the requested changes for Samba.
5771 if (!check_printer_ok(printer->info_2, snum)) {
5772 free_a_printer(&printer,2);
5773 return WERR_INVALID_PARAM;
5777 * When a printer is created, the drivername bound to the printer is used
5778 * to lookup previously saved driver initialization info, which is then
5779 * bound to the new printer, simulating what happens in the Windows arch.
5781 set_driver_init(printer, 2);
5783 /* write the ASCII on disk */
5784 err = add_a_printer(*printer, 2);
5785 if (!W_ERROR_IS_OK(err)) {
5786 free_a_printer(&printer,2);
5790 if (!open_printer_hnd(p, handle, name)) {
5791 /* Handle open failed - remove addition. */
5792 del_a_printer(printer->info_2->sharename);
5793 free_a_printer(&printer,2);
5794 return WERR_ACCESS_DENIED;
5797 free_a_printer(&printer,2);
5799 srv_spoolss_sendnotify(p, handle);
5804 /****************************************************************************
5805 ****************************************************************************/
5807 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
5809 UNISTR2 *uni_srv_name = &q_u->server_name;
5810 uint32 level = q_u->level;
5811 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
5812 uint32 unk0 = q_u->unk0;
5813 uint32 unk1 = q_u->unk1;
5814 uint32 unk2 = q_u->unk2;
5815 uint32 unk3 = q_u->unk3;
5816 uint32 user_switch = q_u->user_switch;
5817 SPOOL_USER_CTR *user = &q_u->user_ctr;
5818 POLICY_HND *handle = &r_u->handle;
5822 /* we don't handle yet */
5823 /* but I know what to do ... */
5824 return WERR_UNKNOWN_LEVEL;
5826 return spoolss_addprinterex_level_2(p, uni_srv_name, info,
5827 unk0, unk1, unk2, unk3,
5828 user_switch, user, handle);
5830 return WERR_UNKNOWN_LEVEL;
5834 /****************************************************************************
5835 ****************************************************************************/
5837 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
5839 /* UNISTR2 *server_name = &q_u->server_name; - notused. */
5840 uint32 level = q_u->level;
5841 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
5842 WERROR err = WERR_OK;
5843 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5844 struct current_user user;
5846 ZERO_STRUCT(driver);
5848 get_current_user(&user, p);
5850 if (!convert_printer_driver_info(info, &driver, level)) {
5855 DEBUG(5,("Cleaning driver's information\n"));
5856 err = clean_up_driver_struct(driver, level, &user);
5857 if (!W_ERROR_IS_OK(err))
5860 DEBUG(5,("Moving driver to final destination\n"));
5861 if(!move_driver_to_download_area(driver, level, &user, &err)) {
5862 if (W_ERROR_IS_OK(err))
5863 err = WERR_ACCESS_DENIED;
5867 if (add_a_printer_driver(driver, level)!=0) {
5868 err = WERR_ACCESS_DENIED;
5873 free_a_printer_driver(driver, level);
5877 /****************************************************************************
5878 ****************************************************************************/
5879 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
5881 init_unistr(&info->name, name);
5884 /****************************************************************************
5885 ****************************************************************************/
5886 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
5890 pstring short_archi;
5891 DRIVER_DIRECTORY_1 *info=NULL;
5893 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
5895 if (get_short_archi(short_archi, long_archi)==False)
5896 return WERR_INVALID_ENVIRONMENT;
5898 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
5901 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
5903 DEBUG(4,("printer driver directory: [%s]\n", path));
5905 fill_driverdir_1(info, path);
5907 *needed += spoolss_size_driverdir_info_1(info);
5909 if (!alloc_buffer_size(buffer, *needed)) {
5911 return WERR_INSUFFICIENT_BUFFER;
5914 smb_io_driverdir_1("", buffer, info, 0);
5918 if (*needed > offered)
5919 return WERR_INSUFFICIENT_BUFFER;
5924 /****************************************************************************
5925 ****************************************************************************/
5927 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
5929 UNISTR2 *name = &q_u->name;
5930 UNISTR2 *uni_environment = &q_u->environment;
5931 uint32 level = q_u->level;
5932 NEW_BUFFER *buffer = NULL;
5933 uint32 offered = q_u->offered;
5934 uint32 *needed = &r_u->needed;
5936 /* that's an [in out] buffer */
5937 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5938 buffer = r_u->buffer;
5940 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
5946 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
5948 return WERR_UNKNOWN_LEVEL;
5952 /****************************************************************************
5953 ****************************************************************************/
5955 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
5957 POLICY_HND *handle = &q_u->handle;
5958 uint32 idx = q_u->index;
5959 uint32 in_value_len = q_u->valuesize;
5960 uint32 in_data_len = q_u->datasize;
5961 uint32 *out_max_value_len = &r_u->valuesize;
5962 uint16 **out_value = &r_u->value;
5963 uint32 *out_value_len = &r_u->realvaluesize;
5964 uint32 *out_type = &r_u->type;
5965 uint32 *out_max_data_len = &r_u->datasize;
5966 uint8 **data_out = &r_u->data;
5967 uint32 *out_data_len = &r_u->realdatasize;
5969 NT_PRINTER_INFO_LEVEL *printer = NULL;
5974 uint32 biggest_valuesize;
5975 uint32 biggest_datasize;
5977 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5983 ZERO_STRUCT(printer);
5987 *out_max_data_len=0;
5991 DEBUG(5,("spoolss_enumprinterdata\n"));
5994 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
5998 if (!get_printer_snum(p,handle, &snum))
6001 result = get_a_printer(&printer, 2, lp_servicename(snum));
6002 if (!W_ERROR_IS_OK(result))
6006 * The NT machine wants to know the biggest size of value and data
6008 * cf: MSDN EnumPrinterData remark section
6010 if ( (in_value_len==0) && (in_data_len==0) ) {
6011 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
6015 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
6016 * if this parameter size doesn't exist.
6017 * Ok - my opinion here is that the client is not asking for the greatest
6018 * possible size of all the parameters, but is asking specifically for the size needed
6019 * for this specific parameter. In that case we can remove the loop below and
6020 * simplify this lookup code considerably. JF - comments welcome. JRA.
6023 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
6025 free_a_printer(&printer, 2);
6026 return WERR_NO_MORE_ITEMS;
6033 biggest_valuesize=0;
6036 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
6037 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
6038 if (data_len > biggest_datasize) biggest_datasize=data_len;
6040 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
6046 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
6047 *out_value_len=2*(1+biggest_valuesize);
6048 *out_data_len=biggest_datasize;
6050 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
6052 free_a_printer(&printer, 2);
6057 * the value len is wrong in NT sp3
6058 * that's the number of bytes not the number of unicode chars
6061 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
6064 free_a_printer(&printer, 2);
6066 /* out_value should default to "" or else NT4 has
6067 problems unmarshalling the response */
6069 *out_max_value_len=(in_value_len/sizeof(uint16));
6070 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL)
6073 ZERO_STRUCTP(*out_value);
6074 *out_value_len = rpcstr_push((char *)*out_value, "", in_value_len, 0);
6076 /* the data is counted in bytes */
6077 *out_max_data_len = in_data_len;
6078 *out_data_len = in_data_len;
6079 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL)
6082 memset(*data_out,'\0',in_data_len);
6084 return WERR_NO_MORE_ITEMS;
6087 free_a_printer(&printer, 2);
6091 * - counted in bytes in the request
6092 * - counted in UNICODE chars in the max reply
6093 * - counted in bytes in the real size
6095 * take a pause *before* coding not *during* coding
6098 *out_max_value_len=(in_value_len/sizeof(uint16));
6099 if((*out_value=(uint16 *)talloc_zero(p->mem_ctx,in_value_len*sizeof(uint8))) == NULL) {
6104 *out_value_len = rpcstr_push((char *)*out_value,value, in_value_len, 0);
6108 /* the data is counted in bytes */
6109 *out_max_data_len=in_data_len;
6110 if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) {
6115 memcpy(*data_out, data, (size_t)data_len);
6116 *out_data_len=data_len;
6123 /****************************************************************************
6124 ****************************************************************************/
6126 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
6128 POLICY_HND *handle = &q_u->handle;
6129 UNISTR2 *value = &q_u->value;
6130 uint32 type = q_u->type;
6131 /* uint32 max_len = q_u->max_len; - notused. */
6132 uint8 *data = q_u->data;
6133 uint32 real_len = q_u->real_len;
6134 /* uint32 numeric_data = q_u->numeric_data; - notused. */
6136 NT_PRINTER_INFO_LEVEL *printer = NULL;
6137 NT_PRINTER_PARAM *param = NULL, old_param;
6139 WERROR status = WERR_OK;
6140 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
6142 DEBUG(5,("spoolss_setprinterdata\n"));
6145 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6149 if (!get_printer_snum(p,handle, &snum))
6152 ZERO_STRUCT(old_param);
6155 * Access check : NT returns "access denied" if you make a
6156 * SetPrinterData call without the necessary privildge.
6157 * we were originally returning OK if nothing changed
6158 * which made Win2k issue **a lot** of SetPrinterData
6159 * when connecting to a printer --jerry
6162 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
6163 DEBUG(3, ("security descriptor change denied by existing "
6164 "security descriptor\n"));
6165 status = WERR_ACCESS_DENIED;
6169 /* Check if we are making any changes or not. Return true if
6170 nothing is actually changing. This is not needed anymore but
6171 has been left in as an optimization to keep from from
6172 writing to disk as often --jerry */
6174 status = get_a_printer(&printer, 2, lp_servicename(snum));
6175 if (!W_ERROR_IS_OK(status))
6178 convert_specific_param(¶m, value , type, data, real_len);
6181 if (get_specific_param(*printer, 2, param->value, &old_param.data,
6182 &old_param.type, (uint32 *)&old_param.data_len)) {
6184 if (param->type == old_param.type &&
6185 param->data_len == old_param.data_len &&
6186 memcmp(param->data, old_param.data,
6187 old_param.data_len) == 0) {
6189 DEBUG(3, ("setprinterdata hasn't changed\n"));
6195 unlink_specific_param_if_exist(printer->info_2, param);
6198 * When client side code sets a magic printer data key, detect it and save
6199 * the current printer data and the magic key's data (its the DEVMODE) for
6200 * future printer/driver initializations.
6202 if (param->type==3 && !strcmp( param->value, PHANTOM_DEVMODE_KEY)) {
6204 * Set devmode and printer initialization info
6206 status = save_driver_init(printer, 2, param);
6209 add_a_specific_param(printer->info_2, ¶m);
6210 status = mod_a_printer(*printer, 2);
6214 free_a_printer(&printer, 2);
6216 free_nt_printer_param(¶m);
6217 SAFE_FREE(old_param.data);
6222 /****************************************************************************
6223 ****************************************************************************/
6225 WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
6227 POLICY_HND *handle = &q_u->handle;
6228 UNISTR2 *value = &q_u->valuename;
6230 NT_PRINTER_INFO_LEVEL *printer = NULL;
6231 NT_PRINTER_PARAM param;
6233 WERROR status = WERR_OK;
6234 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
6236 DEBUG(5,("spoolss_deleteprinterdata\n"));
6239 DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6243 if (!get_printer_snum(p, handle, &snum))
6246 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
6247 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
6248 "change denied by existing security descriptor\n"));
6249 return WERR_ACCESS_DENIED;
6252 status = get_a_printer(&printer, 2, lp_servicename(snum));
6253 if (!W_ERROR_IS_OK(status))
6256 ZERO_STRUCTP(¶m);
6257 unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
6259 if(!unlink_specific_param_if_exist(printer->info_2, ¶m))
6260 status = WERR_INVALID_PARAM;
6262 status = mod_a_printer(*printer, 2);
6264 free_a_printer(&printer, 2);
6268 /****************************************************************************
6269 ****************************************************************************/
6271 WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
6273 POLICY_HND *handle = &q_u->handle;
6274 /* uint32 level = q_u->level; - notused. */
6275 FORM *form = &q_u->form;
6276 nt_forms_struct tmpForm;
6279 nt_forms_struct *list=NULL;
6280 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6282 DEBUG(5,("spoolss_addform\n"));
6285 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6290 * FIXME!! Feels like there should be an access check here, but haven't
6291 * had time to verify. --jerry
6294 /* can't add if builtin */
6295 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
6296 return WERR_INVALID_PARAM;
6299 count=get_ntforms(&list);
6300 if(!add_a_form(&list, form, &count))
6302 write_ntforms(&list, count);
6309 /****************************************************************************
6310 ****************************************************************************/
6312 WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u)
6314 POLICY_HND *handle = &q_u->handle;
6315 UNISTR2 *form_name = &q_u->name;
6316 nt_forms_struct tmpForm;
6318 WERROR ret = WERR_OK;
6319 nt_forms_struct *list=NULL;
6320 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6322 DEBUG(5,("spoolss_deleteform\n"));
6325 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6329 /* can't delete if builtin */
6330 if (get_a_builtin_ntform(form_name,&tmpForm)) {
6331 return WERR_INVALID_PARAM;
6334 count = get_ntforms(&list);
6335 if(!delete_a_form(&list, form_name, &count, &ret))
6336 return WERR_INVALID_PARAM;
6343 /****************************************************************************
6344 ****************************************************************************/
6346 WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
6348 POLICY_HND *handle = &q_u->handle;
6349 /* UNISTR2 *uni_name = &q_u->name; - notused. */
6350 /* uint32 level = q_u->level; - notused. */
6351 FORM *form = &q_u->form;
6352 nt_forms_struct tmpForm;
6355 nt_forms_struct *list=NULL;
6356 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6358 DEBUG(5,("spoolss_setform\n"));
6361 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6364 /* can't set if builtin */
6365 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
6366 return WERR_INVALID_PARAM;
6369 count=get_ntforms(&list);
6370 update_a_form(&list, form, count);
6371 write_ntforms(&list, count);
6378 /****************************************************************************
6379 enumprintprocessors level 1.
6380 ****************************************************************************/
6381 static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6383 PRINTPROCESSOR_1 *info_1=NULL;
6385 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
6390 init_unistr(&info_1->name, "winprint");
6392 *needed += spoolss_size_printprocessor_info_1(info_1);
6394 if (!alloc_buffer_size(buffer, *needed))
6395 return WERR_INSUFFICIENT_BUFFER;
6397 smb_io_printprocessor_info_1("", buffer, info_1, 0);
6401 if (*needed > offered) {
6403 return WERR_INSUFFICIENT_BUFFER;
6409 /****************************************************************************
6410 ****************************************************************************/
6412 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
6414 /* UNISTR2 *name = &q_u->name; - notused. */
6415 /* UNISTR2 *environment = &q_u->environment; - notused. */
6416 uint32 level = q_u->level;
6417 NEW_BUFFER *buffer = NULL;
6418 uint32 offered = q_u->offered;
6419 uint32 *needed = &r_u->needed;
6420 uint32 *returned = &r_u->returned;
6422 /* that's an [in out] buffer */
6423 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6424 buffer = r_u->buffer;
6426 DEBUG(5,("spoolss_enumprintprocessors\n"));
6429 * Enumerate the print processors ...
6431 * Just reply with "winprint", to keep NT happy
6432 * and I can use my nice printer checker.
6440 return enumprintprocessors_level_1(buffer, offered, needed, returned);
6442 return WERR_UNKNOWN_LEVEL;
6446 /****************************************************************************
6447 enumprintprocdatatypes level 1.
6448 ****************************************************************************/
6449 static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6451 PRINTPROCDATATYPE_1 *info_1=NULL;
6453 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
6458 init_unistr(&info_1->name, "RAW");
6460 *needed += spoolss_size_printprocdatatype_info_1(info_1);
6462 if (!alloc_buffer_size(buffer, *needed))
6463 return WERR_INSUFFICIENT_BUFFER;
6465 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
6469 if (*needed > offered) {
6471 return WERR_INSUFFICIENT_BUFFER;
6477 /****************************************************************************
6478 ****************************************************************************/
6480 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
6482 /* UNISTR2 *name = &q_u->name; - notused. */
6483 /* UNISTR2 *processor = &q_u->processor; - notused. */
6484 uint32 level = q_u->level;
6485 NEW_BUFFER *buffer = NULL;
6486 uint32 offered = q_u->offered;
6487 uint32 *needed = &r_u->needed;
6488 uint32 *returned = &r_u->returned;
6490 /* that's an [in out] buffer */
6491 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6492 buffer = r_u->buffer;
6494 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
6501 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
6503 return WERR_UNKNOWN_LEVEL;
6507 /****************************************************************************
6508 enumprintmonitors level 1.
6509 ****************************************************************************/
6511 static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6513 PRINTMONITOR_1 *info_1=NULL;
6515 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
6520 init_unistr(&info_1->name, "Local Port");
6522 *needed += spoolss_size_printmonitor_info_1(info_1);
6524 if (!alloc_buffer_size(buffer, *needed))
6525 return WERR_INSUFFICIENT_BUFFER;
6527 smb_io_printmonitor_info_1("", buffer, info_1, 0);
6531 if (*needed > offered) {
6533 return WERR_INSUFFICIENT_BUFFER;
6539 /****************************************************************************
6540 enumprintmonitors level 2.
6541 ****************************************************************************/
6542 static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6544 PRINTMONITOR_2 *info_2=NULL;
6546 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
6551 init_unistr(&info_2->name, "Local Port");
6552 init_unistr(&info_2->environment, "Windows NT X86");
6553 init_unistr(&info_2->dll_name, "localmon.dll");
6555 *needed += spoolss_size_printmonitor_info_2(info_2);
6557 if (!alloc_buffer_size(buffer, *needed))
6558 return WERR_INSUFFICIENT_BUFFER;
6560 smb_io_printmonitor_info_2("", buffer, info_2, 0);
6564 if (*needed > offered) {
6566 return WERR_INSUFFICIENT_BUFFER;
6572 /****************************************************************************
6573 ****************************************************************************/
6575 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
6577 /* UNISTR2 *name = &q_u->name; - notused. */
6578 uint32 level = q_u->level;
6579 NEW_BUFFER *buffer = NULL;
6580 uint32 offered = q_u->offered;
6581 uint32 *needed = &r_u->needed;
6582 uint32 *returned = &r_u->returned;
6584 /* that's an [in out] buffer */
6585 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6586 buffer = r_u->buffer;
6588 DEBUG(5,("spoolss_enumprintmonitors\n"));
6591 * Enumerate the print monitors ...
6593 * Just reply with "Local Port", to keep NT happy
6594 * and I can use my nice printer checker.
6602 return enumprintmonitors_level_1(buffer, offered, needed, returned);
6604 return enumprintmonitors_level_2(buffer, offered, needed, returned);
6606 return WERR_UNKNOWN_LEVEL;
6610 /****************************************************************************
6611 ****************************************************************************/
6612 static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
6616 JOB_INFO_1 *info_1=NULL;
6618 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
6620 if (info_1 == NULL) {
6625 for (i=0; i<count && found==False; i++) {
6626 if (queue[i].job==(int)jobid)
6633 /* NT treats not found as bad param... yet another bad choice */
6634 return WERR_INVALID_PARAM;
6637 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
6641 *needed += spoolss_size_job_info_1(info_1);
6643 if (!alloc_buffer_size(buffer, *needed)) {
6645 return WERR_INSUFFICIENT_BUFFER;
6648 smb_io_job_info_1("", buffer, info_1, 0);
6652 if (*needed > offered)
6653 return WERR_INSUFFICIENT_BUFFER;
6659 /****************************************************************************
6660 ****************************************************************************/
6661 static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
6666 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6669 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
6671 ZERO_STRUCTP(info_2);
6673 if (info_2 == NULL) {
6678 for (i=0; i<count && found==False; i++) {
6679 if (queue[i].job==(int)jobid)
6686 /* NT treats not found as bad param... yet another bad choice */
6687 return WERR_INVALID_PARAM;
6690 ret = get_a_printer(&ntprinter, 2, lp_servicename(snum));
6691 if (!W_ERROR_IS_OK(ret)) {
6696 fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter);
6698 free_a_printer(&ntprinter, 2);
6701 *needed += spoolss_size_job_info_2(info_2);
6703 if (!alloc_buffer_size(buffer, *needed)) {
6705 return WERR_INSUFFICIENT_BUFFER;
6708 smb_io_job_info_2("", buffer, info_2, 0);
6710 free_job_info_2(info_2);
6713 if (*needed > offered)
6714 return WERR_INSUFFICIENT_BUFFER;
6719 /****************************************************************************
6720 ****************************************************************************/
6722 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
6724 POLICY_HND *handle = &q_u->handle;
6725 uint32 jobid = q_u->jobid;
6726 uint32 level = q_u->level;
6727 NEW_BUFFER *buffer = NULL;
6728 uint32 offered = q_u->offered;
6729 uint32 *needed = &r_u->needed;
6733 print_queue_struct *queue=NULL;
6734 print_status_struct prt_status;
6736 /* that's an [in out] buffer */
6737 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6738 buffer = r_u->buffer;
6740 DEBUG(5,("spoolss_getjob\n"));
6744 if (!get_printer_snum(p, handle, &snum))
6747 count = print_queue_status(snum, &queue, &prt_status);
6749 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
6750 count, prt_status.status, prt_status.message));
6754 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
6756 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
6759 return WERR_UNKNOWN_LEVEL;
6763 /********************************************************************
6764 * spoolss_getprinterdataex
6765 ********************************************************************/
6767 WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
6769 POLICY_HND *handle = &q_u->handle;
6770 uint32 in_size = q_u->size;
6771 uint32 *type = &r_u->type;
6772 uint32 *out_size = &r_u->size;
6773 uint8 **data = &r_u->data;
6774 uint32 *needed = &r_u->needed;
6777 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6780 DEBUG(4,("_spoolss_getprinterdataex\n"));
6782 unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
6783 unistr2_to_ascii(value, &q_u->valuename, sizeof(value) - 1);
6785 /* in case of problem, return some default values */
6792 if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL)
6794 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6799 /* Is the handle to a printer or to the server? */
6801 if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
6803 DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
6804 return WERR_INVALID_PARAM;
6809 * From MSDN documentation of GetPrinterDataEx: pass request
6810 * to GetPrinterData if key is "PrinterDriverData". This is
6811 * the only key we really support. Other keys to implement:
6817 if (strcmp(key, "PrinterDriverData") != 0)
6818 return WERR_INVALID_PARAM;
6820 DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
6821 found = getprinterdata_printer(p, p->mem_ctx, handle, value,
6822 type, data, needed, in_size);
6827 DEBUG(5, ("value not found, allocating %d\n", *out_size));
6829 /* reply this param doesn't exist */
6831 if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
6837 return WERR_INVALID_PARAM;
6840 if (*needed > *out_size)
6841 return WERR_MORE_DATA;
6846 /********************************************************************
6847 * spoolss_setprinterdata
6848 ********************************************************************/
6850 WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
6852 SPOOL_Q_SETPRINTERDATA q_u_local;
6853 SPOOL_R_SETPRINTERDATA r_u_local;
6856 DEBUG(4,("_spoolss_setprinterdataex\n"));
6858 /* From MSDN documentation of SetPrinterDataEx: pass request to
6859 SetPrinterData if key is "PrinterDriverData" */
6861 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
6863 if (strcmp(key, "PrinterDriverData") == 0)
6864 return WERR_INVALID_PARAM;
6866 ZERO_STRUCT(q_u_local);
6867 ZERO_STRUCT(r_u_local);
6869 /* make a copy to call _spoolss_setprinterdata() */
6871 memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND));
6872 copy_unistr2(&q_u_local.value, &q_u->value);
6873 q_u_local.type = q_u->type;
6874 q_u_local.max_len = q_u->max_len;
6875 q_u_local.data = q_u->data;
6876 q_u_local.real_len = q_u->real_len;
6877 q_u_local.numeric_data = q_u->numeric_data;
6879 return _spoolss_setprinterdata(p, &q_u_local, &r_u_local);
6882 /********************************************************************
6883 * spoolss_enumprinterkey
6884 ********************************************************************/
6886 /* constants for EnumPrinterKey() */
6887 #define ENUMERATED_KEY_SIZE 19
6889 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
6892 uint16 enumkeys[ENUMERATED_KEY_SIZE+1];
6895 char *PrinterKey = "PrinterDriverData";
6897 DEBUG(4,("_spoolss_enumprinterkey\n"));
6899 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
6902 * we only support enumating all keys (key == "")
6903 * Of course, the only key we support is the "PrinterDriverData"
6906 if (strlen(key) == 0)
6908 r_u->needed = ENUMERATED_KEY_SIZE *2;
6909 if (q_u->size < r_u->needed)
6910 return WERR_MORE_DATA;
6913 for (i=0; i<ENUMERATED_KEY_SIZE-2; i++)
6915 enumkeys[i] = (uint16)(*ptr);
6919 /* tag of with 2 '\0's */
6920 enumkeys[i++] = '\0';
6923 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, ENUMERATED_KEY_SIZE, enumkeys))
6924 return WERR_BADFILE;
6929 /* The "PrinterDriverData" key should have no subkeys */
6930 if (strcmp(key, PrinterKey) == 0)
6933 if (q_u->size < r_u->needed)
6934 return WERR_MORE_DATA;
6936 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, enumkeys))
6937 return WERR_BADFILE;
6943 /* The return value for an unknown key is documented in MSDN
6944 EnumPrinterKey description */
6945 return WERR_BADFILE;
6948 /********************************************************************
6949 * spoolss_enumprinterdataex
6950 ********************************************************************/
6952 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
6954 POLICY_HND *handle = &q_u->handle;
6955 uint32 in_size = q_u->size;
6958 NT_PRINTER_INFO_LEVEL *printer = NULL;
6959 PRINTER_ENUM_VALUES *enum_values = NULL;
6961 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6970 DEBUG(4,("_spoolss_enumprinterdataex\n"));
6973 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6979 * The only key we support is "PrinterDriverData". This should return
6980 > an array of all the key/value pairs returned by EnumPrinterDataSee
6981 * _spoolss_getprinterdataex() for details --jerry
6984 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
6985 if (strcmp(key, "PrinterDriverData") != 0)
6987 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
6988 return WERR_INVALID_PARAM;
6992 if (!get_printer_snum(p,handle, &snum))
6995 ZERO_STRUCT(printer);
6996 result = get_a_printer(&printer, 2, lp_servicename(snum));
6997 if (!W_ERROR_IS_OK(result))
7002 * loop through all params and build the array to pass
7003 * back to the client
7010 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len))
7012 PRINTER_ENUM_VALUES *ptr;
7015 DEBUG(10,("retrieved value number [%d] [%s]\n", num_entries, value));
7017 if ((ptr=talloc_realloc(p->mem_ctx, enum_values, (num_entries+1) * sizeof(PRINTER_ENUM_VALUES))) == NULL)
7019 DEBUG(0,("talloc_realloc failed to allocate more memory!\n"));
7020 result = WERR_NOMEM;
7026 init_unistr(&enum_values[num_entries].valuename, value);
7027 enum_values[num_entries].value_len = (strlen(value)+1) * 2;
7028 enum_values[num_entries].type = type;
7031 * NULL terminate REG_SZ
7032 * FIXME!!! We should not be correctly problems in the way
7033 * we store PrinterData here. Need to investogate
7034 * SetPrinterData[Ex] --jerry
7037 if (type == REG_SZ) {
7038 /* fix alignment if the string was stored
7039 in a bizarre fashion */
7040 if ((data_len % 2) == 0)
7043 add_len = data_len % 2;
7046 if (!(enum_values[num_entries].data=talloc_zero(p->mem_ctx, data_len+add_len))) {
7047 DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n"));
7048 result = WERR_NOMEM;
7051 memcpy(enum_values[num_entries].data, data, data_len);
7052 enum_values[num_entries].data_len = data_len + add_len;
7054 /* keep track of the size of the array in bytes */
7056 needed += spoolss_size_printer_enum_values(&enum_values[num_entries]);
7062 r_u->needed = needed;
7063 r_u->returned = num_entries;
7065 if (needed > in_size) {
7066 result = WERR_MORE_DATA;
7070 /* copy data into the reply */
7072 r_u->ctr.size = r_u->needed;
7073 r_u->ctr.size_of_array = r_u->returned;
7074 r_u->ctr.values = enum_values;
7079 free_a_printer(&printer, 2);
7084 /****************************************************************************
7085 ****************************************************************************/
7087 /* Disabled because it doesn't fix the bug I am looking at but it would be
7088 a shame to throw away the code. -tpot */
7092 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name)
7094 init_unistr(&info->name, name);
7097 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
7098 UNISTR2 *environment,
7105 pstring short_archi;
7106 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
7108 unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
7110 if (get_short_archi(short_archi, long_archi)==False)
7111 return WERR_INVALID_ENVIRONMENT;
7113 if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
7116 /* Not sure what to return here - are UNC names valid here?.
7117 Windows returns the string: C:\WINNT\System32\spool\PRTPROCS\W32X86
7118 which is pretty bogus for a RPC. */
7120 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
7122 DEBUG(4,("print processor directory: [%s]\n", path));
7124 fill_printprocessordirectory_1(info, path);
7126 *needed += spoolss_size_printprocessordirectory_info_1(info);
7128 if (!alloc_buffer_size(buffer, *needed)) {
7130 return WERR_INSUFFICIENT_BUFFER;
7133 smb_io_printprocessordirectory_1("", buffer, info, 0);
7137 if (*needed > offered)
7138 return WERR_INSUFFICIENT_BUFFER;
7143 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
7145 uint32 level = q_u->level;
7146 NEW_BUFFER *buffer = NULL;
7147 uint32 offered = q_u->offered;
7148 uint32 *needed = &r_u->needed;
7150 /* that's an [in out] buffer */
7151 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
7152 buffer = r_u->buffer;
7154 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
7160 return getprintprocessordirectory_level_1
7161 (&q_u->name, &q_u->environment, buffer, offered, needed);
7163 return WERR_UNKNOWN_LEVEL;
7166 return WERR_ACCESS_DENIED;