2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 * Copyright (C) Jean François Micouleau 1998-2000.
8 * Copyright (C) Jeremy Allison 2001.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
26 up, all the errors returned are DOS errors, not NT status codes. */
30 extern pstring global_myname;
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 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer, strlen(printer) + 1, False); /* Null terminate... */
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;
808 * If we are not serving the printer driver for this printer,
809 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
810 * will keep NT clients happy --jerry
813 if (lp_use_client_driver(snum)
814 && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
816 printer_default->access_required = PRINTER_ACCESS_USE;
819 if (!print_access_check(&user, snum, printer_default->access_required)) {
820 DEBUG(3, ("access DENIED for printer open\n"));
821 close_printer_handle(p, handle);
822 return WERR_ACCESS_DENIED;
826 * If we have a default device pointer in the
827 * printer_default struct, then we need to get
828 * the printer info from the tdb and if there is
829 * no default devicemode there then we do a *SET*
830 * here ! This is insanity.... JRA.
834 * If the openprinterex rpc call contains a devmode,
835 * it's a per-user one. This per-user devmode is derivated
836 * from the global devmode. Openprinterex() contains a per-user
837 * devmode for when you do EMF printing and spooling.
838 * In the EMF case, the NT workstation is only doing half the job
839 * of rendering the page. The other half is done by running the printer
840 * driver on the server.
841 * The EMF file doesn't contain the page description (paper size, orientation, ...).
842 * The EMF file only contains what is to be printed on the page.
843 * So in order for the server to know how to print, the NT client sends
844 * a devicemode attached to the openprinterex call.
845 * But this devicemode is short lived, it's only valid for the current print job.
847 * If Samba would have supported EMF spooling, this devicemode would
848 * have been attached to the handle, to sent it to the driver to correctly
849 * rasterize the EMF file.
851 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
852 * we just act as a pass-thru between windows and the printer.
854 * In order to know that Samba supports only RAW spooling, NT has to call
855 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
856 * and until NT sends a RAW job, we refuse it.
858 * But to call getprinter() or startdoc(), you first need a valid handle,
859 * and to get an handle you have to call openprintex(). Hence why you have
860 * a devicemode in the openprinterex() call.
863 * Differences between NT4 and NT 2000.
866 * On NT4, you only have a global devicemode. This global devicemode can be changed
867 * by the administrator (or by a user with enough privs). Everytime a user
868 * wants to print, the devicemode is resetted to the default. In Word, everytime
869 * you print, the printer's characteristics are always reset to the global devicemode.
873 * In W2K, there is the notion of per-user devicemode. The first time you use
874 * a printer, a per-user devicemode is build from the global devicemode.
875 * If you change your per-user devicemode, it is saved in the registry, under the
876 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
877 * printer preferences available.
879 * To change the per-user devicemode: it's the "Printing Preferences ..." button
880 * on the General Tab of the printer properties windows.
882 * To change the global devicemode: it's the "Printing Defaults..." button
883 * on the Advanced Tab of the printer properties window.
891 if (printer_default->devmode_cont.devmode != NULL) {
892 result = printer_write_default_dev( snum, printer_default);
894 close_printer_handle(p, handle);
904 /****************************************************************************
905 ****************************************************************************/
906 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
907 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
911 uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
920 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
921 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
927 printer->info_3=NULL;
928 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
932 printer->info_6=NULL;
933 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
943 BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
944 NT_DEVICEMODE **pp_nt_devmode)
946 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
949 * Ensure nt_devmode is a valid pointer
950 * as we will be overwriting it.
953 if (nt_devmode == NULL) {
954 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
955 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
959 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
960 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
962 nt_devmode->specversion=devmode->specversion;
963 nt_devmode->driverversion=devmode->driverversion;
964 nt_devmode->size=devmode->size;
965 nt_devmode->fields=devmode->fields;
966 nt_devmode->orientation=devmode->orientation;
967 nt_devmode->papersize=devmode->papersize;
968 nt_devmode->paperlength=devmode->paperlength;
969 nt_devmode->paperwidth=devmode->paperwidth;
970 nt_devmode->scale=devmode->scale;
971 nt_devmode->copies=devmode->copies;
972 nt_devmode->defaultsource=devmode->defaultsource;
973 nt_devmode->printquality=devmode->printquality;
974 nt_devmode->color=devmode->color;
975 nt_devmode->duplex=devmode->duplex;
976 nt_devmode->yresolution=devmode->yresolution;
977 nt_devmode->ttoption=devmode->ttoption;
978 nt_devmode->collate=devmode->collate;
980 nt_devmode->logpixels=devmode->logpixels;
981 nt_devmode->bitsperpel=devmode->bitsperpel;
982 nt_devmode->pelswidth=devmode->pelswidth;
983 nt_devmode->pelsheight=devmode->pelsheight;
984 nt_devmode->displayflags=devmode->displayflags;
985 nt_devmode->displayfrequency=devmode->displayfrequency;
986 nt_devmode->icmmethod=devmode->icmmethod;
987 nt_devmode->icmintent=devmode->icmintent;
988 nt_devmode->mediatype=devmode->mediatype;
989 nt_devmode->dithertype=devmode->dithertype;
990 nt_devmode->reserved1=devmode->reserved1;
991 nt_devmode->reserved2=devmode->reserved2;
992 nt_devmode->panningwidth=devmode->panningwidth;
993 nt_devmode->panningheight=devmode->panningheight;
996 * Only change private and driverextra if the incoming devmode
997 * has a new one. JRA.
1000 if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
1001 SAFE_FREE(nt_devmode->private);
1002 nt_devmode->driverextra=devmode->driverextra;
1003 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
1005 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
1008 *pp_nt_devmode = nt_devmode;
1013 /********************************************************************
1014 * _spoolss_enddocprinter_internal.
1015 ********************************************************************/
1017 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1019 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1022 DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle)));
1026 Printer->document_started=False;
1027 print_job_end(Printer->jobid,True);
1028 /* error codes unhandled so far ... */
1033 /********************************************************************
1034 * api_spoolss_closeprinter
1035 ********************************************************************/
1037 WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u)
1039 POLICY_HND *handle = &q_u->handle;
1041 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1043 if (Printer && Printer->document_started)
1044 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1046 memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
1048 if (!close_printer_handle(p, handle))
1054 /********************************************************************
1055 * api_spoolss_deleteprinter
1057 ********************************************************************/
1059 WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u)
1061 POLICY_HND *handle = &q_u->handle;
1062 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1065 if (Printer && Printer->document_started)
1066 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1068 memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
1070 result = delete_printer_handle(p, handle);
1072 if (W_ERROR_IS_OK(result)) {
1073 srv_spoolss_sendnotify(p, handle);
1079 /*******************************************************************
1080 * static function to lookup the version id corresponding to an
1081 * long architecture string
1082 ******************************************************************/
1083 static int get_version_id (char * arch)
1086 struct table_node archi_table[]= {
1088 {"Windows 4.0", "WIN40", 0 },
1089 {"Windows NT x86", "W32X86", 2 },
1090 {"Windows NT R4000", "W32MIPS", 2 },
1091 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1092 {"Windows NT PowerPC", "W32PPC", 2 },
1096 for (i=0; archi_table[i].long_archi != NULL; i++)
1098 if (strcmp(arch, archi_table[i].long_archi) == 0)
1099 return (archi_table[i].version);
1105 /********************************************************************
1106 * _spoolss_deleteprinterdriver
1108 * We currently delete the driver for the architecture only.
1109 * This can leave the driver for other archtectures. However,
1110 * since every printer associates a "Windows NT x86" driver name
1111 * and we cannot delete that one while it is in use, **and** since
1112 * it is impossible to assign a driver to a Samba printer without
1113 * having the "Windows NT x86" driver installed,...
1115 * ....we should not get into trouble here.
1118 ********************************************************************/
1120 WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
1121 SPOOL_R_DELETEPRINTERDRIVER *r_u)
1125 NT_PRINTER_DRIVER_INFO_LEVEL info;
1128 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
1129 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
1131 /* check that we have a valid driver name first */
1132 if ((version=get_version_id(arch)) == -1) {
1133 return WERR_INVALID_ENVIRONMENT;
1137 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
1138 return WERR_UNKNOWN_PRINTER_DRIVER;
1142 if (printer_driver_in_use(arch, driver))
1144 return WERR_PRINTER_DRIVER_IN_USE;
1147 return delete_printer_driver(info.info_3);
1151 /********************************************************************
1152 GetPrinterData on a printer server Handle.
1153 ********************************************************************/
1154 static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
1158 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
1160 if (!strcmp(value, "BeepEnabled")) {
1162 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1164 SIVAL(*data, 0, 0x01);
1169 if (!strcmp(value, "EventLog")) {
1171 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1173 SIVAL(*data, 0, 0x1B);
1178 if (!strcmp(value, "NetPopup")) {
1180 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1182 SIVAL(*data, 0, 0x01);
1187 if (!strcmp(value, "MajorVersion")) {
1189 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
1191 SIVAL(*data, 0, 0x02);
1196 if (!strcmp(value, "DefaultSpoolDirectory")) {
1197 pstring string="You are using a Samba server";
1199 *needed = 2*(strlen(string)+1);
1200 if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
1202 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
1204 /* it's done by hand ready to go on the wire */
1205 for (i=0; i<strlen(string); i++) {
1206 (*data)[2*i]=string[i];
1207 (*data)[2*i+1]='\0';
1212 if (!strcmp(value, "Architecture")) {
1213 pstring string="Windows NT x86";
1215 *needed = 2*(strlen(string)+1);
1216 if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
1218 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
1219 for (i=0; i<strlen(string); i++) {
1220 (*data)[2*i]=string[i];
1221 (*data)[2*i+1]='\0';
1229 /********************************************************************
1230 GetPrinterData on a printer Handle.
1231 ********************************************************************/
1232 static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND *handle,
1233 fstring value, uint32 *type,
1234 uint8 **data, uint32 *needed, uint32 in_size )
1236 NT_PRINTER_INFO_LEVEL *printer = NULL;
1240 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
1242 DEBUG(5,("getprinterdata_printer\n"));
1245 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
1249 if(!get_printer_snum(p, handle, &snum))
1252 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
1255 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
1256 free_a_printer(&printer, 2);
1260 free_a_printer(&printer, 2);
1262 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
1265 if((*data = (uint8 *)talloc(ctx, in_size *sizeof(uint8) )) == NULL) {
1269 memset(*data, 0, in_size *sizeof(uint8));
1270 /* copy the min(in_size, len) */
1271 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
1278 DEBUG(5,("getprinterdata_printer:copy done\n"));
1285 /********************************************************************
1286 * spoolss_getprinterdata
1287 ********************************************************************/
1289 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
1291 POLICY_HND *handle = &q_u->handle;
1292 UNISTR2 *valuename = &q_u->valuename;
1293 uint32 in_size = q_u->size;
1294 uint32 *type = &r_u->type;
1295 uint32 *out_size = &r_u->size;
1296 uint8 **data = &r_u->data;
1297 uint32 *needed = &r_u->needed;
1301 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
1304 * Reminder: when it's a string, the length is in BYTES
1305 * even if UNICODE is negociated.
1312 /* in case of problem, return some default values */
1316 DEBUG(4,("_spoolss_getprinterdata\n"));
1319 if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
1321 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
1325 unistr2_to_ascii(value, valuename, sizeof(value)-1);
1327 if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
1328 found=getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
1330 found= getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
1333 DEBUG(5, ("value not found, allocating %d\n", *out_size));
1334 /* reply this param doesn't exist */
1336 if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
1342 return WERR_INVALID_PARAM;
1345 if (*needed > *out_size)
1346 return WERR_STATUS_MORE_ENTRIES;
1352 /***************************************************************************
1353 connect to the client
1354 ****************************************************************************/
1355 static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle)
1360 * If it's the first connection, contact the client
1361 * and connect to the IPC$ share anonumously
1363 if (smb_connections==0) {
1364 fstring unix_printer;
1366 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
1368 if(!spoolss_connect_to_client(&cli, unix_printer))
1370 message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message);
1376 if(!cli_spoolss_reply_open_printer(&cli, printer, localprinter, type, &status, handle))
1382 /********************************************************************
1384 * ReplyFindFirstPrinterChangeNotifyEx
1386 * jfmxxxx: before replying OK: status=0
1387 * should do a rpc call to the workstation asking ReplyOpenPrinter
1388 * have to code it, later.
1390 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
1391 * called from api_spoolss_rffpcnex
1392 ********************************************************************/
1394 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
1396 POLICY_HND *handle = &q_u->handle;
1397 uint32 flags = q_u->flags;
1398 uint32 options = q_u->options;
1399 UNISTR2 *localmachine = &q_u->localmachine;
1400 uint32 printerlocal = q_u->printerlocal;
1401 SPOOL_NOTIFY_OPTION *option = q_u->option;
1403 /* store the notify value in the printer struct */
1405 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1408 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
1412 Printer->notify.flags=flags;
1413 Printer->notify.options=options;
1414 Printer->notify.printerlocal=printerlocal;
1416 if (Printer->notify.option)
1417 free_spool_notify_option(&Printer->notify.option);
1419 Printer->notify.option=dup_spool_notify_option(option);
1421 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
1423 /* connect to the client machine and send a ReplyOpenPrinter */
1424 if(srv_spoolss_replyopenprinter(Printer->notify.localmachine,
1425 Printer->notify.printerlocal, 1,
1426 &Printer->notify.client_hnd))
1427 Printer->notify.client_connected=True;
1432 /*******************************************************************
1433 * fill a notify_info_data with the servername
1434 ********************************************************************/
1436 static void spoolss_notify_server_name(int snum,
1437 SPOOL_NOTIFY_INFO_DATA *data,
1438 print_queue_struct *queue,
1439 NT_PRINTER_INFO_LEVEL *printer,
1440 TALLOC_CTX *mem_ctx)
1442 pstring temp_name, temp;
1445 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
1447 len = rpcstr_push(temp, temp_name, sizeof(temp)-2, 0);
1449 data->notify_data.data.length = len / 2 - 1;
1450 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1452 if (!data->notify_data.data.string) {
1453 data->notify_data.data.length = 0;
1457 memcpy(data->notify_data.data.string, temp, len);
1460 /*******************************************************************
1461 * fill a notify_info_data with the printername (not including the servername).
1462 ********************************************************************/
1463 static void spoolss_notify_printer_name(int snum,
1464 SPOOL_NOTIFY_INFO_DATA *data,
1465 print_queue_struct *queue,
1466 NT_PRINTER_INFO_LEVEL *printer,
1467 TALLOC_CTX *mem_ctx)
1472 /* the notify name should not contain the \\server\ part */
1473 char *p = strrchr_m(printer->info_2->printername, '\\');
1476 p = printer->info_2->printername;
1481 len = rpcstr_push(temp, p, sizeof(temp)-2, 0);
1482 data->notify_data.data.length = len / 2 - 1;
1483 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1485 if (!data->notify_data.data.string) {
1486 data->notify_data.data.length = 0;
1490 memcpy(data->notify_data.data.string, temp, len);
1493 /*******************************************************************
1494 * fill a notify_info_data with the servicename
1495 ********************************************************************/
1496 static void spoolss_notify_share_name(int snum,
1497 SPOOL_NOTIFY_INFO_DATA *data,
1498 print_queue_struct *queue,
1499 NT_PRINTER_INFO_LEVEL *printer,
1500 TALLOC_CTX *mem_ctx)
1505 len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp) - 2, 0);
1507 data->notify_data.data.length = len / 2 - 1;
1508 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1510 if (!data->notify_data.data.string) {
1511 data->notify_data.data.length = 0;
1515 memcpy(data->notify_data.data.string, temp, len);
1518 /*******************************************************************
1519 * fill a notify_info_data with the port name
1520 ********************************************************************/
1521 static void spoolss_notify_port_name(int snum,
1522 SPOOL_NOTIFY_INFO_DATA *data,
1523 print_queue_struct *queue,
1524 NT_PRINTER_INFO_LEVEL *printer,
1525 TALLOC_CTX *mem_ctx)
1530 /* even if it's strange, that's consistant in all the code */
1532 len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp) - 2, 0);
1534 data->notify_data.data.length = len / 2 - 1;
1535 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1537 if (!data->notify_data.data.string) {
1538 data->notify_data.data.length = 0;
1542 memcpy(data->notify_data.data.string, temp, len);
1545 /*******************************************************************
1546 * fill a notify_info_data with the printername
1547 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
1548 * but it doesn't exist, have to see what to do
1549 ********************************************************************/
1550 static void spoolss_notify_driver_name(int snum,
1551 SPOOL_NOTIFY_INFO_DATA *data,
1552 print_queue_struct *queue,
1553 NT_PRINTER_INFO_LEVEL *printer,
1554 TALLOC_CTX *mem_ctx)
1559 len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp) - 2, 0);
1560 data->notify_data.data.length = len / 2 - 1;
1561 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1563 if (!data->notify_data.data.string) {
1564 data->notify_data.data.length = 0;
1568 memcpy(data->notify_data.data.string, temp, len);
1571 /*******************************************************************
1572 * fill a notify_info_data with the comment
1573 ********************************************************************/
1574 static void spoolss_notify_comment(int snum,
1575 SPOOL_NOTIFY_INFO_DATA *data,
1576 print_queue_struct *queue,
1577 NT_PRINTER_INFO_LEVEL *printer,
1578 TALLOC_CTX *mem_ctx)
1583 if (*printer->info_2->comment == '\0')
1584 len = rpcstr_push(temp, lp_comment(snum), sizeof(temp) - 2, 0);
1587 len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp) - 2, 0);
1589 data->notify_data.data.length = len / 2 - 1;
1590 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1592 if (!data->notify_data.data.string) {
1593 data->notify_data.data.length = 0;
1597 memcpy(data->notify_data.data.string, temp, len);
1600 /*******************************************************************
1601 * fill a notify_info_data with the comment
1602 * jfm:xxxx incorrect, have to create a new smb.conf option
1603 * location = "Room 1, floor 2, building 3"
1604 ********************************************************************/
1605 static void spoolss_notify_location(int snum,
1606 SPOOL_NOTIFY_INFO_DATA *data,
1607 print_queue_struct *queue,
1608 NT_PRINTER_INFO_LEVEL *printer,
1609 TALLOC_CTX *mem_ctx)
1614 len = rpcstr_push(temp, printer->info_2->location,sizeof(temp) - 2, 0);
1616 data->notify_data.data.length = len / 2 - 1;
1617 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1619 if (!data->notify_data.data.string) {
1620 data->notify_data.data.length = 0;
1624 memcpy(data->notify_data.data.string, temp, len);
1627 /*******************************************************************
1628 * fill a notify_info_data with the device mode
1629 * jfm:xxxx don't to it for know but that's a real problem !!!
1630 ********************************************************************/
1631 static void spoolss_notify_devmode(int snum,
1632 SPOOL_NOTIFY_INFO_DATA *data,
1633 print_queue_struct *queue,
1634 NT_PRINTER_INFO_LEVEL *printer,
1635 TALLOC_CTX *mem_ctx)
1639 /*******************************************************************
1640 * fill a notify_info_data with the separator file name
1641 * jfm:xxxx just return no file could add an option to smb.conf
1642 * separator file = "separator.txt"
1643 ********************************************************************/
1644 static void spoolss_notify_sepfile(int snum,
1645 SPOOL_NOTIFY_INFO_DATA *data,
1646 print_queue_struct *queue,
1647 NT_PRINTER_INFO_LEVEL *printer,
1648 TALLOC_CTX *mem_ctx)
1653 len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp) - 2, 0);
1655 data->notify_data.data.length = len / 2 - 1;
1656 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1658 if (!data->notify_data.data.string) {
1659 data->notify_data.data.length = 0;
1663 memcpy(data->notify_data.data.string, temp, len);
1666 /*******************************************************************
1667 * fill a notify_info_data with the print processor
1668 * jfm:xxxx return always winprint to indicate we don't do anything to it
1669 ********************************************************************/
1670 static void spoolss_notify_print_processor(int snum,
1671 SPOOL_NOTIFY_INFO_DATA *data,
1672 print_queue_struct *queue,
1673 NT_PRINTER_INFO_LEVEL *printer,
1674 TALLOC_CTX *mem_ctx)
1679 len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp) - 2, 0);
1681 data->notify_data.data.length = len / 2 - 1;
1682 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1684 if (!data->notify_data.data.string) {
1685 data->notify_data.data.length = 0;
1689 memcpy(data->notify_data.data.string, temp, len);
1692 /*******************************************************************
1693 * fill a notify_info_data with the print processor options
1694 * jfm:xxxx send an empty string
1695 ********************************************************************/
1696 static void spoolss_notify_parameters(int snum,
1697 SPOOL_NOTIFY_INFO_DATA *data,
1698 print_queue_struct *queue,
1699 NT_PRINTER_INFO_LEVEL *printer,
1700 TALLOC_CTX *mem_ctx)
1705 len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp) -
1708 data->notify_data.data.length = len / 2 - 1;
1709 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1711 if (!data->notify_data.data.string) {
1712 data->notify_data.data.length = 0;
1716 memcpy(data->notify_data.data.string, temp, len);
1719 /*******************************************************************
1720 * fill a notify_info_data with the data type
1721 * jfm:xxxx always send RAW as data type
1722 ********************************************************************/
1723 static void spoolss_notify_datatype(int snum,
1724 SPOOL_NOTIFY_INFO_DATA *data,
1725 print_queue_struct *queue,
1726 NT_PRINTER_INFO_LEVEL *printer,
1727 TALLOC_CTX *mem_ctx)
1732 len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, 0);
1734 data->notify_data.data.length = len / 2 - 1;
1735 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1737 if (!data->notify_data.data.string) {
1738 data->notify_data.data.length = 0;
1742 memcpy(data->notify_data.data.string, temp, len);
1745 /*******************************************************************
1746 * fill a notify_info_data with the security descriptor
1747 * jfm:xxxx send an null pointer to say no security desc
1748 * have to implement security before !
1749 ********************************************************************/
1750 static void spoolss_notify_security_desc(int snum,
1751 SPOOL_NOTIFY_INFO_DATA *data,
1752 print_queue_struct *queue,
1753 NT_PRINTER_INFO_LEVEL *printer,
1754 TALLOC_CTX *mem_ctx)
1756 data->notify_data.data.length=0;
1757 data->notify_data.data.string = NULL;
1760 /*******************************************************************
1761 * fill a notify_info_data with the attributes
1762 * jfm:xxxx a samba printer is always shared
1763 ********************************************************************/
1764 static void spoolss_notify_attributes(int snum,
1765 SPOOL_NOTIFY_INFO_DATA *data,
1766 print_queue_struct *queue,
1767 NT_PRINTER_INFO_LEVEL *printer,
1768 TALLOC_CTX *mem_ctx)
1770 data->notify_data.value[0] = printer->info_2->attributes;
1773 /*******************************************************************
1774 * fill a notify_info_data with the priority
1775 ********************************************************************/
1776 static void spoolss_notify_priority(int snum,
1777 SPOOL_NOTIFY_INFO_DATA *data,
1778 print_queue_struct *queue,
1779 NT_PRINTER_INFO_LEVEL *printer,
1780 TALLOC_CTX *mem_ctx)
1782 data->notify_data.value[0] = printer->info_2->priority;
1785 /*******************************************************************
1786 * fill a notify_info_data with the default priority
1787 ********************************************************************/
1788 static void spoolss_notify_default_priority(int snum,
1789 SPOOL_NOTIFY_INFO_DATA *data,
1790 print_queue_struct *queue,
1791 NT_PRINTER_INFO_LEVEL *printer,
1792 TALLOC_CTX *mem_ctx)
1794 data->notify_data.value[0] = printer->info_2->default_priority;
1797 /*******************************************************************
1798 * fill a notify_info_data with the start time
1799 ********************************************************************/
1800 static void spoolss_notify_start_time(int snum,
1801 SPOOL_NOTIFY_INFO_DATA *data,
1802 print_queue_struct *queue,
1803 NT_PRINTER_INFO_LEVEL *printer,
1804 TALLOC_CTX *mem_ctx)
1806 data->notify_data.value[0] = printer->info_2->starttime;
1809 /*******************************************************************
1810 * fill a notify_info_data with the until time
1811 ********************************************************************/
1812 static void spoolss_notify_until_time(int snum,
1813 SPOOL_NOTIFY_INFO_DATA *data,
1814 print_queue_struct *queue,
1815 NT_PRINTER_INFO_LEVEL *printer,
1816 TALLOC_CTX *mem_ctx)
1818 data->notify_data.value[0] = printer->info_2->untiltime;
1821 /*******************************************************************
1822 * fill a notify_info_data with the status
1823 ********************************************************************/
1824 static void spoolss_notify_status(int snum,
1825 SPOOL_NOTIFY_INFO_DATA *data,
1826 print_queue_struct *queue,
1827 NT_PRINTER_INFO_LEVEL *printer,
1828 TALLOC_CTX *mem_ctx)
1830 print_queue_struct *q=NULL;
1831 print_status_struct status;
1833 memset(&status, 0, sizeof(status));
1834 print_queue_status(snum, &q, &status);
1835 data->notify_data.value[0]=(uint32) status.status;
1839 /*******************************************************************
1840 * fill a notify_info_data with the number of jobs queued
1841 ********************************************************************/
1842 static void spoolss_notify_cjobs(int snum,
1843 SPOOL_NOTIFY_INFO_DATA *data,
1844 print_queue_struct *queue,
1845 NT_PRINTER_INFO_LEVEL *printer,
1846 TALLOC_CTX *mem_ctx)
1848 print_queue_struct *q=NULL;
1849 print_status_struct status;
1851 memset(&status, 0, sizeof(status));
1852 data->notify_data.value[0] = print_queue_status(snum, &q, &status);
1856 /*******************************************************************
1857 * fill a notify_info_data with the average ppm
1858 ********************************************************************/
1859 static void spoolss_notify_average_ppm(int snum,
1860 SPOOL_NOTIFY_INFO_DATA *data,
1861 print_queue_struct *queue,
1862 NT_PRINTER_INFO_LEVEL *printer,
1863 TALLOC_CTX *mem_ctx)
1865 /* always respond 8 pages per minutes */
1866 /* a little hard ! */
1867 data->notify_data.value[0] = printer->info_2->averageppm;
1870 /*******************************************************************
1871 * fill a notify_info_data with username
1872 ********************************************************************/
1873 static void spoolss_notify_username(int snum,
1874 SPOOL_NOTIFY_INFO_DATA *data,
1875 print_queue_struct *queue,
1876 NT_PRINTER_INFO_LEVEL *printer,
1877 TALLOC_CTX *mem_ctx)
1882 len = rpcstr_push(temp, queue->user, sizeof(temp) - 2, 0);
1885 data->notify_data.data.length = len / 2 - 1;
1886 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1888 if (!data->notify_data.data.string) {
1889 data->notify_data.data.length = 0;
1893 memcpy(data->notify_data.data.string, temp, len);
1896 /*******************************************************************
1897 * fill a notify_info_data with job status
1898 ********************************************************************/
1899 static void spoolss_notify_job_status(int snum,
1900 SPOOL_NOTIFY_INFO_DATA *data,
1901 print_queue_struct *queue,
1902 NT_PRINTER_INFO_LEVEL *printer,
1903 TALLOC_CTX *mem_ctx)
1905 data->notify_data.value[0]=nt_printj_status(queue->status);
1908 /*******************************************************************
1909 * fill a notify_info_data with job name
1910 ********************************************************************/
1911 static void spoolss_notify_job_name(int snum,
1912 SPOOL_NOTIFY_INFO_DATA *data,
1913 print_queue_struct *queue,
1914 NT_PRINTER_INFO_LEVEL *printer,
1915 TALLOC_CTX *mem_ctx)
1920 len = rpcstr_push(temp, queue->file, sizeof(temp) - 2, 0);
1922 data->notify_data.data.length = len / 2 - 1;
1923 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1925 if (!data->notify_data.data.string) {
1926 data->notify_data.data.length = 0;
1930 memcpy(data->notify_data.data.string, temp, len);
1933 /*******************************************************************
1934 * fill a notify_info_data with job status
1935 ********************************************************************/
1936 static void spoolss_notify_job_status_string(int snum,
1937 SPOOL_NOTIFY_INFO_DATA *data,
1938 print_queue_struct *queue,
1939 NT_PRINTER_INFO_LEVEL *printer,
1940 TALLOC_CTX *mem_ctx)
1943 * Now we're returning job status codes we just return a "" here. JRA.
1950 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
1953 switch (queue->status) {
1958 p = ""; /* NT provides the paused string */
1967 #endif /* NO LONGER NEEDED. */
1969 len = rpcstr_push(temp, p, sizeof(temp) - 2, 0);
1971 data->notify_data.data.length = len / 2 - 1;
1972 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
1974 if (!data->notify_data.data.string) {
1975 data->notify_data.data.length = 0;
1979 memcpy(data->notify_data.data.string, temp, len);
1982 /*******************************************************************
1983 * fill a notify_info_data with job time
1984 ********************************************************************/
1985 static void spoolss_notify_job_time(int snum,
1986 SPOOL_NOTIFY_INFO_DATA *data,
1987 print_queue_struct *queue,
1988 NT_PRINTER_INFO_LEVEL *printer,
1989 TALLOC_CTX *mem_ctx)
1991 data->notify_data.value[0]=0x0;
1994 /*******************************************************************
1995 * fill a notify_info_data with job size
1996 ********************************************************************/
1997 static void spoolss_notify_job_size(int snum,
1998 SPOOL_NOTIFY_INFO_DATA *data,
1999 print_queue_struct *queue,
2000 NT_PRINTER_INFO_LEVEL *printer,
2001 TALLOC_CTX *mem_ctx)
2003 data->notify_data.value[0]=queue->size;
2006 /*******************************************************************
2007 * fill a notify_info_data with job position
2008 ********************************************************************/
2009 static void spoolss_notify_job_position(int snum,
2010 SPOOL_NOTIFY_INFO_DATA *data,
2011 print_queue_struct *queue,
2012 NT_PRINTER_INFO_LEVEL *printer,
2013 TALLOC_CTX *mem_ctx)
2015 data->notify_data.value[0]=queue->job;
2018 /*******************************************************************
2019 * fill a notify_info_data with submitted time
2020 ********************************************************************/
2021 static void spoolss_notify_submitted_time(int snum,
2022 SPOOL_NOTIFY_INFO_DATA *data,
2023 print_queue_struct *queue,
2024 NT_PRINTER_INFO_LEVEL *printer,
2025 TALLOC_CTX *mem_ctx)
2031 t=gmtime(&queue->time);
2033 len = sizeof(SYSTEMTIME);
2035 data->notify_data.data.length = len/2 - 1;
2036 data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2038 if (!data->notify_data.data.string) {
2039 data->notify_data.data.length = 0;
2043 make_systemtime(&st, t);
2044 memcpy(data->notify_data.data.string,&st,len);
2049 struct s_notify_info_data_table
2055 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
2056 print_queue_struct *queue,
2057 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
2060 struct s_notify_info_data_table notify_info_data_table[] =
2062 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
2063 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
2064 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
2065 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
2066 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
2067 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
2068 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
2069 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
2070 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
2071 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
2072 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
2073 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
2074 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
2075 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
2076 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
2077 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
2078 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
2079 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
2080 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
2081 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
2082 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
2083 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
2084 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
2085 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
2086 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
2087 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
2088 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
2089 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
2090 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
2091 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
2092 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
2093 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
2094 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
2095 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
2096 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
2097 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
2098 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
2099 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
2100 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
2101 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
2102 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
2103 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
2104 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, spoolss_notify_submitted_time },
2105 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
2106 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
2107 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
2108 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
2109 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
2110 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
2111 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
2112 { END, END, "", END, NULL }
2115 /*******************************************************************
2116 return the size of info_data structure
2117 ********************************************************************/
2118 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
2122 while (notify_info_data_table[i].type != END)
2124 if ( (notify_info_data_table[i].type == type ) &&
2125 (notify_info_data_table[i].field == field ) )
2127 return (notify_info_data_table[i].size);
2134 /*******************************************************************
2135 return the type of notify_info_data
2136 ********************************************************************/
2137 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
2141 while (notify_info_data_table[i].type != END)
2143 if ( (notify_info_data_table[i].type == type ) &&
2144 (notify_info_data_table[i].field == field ) )
2146 if (notify_info_data_table[i].size == POINTER)
2160 /****************************************************************************
2161 ****************************************************************************/
2162 static int search_notify(uint16 type, uint16 field, int *value)
2167 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
2169 if ( (notify_info_data_table[j].type == type ) &&
2170 (notify_info_data_table[j].field == field ) )
2175 if ( found && (notify_info_data_table[j].fn != NULL) )
2181 /****************************************************************************
2182 ****************************************************************************/
2183 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
2185 info_data->type = type;
2186 info_data->field = field;
2187 info_data->reserved = 0;
2189 info_data->size = size_of_notify_info_data(type, field);
2190 info_data->enc_type = type_of_notify_info_data(type, field);
2194 /*******************************************************************
2196 * fill a notify_info struct with info asked
2198 ********************************************************************/
2199 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
2200 snum, SPOOL_NOTIFY_OPTION_TYPE
2201 *option_type, uint32 id,
2202 TALLOC_CTX *mem_ctx)
2208 SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
2209 NT_PRINTER_INFO_LEVEL *printer = NULL;
2210 print_queue_struct *queue=NULL;
2212 type=option_type->type;
2214 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
2215 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2216 option_type->count, lp_servicename(snum)));
2218 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2221 for(field_num=0; field_num<option_type->count; field_num++) {
2222 field = option_type->fields[field_num];
2223 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
2225 if (!search_notify(type, field, &j) )
2228 if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
2229 DEBUG(0,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
2232 else info->data = tid;
2234 current_data=&info->data[info->count];
2236 construct_info_data(current_data, type, field, id);
2238 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
2239 notify_info_data_table[j].name, snum, printer->info_2->printername ));
2241 notify_info_data_table[j].fn(snum, current_data, queue,
2247 free_a_printer(&printer, 2);
2251 /*******************************************************************
2253 * fill a notify_info struct with info asked
2255 ********************************************************************/
2256 static BOOL construct_notify_jobs_info(print_queue_struct *queue,
2257 SPOOL_NOTIFY_INFO *info,
2258 NT_PRINTER_INFO_LEVEL *printer,
2259 int snum, SPOOL_NOTIFY_OPTION_TYPE
2260 *option_type, uint32 id,
2261 TALLOC_CTX *mem_ctx)
2267 SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
2269 DEBUG(4,("construct_notify_jobs_info\n"));
2271 type = option_type->type;
2273 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
2274 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
2275 option_type->count));
2277 for(field_num=0; field_num<option_type->count; field_num++) {
2278 field = option_type->fields[field_num];
2280 if (!search_notify(type, field, &j) )
2283 if((tid=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
2284 DEBUG(0,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
2287 else info->data = tid;
2289 current_data=&(info->data[info->count]);
2291 construct_info_data(current_data, type, field, id);
2292 notify_info_data_table[j].fn(snum, current_data, queue,
2301 * JFM: The enumeration is not that simple, it's even non obvious.
2303 * let's take an example: I want to monitor the PRINTER SERVER for
2304 * the printer's name and the number of jobs currently queued.
2305 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
2306 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
2308 * I have 3 printers on the back of my server.
2310 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
2313 * 1 printer 1 name 1
2314 * 2 printer 1 cjob 1
2315 * 3 printer 2 name 2
2316 * 4 printer 2 cjob 2
2317 * 5 printer 3 name 3
2318 * 6 printer 3 name 3
2320 * that's the print server case, the printer case is even worse.
2323 /*******************************************************************
2325 * enumerate all printers on the printserver
2326 * fill a notify_info struct with info asked
2328 ********************************************************************/
2330 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
2331 SPOOL_NOTIFY_INFO *info,
2332 TALLOC_CTX *mem_ctx)
2335 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
2336 int n_services=lp_numservices();
2339 SPOOL_NOTIFY_OPTION *option;
2340 SPOOL_NOTIFY_OPTION_TYPE *option_type;
2342 DEBUG(4,("printserver_notify_info\n"));
2344 option=Printer->notify.option;
2350 for (i=0; i<option->count; i++) {
2351 option_type=&(option->ctr.type[i]);
2353 if (option_type->type!=PRINTER_NOTIFY_TYPE)
2356 for (snum=0; snum<n_services; snum++)
2357 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
2358 if (construct_notify_printer_info
2359 (info, snum, option_type, id, mem_ctx))
2364 * Debugging information, don't delete.
2367 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2368 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2369 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2371 for (i=0; i<info->count; i++) {
2372 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2373 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2374 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2381 /*******************************************************************
2383 * fill a notify_info struct with info asked
2385 ********************************************************************/
2386 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
2387 TALLOC_CTX *mem_ctx)
2390 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
2393 SPOOL_NOTIFY_OPTION *option;
2394 SPOOL_NOTIFY_OPTION_TYPE *option_type;
2396 print_queue_struct *queue=NULL;
2397 print_status_struct status;
2399 DEBUG(4,("printer_notify_info\n"));
2401 option=Printer->notify.option;
2407 get_printer_snum(p, hnd, &snum);
2409 for (i=0; i<option->count; i++) {
2410 option_type=&option->ctr.type[i];
2412 switch ( option_type->type ) {
2413 case PRINTER_NOTIFY_TYPE:
2414 if(construct_notify_printer_info(info, snum,
2420 case JOB_NOTIFY_TYPE: {
2421 NT_PRINTER_INFO_LEVEL *printer = NULL;
2423 memset(&status, 0, sizeof(status));
2424 count = print_queue_status(snum, &queue, &status);
2426 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2,
2427 lp_servicename(snum))))
2430 for (j=0; j<count; j++) {
2431 construct_notify_jobs_info(&queue[j], info,
2438 free_a_printer(&printer, 2);
2448 * Debugging information, don't delete.
2451 DEBUG(1,("dumping the NOTIFY_INFO\n"));
2452 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
2453 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
2455 for (i=0; i<info->count; i++) {
2456 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
2457 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
2458 info->data[i].id, info->data[i].size, info->data[i].enc_type));
2464 /********************************************************************
2466 ********************************************************************/
2468 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
2470 POLICY_HND *handle = &q_u->handle;
2471 /* uint32 change = q_u->change; - notused. */
2472 /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
2473 SPOOL_NOTIFY_INFO *info = &r_u->info;
2475 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2476 WERROR result = WERR_BADFID;
2478 /* we always have a NOTIFY_INFO struct */
2482 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",
2483 OUR_HANDLE(handle)));
2487 DEBUG(4,("Printer type %x\n",Printer->printer_type));
2489 /* jfm: the change value isn't used right now.
2490 * we will honour it when
2491 * a) we'll be able to send notification to the client
2492 * b) we'll have a way to communicate between the spoolss process.
2494 * same thing for option->flags
2495 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
2496 * I don't have a global notification system, I'm sending back all the
2497 * informations even when _NOTHING_ has changed.
2500 /* just ignore the SPOOL_NOTIFY_OPTION */
2502 switch (Printer->printer_type) {
2503 case PRINTER_HANDLE_IS_PRINTSERVER:
2504 result = printserver_notify_info(p, handle, info, p->mem_ctx);
2507 case PRINTER_HANDLE_IS_PRINTER:
2508 result = printer_notify_info(p, handle, info, p->mem_ctx);
2516 /********************************************************************
2517 * construct_printer_info_0
2518 * fill a printer_info_0 struct
2519 ********************************************************************/
2520 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
2524 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2525 counter_printer_0 *session_counter;
2526 uint32 global_counter;
2530 print_queue_struct *queue=NULL;
2531 print_status_struct status;
2533 memset(&status, 0, sizeof(status));
2535 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2538 count = print_queue_status(snum, &queue, &status);
2540 /* check if we already have a counter for this printer */
2541 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
2543 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
2544 if (session_counter->snum == snum)
2548 /* it's the first time, add it to the list */
2549 if (session_counter==NULL) {
2550 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
2551 free_a_printer(&ntprinter, 2);
2554 ZERO_STRUCTP(session_counter);
2555 session_counter->snum=snum;
2556 session_counter->counter=0;
2557 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
2561 session_counter->counter++;
2564 * the global_counter should be stored in a TDB as it's common to all the clients
2565 * and should be zeroed on samba startup
2567 global_counter=session_counter->counter;
2569 pstrcpy(chaine,ntprinter->info_2->printername);
2571 init_unistr(&printer->printername, chaine);
2573 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", global_myname);
2574 init_unistr(&printer->servername, chaine);
2576 printer->cjobs = count;
2577 printer->total_jobs = 0;
2578 printer->total_bytes = 0;
2580 setuptime = (time_t)ntprinter->info_2->setuptime;
2581 t=gmtime(&setuptime);
2583 printer->year = t->tm_year+1900;
2584 printer->month = t->tm_mon+1;
2585 printer->dayofweek = t->tm_wday;
2586 printer->day = t->tm_mday;
2587 printer->hour = t->tm_hour;
2588 printer->minute = t->tm_min;
2589 printer->second = t->tm_sec;
2590 printer->milliseconds = 0;
2592 printer->global_counter = global_counter;
2593 printer->total_pages = 0;
2594 printer->major_version = 0x0004; /* NT 4 */
2595 printer->build_version = 0x0565; /* build 1381 */
2596 printer->unknown7 = 0x1;
2597 printer->unknown8 = 0x0;
2598 printer->unknown9 = 0x0;
2599 printer->session_counter = session_counter->counter;
2600 printer->unknown11 = 0x0;
2601 printer->printer_errors = 0x0; /* number of print failure */
2602 printer->unknown13 = 0x0;
2603 printer->unknown14 = 0x1;
2604 printer->unknown15 = 0x024a; /* 586 Pentium ? */
2605 printer->unknown16 = 0x0;
2606 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
2607 printer->unknown18 = 0x0;
2608 printer->status = nt_printq_status(status.status);
2609 printer->unknown20 = 0x0;
2610 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
2611 printer->unknown22 = 0x0;
2612 printer->unknown23 = 0x6; /* 6 ???*/
2613 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
2614 printer->unknown25 = 0;
2615 printer->unknown26 = 0;
2616 printer->unknown27 = 0;
2617 printer->unknown28 = 0;
2618 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",global_myname, 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",global_myname, 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_queue_struct *queue=NULL;
2770 print_status_struct status;
2771 memset(&status, 0, sizeof(status));
2773 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2776 memset(&status, 0, sizeof(status));
2777 count = print_queue_status(snum, &queue, &status);
2779 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
2780 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
2781 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
2782 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
2783 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
2785 if (*ntprinter->info_2->comment == '\0')
2786 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
2788 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
2790 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
2791 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
2792 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
2793 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
2794 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
2796 printer->attributes = ntprinter->info_2->attributes;
2798 printer->priority = ntprinter->info_2->priority; /* priority */
2799 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
2800 printer->starttime = ntprinter->info_2->starttime; /* starttime */
2801 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
2802 printer->status = nt_printq_status(status.status); /* status */
2803 printer->cjobs = count; /* jobs */
2804 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
2806 if((printer->devmode = construct_dev_mode(snum)) == NULL) {
2807 DEBUG(8, ("Returning NULL Devicemode!\n"));
2810 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
2811 /* steal the printer info sec_desc structure. [badly done]. */
2812 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2813 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
2814 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
2815 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
2818 printer->secdesc = NULL;
2821 free_a_printer(&ntprinter, 2);
2826 /********************************************************************
2827 * construct_printer_info_3
2828 * fill a printer_info_3 struct
2829 ********************************************************************/
2830 static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum)
2832 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
2833 PRINTER_INFO_3 *printer = NULL;
2835 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
2839 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
2840 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
2844 ZERO_STRUCTP(printer);
2846 printer->flags = 4; /* These are the components of the SD we are returning. */
2847 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
2848 /* steal the printer info sec_desc structure. [badly done]. */
2849 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2853 * Set the flags for the components we are returning.
2856 if (printer->secdesc->owner_sid)
2857 printer->flags |= OWNER_SECURITY_INFORMATION;
2859 if (printer->secdesc->grp_sid)
2860 printer->flags |= GROUP_SECURITY_INFORMATION;
2862 if (printer->secdesc->dacl)
2863 printer->flags |= DACL_SECURITY_INFORMATION;
2865 if (printer->secdesc->sacl)
2866 printer->flags |= SACL_SECURITY_INFORMATION;
2869 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
2870 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
2871 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
2874 free_a_printer(&ntprinter, 2);
2876 *pp_printer = printer;
2880 /********************************************************************
2881 Spoolss_enumprinters.
2882 ********************************************************************/
2883 static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2887 int n_services=lp_numservices();
2888 PRINTER_INFO_1 *tp, *printers=NULL;
2889 PRINTER_INFO_1 current_prt;
2891 DEBUG(4,("enum_all_printers_info_1\n"));
2893 for (snum=0; snum<n_services; snum++) {
2894 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2895 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2897 if (construct_printer_info_1(flags, ¤t_prt, snum)) {
2898 if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
2899 DEBUG(0,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
2900 SAFE_FREE(printers);
2905 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2906 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
2912 /* check the required size. */
2913 for (i=0; i<*returned; i++)
2914 (*needed) += spoolss_size_printer_info_1(&printers[i]);
2916 if (!alloc_buffer_size(buffer, *needed))
2917 return WERR_INSUFFICIENT_BUFFER;
2919 /* fill the buffer with the structures */
2920 for (i=0; i<*returned; i++)
2921 smb_io_printer_info_1("", buffer, &printers[i], 0);
2924 SAFE_FREE(printers);
2926 if (*needed > offered) {
2928 return WERR_INSUFFICIENT_BUFFER;
2934 /********************************************************************
2935 enum_all_printers_info_1_local.
2936 *********************************************************************/
2937 static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2939 DEBUG(4,("enum_all_printers_info_1_local\n"));
2941 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2944 /********************************************************************
2945 enum_all_printers_info_1_name.
2946 *********************************************************************/
2947 static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2950 DEBUG(4,("enum_all_printers_info_1_name\n"));
2952 fstrcpy(temp, "\\\\");
2953 fstrcat(temp, global_myname);
2955 if (strequal(name, temp)) {
2956 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2959 return WERR_INVALID_NAME;
2962 /********************************************************************
2963 enum_all_printers_info_1_remote.
2964 *********************************************************************/
2965 static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2967 PRINTER_INFO_1 *printer;
2968 fstring printername;
2971 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2973 /* JFM: currently it's more a place holder than anything else.
2974 * In the spooler world there is a notion of server registration.
2975 * the print servers are registring (sp ?) on the PDC (in the same domain)
2977 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2980 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2985 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
2986 slprintf(desc, sizeof(desc)-1,"%s", global_myname);
2987 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
2989 init_unistr(&printer->description, desc);
2990 init_unistr(&printer->name, printername);
2991 init_unistr(&printer->comment, comment);
2992 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2994 /* check the required size. */
2995 *needed += spoolss_size_printer_info_1(printer);
2997 if (!alloc_buffer_size(buffer, *needed)) {
2999 return WERR_INSUFFICIENT_BUFFER;
3002 /* fill the buffer with the structures */
3003 smb_io_printer_info_1("", buffer, printer, 0);
3008 if (*needed > offered) {
3010 return WERR_INSUFFICIENT_BUFFER;
3016 /********************************************************************
3017 enum_all_printers_info_1_network.
3018 *********************************************************************/
3020 static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3022 DEBUG(4,("enum_all_printers_info_1_network\n"));
3024 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
3027 /********************************************************************
3028 * api_spoolss_enumprinters
3030 * called from api_spoolss_enumprinters (see this to understand)
3031 ********************************************************************/
3033 static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3037 int n_services=lp_numservices();
3038 PRINTER_INFO_2 *tp, *printers=NULL;
3039 PRINTER_INFO_2 current_prt;
3041 for (snum=0; snum<n_services; snum++) {
3042 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3043 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
3045 if (construct_printer_info_2(¤t_prt, snum)) {
3046 if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) {
3047 DEBUG(0,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
3048 SAFE_FREE(printers);
3053 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
3054 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
3060 /* check the required size. */
3061 for (i=0; i<*returned; i++)
3062 (*needed) += spoolss_size_printer_info_2(&printers[i]);
3064 if (!alloc_buffer_size(buffer, *needed)) {
3065 for (i=0; i<*returned; i++) {
3066 free_devmode(printers[i].devmode);
3068 SAFE_FREE(printers);
3069 return WERR_INSUFFICIENT_BUFFER;
3072 /* fill the buffer with the structures */
3073 for (i=0; i<*returned; i++)
3074 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
3077 for (i=0; i<*returned; i++) {
3078 free_devmode(printers[i].devmode);
3080 SAFE_FREE(printers);
3082 if (*needed > offered) {
3084 return WERR_INSUFFICIENT_BUFFER;
3090 /********************************************************************
3091 * handle enumeration of printers at level 1
3092 ********************************************************************/
3093 static WERROR enumprinters_level1( uint32 flags, fstring name,
3094 NEW_BUFFER *buffer, uint32 offered,
3095 uint32 *needed, uint32 *returned)
3097 /* Not all the flags are equals */
3099 if (flags & PRINTER_ENUM_LOCAL)
3100 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
3102 if (flags & PRINTER_ENUM_NAME)
3103 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
3105 if (flags & PRINTER_ENUM_REMOTE)
3106 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
3108 if (flags & PRINTER_ENUM_NETWORK)
3109 return enum_all_printers_info_1_network(buffer, offered, needed, returned);
3111 return WERR_OK; /* NT4sp5 does that */
3114 /********************************************************************
3115 * handle enumeration of printers at level 2
3116 ********************************************************************/
3117 static WERROR enumprinters_level2( uint32 flags, fstring servername,
3118 NEW_BUFFER *buffer, uint32 offered,
3119 uint32 *needed, uint32 *returned)
3123 fstrcpy(temp, "\\\\");
3124 fstrcat(temp, global_myname);
3126 if (flags & PRINTER_ENUM_LOCAL) {
3127 if (strequal(servername, temp))
3128 return enum_all_printers_info_2(buffer, offered, needed, returned);
3130 return enum_all_printers_info_2(buffer, offered, needed, returned);
3133 if (flags & PRINTER_ENUM_NAME) {
3134 if (strequal(servername, temp))
3135 return enum_all_printers_info_2(buffer, offered, needed, returned);
3137 return WERR_INVALID_NAME;
3140 if (flags & PRINTER_ENUM_REMOTE)
3141 return WERR_UNKNOWN_LEVEL;
3146 /********************************************************************
3147 * handle enumeration of printers at level 5
3148 ********************************************************************/
3149 static WERROR enumprinters_level5( uint32 flags, fstring servername,
3150 NEW_BUFFER *buffer, uint32 offered,
3151 uint32 *needed, uint32 *returned)
3153 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
3157 /********************************************************************
3158 * api_spoolss_enumprinters
3160 * called from api_spoolss_enumprinters (see this to understand)
3161 ********************************************************************/
3163 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
3165 uint32 flags = q_u->flags;
3166 UNISTR2 *servername = &q_u->servername;
3167 uint32 level = q_u->level;
3168 NEW_BUFFER *buffer = NULL;
3169 uint32 offered = q_u->offered;
3170 uint32 *needed = &r_u->needed;
3171 uint32 *returned = &r_u->returned;
3174 /* that's an [in out] buffer */
3175 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3176 buffer = r_u->buffer;
3178 DEBUG(4,("_spoolss_enumprinters\n"));
3185 * flags==PRINTER_ENUM_NAME
3186 * if name=="" then enumerates all printers
3187 * if name!="" then enumerate the printer
3188 * flags==PRINTER_ENUM_REMOTE
3189 * name is NULL, enumerate printers
3190 * Level 2: name!="" enumerates printers, name can't be NULL
3191 * Level 3: doesn't exist
3192 * Level 4: does a local registry lookup
3193 * Level 5: same as Level 2
3196 unistr2_to_ascii(name, servername, sizeof(name)-1);
3201 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
3203 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
3205 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
3210 return WERR_UNKNOWN_LEVEL;
3213 /****************************************************************************
3214 ****************************************************************************/
3215 static WERROR getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3217 PRINTER_INFO_0 *printer=NULL;
3219 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
3222 construct_printer_info_0(printer, snum);
3224 /* check the required size. */
3225 *needed += spoolss_size_printer_info_0(printer);
3227 if (!alloc_buffer_size(buffer, *needed)) {
3229 return WERR_INSUFFICIENT_BUFFER;
3232 /* fill the buffer with the structures */
3233 smb_io_printer_info_0("", buffer, printer, 0);
3238 if (*needed > offered) {
3239 return WERR_INSUFFICIENT_BUFFER;
3245 /****************************************************************************
3246 ****************************************************************************/
3247 static WERROR getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3249 PRINTER_INFO_1 *printer=NULL;
3251 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
3254 construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum);
3256 /* check the required size. */
3257 *needed += spoolss_size_printer_info_1(printer);
3259 if (!alloc_buffer_size(buffer, *needed)) {
3261 return WERR_INSUFFICIENT_BUFFER;
3264 /* fill the buffer with the structures */
3265 smb_io_printer_info_1("", buffer, printer, 0);
3270 if (*needed > offered) {
3271 return WERR_INSUFFICIENT_BUFFER;
3277 /****************************************************************************
3278 ****************************************************************************/
3279 static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3281 PRINTER_INFO_2 *printer=NULL;
3283 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
3286 construct_printer_info_2(printer, snum);
3288 /* check the required size. */
3289 *needed += spoolss_size_printer_info_2(printer);
3291 if (!alloc_buffer_size(buffer, *needed)) {
3292 free_printer_info_2(printer);
3293 return WERR_INSUFFICIENT_BUFFER;
3296 /* fill the buffer with the structures */
3297 if (!smb_io_printer_info_2("", buffer, printer, 0)) {
3298 free_printer_info_2(printer);
3303 free_printer_info_2(printer);
3305 if (*needed > offered) {
3306 return WERR_INSUFFICIENT_BUFFER;
3312 /****************************************************************************
3313 ****************************************************************************/
3314 static WERROR getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3316 PRINTER_INFO_3 *printer=NULL;
3318 if (!construct_printer_info_3(&printer, snum))
3321 /* check the required size. */
3322 *needed += spoolss_size_printer_info_3(printer);
3324 if (!alloc_buffer_size(buffer, *needed)) {
3325 free_printer_info_3(printer);
3326 return WERR_INSUFFICIENT_BUFFER;
3329 /* fill the buffer with the structures */
3330 smb_io_printer_info_3("", buffer, printer, 0);
3333 free_printer_info_3(printer);
3335 if (*needed > offered) {
3336 return WERR_INSUFFICIENT_BUFFER;
3342 /****************************************************************************
3343 ****************************************************************************/
3345 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
3347 POLICY_HND *handle = &q_u->handle;
3348 uint32 level = q_u->level;
3349 NEW_BUFFER *buffer = NULL;
3350 uint32 offered = q_u->offered;
3351 uint32 *needed = &r_u->needed;
3355 /* that's an [in out] buffer */
3356 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3357 buffer = r_u->buffer;
3361 if (!get_printer_snum(p, handle, &snum))
3366 return getprinter_level_0(snum, buffer, offered, needed);
3368 return getprinter_level_1(snum, buffer, offered, needed);
3370 return getprinter_level_2(snum, buffer, offered, needed);
3372 return getprinter_level_3(snum, buffer, offered, needed);
3374 return WERR_UNKNOWN_LEVEL;
3377 /********************************************************************
3378 * fill a DRIVER_INFO_1 struct
3379 ********************************************************************/
3380 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
3382 init_unistr( &info->name, driver.info_3->name);
3385 /********************************************************************
3386 * construct_printer_driver_info_1
3387 ********************************************************************/
3388 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
3390 NT_PRINTER_INFO_LEVEL *printer = NULL;
3391 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3393 ZERO_STRUCT(driver);
3395 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3396 return WERR_INVALID_PRINTER_NAME;
3398 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
3399 return WERR_UNKNOWN_PRINTER_DRIVER;
3401 fill_printer_driver_info_1(info, driver, servername, architecture);
3403 free_a_printer(&printer,2);
3408 /********************************************************************
3409 * construct_printer_driver_info_2
3410 * fill a printer_info_2 struct
3411 ********************************************************************/
3412 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3416 info->version=driver.info_3->cversion;
3418 init_unistr( &info->name, driver.info_3->name );
3419 init_unistr( &info->architecture, driver.info_3->environment );
3422 if (strlen(driver.info_3->driverpath)) {
3423 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3424 init_unistr( &info->driverpath, temp );
3426 init_unistr( &info->driverpath, "" );
3428 if (strlen(driver.info_3->datafile)) {
3429 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3430 init_unistr( &info->datafile, temp );
3432 init_unistr( &info->datafile, "" );
3434 if (strlen(driver.info_3->configfile)) {
3435 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3436 init_unistr( &info->configfile, temp );
3438 init_unistr( &info->configfile, "" );
3441 /********************************************************************
3442 * construct_printer_driver_info_2
3443 * fill a printer_info_2 struct
3444 ********************************************************************/
3445 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
3447 NT_PRINTER_INFO_LEVEL *printer = NULL;
3448 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3450 ZERO_STRUCT(printer);
3451 ZERO_STRUCT(driver);
3453 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3454 return WERR_INVALID_PRINTER_NAME;
3456 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
3457 return WERR_UNKNOWN_PRINTER_DRIVER;
3459 fill_printer_driver_info_2(info, driver, servername);
3461 free_a_printer(&printer,2);
3466 /********************************************************************
3467 * copy a strings array and convert to UNICODE
3469 * convert an array of ascii string to a UNICODE string
3470 ********************************************************************/
3471 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
3479 DEBUG(6,("init_unistr_array\n"));
3483 if (char_array == NULL)
3487 if (!v) v = ""; /* hack to handle null lists */
3489 if (strlen(v) == 0) break;
3490 slprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
3491 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
3492 if((tuary=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
3493 DEBUG(0,("init_unistr_array: Realloc error\n" ));
3496 else *uni_array = tuary;
3497 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, 0)/ sizeof(uint16));
3502 (*uni_array)[j]=0x0000;
3505 DEBUGADD(6,("last one:done\n"));
3508 /********************************************************************
3509 * construct_printer_info_3
3510 * fill a printer_info_3 struct
3511 ********************************************************************/
3512 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3518 info->version=driver.info_3->cversion;
3520 init_unistr( &info->name, driver.info_3->name );
3521 init_unistr( &info->architecture, driver.info_3->environment );
3523 if (strlen(driver.info_3->driverpath)) {
3524 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3525 init_unistr( &info->driverpath, temp );
3527 init_unistr( &info->driverpath, "" );
3529 if (strlen(driver.info_3->datafile)) {
3530 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3531 init_unistr( &info->datafile, temp );
3533 init_unistr( &info->datafile, "" );
3535 if (strlen(driver.info_3->configfile)) {
3536 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3537 init_unistr( &info->configfile, temp );
3539 init_unistr( &info->configfile, "" );
3541 if (strlen(driver.info_3->helpfile)) {
3542 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
3543 init_unistr( &info->helpfile, temp );
3545 init_unistr( &info->helpfile, "" );
3547 init_unistr( &info->monitorname, driver.info_3->monitorname );
3548 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
3550 info->dependentfiles=NULL;
3551 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
3554 /********************************************************************
3555 * construct_printer_info_3
3556 * fill a printer_info_3 struct
3557 ********************************************************************/
3558 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
3560 NT_PRINTER_INFO_LEVEL *printer = NULL;
3561 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3563 ZERO_STRUCT(driver);
3565 status=get_a_printer(&printer, 2, lp_servicename(snum) );
3566 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status)));
3567 if (!W_ERROR_IS_OK(status))
3568 return WERR_INVALID_PRINTER_NAME;
3570 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
3571 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status)));
3572 if (!W_ERROR_IS_OK(status)) {
3573 free_a_printer(&printer,2);
3574 return WERR_UNKNOWN_PRINTER_DRIVER;
3577 fill_printer_driver_info_3(info, driver, servername);
3579 free_a_printer(&printer,2);
3584 /********************************************************************
3585 * construct_printer_info_6
3586 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
3587 ********************************************************************/
3589 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
3595 memset(&nullstr, '\0', sizeof(fstring));
3597 info->version=driver.info_3->cversion;
3599 init_unistr( &info->name, driver.info_3->name );
3600 init_unistr( &info->architecture, driver.info_3->environment );
3602 if (strlen(driver.info_3->driverpath)) {
3603 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
3604 init_unistr( &info->driverpath, temp );
3606 init_unistr( &info->driverpath, "" );
3608 if (strlen(driver.info_3->datafile)) {
3609 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
3610 init_unistr( &info->datafile, temp );
3612 init_unistr( &info->datafile, "" );
3614 if (strlen(driver.info_3->configfile)) {
3615 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
3616 init_unistr( &info->configfile, temp );
3618 init_unistr( &info->configfile, "" );
3620 if (strlen(driver.info_3->helpfile)) {
3621 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
3622 init_unistr( &info->helpfile, temp );
3624 init_unistr( &info->helpfile, "" );
3626 init_unistr( &info->monitorname, driver.info_3->monitorname );
3627 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
3629 info->dependentfiles=NULL;
3630 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
3632 info->previousdrivernames=NULL;
3633 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
3635 info->driver_date.low=0;
3636 info->driver_date.high=0;
3639 info->driver_version_low=0;
3640 info->driver_version_high=0;
3642 init_unistr( &info->mfgname, "");
3643 init_unistr( &info->oem_url, "");
3644 init_unistr( &info->hardware_id, "");
3645 init_unistr( &info->provider, "");
3648 /********************************************************************
3649 * construct_printer_info_6
3650 * fill a printer_info_6 struct
3651 ********************************************************************/
3652 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
3654 NT_PRINTER_INFO_LEVEL *printer = NULL;
3655 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3657 ZERO_STRUCT(driver);
3659 status=get_a_printer(&printer, 2, lp_servicename(snum) );
3660 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
3661 if (!W_ERROR_IS_OK(status))
3662 return WERR_INVALID_PRINTER_NAME;
3664 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
3665 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
3666 if (!W_ERROR_IS_OK(status)) {
3668 * Is this a W2k client ?
3672 free_a_printer(&printer,2);
3673 return WERR_UNKNOWN_PRINTER_DRIVER;
3676 /* Yes - try again with a WinNT driver. */
3678 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
3679 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
3680 if (!W_ERROR_IS_OK(status)) {
3681 free_a_printer(&printer,2);
3682 return WERR_UNKNOWN_PRINTER_DRIVER;
3686 fill_printer_driver_info_6(info, driver, servername);
3688 free_a_printer(&printer,2);
3693 /****************************************************************************
3694 ****************************************************************************/
3696 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
3698 SAFE_FREE(info->dependentfiles);
3701 /****************************************************************************
3702 ****************************************************************************/
3704 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
3706 SAFE_FREE(info->dependentfiles);
3710 /****************************************************************************
3711 ****************************************************************************/
3712 static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3714 DRIVER_INFO_1 *info=NULL;
3717 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
3720 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
3721 if (!W_ERROR_IS_OK(status)) {
3726 /* check the required size. */
3727 *needed += spoolss_size_printer_driver_info_1(info);
3729 if (!alloc_buffer_size(buffer, *needed)) {
3731 return WERR_INSUFFICIENT_BUFFER;
3734 /* fill the buffer with the structures */
3735 smb_io_printer_driver_info_1("", buffer, info, 0);
3740 if (*needed > offered)
3741 return WERR_INSUFFICIENT_BUFFER;
3746 /****************************************************************************
3747 ****************************************************************************/
3748 static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3750 DRIVER_INFO_2 *info=NULL;
3753 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
3756 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
3757 if (!W_ERROR_IS_OK(status)) {
3762 /* check the required size. */
3763 *needed += spoolss_size_printer_driver_info_2(info);
3765 if (!alloc_buffer_size(buffer, *needed)) {
3767 return WERR_INSUFFICIENT_BUFFER;
3770 /* fill the buffer with the structures */
3771 smb_io_printer_driver_info_2("", buffer, info, 0);
3776 if (*needed > offered)
3777 return WERR_INSUFFICIENT_BUFFER;
3782 /****************************************************************************
3783 ****************************************************************************/
3784 static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3791 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
3792 if (!W_ERROR_IS_OK(status)) {
3796 /* check the required size. */
3797 *needed += spoolss_size_printer_driver_info_3(&info);
3799 if (!alloc_buffer_size(buffer, *needed)) {
3800 free_printer_driver_info_3(&info);
3801 return WERR_INSUFFICIENT_BUFFER;
3804 /* fill the buffer with the structures */
3805 smb_io_printer_driver_info_3("", buffer, &info, 0);
3807 free_printer_driver_info_3(&info);
3809 if (*needed > offered)
3810 return WERR_INSUFFICIENT_BUFFER;
3815 /****************************************************************************
3816 ****************************************************************************/
3817 static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3824 status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
3825 if (!W_ERROR_IS_OK(status)) {
3829 /* check the required size. */
3830 *needed += spoolss_size_printer_driver_info_6(&info);
3832 if (!alloc_buffer_size(buffer, *needed)) {
3833 free_printer_driver_info_6(&info);
3834 return WERR_INSUFFICIENT_BUFFER;
3837 /* fill the buffer with the structures */
3838 smb_io_printer_driver_info_6("", buffer, &info, 0);
3840 free_printer_driver_info_6(&info);
3842 if (*needed > offered)
3843 return WERR_INSUFFICIENT_BUFFER;
3848 /****************************************************************************
3849 ****************************************************************************/
3851 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
3853 POLICY_HND *handle = &q_u->handle;
3854 UNISTR2 *uni_arch = &q_u->architecture;
3855 uint32 level = q_u->level;
3856 uint32 clientmajorversion = q_u->clientmajorversion;
3857 /* uint32 clientminorversion = q_u->clientminorversion; - notused. */
3858 NEW_BUFFER *buffer = NULL;
3859 uint32 offered = q_u->offered;
3860 uint32 *needed = &r_u->needed;
3861 uint32 *servermajorversion = &r_u->servermajorversion;
3862 uint32 *serverminorversion = &r_u->serverminorversion;
3865 fstring architecture;
3868 /* that's an [in out] buffer */
3869 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
3870 buffer = r_u->buffer;
3872 DEBUG(4,("_spoolss_getprinterdriver2\n"));
3875 *servermajorversion=0;
3876 *serverminorversion=0;
3878 pstrcpy(servername, global_myname);
3879 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
3881 if (!get_printer_snum(p, handle, &snum))
3886 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3888 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3890 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3892 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
3894 return WERR_UNKNOWN_LEVEL;
3897 /****************************************************************************
3898 ****************************************************************************/
3900 WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u)
3902 POLICY_HND *handle = &q_u->handle;
3904 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
3907 Printer->page_started=True;
3911 DEBUG(3,("Error in startpageprinter printer handle\n"));
3915 /****************************************************************************
3916 ****************************************************************************/
3918 WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u)
3920 POLICY_HND *handle = &q_u->handle;
3922 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
3925 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
3929 Printer->page_started=False;
3934 /********************************************************************
3935 * api_spoolss_getprinter
3936 * called from the spoolss dispatcher
3938 ********************************************************************/
3940 WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
3942 POLICY_HND *handle = &q_u->handle;
3943 /* uint32 level = q_u->doc_info_container.level; - notused. */
3944 DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
3945 uint32 *jobid = &r_u->jobid;
3947 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
3951 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
3952 struct current_user user;
3955 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3959 get_current_user(&user, p);
3962 * a nice thing with NT is it doesn't listen to what you tell it.
3963 * when asked to send _only_ RAW datas, it tries to send datas
3966 * So I add checks like in NT Server ...
3968 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
3969 * there's a bug in NT client-side code, so we'll fix it in the
3970 * server-side code. *nnnnnggggh!*
3973 if (info_1->p_datatype != 0) {
3974 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
3975 if (strcmp(datatype, "RAW") != 0) {
3977 return WERR_INVALID_DATATYPE;
3981 /* get the share number of the printer */
3982 if (!get_printer_snum(p, handle, &snum)) {
3986 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
3988 Printer->jobid = print_job_start(&user, snum, jobname);
3990 /* An error occured in print_job_start() so return an appropriate
3993 if (Printer->jobid == -1) {
3994 return map_werror_from_unix(errno);
3997 Printer->document_started=True;
3998 (*jobid) = Printer->jobid;
4003 /********************************************************************
4004 * api_spoolss_getprinter
4005 * called from the spoolss dispatcher
4007 ********************************************************************/
4009 WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u)
4011 POLICY_HND *handle = &q_u->handle;
4013 return _spoolss_enddocprinter_internal(p, handle);
4016 /****************************************************************************
4017 ****************************************************************************/
4019 WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u)
4021 POLICY_HND *handle = &q_u->handle;
4022 uint32 buffer_size = q_u->buffer_size;
4023 uint8 *buffer = q_u->buffer;
4024 uint32 *buffer_written = &q_u->buffer_size2;
4026 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4029 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
4030 r_u->buffer_written = q_u->buffer_size2;
4034 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer, buffer_size);
4037 r_u->buffer_written = q_u->buffer_size2;
4042 /********************************************************************
4043 * api_spoolss_getprinter
4044 * called from the spoolss dispatcher
4046 ********************************************************************/
4047 static WERROR control_printer(POLICY_HND *handle, uint32 command,
4050 struct current_user user;
4052 WERROR errcode = WERR_BADFUNC;
4053 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4055 get_current_user(&user, p);
4058 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
4062 if (!get_printer_snum(p, handle, &snum))
4066 case PRINTER_CONTROL_PAUSE:
4067 if (print_queue_pause(&user, snum, &errcode)) {
4071 case PRINTER_CONTROL_RESUME:
4072 case PRINTER_CONTROL_UNPAUSE:
4073 if (print_queue_resume(&user, snum, &errcode)) {
4077 case PRINTER_CONTROL_PURGE:
4078 if (print_queue_purge(&user, snum, &errcode)) {
4083 return WERR_UNKNOWN_LEVEL;
4089 /********************************************************************
4090 * api_spoolss_abortprinter
4091 ********************************************************************/
4093 WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u)
4095 POLICY_HND *handle = &q_u->handle;
4097 return control_printer(handle, PRINTER_CONTROL_PURGE, p);
4100 /********************************************************************
4101 * called by spoolss_api_setprinter
4102 * when updating a printer description
4103 ********************************************************************/
4104 static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
4105 const SPOOL_PRINTER_INFO_LEVEL *info,
4106 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
4108 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
4109 struct current_user user;
4113 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4115 if (!Printer || !get_printer_snum(p, handle, &snum)) {
4116 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n",
4117 OUR_HANDLE(handle)));
4119 result = WERR_BADFID;
4123 /* NT seems to like setting the security descriptor even though
4124 nothing may have actually changed. This causes annoying
4125 dialog boxes when the user doesn't have permission to change
4126 the security descriptor. */
4128 nt_printing_getsec(p->mem_ctx, Printer->dev.handlename, &old_secdesc_ctr);
4130 if (DEBUGLEVEL >= 10) {
4134 the_acl = old_secdesc_ctr->sec->dacl;
4135 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
4136 PRINTERNAME(snum), the_acl->num_aces));
4138 for (i = 0; i < the_acl->num_aces; i++) {
4141 sid_to_string(sid_str, &the_acl->ace[i].sid);
4143 DEBUG(10, ("%s 0x%08x\n", sid_str,
4144 the_acl->ace[i].info.mask));
4147 the_acl = secdesc_ctr->sec->dacl;
4150 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4151 PRINTERNAME(snum), the_acl->num_aces));
4153 for (i = 0; i < the_acl->num_aces; i++) {
4156 sid_to_string(sid_str, &the_acl->ace[i].sid);
4158 DEBUG(10, ("%s 0x%08x\n", sid_str,
4159 the_acl->ace[i].info.mask));
4162 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
4166 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
4168 if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
4173 /* Work out which user is performing the operation */
4175 get_current_user(&user, p);
4177 /* Check the user has permissions to change the security
4178 descriptor. By experimentation with two NT machines, the user
4179 requires Full Access to the printer to change security
4182 if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
4183 result = WERR_ACCESS_DENIED;
4187 result = nt_printing_setsec(Printer->dev.handlename, new_secdesc_ctr);
4194 /********************************************************************
4195 Do Samba sanity checks on a printer info struct.
4196 this has changed purpose: it now "canonicalises" printer
4197 info from a client rather than just checking it is correct
4198 ********************************************************************/
4200 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
4202 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
4203 info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
4205 /* we force some elements to "correct" values */
4206 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname);
4207 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
4208 global_myname, lp_servicename(snum));
4209 fstrcpy(info->sharename, lp_servicename(snum));
4210 info->attributes = PRINTER_ATTRIBUTE_SHARED \
4211 | PRINTER_ATTRIBUTE_LOCAL \
4212 | PRINTER_ATTRIBUTE_RAW_ONLY \
4213 | PRINTER_ATTRIBUTE_QUEUED ;
4218 /****************************************************************************
4219 ****************************************************************************/
4220 static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
4222 char *cmd = lp_addprinter_cmd();
4225 pstring driverlocation;
4230 /* build driver path... only 9X architecture is needed for legacy reasons */
4231 slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
4233 /* change \ to \\ for the shell */
4234 all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
4236 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4237 cmd, printer->info_2->printername, printer->info_2->sharename,
4238 printer->info_2->portname, printer->info_2->drivername,
4239 printer->info_2->location, driverlocation);
4241 DEBUG(10,("Running [%s]\n", command));
4242 ret = smbrun(command, &fd);
4243 DEBUGADD(10,("returned [%d]\n", ret));
4252 /* Get lines and convert them back to dos-codepage */
4253 qlines = fd_lines_load(fd, &numlines);
4254 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4258 /* Set the portname to what the script says the portname should be. */
4259 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
4260 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
4262 /* Send SIGHUP to process group... is there a better way? */
4267 file_lines_free(qlines);
4271 /* Return true if two devicemodes are equal */
4273 #define DEVMODE_CHECK_INT(field) \
4274 if (d1->field != d2->field) { \
4275 DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
4276 d1->field, d2->field)); \
4280 static BOOL nt_devicemode_equal(NT_DEVICEMODE *d1, NT_DEVICEMODE *d2)
4282 if (!d1 && !d2) goto equal; /* if both are NULL they are equal */
4285 DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
4286 return False; /* if either is exclusively NULL are not equal */
4289 if (!strequal(d1->devicename, d2->devicename)) {
4290 DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1->devicename, d2->devicename));
4294 if (!strequal(d1->formname, d2->formname)) {
4295 DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1->formname, d2->formname));
4299 DEVMODE_CHECK_INT(specversion);
4300 DEVMODE_CHECK_INT(driverversion);
4301 DEVMODE_CHECK_INT(driverextra);
4302 DEVMODE_CHECK_INT(orientation);
4303 DEVMODE_CHECK_INT(papersize);
4304 DEVMODE_CHECK_INT(paperlength);
4305 DEVMODE_CHECK_INT(paperwidth);
4306 DEVMODE_CHECK_INT(scale);
4307 DEVMODE_CHECK_INT(copies);
4308 DEVMODE_CHECK_INT(defaultsource);
4309 DEVMODE_CHECK_INT(printquality);
4310 DEVMODE_CHECK_INT(color);
4311 DEVMODE_CHECK_INT(duplex);
4312 DEVMODE_CHECK_INT(yresolution);
4313 DEVMODE_CHECK_INT(ttoption);
4314 DEVMODE_CHECK_INT(collate);
4315 DEVMODE_CHECK_INT(logpixels);
4317 DEVMODE_CHECK_INT(fields);
4318 DEVMODE_CHECK_INT(bitsperpel);
4319 DEVMODE_CHECK_INT(pelswidth);
4320 DEVMODE_CHECK_INT(pelsheight);
4321 DEVMODE_CHECK_INT(displayflags);
4322 DEVMODE_CHECK_INT(displayfrequency);
4323 DEVMODE_CHECK_INT(icmmethod);
4324 DEVMODE_CHECK_INT(icmintent);
4325 DEVMODE_CHECK_INT(mediatype);
4326 DEVMODE_CHECK_INT(dithertype);
4327 DEVMODE_CHECK_INT(reserved1);
4328 DEVMODE_CHECK_INT(reserved2);
4329 DEVMODE_CHECK_INT(panningwidth);
4330 DEVMODE_CHECK_INT(panningheight);
4332 /* compare the private data if it exists */
4333 if (!d1->driverextra && !d2->driverextra) goto equal;
4336 DEVMODE_CHECK_INT(driverextra);
4338 if (memcmp(d1->private, d2->private, d1->driverextra)) {
4339 DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
4344 DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
4348 /* Return true if two NT_PRINTER_PARAM structures are equal */
4350 static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
4351 NT_PRINTER_PARAM *p2)
4353 if (!p1 && !p2) goto equal;
4355 if ((!p1 && p2) || (p1 && !p2)) {
4356 DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
4360 /* Compare lists of printer parameters */
4364 NT_PRINTER_PARAM *q = p1;
4366 /* Find the parameter in the second structure */
4370 if (strequal(p1->value, q->value)) {
4372 if (p1->type != q->type) {
4373 DEBUG(10, ("nt_printer_param_equal():"
4374 "types for %s differ (%d != %d)\n",
4375 p1->value, p1->type,
4380 if (p1->data_len != q->data_len) {
4381 DEBUG(10, ("nt_printer_param_equal():"
4382 "len for %s differs (%d != %d)\n",
4383 p1->value, p1->data_len,
4388 if (memcmp(p1->data, q->data, p1->data_len) == 0) {
4391 DEBUG(10, ("nt_printer_param_equal():"
4392 "data for %s differs\n", p1->value));
4402 DEBUG(10, ("nt_printer_param_equal(): param %s "
4403 "does not exist\n", p1->value));
4412 DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
4416 /********************************************************************
4417 * Called by update_printer when trying to work out whether to
4418 * actually update printer info.
4419 ********************************************************************/
4421 #define PI_CHECK_INT(field) \
4422 if (pi1->field != pi2->field) { \
4423 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
4424 pi1->field, pi2->field)); \
4428 #define PI_CHECK_STR(field) \
4429 if (!strequal(pi1->field, pi2->field)) { \
4430 DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
4431 pi1->field, pi2->field)); \
4435 static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
4436 NT_PRINTER_INFO_LEVEL *p2)
4438 NT_PRINTER_INFO_LEVEL_2 *pi1, *pi2;
4440 /* Trivial conditions */
4442 if ((!p1 && !p2) || (!p1->info_2 && !p2->info_2)) {
4446 if ((!p1 && p2) || (p1 && !p2) ||
4447 (!p1->info_2 && p2->info_2) ||
4448 (p1->info_2 && !p2->info_2)) {
4449 DEBUG(10, ("nt_printer_info_level_equal(): info levels "
4454 /* Compare two nt_printer_info_level structures. Don't compare
4455 status or cjobs as they seem to have something to do with the
4461 /* Don't check the attributes as we stomp on the value in
4462 check_printer_ok() anyway. */
4465 PI_CHECK_INT(attributes);
4468 PI_CHECK_INT(priority);
4469 PI_CHECK_INT(default_priority);
4470 PI_CHECK_INT(starttime);
4471 PI_CHECK_INT(untiltime);
4472 PI_CHECK_INT(averageppm);
4474 /* Yuck - don't check the printername or servername as the
4475 add_a_printer() code plays games with them. You can't
4476 change the printername or the sharename through this interface
4479 PI_CHECK_STR(sharename);
4480 PI_CHECK_STR(portname);
4481 PI_CHECK_STR(drivername);
4482 PI_CHECK_STR(comment);
4483 PI_CHECK_STR(location);
4485 if (!nt_devicemode_equal(pi1->devmode, pi2->devmode)) {
4489 PI_CHECK_STR(sepfile);
4490 PI_CHECK_STR(printprocessor);
4491 PI_CHECK_STR(datatype);
4492 PI_CHECK_STR(parameters);
4494 if (!nt_printer_param_equal(pi1->specific, pi2->specific)) {
4498 if (!sec_desc_equal(pi1->secdesc_buf->sec, pi2->secdesc_buf->sec)) {
4502 PI_CHECK_INT(changeid);
4503 PI_CHECK_INT(c_setprinter);
4504 PI_CHECK_INT(setuptime);
4507 DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
4511 /********************************************************************
4512 * called by spoolss_api_setprinter
4513 * when updating a printer description
4514 ********************************************************************/
4516 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
4517 const SPOOL_PRINTER_INFO_LEVEL *info,
4518 DEVICEMODE *devmode)
4521 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
4522 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4525 DEBUG(8,("update_printer\n"));
4530 DEBUG(0,("Send a mail to samba@samba.org\n"));
4531 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
4532 result = WERR_UNKNOWN_LEVEL;
4537 result = WERR_BADFID;
4541 if (!get_printer_snum(p, handle, &snum)) {
4542 result = WERR_BADFID;
4546 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) ||
4547 (!W_ERROR_IS_OK(get_a_printer(&old_printer, 2, lp_servicename(snum))))) {
4548 result = WERR_BADFID;
4552 DEBUGADD(8,("Converting info_2 struct\n"));
4555 * convert_printer_info converts the incoming
4556 * info from the client and overwrites the info
4557 * just read from the tdb in the pointer 'printer'.
4560 convert_printer_info(info, printer, level);
4562 if (info->info_2->devmode_ptr != 0) {
4563 /* we have a valid devmode
4564 convert it and link it*/
4566 DEBUGADD(8,("Converting the devicemode struct\n"));
4567 if (!convert_devicemode(printer->info_2->printername, devmode,
4568 &printer->info_2->devmode)) {
4569 result = WERR_NOMEM;
4574 /* Do sanity check on the requested changes for Samba */
4576 if (!check_printer_ok(printer->info_2, snum)) {
4577 result = WERR_INVALID_PARAM;
4581 /* NT likes to call this function even though nothing has actually
4582 changed. Check this so the user doesn't end up with an
4583 annoying permission denied dialog box. */
4585 if (nt_printer_info_level_equal(printer, old_printer)) {
4586 DEBUG(3, ("printer info has not changed\n"));
4591 /* Check calling user has permission to update printer description */
4593 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4594 DEBUG(3, ("printer property change denied by security "
4596 result = WERR_ACCESS_DENIED;
4600 /* Call addprinter hook */
4602 if (*lp_addprinter_cmd()) {
4603 if (!add_printer_hook(printer)) {
4604 result = WERR_ACCESS_DENIED;
4609 /* Update printer info */
4610 result = add_a_printer(*printer, 2);
4613 free_a_printer(&printer, 2);
4614 free_a_printer(&old_printer, 2);
4616 srv_spoolss_sendnotify(p, handle);
4621 /****************************************************************************
4622 ****************************************************************************/
4624 WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
4626 POLICY_HND *handle = &q_u->handle;
4627 uint32 level = q_u->level;
4628 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
4629 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
4630 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
4631 uint32 command = q_u->command;
4633 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
4636 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
4640 /* check the level */
4643 return control_printer(handle, command, p);
4645 return update_printer(p, handle, level, info, devmode_ctr.devmode);
4647 return update_printer_sec(handle, level, info, p,
4650 return WERR_UNKNOWN_LEVEL;
4654 /****************************************************************************
4655 ****************************************************************************/
4657 WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
4659 POLICY_HND *handle = &q_u->handle;
4661 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
4664 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
4668 if (Printer->notify.client_connected==True)
4669 srv_spoolss_replycloseprinter(&Printer->notify.client_hnd);
4671 Printer->notify.flags=0;
4672 Printer->notify.options=0;
4673 Printer->notify.localmachine[0]='\0';
4674 Printer->notify.printerlocal=0;
4675 if (Printer->notify.option)
4676 free_spool_notify_option(&Printer->notify.option);
4677 Printer->notify.client_connected=False;
4682 /****************************************************************************
4683 ****************************************************************************/
4685 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
4687 /* that's an [in out] buffer (despite appearences to the contrary) */
4688 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
4691 return WERR_INVALID_PARAM; /* this is what a NT server
4692 returns for AddJob. AddJob
4693 must fail on non-local
4697 /****************************************************************************
4698 ****************************************************************************/
4699 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
4700 int position, int snum)
4706 t=gmtime(&queue->time);
4707 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
4709 job_info->jobid=queue->job;
4710 init_unistr(&job_info->printername, lp_servicename(snum));
4711 init_unistr(&job_info->machinename, temp_name);
4712 init_unistr(&job_info->username, queue->user);
4713 init_unistr(&job_info->document, queue->file);
4714 init_unistr(&job_info->datatype, "RAW");
4715 init_unistr(&job_info->text_status, "");
4716 job_info->status=nt_printj_status(queue->status);
4717 job_info->priority=queue->priority;
4718 job_info->position=position;
4719 job_info->totalpages=0;
4720 job_info->pagesprinted=0;
4722 make_systemtime(&job_info->submitted, t);
4725 /****************************************************************************
4726 ****************************************************************************/
4727 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
4728 int position, int snum,
4729 NT_PRINTER_INFO_LEVEL *ntprinter)
4735 t=gmtime(&queue->time);
4736 slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
4738 job_info->jobid=queue->job;
4740 slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
4742 init_unistr(&job_info->printername, chaine);
4744 init_unistr(&job_info->machinename, temp_name);
4745 init_unistr(&job_info->username, queue->user);
4746 init_unistr(&job_info->document, queue->file);
4747 init_unistr(&job_info->notifyname, queue->user);
4748 init_unistr(&job_info->datatype, "RAW");
4749 init_unistr(&job_info->printprocessor, "winprint");
4750 init_unistr(&job_info->parameters, "");
4751 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
4752 init_unistr(&job_info->text_status, "");
4754 /* and here the security descriptor */
4756 job_info->status=nt_printj_status(queue->status);
4757 job_info->priority=queue->priority;
4758 job_info->position=position;
4759 job_info->starttime=0;
4760 job_info->untiltime=0;
4761 job_info->totalpages=0;
4762 job_info->size=queue->size;
4763 make_systemtime(&(job_info->submitted), t);
4764 job_info->timeelapsed=0;
4765 job_info->pagesprinted=0;
4767 if((job_info->devmode = construct_dev_mode(snum)) == NULL) {
4774 /****************************************************************************
4775 Enumjobs at level 1.
4776 ****************************************************************************/
4777 static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
4778 NEW_BUFFER *buffer, uint32 offered,
4779 uint32 *needed, uint32 *returned)
4784 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
4791 for (i=0; i<*returned; i++)
4792 fill_job_info_1(&info[i], &queue[i], i, snum);
4796 /* check the required size. */
4797 for (i=0; i<*returned; i++)
4798 (*needed) += spoolss_size_job_info_1(&info[i]);
4800 if (!alloc_buffer_size(buffer, *needed)) {
4802 return WERR_INSUFFICIENT_BUFFER;
4805 /* fill the buffer with the structures */
4806 for (i=0; i<*returned; i++)
4807 smb_io_job_info_1("", buffer, &info[i], 0);
4812 if (*needed > offered) {
4814 return WERR_INSUFFICIENT_BUFFER;
4820 /****************************************************************************
4821 Enumjobs at level 2.
4822 ****************************************************************************/
4823 static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
4824 NEW_BUFFER *buffer, uint32 offered,
4825 uint32 *needed, uint32 *returned)
4827 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4832 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
4838 result = get_a_printer(&ntprinter, 2, lp_servicename(snum));
4839 if (!W_ERROR_IS_OK(result)) {
4844 for (i=0; i<*returned; i++)
4845 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter);
4847 free_a_printer(&ntprinter, 2);
4850 /* check the required size. */
4851 for (i=0; i<*returned; i++)
4852 (*needed) += spoolss_size_job_info_2(&info[i]);
4854 if (!alloc_buffer_size(buffer, *needed)) {
4856 return WERR_INSUFFICIENT_BUFFER;
4859 /* fill the buffer with the structures */
4860 for (i=0; i<*returned; i++)
4861 smb_io_job_info_2("", buffer, &info[i], 0);
4864 for (i = 0; i < *returned; i++)
4865 free_job_info_2(&info[i]);
4869 if (*needed > offered) {
4871 return WERR_INSUFFICIENT_BUFFER;
4877 /****************************************************************************
4879 ****************************************************************************/
4881 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
4883 POLICY_HND *handle = &q_u->handle;
4884 /* uint32 firstjob = q_u->firstjob; - notused. */
4885 /* uint32 numofjobs = q_u->numofjobs; - notused. */
4886 uint32 level = q_u->level;
4887 NEW_BUFFER *buffer = NULL;
4888 uint32 offered = q_u->offered;
4889 uint32 *needed = &r_u->needed;
4890 uint32 *returned = &r_u->returned;
4893 print_queue_struct *queue=NULL;
4894 print_status_struct prt_status;
4896 /* that's an [in out] buffer */
4897 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
4898 buffer = r_u->buffer;
4900 DEBUG(4,("_spoolss_enumjobs\n"));
4902 ZERO_STRUCT(prt_status);
4907 if (!get_printer_snum(p, handle, &snum))
4910 *returned = print_queue_status(snum, &queue, &prt_status);
4911 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
4913 if (*returned == 0) {
4920 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
4922 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
4926 return WERR_UNKNOWN_LEVEL;
4930 /****************************************************************************
4931 ****************************************************************************/
4933 WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
4938 /****************************************************************************
4939 ****************************************************************************/
4941 WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
4943 POLICY_HND *handle = &q_u->handle;
4944 uint32 jobid = q_u->jobid;
4945 /* uint32 level = q_u->level; - notused. */
4946 /* JOB_INFO *ctr = &q_u->ctr; - notused. */
4947 uint32 command = q_u->command;
4949 struct current_user user;
4950 print_status_struct prt_status;
4952 WERROR errcode = WERR_BADFUNC;
4954 memset(&prt_status, 0, sizeof(prt_status));
4956 if (!get_printer_snum(p, handle, &snum)) {
4960 if (!print_job_exists(jobid)) {
4961 return WERR_INVALID_PRINTER_NAME;
4964 get_current_user(&user, p);
4967 case JOB_CONTROL_CANCEL:
4968 case JOB_CONTROL_DELETE:
4969 if (print_job_delete(&user, jobid, &errcode)) {
4973 case JOB_CONTROL_PAUSE:
4974 if (print_job_pause(&user, jobid, &errcode)) {
4978 case JOB_CONTROL_RESTART:
4979 case JOB_CONTROL_RESUME:
4980 if (print_job_resume(&user, jobid, &errcode)) {
4985 return WERR_UNKNOWN_LEVEL;
4991 /****************************************************************************
4992 Enumerates all printer drivers at level 1.
4993 ****************************************************************************/
4994 static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4999 fstring *list = NULL;
5000 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5001 DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
5005 #define MAX_VERSION 4
5007 for (version=0; version<MAX_VERSION; version++) {
5009 ndrivers=get_ntdrivers(&list, architecture, version);
5010 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5016 if((tdi1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
5017 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
5018 SAFE_FREE(driver_info_1);
5022 else driver_info_1 = tdi1;
5025 for (i=0; i<ndrivers; i++) {
5027 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5028 ZERO_STRUCT(driver);
5029 status = get_a_printer_driver(&driver, 3, list[i],
5030 architecture, version);
5031 if (!W_ERROR_IS_OK(status)) {
5035 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
5036 free_a_printer_driver(driver, 3);
5039 *returned+=ndrivers;
5043 /* check the required size. */
5044 for (i=0; i<*returned; i++) {
5045 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5046 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
5049 if (!alloc_buffer_size(buffer, *needed)) {
5050 SAFE_FREE(driver_info_1);
5051 return WERR_INSUFFICIENT_BUFFER;
5054 /* fill the buffer with the driver structures */
5055 for (i=0; i<*returned; i++) {
5056 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5057 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
5060 SAFE_FREE(driver_info_1);
5062 if (*needed > offered) {
5064 return WERR_INSUFFICIENT_BUFFER;
5070 /****************************************************************************
5071 Enumerates all printer drivers at level 2.
5072 ****************************************************************************/
5073 static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5078 fstring *list = NULL;
5079 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5080 DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
5084 #define MAX_VERSION 4
5086 for (version=0; version<MAX_VERSION; version++) {
5088 ndrivers=get_ntdrivers(&list, architecture, version);
5089 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5095 if((tdi2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
5096 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
5097 SAFE_FREE(driver_info_2);
5101 else driver_info_2 = tdi2;
5104 for (i=0; i<ndrivers; i++) {
5107 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5108 ZERO_STRUCT(driver);
5109 status = get_a_printer_driver(&driver, 3, list[i],
5110 architecture, version);
5111 if (!W_ERROR_IS_OK(status)) {
5115 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
5116 free_a_printer_driver(driver, 3);
5119 *returned+=ndrivers;
5123 /* check the required size. */
5124 for (i=0; i<*returned; i++) {
5125 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5126 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
5129 if (!alloc_buffer_size(buffer, *needed)) {
5130 SAFE_FREE(driver_info_2);
5131 return WERR_INSUFFICIENT_BUFFER;
5134 /* fill the buffer with the form structures */
5135 for (i=0; i<*returned; i++) {
5136 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5137 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
5140 SAFE_FREE(driver_info_2);
5142 if (*needed > offered) {
5144 return WERR_INSUFFICIENT_BUFFER;
5150 /****************************************************************************
5151 Enumerates all printer drivers at level 3.
5152 ****************************************************************************/
5153 static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5158 fstring *list = NULL;
5159 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5160 DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
5164 #define MAX_VERSION 4
5166 for (version=0; version<MAX_VERSION; version++) {
5168 ndrivers=get_ntdrivers(&list, architecture, version);
5169 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
5175 if((tdi3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
5176 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
5177 SAFE_FREE(driver_info_3);
5181 else driver_info_3 = tdi3;
5184 for (i=0; i<ndrivers; i++) {
5187 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
5188 ZERO_STRUCT(driver);
5189 status = get_a_printer_driver(&driver, 3, list[i],
5190 architecture, version);
5191 if (!W_ERROR_IS_OK(status)) {
5195 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
5196 free_a_printer_driver(driver, 3);
5199 *returned+=ndrivers;
5203 /* check the required size. */
5204 for (i=0; i<*returned; i++) {
5205 DEBUGADD(6,("adding driver [%d]'s size\n",i));
5206 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
5209 if (!alloc_buffer_size(buffer, *needed)) {
5210 SAFE_FREE(driver_info_3);
5211 return WERR_INSUFFICIENT_BUFFER;
5214 /* fill the buffer with the driver structures */
5215 for (i=0; i<*returned; i++) {
5216 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
5217 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
5220 for (i=0; i<*returned; i++)
5221 SAFE_FREE(driver_info_3[i].dependentfiles);
5223 SAFE_FREE(driver_info_3);
5225 if (*needed > offered) {
5227 return WERR_INSUFFICIENT_BUFFER;
5233 /****************************************************************************
5234 Enumerates all printer drivers.
5235 ****************************************************************************/
5237 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
5239 /* UNISTR2 *name = &q_u->name; - notused. */
5240 UNISTR2 *environment = &q_u->environment;
5241 uint32 level = q_u->level;
5242 NEW_BUFFER *buffer = NULL;
5243 uint32 offered = q_u->offered;
5244 uint32 *needed = &r_u->needed;
5245 uint32 *returned = &r_u->returned;
5247 fstring *list = NULL;
5249 fstring architecture;
5251 /* that's an [in out] buffer */
5252 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5253 buffer = r_u->buffer;
5255 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
5256 fstrcpy(servername, global_myname);
5260 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
5264 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
5266 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
5268 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
5272 return WERR_UNKNOWN_LEVEL;
5276 /****************************************************************************
5277 ****************************************************************************/
5279 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
5281 form->flag=list->flag;
5282 init_unistr(&form->name, list->name);
5283 form->width=list->width;
5284 form->length=list->length;
5285 form->left=list->left;
5286 form->top=list->top;
5287 form->right=list->right;
5288 form->bottom=list->bottom;
5291 /****************************************************************************
5292 ****************************************************************************/
5294 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
5296 /* POLICY_HND *handle = &q_u->handle; - notused. */
5297 uint32 level = q_u->level;
5298 NEW_BUFFER *buffer = NULL;
5299 uint32 offered = q_u->offered;
5300 uint32 *needed = &r_u->needed;
5301 uint32 *numofforms = &r_u->numofforms;
5302 uint32 numbuiltinforms;
5304 nt_forms_struct *list=NULL;
5305 nt_forms_struct *builtinlist=NULL;
5310 /* that's an [in out] buffer */
5311 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5312 buffer = r_u->buffer;
5314 DEBUG(4,("_spoolss_enumforms\n"));
5315 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
5316 DEBUGADD(5,("Info level [%d]\n", level));
5318 numbuiltinforms = get_builtin_ntforms(&builtinlist);
5319 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
5320 *numofforms = get_ntforms(&list);
5321 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
5322 *numofforms += numbuiltinforms;
5324 if (*numofforms == 0) return WERR_NO_MORE_ITEMS;
5328 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
5333 /* construct the list of form structures */
5334 for (i=0; i<numbuiltinforms; i++) {
5335 DEBUGADD(6,("Filling form number [%d]\n",i));
5336 fill_form_1(&forms_1[i], &builtinlist[i]);
5339 SAFE_FREE(builtinlist);
5341 for (; i<*numofforms; i++) {
5342 DEBUGADD(6,("Filling form number [%d]\n",i));
5343 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
5348 /* check the required size. */
5349 for (i=0; i<numbuiltinforms; i++) {
5350 DEBUGADD(6,("adding form [%d]'s size\n",i));
5351 buffer_size += spoolss_size_form_1(&forms_1[i]);
5353 for (; i<*numofforms; i++) {
5354 DEBUGADD(6,("adding form [%d]'s size\n",i));
5355 buffer_size += spoolss_size_form_1(&forms_1[i]);
5358 *needed=buffer_size;
5360 if (!alloc_buffer_size(buffer, buffer_size)){
5362 return WERR_INSUFFICIENT_BUFFER;
5365 /* fill the buffer with the form structures */
5366 for (i=0; i<numbuiltinforms; i++) {
5367 DEBUGADD(6,("adding form [%d] to buffer\n",i));
5368 smb_io_form_1("", buffer, &forms_1[i], 0);
5370 for (; i<*numofforms; i++) {
5371 DEBUGADD(6,("adding form [%d] to buffer\n",i));
5372 smb_io_form_1("", buffer, &forms_1[i], 0);
5377 if (*needed > offered) {
5379 return WERR_INSUFFICIENT_BUFFER;
5386 SAFE_FREE(builtinlist);
5387 return WERR_UNKNOWN_LEVEL;
5392 /****************************************************************************
5393 ****************************************************************************/
5395 WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u)
5397 /* POLICY_HND *handle = &q_u->handle; - notused. */
5398 uint32 level = q_u->level;
5399 UNISTR2 *uni_formname = &q_u->formname;
5400 NEW_BUFFER *buffer = NULL;
5401 uint32 offered = q_u->offered;
5402 uint32 *needed = &r_u->needed;
5404 nt_forms_struct *list=NULL;
5405 nt_forms_struct builtin_form;
5410 int numofforms=0, i=0;
5412 /* that's an [in out] buffer */
5413 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5414 buffer = r_u->buffer;
5416 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
5418 DEBUG(4,("_spoolss_getform\n"));
5419 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
5420 DEBUGADD(5,("Info level [%d]\n", level));
5422 foundBuiltin = get_a_builtin_ntform(uni_formname,&builtin_form);
5423 if (!foundBuiltin) {
5424 numofforms = get_ntforms(&list);
5425 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
5427 if (numofforms == 0)
5434 fill_form_1(&form_1, &builtin_form);
5437 /* Check if the requested name is in the list of form structures */
5438 for (i=0; i<numofforms; i++) {
5440 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
5442 if (strequal(form_name, list[i].name)) {
5443 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
5444 fill_form_1(&form_1, &list[i]);
5450 if (i == numofforms) {
5454 /* check the required size. */
5456 *needed=spoolss_size_form_1(&form_1);
5458 if (!alloc_buffer_size(buffer, buffer_size)){
5459 return WERR_INSUFFICIENT_BUFFER;
5462 if (*needed > offered) {
5463 return WERR_INSUFFICIENT_BUFFER;
5466 /* fill the buffer with the form structures */
5467 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
5468 smb_io_form_1("", buffer, &form_1, 0);
5474 return WERR_UNKNOWN_LEVEL;
5478 /****************************************************************************
5479 ****************************************************************************/
5480 static void fill_port_1(PORT_INFO_1 *port, char *name)
5482 init_unistr(&port->port_name, name);
5485 /****************************************************************************
5486 ****************************************************************************/
5487 static void fill_port_2(PORT_INFO_2 *port, char *name)
5489 init_unistr(&port->port_name, name);
5490 init_unistr(&port->monitor_name, "Local Monitor");
5491 init_unistr(&port->description, "Local Port");
5492 #define PORT_TYPE_WRITE 1
5493 port->port_type=PORT_TYPE_WRITE;
5497 /****************************************************************************
5499 ****************************************************************************/
5500 static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5502 PORT_INFO_1 *ports=NULL;
5505 if (*lp_enumports_cmd()) {
5506 char *cmd = lp_enumports_cmd();
5513 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1);
5515 DEBUG(10,("Running [%s]\n", command));
5516 ret = smbrun(command, &fd);
5517 DEBUG(10,("Returned [%d]\n", ret));
5521 /* Is this the best error to return here? */
5522 return WERR_ACCESS_DENIED;
5526 qlines = fd_lines_load(fd, &numlines);
5527 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5531 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
5532 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
5533 werror_str(WERR_NOMEM)));
5534 file_lines_free(qlines);
5538 for (i=0; i<numlines; i++) {
5539 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
5540 fill_port_1(&ports[i], qlines[i]);
5543 file_lines_free(qlines);
5546 *returned = numlines;
5549 *returned = 1; /* Sole Samba port returned. */
5551 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
5554 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
5556 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
5559 /* check the required size. */
5560 for (i=0; i<*returned; i++) {
5561 DEBUGADD(6,("adding port [%d]'s size\n", i));
5562 *needed += spoolss_size_port_info_1(&ports[i]);
5565 if (!alloc_buffer_size(buffer, *needed)) {
5567 return WERR_INSUFFICIENT_BUFFER;
5570 /* fill the buffer with the ports structures */
5571 for (i=0; i<*returned; i++) {
5572 DEBUGADD(6,("adding port [%d] to buffer\n", i));
5573 smb_io_port_1("", buffer, &ports[i], 0);
5578 if (*needed > offered) {
5580 return WERR_INSUFFICIENT_BUFFER;
5586 /****************************************************************************
5588 ****************************************************************************/
5590 static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5592 PORT_INFO_2 *ports=NULL;
5595 if (*lp_enumports_cmd()) {
5596 char *cmd = lp_enumports_cmd();
5605 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
5606 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
5608 path = lp_lockdir();
5610 slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%u.", path, (unsigned int)sys_getpid());
5611 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 2);
5614 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
5615 ret = smbrun(command, &fd);
5616 DEBUGADD(10,("returned [%d]\n", ret));
5620 /* Is this the best error to return here? */
5621 return WERR_ACCESS_DENIED;
5625 qlines = fd_lines_load(fd, &numlines);
5626 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5630 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
5631 file_lines_free(qlines);
5635 for (i=0; i<numlines; i++) {
5636 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
5637 fill_port_2(&(ports[i]), qlines[i]);
5640 file_lines_free(qlines);
5643 *returned = numlines;
5649 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
5652 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
5654 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
5657 /* check the required size. */
5658 for (i=0; i<*returned; i++) {
5659 DEBUGADD(6,("adding port [%d]'s size\n", i));
5660 *needed += spoolss_size_port_info_2(&ports[i]);
5663 if (!alloc_buffer_size(buffer, *needed)) {
5665 return WERR_INSUFFICIENT_BUFFER;
5668 /* fill the buffer with the ports structures */
5669 for (i=0; i<*returned; i++) {
5670 DEBUGADD(6,("adding port [%d] to buffer\n", i));
5671 smb_io_port_2("", buffer, &ports[i], 0);
5676 if (*needed > offered) {
5678 return WERR_INSUFFICIENT_BUFFER;
5684 /****************************************************************************
5686 ****************************************************************************/
5688 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
5690 /* UNISTR2 *name = &q_u->name; - notused. */
5691 uint32 level = q_u->level;
5692 NEW_BUFFER *buffer = NULL;
5693 uint32 offered = q_u->offered;
5694 uint32 *needed = &r_u->needed;
5695 uint32 *returned = &r_u->returned;
5697 /* that's an [in out] buffer */
5698 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5699 buffer = r_u->buffer;
5701 DEBUG(4,("_spoolss_enumports\n"));
5708 return enumports_level_1(buffer, offered, needed, returned);
5710 return enumports_level_2(buffer, offered, needed, returned);
5712 return WERR_UNKNOWN_LEVEL;
5716 /****************************************************************************
5717 ****************************************************************************/
5718 static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
5719 const SPOOL_PRINTER_INFO_LEVEL *info,
5720 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
5721 uint32 user_switch, const SPOOL_USER_CTR *user,
5724 NT_PRINTER_INFO_LEVEL *printer = NULL;
5729 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
5730 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
5734 ZERO_STRUCTP(printer);
5736 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
5737 convert_printer_info(info, printer, 2);
5739 if (*lp_addprinter_cmd() )
5740 if ( !add_printer_hook(printer) ) {
5741 free_a_printer(&printer,2);
5742 return WERR_ACCESS_DENIED;
5745 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
5746 printer->info_2->sharename);
5748 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
5749 free_a_printer(&printer,2);
5750 return WERR_ACCESS_DENIED;
5753 /* you must be a printer admin to add a new printer */
5754 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
5755 free_a_printer(&printer,2);
5756 return WERR_ACCESS_DENIED;
5760 * Do sanity check on the requested changes for Samba.
5763 if (!check_printer_ok(printer->info_2, snum)) {
5764 free_a_printer(&printer,2);
5765 return WERR_INVALID_PARAM;
5769 * When a printer is created, the drivername bound to the printer is used
5770 * to lookup previously saved driver initialization info, which is then
5771 * bound to the new printer, simulating what happens in the Windows arch.
5773 set_driver_init(printer, 2);
5775 /* write the ASCII on disk */
5776 err = add_a_printer(*printer, 2);
5777 if (!W_ERROR_IS_OK(err)) {
5778 free_a_printer(&printer,2);
5782 if (!open_printer_hnd(p, handle, name)) {
5783 /* Handle open failed - remove addition. */
5784 del_a_printer(printer->info_2->sharename);
5785 free_a_printer(&printer,2);
5786 return WERR_ACCESS_DENIED;
5789 free_a_printer(&printer,2);
5791 srv_spoolss_sendnotify(p, handle);
5796 /****************************************************************************
5797 ****************************************************************************/
5799 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
5801 UNISTR2 *uni_srv_name = &q_u->server_name;
5802 uint32 level = q_u->level;
5803 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
5804 uint32 unk0 = q_u->unk0;
5805 uint32 unk1 = q_u->unk1;
5806 uint32 unk2 = q_u->unk2;
5807 uint32 unk3 = q_u->unk3;
5808 uint32 user_switch = q_u->user_switch;
5809 SPOOL_USER_CTR *user = &q_u->user_ctr;
5810 POLICY_HND *handle = &r_u->handle;
5814 /* we don't handle yet */
5815 /* but I know what to do ... */
5816 return WERR_UNKNOWN_LEVEL;
5818 return spoolss_addprinterex_level_2(p, uni_srv_name, info,
5819 unk0, unk1, unk2, unk3,
5820 user_switch, user, handle);
5822 return WERR_UNKNOWN_LEVEL;
5826 /****************************************************************************
5827 ****************************************************************************/
5829 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
5831 /* UNISTR2 *server_name = &q_u->server_name; - notused. */
5832 uint32 level = q_u->level;
5833 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
5834 WERROR err = WERR_OK;
5835 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5836 struct current_user user;
5838 ZERO_STRUCT(driver);
5840 get_current_user(&user, p);
5842 if (!convert_printer_driver_info(info, &driver, level)) {
5847 DEBUG(5,("Cleaning driver's information\n"));
5848 err = clean_up_driver_struct(driver, level, &user);
5849 if (!W_ERROR_IS_OK(err))
5852 DEBUG(5,("Moving driver to final destination\n"));
5853 if(!move_driver_to_download_area(driver, level, &user, &err)) {
5854 if (W_ERROR_IS_OK(err))
5855 err = WERR_ACCESS_DENIED;
5859 if (add_a_printer_driver(driver, level)!=0) {
5860 err = WERR_ACCESS_DENIED;
5865 free_a_printer_driver(driver, level);
5869 /****************************************************************************
5870 ****************************************************************************/
5871 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
5873 init_unistr(&info->name, name);
5876 /****************************************************************************
5877 ****************************************************************************/
5878 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
5882 pstring short_archi;
5883 DRIVER_DIRECTORY_1 *info=NULL;
5885 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
5887 if (get_short_archi(short_archi, long_archi)==FALSE)
5888 return WERR_INVALID_ENVIRONMENT;
5890 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
5893 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
5895 DEBUG(4,("printer driver directory: [%s]\n", path));
5897 fill_driverdir_1(info, path);
5899 *needed += spoolss_size_driverdir_info_1(info);
5901 if (!alloc_buffer_size(buffer, *needed)) {
5903 return WERR_INSUFFICIENT_BUFFER;
5906 smb_io_driverdir_1("", buffer, info, 0);
5910 if (*needed > offered)
5911 return WERR_INSUFFICIENT_BUFFER;
5916 /****************************************************************************
5917 ****************************************************************************/
5919 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
5921 UNISTR2 *name = &q_u->name;
5922 UNISTR2 *uni_environment = &q_u->environment;
5923 uint32 level = q_u->level;
5924 NEW_BUFFER *buffer = NULL;
5925 uint32 offered = q_u->offered;
5926 uint32 *needed = &r_u->needed;
5928 /* that's an [in out] buffer */
5929 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
5930 buffer = r_u->buffer;
5932 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
5938 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
5940 return WERR_UNKNOWN_LEVEL;
5944 /****************************************************************************
5945 ****************************************************************************/
5947 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
5949 POLICY_HND *handle = &q_u->handle;
5950 uint32 idx = q_u->index;
5951 uint32 in_value_len = q_u->valuesize;
5952 uint32 in_data_len = q_u->datasize;
5953 uint32 *out_max_value_len = &r_u->valuesize;
5954 uint16 **out_value = &r_u->value;
5955 uint32 *out_value_len = &r_u->realvaluesize;
5956 uint32 *out_type = &r_u->type;
5957 uint32 *out_max_data_len = &r_u->datasize;
5958 uint8 **data_out = &r_u->data;
5959 uint32 *out_data_len = &r_u->realdatasize;
5961 NT_PRINTER_INFO_LEVEL *printer = NULL;
5966 uint32 biggest_valuesize;
5967 uint32 biggest_datasize;
5969 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5975 ZERO_STRUCT(printer);
5977 *out_max_value_len=0;
5983 *out_max_data_len=0;
5987 DEBUG(5,("spoolss_enumprinterdata\n"));
5990 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
5994 if (!get_printer_snum(p,handle, &snum))
5997 result = get_a_printer(&printer, 2, lp_servicename(snum));
5998 if (!W_ERROR_IS_OK(result))
6002 * The NT machine wants to know the biggest size of value and data
6004 * cf: MSDN EnumPrinterData remark section
6006 if ( (in_value_len==0) && (in_data_len==0) ) {
6007 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
6011 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
6012 * if this parameter size doesn't exist.
6013 * Ok - my opinion here is that the client is not asking for the greatest
6014 * possible size of all the parameters, but is asking specifically for the size needed
6015 * for this specific parameter. In that case we can remove the loop below and
6016 * simplify this lookup code considerably. JF - comments welcome. JRA.
6019 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
6021 free_a_printer(&printer, 2);
6022 return WERR_NO_MORE_ITEMS;
6029 biggest_valuesize=0;
6032 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
6033 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
6034 if (data_len > biggest_datasize) biggest_datasize=data_len;
6036 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
6043 * I think this is correct, it doesn't break APW and
6044 * allows Gerald's Win32 test programs to work correctly,
6045 * but may need altering.... JRA.
6048 if (param_index == 0) {
6049 /* No parameters found. */
6050 free_a_printer(&printer, 2);
6051 return WERR_NO_MORE_ITEMS;
6054 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
6055 *out_value_len=2*(1+biggest_valuesize);
6056 *out_data_len=biggest_datasize;
6058 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
6060 free_a_printer(&printer, 2);
6065 * the value len is wrong in NT sp3
6066 * that's the number of bytes not the number of unicode chars
6069 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
6071 free_a_printer(&printer, 2);
6072 return WERR_NO_MORE_ITEMS;
6075 free_a_printer(&printer, 2);
6079 * - counted in bytes in the request
6080 * - counted in UNICODE chars in the max reply
6081 * - counted in bytes in the real size
6083 * take a pause *before* coding not *during* coding
6086 *out_max_value_len=(in_value_len/sizeof(uint16));
6087 if((*out_value=(uint16 *)talloc_zero(p->mem_ctx,in_value_len*sizeof(uint8))) == NULL) {
6092 *out_value_len = rpcstr_push((char *)*out_value,value, in_value_len, 0);
6096 /* the data is counted in bytes */
6097 *out_max_data_len=in_data_len;
6098 if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) {
6103 memcpy(*data_out, data, (size_t)data_len);
6104 *out_data_len=data_len;
6111 /****************************************************************************
6112 ****************************************************************************/
6114 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
6116 POLICY_HND *handle = &q_u->handle;
6117 UNISTR2 *value = &q_u->value;
6118 uint32 type = q_u->type;
6119 /* uint32 max_len = q_u->max_len; - notused. */
6120 uint8 *data = q_u->data;
6121 uint32 real_len = q_u->real_len;
6122 /* uint32 numeric_data = q_u->numeric_data; - notused. */
6124 NT_PRINTER_INFO_LEVEL *printer = NULL;
6125 NT_PRINTER_PARAM *param = NULL, old_param;
6127 WERROR status = WERR_OK;
6128 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
6130 DEBUG(5,("spoolss_setprinterdata\n"));
6133 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6137 if (!get_printer_snum(p,handle, &snum))
6140 ZERO_STRUCT(old_param);
6143 * Access check : NT returns "access denied" if you make a
6144 * SetPrinterData call without the necessary privildge.
6145 * we were originally returning OK if nothing changed
6146 * which made Win2k issue **a lot** of SetPrinterData
6147 * when connecting to a printer --jerry
6150 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
6151 DEBUG(3, ("security descriptor change denied by existing "
6152 "security descriptor\n"));
6153 status = WERR_ACCESS_DENIED;
6158 /* Check if we are making any changes or not. Return true if
6159 nothing is actually changing. This is not needed anymore but
6160 has been left in as an optimization to keep from from
6161 writing to disk as often --jerry */
6163 status = get_a_printer(&printer, 2, lp_servicename(snum));
6164 if (!W_ERROR_IS_OK(status))
6167 convert_specific_param(¶m, value , type, data, real_len);
6169 if (get_specific_param(*printer, 2, param->value, &old_param.data,
6170 &old_param.type, (uint32 *)&old_param.data_len)) {
6172 if (param->type == old_param.type &&
6173 param->data_len == old_param.data_len &&
6174 memcmp(param->data, old_param.data,
6175 old_param.data_len) == 0) {
6177 DEBUG(3, ("setprinterdata hasn't changed\n"));
6183 unlink_specific_param_if_exist(printer->info_2, param);
6186 * When client side code sets a magic printer data key, detect it and save
6187 * the current printer data and the magic key's data (its the DEVMODE) for
6188 * future printer/driver initializations.
6190 if (param->type==3 && !strcmp( param->value, PHANTOM_DEVMODE_KEY)) {
6192 * Set devmode and printer initialization info
6194 status = save_driver_init(printer, 2, param);
6197 add_a_specific_param(printer->info_2, ¶m);
6198 status = mod_a_printer(*printer, 2);
6202 free_a_printer(&printer, 2);
6204 free_nt_printer_param(¶m);
6205 SAFE_FREE(old_param.data);
6210 /****************************************************************************
6211 ****************************************************************************/
6213 WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
6215 POLICY_HND *handle = &q_u->handle;
6216 UNISTR2 *value = &q_u->valuename;
6218 NT_PRINTER_INFO_LEVEL *printer = NULL;
6219 NT_PRINTER_PARAM param;
6221 WERROR status = WERR_OK;
6222 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
6224 DEBUG(5,("spoolss_deleteprinterdata\n"));
6227 DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6231 if (!get_printer_snum(p, handle, &snum))
6234 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
6235 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
6236 "change denied by existing security descriptor\n"));
6237 return WERR_ACCESS_DENIED;
6240 status = get_a_printer(&printer, 2, lp_servicename(snum));
6241 if (!W_ERROR_IS_OK(status))
6244 ZERO_STRUCTP(¶m);
6245 unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
6247 if(!unlink_specific_param_if_exist(printer->info_2, ¶m))
6248 status = WERR_INVALID_PARAM;
6250 status = mod_a_printer(*printer, 2);
6252 free_a_printer(&printer, 2);
6256 /****************************************************************************
6257 ****************************************************************************/
6259 WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
6261 POLICY_HND *handle = &q_u->handle;
6262 /* uint32 level = q_u->level; - notused. */
6263 FORM *form = &q_u->form;
6264 nt_forms_struct tmpForm;
6267 nt_forms_struct *list=NULL;
6268 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6270 DEBUG(5,("spoolss_addform\n"));
6273 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6277 /* can't add if builtin */
6278 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
6279 return WERR_INVALID_PARAM;
6282 count=get_ntforms(&list);
6283 if(!add_a_form(&list, form, &count))
6285 write_ntforms(&list, count);
6292 /****************************************************************************
6293 ****************************************************************************/
6295 WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u)
6297 POLICY_HND *handle = &q_u->handle;
6298 UNISTR2 *form_name = &q_u->name;
6299 nt_forms_struct tmpForm;
6301 WERROR ret = WERR_OK;
6302 nt_forms_struct *list=NULL;
6303 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6305 DEBUG(5,("spoolss_deleteform\n"));
6308 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6312 /* can't delete if builtin */
6313 if (get_a_builtin_ntform(form_name,&tmpForm)) {
6314 return WERR_INVALID_PARAM;
6317 count = get_ntforms(&list);
6318 if (!delete_a_form(&list, form_name, &count, &ret))
6319 return WERR_INVALID_PARAM;
6326 /****************************************************************************
6327 ****************************************************************************/
6329 WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
6331 POLICY_HND *handle = &q_u->handle;
6332 /* UNISTR2 *uni_name = &q_u->name; - notused. */
6333 /* uint32 level = q_u->level; - notused. */
6334 FORM *form = &q_u->form;
6335 nt_forms_struct tmpForm;
6338 nt_forms_struct *list=NULL;
6339 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6341 DEBUG(5,("spoolss_setform\n"));
6344 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
6347 /* can't set if builtin */
6348 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
6349 return WERR_INVALID_PARAM;
6352 count=get_ntforms(&list);
6353 update_a_form(&list, form, count);
6354 write_ntforms(&list, count);
6361 /****************************************************************************
6362 enumprintprocessors level 1.
6363 ****************************************************************************/
6364 static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6366 PRINTPROCESSOR_1 *info_1=NULL;
6368 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
6373 init_unistr(&info_1->name, "winprint");
6375 *needed += spoolss_size_printprocessor_info_1(info_1);
6377 if (!alloc_buffer_size(buffer, *needed))
6378 return WERR_INSUFFICIENT_BUFFER;
6380 smb_io_printprocessor_info_1("", buffer, info_1, 0);
6384 if (*needed > offered) {
6386 return WERR_INSUFFICIENT_BUFFER;
6392 /****************************************************************************
6393 ****************************************************************************/
6395 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
6397 /* UNISTR2 *name = &q_u->name; - notused. */
6398 /* UNISTR2 *environment = &q_u->environment; - notused. */
6399 uint32 level = q_u->level;
6400 NEW_BUFFER *buffer = NULL;
6401 uint32 offered = q_u->offered;
6402 uint32 *needed = &r_u->needed;
6403 uint32 *returned = &r_u->returned;
6405 /* that's an [in out] buffer */
6406 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6407 buffer = r_u->buffer;
6409 DEBUG(5,("spoolss_enumprintprocessors\n"));
6412 * Enumerate the print processors ...
6414 * Just reply with "winprint", to keep NT happy
6415 * and I can use my nice printer checker.
6423 return enumprintprocessors_level_1(buffer, offered, needed, returned);
6425 return WERR_UNKNOWN_LEVEL;
6429 /****************************************************************************
6430 enumprintprocdatatypes level 1.
6431 ****************************************************************************/
6432 static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6434 PRINTPROCDATATYPE_1 *info_1=NULL;
6436 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
6441 init_unistr(&info_1->name, "RAW");
6443 *needed += spoolss_size_printprocdatatype_info_1(info_1);
6445 if (!alloc_buffer_size(buffer, *needed))
6446 return WERR_INSUFFICIENT_BUFFER;
6448 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
6452 if (*needed > offered) {
6454 return WERR_INSUFFICIENT_BUFFER;
6460 /****************************************************************************
6461 ****************************************************************************/
6463 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
6465 /* UNISTR2 *name = &q_u->name; - notused. */
6466 /* UNISTR2 *processor = &q_u->processor; - notused. */
6467 uint32 level = q_u->level;
6468 NEW_BUFFER *buffer = NULL;
6469 uint32 offered = q_u->offered;
6470 uint32 *needed = &r_u->needed;
6471 uint32 *returned = &r_u->returned;
6473 /* that's an [in out] buffer */
6474 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6475 buffer = r_u->buffer;
6477 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
6484 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
6486 return WERR_UNKNOWN_LEVEL;
6490 /****************************************************************************
6491 enumprintmonitors level 1.
6492 ****************************************************************************/
6494 static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6496 PRINTMONITOR_1 *info_1=NULL;
6498 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
6503 init_unistr(&info_1->name, "Local Port");
6505 *needed += spoolss_size_printmonitor_info_1(info_1);
6507 if (!alloc_buffer_size(buffer, *needed))
6508 return WERR_INSUFFICIENT_BUFFER;
6510 smb_io_printmonitor_info_1("", buffer, info_1, 0);
6514 if (*needed > offered) {
6516 return WERR_INSUFFICIENT_BUFFER;
6522 /****************************************************************************
6523 enumprintmonitors level 2.
6524 ****************************************************************************/
6525 static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6527 PRINTMONITOR_2 *info_2=NULL;
6529 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
6534 init_unistr(&info_2->name, "Local Port");
6535 init_unistr(&info_2->environment, "Windows NT X86");
6536 init_unistr(&info_2->dll_name, "localmon.dll");
6538 *needed += spoolss_size_printmonitor_info_2(info_2);
6540 if (!alloc_buffer_size(buffer, *needed))
6541 return WERR_INSUFFICIENT_BUFFER;
6543 smb_io_printmonitor_info_2("", buffer, info_2, 0);
6547 if (*needed > offered) {
6549 return WERR_INSUFFICIENT_BUFFER;
6555 /****************************************************************************
6556 ****************************************************************************/
6558 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
6560 /* UNISTR2 *name = &q_u->name; - notused. */
6561 uint32 level = q_u->level;
6562 NEW_BUFFER *buffer = NULL;
6563 uint32 offered = q_u->offered;
6564 uint32 *needed = &r_u->needed;
6565 uint32 *returned = &r_u->returned;
6567 /* that's an [in out] buffer */
6568 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6569 buffer = r_u->buffer;
6571 DEBUG(5,("spoolss_enumprintmonitors\n"));
6574 * Enumerate the print monitors ...
6576 * Just reply with "Local Port", to keep NT happy
6577 * and I can use my nice printer checker.
6585 return enumprintmonitors_level_1(buffer, offered, needed, returned);
6587 return enumprintmonitors_level_2(buffer, offered, needed, returned);
6589 return WERR_UNKNOWN_LEVEL;
6593 /****************************************************************************
6594 ****************************************************************************/
6595 static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
6599 JOB_INFO_1 *info_1=NULL;
6601 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
6603 if (info_1 == NULL) {
6608 for (i=0; i<count && found==False; i++) {
6609 if (queue[i].job==(int)jobid)
6616 /* I shoud reply something else ... I can't find the good one */
6620 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
6624 *needed += spoolss_size_job_info_1(info_1);
6626 if (!alloc_buffer_size(buffer, *needed)) {
6628 return WERR_INSUFFICIENT_BUFFER;
6631 smb_io_job_info_1("", buffer, info_1, 0);
6635 if (*needed > offered)
6636 return WERR_INSUFFICIENT_BUFFER;
6642 /****************************************************************************
6643 ****************************************************************************/
6644 static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
6649 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6652 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
6654 ZERO_STRUCTP(info_2);
6656 if (info_2 == NULL) {
6661 for (i=0; i<count && found==False; i++) {
6662 if (queue[i].job==(int)jobid)
6669 /* I shoud reply something else ... I can't find the good one */
6673 ret = get_a_printer(&ntprinter, 2, lp_servicename(snum));
6674 if (!W_ERROR_IS_OK(ret)) {
6679 fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter);
6681 free_a_printer(&ntprinter, 2);
6684 *needed += spoolss_size_job_info_2(info_2);
6686 if (!alloc_buffer_size(buffer, *needed)) {
6688 return WERR_INSUFFICIENT_BUFFER;
6691 smb_io_job_info_2("", buffer, info_2, 0);
6693 free_job_info_2(info_2);
6696 if (*needed > offered)
6697 return WERR_INSUFFICIENT_BUFFER;
6702 /****************************************************************************
6703 ****************************************************************************/
6705 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
6707 POLICY_HND *handle = &q_u->handle;
6708 uint32 jobid = q_u->jobid;
6709 uint32 level = q_u->level;
6710 NEW_BUFFER *buffer = NULL;
6711 uint32 offered = q_u->offered;
6712 uint32 *needed = &r_u->needed;
6716 print_queue_struct *queue=NULL;
6717 print_status_struct prt_status;
6719 /* that's an [in out] buffer */
6720 spoolss_move_buffer(q_u->buffer, &r_u->buffer);
6721 buffer = r_u->buffer;
6723 DEBUG(5,("spoolss_getjob\n"));
6725 memset(&prt_status, 0, sizeof(prt_status));
6729 if (!get_printer_snum(p, handle, &snum))
6732 count = print_queue_status(snum, &queue, &prt_status);
6734 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
6735 count, prt_status.status, prt_status.message));
6739 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
6741 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
6744 return WERR_UNKNOWN_LEVEL;