3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-2000,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
8 * Copyright (C) Jean François Micouleau 1998-2000.
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.
28 extern int DEBUGLEVEL;
29 extern pstring global_myname;
31 #ifndef MAX_OPEN_PRINTER_EXS
32 #define MAX_OPEN_PRINTER_EXS 50
35 #define PRINTER_HANDLE_IS_PRINTER 0
36 #define PRINTER_HANDLE_IS_PRINTSERVER 1
38 /* structure to store the printer handles */
39 /* and a reference to what it's pointing to */
40 /* and the notify info asked about */
41 /* that's the central struct */
42 typedef struct _Printer{
47 BOOL document_started;
49 int jobid; /* jobid in printing backend */
50 POLICY_HND printer_hnd;
54 fstring printerservername;
63 SPOOL_NOTIFY_OPTION *option;
71 typedef struct _counter_printer_0 {
79 static ubi_dlList Printer_list;
80 static ubi_dlList counter_list;
83 #define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False) && (IVAL(pnum->printer_hnd.data,16)==(uint32)sys_getpid()))
84 #define OUR_HANDLE(pnum) ((pnum==NULL)?"NULL":(IVAL(pnum->data,16)==sys_getpid()?"OURS":"OTHER"))
86 /* translate between internal status numbers and NT status numbers */
87 static int nt_printj_status(int v)
91 return PRINTER_STATUS_PAUSED;
100 static int nt_printq_status(int v)
104 return PRINTER_STATUS_ERROR;
113 /****************************************************************************
114 initialise printer handle states...
115 ****************************************************************************/
116 void init_printer_hnd(void)
118 ubi_dlInitList(&Printer_list);
119 ubi_dlInitList(&counter_list);
122 /****************************************************************************
123 create a unique printer handle
124 ****************************************************************************/
125 static void create_printer_hnd(POLICY_HND *hnd)
127 static uint32 prt_hnd_low = 0;
128 static uint32 prt_hnd_high = 0;
130 if (hnd == NULL) return;
132 /* i severely doubt that prt_hnd_high will ever be non-zero... */
134 if (prt_hnd_low == 0) prt_hnd_high++;
136 SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
137 SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
138 SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
139 SIVAL(hnd->data, 12, time(NULL)); /* something random */
140 SIVAL(hnd->data, 16, sys_getpid()); /* something more random */
143 /****************************************************************************
144 find printer index by handle
145 ****************************************************************************/
146 static Printer_entry *find_printer_index_by_hnd(const POLICY_HND *hnd)
148 Printer_entry *find_printer;
150 find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
152 for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) {
154 if (memcmp(&(find_printer->printer_hnd), hnd, sizeof(*hnd)) == 0) {
155 DEBUG(4,("Found printer handle \n"));
156 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
161 DEBUG(3,("Whoops, Printer handle not found: "));
162 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
166 /****************************************************************************
168 ****************************************************************************/
169 static void clear_handle(POLICY_HND *hnd)
174 /****************************************************************************
175 close printer index by handle
176 ****************************************************************************/
177 static BOOL close_printer_handle(POLICY_HND *hnd)
179 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
181 if (!OPEN_HANDLE(Printer)) {
182 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
187 Printer->notify.flags=0;
188 Printer->notify.options=0;
189 Printer->notify.localmachine[0]='\0';
190 Printer->notify.printerlocal=0;
191 safe_free(Printer->notify.option);
192 Printer->notify.option=NULL;
196 ubi_dlRemThis(&Printer_list, Printer);
203 /****************************************************************************
204 delete a printer given a handle
205 ****************************************************************************/
206 static BOOL delete_printer_handle(POLICY_HND *hnd)
208 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
210 if (!OPEN_HANDLE(Printer)) {
211 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
215 if (del_a_printer(Printer->dev.handlename) != 0) {
216 DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
220 if (*lp_deleteprinter_cmd()) {
222 pid_t local_pid = sys_getpid();
223 char *cmd = lp_deleteprinter_cmd();
230 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
231 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
235 /* Printer->dev.handlename equals portname equals sharename */
236 slprintf(command, sizeof(command), "%s \"%s\"", cmd,
237 Printer->dev.handlename);
238 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
241 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
242 ret = smbrun(command, tmp_file, False);
247 DEBUGADD(10,("returned [%d]\n", ret));
248 DEBUGADD(10,("Unlinking output file [%s]\n", tmp_file));
251 if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
252 lp_remove_service( i );
262 /****************************************************************************
263 return the snum of a printer corresponding to an handle
264 ****************************************************************************/
265 static BOOL get_printer_snum(POLICY_HND *hnd, int *number)
267 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
269 if (!OPEN_HANDLE(Printer)) {
270 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
274 switch (Printer->printer_type) {
275 case PRINTER_HANDLE_IS_PRINTER:
276 DEBUG(4,("short name:%s\n", Printer->dev.handlename));
277 *number = print_queue_snum(Printer->dev.handlename);
278 return (*number != -1);
279 case PRINTER_HANDLE_IS_PRINTSERVER:
288 /****************************************************************************
289 set printer handle type.
290 ****************************************************************************/
291 static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required)
293 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
295 if (!OPEN_HANDLE(Printer)) {
296 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd)));
300 DEBUG(4,("Setting printer access=%x\n", access_required));
301 Printer->access = access_required;
305 /****************************************************************************
306 Set printer handle type.
307 Check if it's \\server or \\server\printer
308 ****************************************************************************/
310 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
312 DEBUG(3,("Setting printer type=%s\n", handlename));
314 if ( strlen(handlename) < 3 ) {
315 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
319 /* it's a print server */
320 if (!strchr(handlename+2, '\\')) {
321 DEBUGADD(4,("Printer is a print server\n"));
322 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
327 DEBUGADD(4,("Printer is a printer\n"));
328 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
335 /****************************************************************************
336 Set printer handle name.
337 ****************************************************************************/
339 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
341 NT_PRINTER_INFO_LEVEL *printer = NULL;
343 int n_services=lp_numservices();
347 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
349 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
350 ZERO_STRUCT(Printer->dev.printerservername);
351 strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
355 if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
358 aprinter=strchr(handlename+2, '\\');
361 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
364 * store the Samba share name in it
365 * in back we have the long printer name
366 * need to iterate all the snum and do a
367 * get_a_printer each time to find the printer
368 * faster to do it here than later.
371 for (snum=0;snum<n_services && found==False;snum++) {
373 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
376 DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
378 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
381 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
382 printer->info_2->printername, aprinter ));
384 if ( strlen(printer->info_2->printername) != strlen(aprinter) ) {
385 free_a_printer(&printer, 2);
389 if ( strncasecmp(printer->info_2->printername, aprinter, strlen(aprinter))) {
390 free_a_printer(&printer, 2);
398 * if we haven't found a printer with the given handlename
399 * then it can be a share name as you can open both \\server\printer and
404 * we still check if the printer description file exists as NT won't be happy
405 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
409 DEBUGADD(5,("Printer not found, checking for share now\n"));
411 for (snum=0;snum<n_services && found==False;snum++) {
413 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
416 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum)));
418 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
421 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
422 printer->info_2->printername, aprinter ));
424 if ( strlen(lp_servicename(snum)) != strlen(aprinter) ) {
425 free_a_printer(&printer, 2);
429 if ( strncasecmp(lp_servicename(snum), aprinter, strlen(aprinter))) {
430 free_a_printer(&printer, 2);
439 DEBUGADD(4,("Printer not found\n"));
444 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
445 printer->info_2->printername, lp_servicename(snum),snum));
447 ZERO_STRUCT(Printer->dev.handlename);
448 strncpy(Printer->dev.handlename, lp_servicename(snum), strlen(lp_servicename(snum)));
450 free_a_printer(&printer, 2);
455 /****************************************************************************
456 find first available printer slot. creates a printer handle for you.
457 ****************************************************************************/
459 static BOOL open_printer_hnd(POLICY_HND *hnd, char *name)
461 Printer_entry *new_printer;
464 create_printer_hnd(hnd);
466 if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
469 ZERO_STRUCTP(new_printer);
471 new_printer->open = True;
472 new_printer->notify.option=NULL;
474 memcpy(&new_printer->printer_hnd, hnd, sizeof(*hnd));
476 ubi_dlAddHead( &Printer_list, (ubi_dlNode *)new_printer);
478 if (!set_printer_hnd_printertype(new_printer, name)) {
479 close_printer_handle(hnd);
483 if (!set_printer_hnd_name(new_printer, name)) {
484 close_printer_handle(hnd);
491 /********************************************************************
492 Return True is the handle is a print server.
493 ********************************************************************/
494 static BOOL handle_is_printserver(const POLICY_HND *handle)
496 Printer_entry *Printer=find_printer_index_by_hnd(handle);
498 if (!OPEN_HANDLE(Printer))
501 if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
507 /****************************************************************************
508 allocate more memory for a BUFFER.
509 ****************************************************************************/
510 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
518 /* damn, I'm doing the reverse operation of prs_grow() :) */
519 if (buffer_size < prs_data_size(ps))
522 extra_space = buffer_size - prs_data_size(ps);
525 * save the offset and move to the end of the buffer
526 * prs_grow() checks the extra_space against the offset
528 old_offset=prs_offset(ps);
529 prs_set_offset(ps, prs_data_size(ps));
531 if (!prs_grow(ps, extra_space))
534 prs_set_offset(ps, old_offset);
537 buffer->string_at_end = buffer_size;
539 buffer->string_at_end=prs_data_size(ps);
545 /********************************************************************
546 * spoolss_open_printer
548 * called from the spoolss dispatcher
549 ********************************************************************/
550 uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
551 const PRINTER_DEFAULT *printer_default,
552 uint32 user_switch, SPOOL_USER_CTR user_ctr,
557 if (printername == NULL)
558 return ERROR_INVALID_PRINTER_NAME;
560 /* some sanity check because you can open a printer or a print server */
561 /* aka: \\server\printer or \\server */
562 unistr2_to_ascii(name, printername, sizeof(name)-1);
564 DEBUGADD(3,("checking name: %s\n",name));
566 if (!open_printer_hnd(handle, name))
567 return ERROR_INVALID_PRINTER_NAME;
570 if (printer_default->datatype_ptr != NULL)
572 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
573 set_printer_hnd_datatype(handle, datatype);
576 set_printer_hnd_datatype(handle, "");
579 if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
580 close_printer_handle(handle);
581 return ERROR_ACCESS_DENIED;
584 return NT_STATUS_NO_PROBLEMO;
587 /****************************************************************************
588 ****************************************************************************/
589 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
590 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
594 uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
603 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
604 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
608 printer->info_3=NULL;
609 uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3);
612 printer->info_6=NULL;
613 uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6);
622 static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devmode)
624 unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
625 unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
627 nt_devmode->specversion=devmode->specversion;
628 nt_devmode->driverversion=devmode->driverversion;
629 nt_devmode->size=devmode->size;
630 nt_devmode->driverextra=devmode->driverextra;
631 nt_devmode->fields=devmode->fields;
632 nt_devmode->orientation=devmode->orientation;
633 nt_devmode->papersize=devmode->papersize;
634 nt_devmode->paperlength=devmode->paperlength;
635 nt_devmode->paperwidth=devmode->paperwidth;
636 nt_devmode->scale=devmode->scale;
637 nt_devmode->copies=devmode->copies;
638 nt_devmode->defaultsource=devmode->defaultsource;
639 nt_devmode->printquality=devmode->printquality;
640 nt_devmode->color=devmode->color;
641 nt_devmode->duplex=devmode->duplex;
642 nt_devmode->yresolution=devmode->yresolution;
643 nt_devmode->ttoption=devmode->ttoption;
644 nt_devmode->collate=devmode->collate;
646 nt_devmode->logpixels=devmode->logpixels;
647 nt_devmode->bitsperpel=devmode->bitsperpel;
648 nt_devmode->pelswidth=devmode->pelswidth;
649 nt_devmode->pelsheight=devmode->pelsheight;
650 nt_devmode->displayflags=devmode->displayflags;
651 nt_devmode->displayfrequency=devmode->displayfrequency;
652 nt_devmode->icmmethod=devmode->icmmethod;
653 nt_devmode->icmintent=devmode->icmintent;
654 nt_devmode->mediatype=devmode->mediatype;
655 nt_devmode->dithertype=devmode->dithertype;
656 nt_devmode->reserved1=devmode->reserved1;
657 nt_devmode->reserved2=devmode->reserved2;
658 nt_devmode->panningwidth=devmode->panningwidth;
659 nt_devmode->panningheight=devmode->panningheight;
661 if (nt_devmode->driverextra != 0) {
662 /* if we had a previous private delete it and make a new one */
663 safe_free(nt_devmode->private);
664 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
666 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
672 /********************************************************************
673 * api_spoolss_closeprinter
674 ********************************************************************/
675 uint32 _spoolss_closeprinter(POLICY_HND *handle)
677 if (!close_printer_handle(handle))
678 return ERROR_INVALID_HANDLE;
680 return NT_STATUS_NO_PROBLEMO;
683 /********************************************************************
684 * api_spoolss_deleteprinter
685 ********************************************************************/
686 uint32 _spoolss_deleteprinter(POLICY_HND *handle)
688 if (!delete_printer_handle(handle))
689 return ERROR_INVALID_HANDLE;
691 return NT_STATUS_NO_PROBLEMO;
694 /********************************************************************
695 GetPrinterData on a printer server Handle.
696 ********************************************************************/
697 static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
701 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
703 if (!strcmp(value, "BeepEnabled")) {
705 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
707 SIVAL(*data, 0, 0x01);
712 if (!strcmp(value, "EventLog")) {
714 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
716 SIVAL(*data, 0, 0x1B);
721 if (!strcmp(value, "NetPopup")) {
723 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
725 SIVAL(*data, 0, 0x01);
730 if (!strcmp(value, "MajorVersion")) {
732 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
734 SIVAL(*data, 0, 0x02);
739 if (!strcmp(value, "DefaultSpoolDirectory")) {
740 pstring string="You are using a Samba server";
742 *needed = 2*(strlen(string)+1);
743 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
745 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
747 /* it's done by hand ready to go on the wire */
748 for (i=0; i<strlen(string); i++) {
749 (*data)[2*i]=string[i];
755 if (!strcmp(value, "Architecture")) {
756 pstring string="Windows NT x86";
758 *needed = 2*(strlen(string)+1);
759 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
761 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
762 for (i=0; i<strlen(string); i++) {
763 (*data)[2*i]=string[i];
772 /********************************************************************
773 GetPrinterData on a printer Handle.
774 ********************************************************************/
775 static BOOL getprinterdata_printer(POLICY_HND *handle,
776 fstring value, uint32 *type,
777 uint8 **data, uint32 *needed, uint32 in_size )
779 NT_PRINTER_INFO_LEVEL *printer = NULL;
783 Printer_entry *Printer = find_printer_index_by_hnd(handle);
785 DEBUG(5,("getprinterdata_printer\n"));
787 if (!OPEN_HANDLE(Printer)) {
788 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
792 if(!get_printer_snum(handle, &snum))
795 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
798 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
799 free_a_printer(&printer, 2);
803 free_a_printer(&printer, 2);
805 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
808 if((*data = (uint8 *)malloc( in_size *sizeof(uint8) )) == NULL) {
812 memset(*data, 0, in_size *sizeof(uint8));
813 /* copy the min(in_size, len) */
814 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
821 DEBUG(5,("getprinterdata_printer:copy done\n"));
828 /********************************************************************
829 * spoolss_getprinterdata
830 ********************************************************************/
831 uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
840 Printer_entry *Printer = find_printer_index_by_hnd(handle);
843 * Reminder: when it's a string, the length is in BYTES
844 * even if UNICODE is negociated.
851 /* in case of problem, return some default values */
855 DEBUG(4,("_spoolss_getprinterdata\n"));
857 if (!OPEN_HANDLE(Printer)) {
858 if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
859 return ERROR_NOT_ENOUGH_MEMORY;
860 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
861 return ERROR_INVALID_HANDLE;
864 unistr2_to_ascii(value, valuename, sizeof(value)-1);
866 if (handle_is_printserver(handle))
867 found=getprinterdata_printer_server(value, type, data, needed, *out_size);
869 found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
872 DEBUG(5, ("value not found, allocating %d\n", *out_size));
873 /* reply this param doesn't exist */
875 if((*data=(uint8 *)malloc(*out_size*sizeof(uint8))) == NULL)
876 return ERROR_NOT_ENOUGH_MEMORY;
877 memset(*data, '\0', *out_size*sizeof(uint8));
882 return ERROR_INVALID_PARAMETER;
885 if (*needed > *out_size)
886 return ERROR_INSUFFICIENT_BUFFER;
888 return NT_STATUS_NO_PROBLEMO;
891 /********************************************************************
893 * ReplyFindFirstPrinterChangeNotifyEx
895 * jfmxxxx: before replying OK: status=0
896 * should do a rpc call to the workstation asking ReplyOpenPrinter
897 * have to code it, later.
899 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
900 * called from api_spoolss_rffpcnex
901 ********************************************************************/
902 uint32 _spoolss_rffpcnex(POLICY_HND *handle, uint32 flags, uint32 options,
903 const UNISTR2 *localmachine, uint32 printerlocal,
904 SPOOL_NOTIFY_OPTION *option)
906 /* store the notify value in the printer struct */
908 Printer_entry *Printer=find_printer_index_by_hnd(handle);
910 if (!OPEN_HANDLE(Printer)) {
911 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
912 return ERROR_INVALID_HANDLE;
915 Printer->notify.flags=flags;
916 Printer->notify.options=options;
917 Printer->notify.printerlocal=printerlocal;
918 Printer->notify.option=option;
919 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
921 return NT_STATUS_NO_PROBLEMO;
924 /*******************************************************************
925 * fill a notify_info_data with the servername
926 ********************************************************************/
927 static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
928 NT_PRINTER_INFO_LEVEL *printer)
932 snprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
934 data->notify_data.data.length= (uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
935 temp_name, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
938 /*******************************************************************
939 * fill a notify_info_data with the servicename
940 * jfmxxxx: it's incorrect should be long_printername
941 ********************************************************************/
942 static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
943 NT_PRINTER_INFO_LEVEL *printer)
946 data->notify_data.data.length=strlen(lp_servicename(snum));
947 dos_PutUniCode(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string), True);
949 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
950 printer->info_2->printername, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
953 /*******************************************************************
954 * fill a notify_info_data with the servicename
955 ********************************************************************/
956 static void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
958 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
959 lp_servicename(snum), sizeof(data->notify_data.data.string),True) - sizeof(uint16))/sizeof(uint16));
962 /*******************************************************************
963 * fill a notify_info_data with the port name
964 ********************************************************************/
965 static void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
967 /* even if it's strange, that's consistant in all the code */
969 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
970 lp_servicename(snum), sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
973 /*******************************************************************
974 * fill a notify_info_data with the printername
975 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
976 * but it doesn't exist, have to see what to do
977 ********************************************************************/
978 static void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
980 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
981 printer->info_2->drivername, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
984 /*******************************************************************
985 * fill a notify_info_data with the comment
986 ********************************************************************/
987 static void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
989 if (*printer->info_2->comment == '\0')
990 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
991 lp_comment(snum), sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
993 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
994 printer->info_2->comment, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
997 /*******************************************************************
998 * fill a notify_info_data with the comment
999 * jfm:xxxx incorrect, have to create a new smb.conf option
1000 * location = "Room 1, floor 2, building 3"
1001 ********************************************************************/
1002 static void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1004 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1005 printer->info_2->location, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1008 /*******************************************************************
1009 * fill a notify_info_data with the device mode
1010 * jfm:xxxx don't to it for know but that's a real problem !!!
1011 ********************************************************************/
1012 static void spoolss_notify_devmode(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1016 /*******************************************************************
1017 * fill a notify_info_data with the separator file name
1018 * jfm:xxxx just return no file could add an option to smb.conf
1019 * separator file = "separator.txt"
1020 ********************************************************************/
1021 static void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1023 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1024 printer->info_2->sepfile, sizeof(data->notify_data.data.string)-1,True) - sizeof(uint16))/sizeof(uint16));
1027 /*******************************************************************
1028 * fill a notify_info_data with the print processor
1029 * jfm:xxxx return always winprint to indicate we don't do anything to it
1030 ********************************************************************/
1031 static void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1033 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1034 printer->info_2->printprocessor, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1037 /*******************************************************************
1038 * fill a notify_info_data with the print processor options
1039 * jfm:xxxx send an empty string
1040 ********************************************************************/
1041 static void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1043 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1044 printer->info_2->parameters, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1047 /*******************************************************************
1048 * fill a notify_info_data with the data type
1049 * jfm:xxxx always send RAW as data type
1050 ********************************************************************/
1051 static void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1053 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1054 printer->info_2->datatype, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1057 /*******************************************************************
1058 * fill a notify_info_data with the security descriptor
1059 * jfm:xxxx send an null pointer to say no security desc
1060 * have to implement security before !
1061 ********************************************************************/
1062 static void spoolss_notify_security_desc(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1064 data->notify_data.data.length=0;
1065 data->notify_data.data.string[0]=0x00;
1068 /*******************************************************************
1069 * fill a notify_info_data with the attributes
1070 * jfm:xxxx a samba printer is always shared
1071 ********************************************************************/
1072 static void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1074 data->notify_data.value[0] = PRINTER_ATTRIBUTE_SHARED \
1075 | PRINTER_ATTRIBUTE_LOCAL \
1076 | PRINTER_ATTRIBUTE_RAW_ONLY ;
1079 /*******************************************************************
1080 * fill a notify_info_data with the priority
1081 ********************************************************************/
1082 static void spoolss_notify_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1084 data->notify_data.value[0] = printer->info_2->priority;
1087 /*******************************************************************
1088 * fill a notify_info_data with the default priority
1089 ********************************************************************/
1090 static void spoolss_notify_default_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1092 data->notify_data.value[0] = printer->info_2->default_priority;
1095 /*******************************************************************
1096 * fill a notify_info_data with the start time
1097 ********************************************************************/
1098 static void spoolss_notify_start_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1100 data->notify_data.value[0] = printer->info_2->starttime;
1103 /*******************************************************************
1104 * fill a notify_info_data with the until time
1105 ********************************************************************/
1106 static void spoolss_notify_until_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1108 data->notify_data.value[0] = printer->info_2->untiltime;
1111 /*******************************************************************
1112 * fill a notify_info_data with the status
1113 ********************************************************************/
1114 static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1117 print_queue_struct *q=NULL;
1118 print_status_struct status;
1120 memset(&status, 0, sizeof(status));
1121 count = print_queue_status(snum, &q, &status);
1122 data->notify_data.value[0]=(uint32) status.status;
1126 /*******************************************************************
1127 * fill a notify_info_data with the number of jobs queued
1128 ********************************************************************/
1129 static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1131 print_queue_struct *q=NULL;
1132 print_status_struct status;
1134 memset(&status, 0, sizeof(status));
1135 data->notify_data.value[0] = print_queue_status(snum, &q, &status);
1139 /*******************************************************************
1140 * fill a notify_info_data with the average ppm
1141 ********************************************************************/
1142 static void spoolss_notify_average_ppm(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1144 /* always respond 8 pages per minutes */
1145 /* a little hard ! */
1146 data->notify_data.value[0] = printer->info_2->averageppm;
1149 /*******************************************************************
1150 * fill a notify_info_data with
1151 ********************************************************************/
1152 static void spoolss_notify_username(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1154 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1155 queue->user, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1158 /*******************************************************************
1159 * fill a notify_info_data with
1160 ********************************************************************/
1161 static void spoolss_notify_job_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1163 data->notify_data.value[0]=nt_printj_status(queue->status);
1166 /*******************************************************************
1167 * fill a notify_info_data with
1168 ********************************************************************/
1169 static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1171 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1172 queue->file, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1175 /*******************************************************************
1176 * fill a notify_info_data with
1177 ********************************************************************/
1178 static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1180 char *p = "unknown";
1181 switch (queue->status) {
1195 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1196 p, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1199 /*******************************************************************
1200 * fill a notify_info_data with
1201 ********************************************************************/
1202 static void spoolss_notify_job_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1204 data->notify_data.value[0]=0x0;
1207 /*******************************************************************
1208 * fill a notify_info_data with
1209 ********************************************************************/
1210 static void spoolss_notify_job_size(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1212 data->notify_data.value[0]=queue->size;
1215 /*******************************************************************
1216 * fill a notify_info_data with
1217 ********************************************************************/
1218 static void spoolss_notify_job_position(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1220 data->notify_data.value[0]=queue->job;
1225 struct s_notify_info_data_table
1231 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
1232 print_queue_struct *queue,
1233 NT_PRINTER_INFO_LEVEL *printer);
1236 struct s_notify_info_data_table notify_info_data_table[] =
1238 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
1239 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1240 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
1241 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1242 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1243 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
1244 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
1245 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1246 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
1247 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1248 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1249 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1250 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
1251 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
1252 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1253 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
1254 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1255 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1256 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
1257 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
1258 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
1259 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
1260 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
1261 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
1262 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
1263 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
1264 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1265 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
1266 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1267 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
1268 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
1269 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1270 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1271 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1272 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1273 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1274 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
1275 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
1276 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
1277 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
1278 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1279 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
1280 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, NULL },
1281 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1282 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1283 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
1284 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
1285 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
1286 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
1287 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
1288 { END, END, "", END, NULL }
1291 /*******************************************************************
1292 return the size of info_data structure
1293 ********************************************************************/
1294 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
1298 while (notify_info_data_table[i].type != END)
1300 if ( (notify_info_data_table[i].type == type ) &&
1301 (notify_info_data_table[i].field == field ) )
1303 return (notify_info_data_table[i].size);
1311 /*******************************************************************
1312 return the type of notify_info_data
1313 ********************************************************************/
1314 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
1318 while (notify_info_data_table[i].type != END)
1320 if ( (notify_info_data_table[i].type == type ) &&
1321 (notify_info_data_table[i].field == field ) )
1323 if (notify_info_data_table[i].size == POINTER)
1338 /****************************************************************************
1339 ****************************************************************************/
1340 static int search_notify(uint16 type, uint16 field, int *value)
1345 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1347 if ( (notify_info_data_table[j].type == type ) &&
1348 (notify_info_data_table[j].field == field ) )
1353 if ( found && (notify_info_data_table[j].fn != NULL) )
1359 /****************************************************************************
1360 ****************************************************************************/
1361 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1363 info_data->type = type;
1364 info_data->field = field;
1365 info_data->reserved = 0;
1367 info_data->size = size_of_notify_info_data(type, field);
1368 info_data->enc_type = type_of_notify_info_data(type, field);
1372 /*******************************************************************
1374 * fill a notify_info struct with info asked
1376 ********************************************************************/
1377 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1383 SPOOL_NOTIFY_INFO_DATA *current_data;
1384 NT_PRINTER_INFO_LEVEL *printer = NULL;
1385 print_queue_struct *queue=NULL;
1387 DEBUG(4,("construct_notify_printer_info\n"));
1389 type=option_type->type;
1391 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
1392 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1393 option_type->count, lp_servicename(snum)));
1395 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1398 for(field_num=0; field_num<option_type->count; field_num++) {
1399 field = option_type->fields[field_num];
1400 DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field));
1402 if (!search_notify(type, field, &j) )
1405 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1408 current_data=&info->data[info->count];
1410 construct_info_data(current_data, type, field, id);
1411 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1416 free_a_printer(&printer, 2);
1420 /*******************************************************************
1422 * fill a notify_info struct with info asked
1424 ********************************************************************/
1425 static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1431 SPOOL_NOTIFY_INFO_DATA *current_data;
1432 NT_PRINTER_INFO_LEVEL *printer = NULL;
1434 DEBUG(4,("construct_notify_jobs_info\n"));
1436 type = option_type->type;
1438 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
1439 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1440 option_type->count));
1442 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1445 for(field_num=0; field_num<option_type->count; field_num++) {
1446 field = option_type->fields[field_num];
1448 if (!search_notify(type, field, &j) )
1451 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1455 current_data=&(info->data[info->count]);
1457 construct_info_data(current_data, type, field, id);
1458 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1462 free_a_printer(&printer, 2);
1467 * JFM: The enumeration is not that simple, it's even non obvious.
1469 * let's take an example: I want to monitor the PRINTER SERVER for
1470 * the printer's name and the number of jobs currently queued.
1471 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
1472 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
1474 * I have 3 printers on the back of my server.
1476 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
1479 * 1 printer 1 name 1
1480 * 2 printer 1 cjob 1
1481 * 3 printer 2 name 2
1482 * 4 printer 2 cjob 2
1483 * 5 printer 3 name 3
1484 * 6 printer 3 name 3
1486 * that's the print server case, the printer case is even worse.
1491 /*******************************************************************
1493 * enumerate all printers on the printserver
1494 * fill a notify_info struct with info asked
1496 ********************************************************************/
1497 static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1500 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1501 int n_services=lp_numservices();
1504 SPOOL_NOTIFY_OPTION *option;
1505 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1507 DEBUG(4,("printserver_notify_info\n"));
1509 option=Printer->notify.option;
1515 for (i=0; i<option->count; i++) {
1516 option_type=&(option->ctr.type[i]);
1518 if (option_type->type!=PRINTER_NOTIFY_TYPE)
1521 for (snum=0; snum<n_services; snum++)
1522 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1523 if (construct_notify_printer_info(info, snum, option_type, id))
1528 * Debugging information, don't delete.
1531 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1532 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1533 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1535 for (i=0; i<info->count; i++) {
1536 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1537 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1538 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1542 return NT_STATUS_NO_PROBLEMO;
1545 /*******************************************************************
1547 * fill a notify_info struct with info asked
1549 ********************************************************************/
1550 static uint32 printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1553 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1556 SPOOL_NOTIFY_OPTION *option;
1557 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1559 print_queue_struct *queue=NULL;
1560 print_status_struct status;
1562 DEBUG(4,("printer_notify_info\n"));
1564 option=Printer->notify.option;
1570 get_printer_snum(hnd, &snum);
1572 for (i=0; i<option->count; i++) {
1573 option_type=&option->ctr.type[i];
1575 switch ( option_type->type ) {
1576 case PRINTER_NOTIFY_TYPE:
1577 if(construct_notify_printer_info(info, snum, option_type, id))
1581 case JOB_NOTIFY_TYPE:
1582 memset(&status, 0, sizeof(status));
1583 count = print_queue_status(snum, &queue, &status);
1584 for (j=0; j<count; j++)
1585 construct_notify_jobs_info(&queue[j], info, snum, option_type, queue[j].job);
1592 * Debugging information, don't delete.
1595 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1596 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1597 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1599 for (i=0; i<info->count; i++) {
1600 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1601 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1602 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1605 return NT_STATUS_NO_PROBLEMO;
1608 /********************************************************************
1610 ********************************************************************/
1611 uint32 _spoolss_rfnpcnex( POLICY_HND *handle, uint32 change,
1612 SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info)
1614 Printer_entry *Printer=find_printer_index_by_hnd(handle);
1616 if (!OPEN_HANDLE(Printer)) {
1617 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",OUR_HANDLE(handle)));
1618 return ERROR_INVALID_HANDLE;
1621 DEBUG(4,("Printer type %x\n",Printer->printer_type));
1623 /* jfm: the change value isn't used right now.
1624 * we will honour it when
1625 * a) we'll be able to send notification to the client
1626 * b) we'll have a way to communicate between the spoolss process.
1628 * same thing for option->flags
1629 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
1630 * I don't have a global notification system, I'm sending back all the
1631 * informations even when _NOTHING_ has changed.
1634 /* just discard the SPOOL_NOTIFY_OPTION */
1636 safe_free(option->ctr.type);
1638 switch (Printer->printer_type) {
1639 case PRINTER_HANDLE_IS_PRINTSERVER:
1640 return printserver_notify_info(handle, info);
1642 case PRINTER_HANDLE_IS_PRINTER:
1643 return printer_notify_info(handle, info);
1647 return ERROR_INVALID_HANDLE;
1650 /********************************************************************
1651 * construct_printer_info_0
1652 * fill a printer_info_1 struct
1653 ********************************************************************/
1654 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring servername)
1658 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1659 counter_printer_0 *session_counter;
1660 uint32 global_counter;
1662 time_t setup_time = time(NULL);
1664 print_queue_struct *queue=NULL;
1665 print_status_struct status;
1667 memset(&status, 0, sizeof(status));
1669 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1672 count = print_queue_status(snum, &queue, &status);
1674 /* check if we already have a counter for this printer */
1675 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
1677 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
1678 if (session_counter->snum == snum)
1682 /* it's the first time, add it to the list */
1683 if (session_counter==NULL) {
1684 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
1685 free_a_printer(&ntprinter, 2);
1688 ZERO_STRUCTP(session_counter);
1689 session_counter->snum=snum;
1690 session_counter->counter=0;
1691 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
1695 session_counter->counter++;
1698 * the global_counter should be stored in a TDB as it's common to all the clients
1699 * and should be zeroed on samba startup
1701 global_counter=session_counter->counter;
1703 /* the description and the name are of the form \\server\share */
1704 slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter->info_2->printername);
1706 init_unistr(&printer->printername, chaine);
1708 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1709 init_unistr(&printer->servername, chaine);
1711 printer->cjobs = count;
1712 printer->total_jobs = 0;
1713 printer->total_bytes = 0;
1715 t=gmtime(&setup_time);
1716 ntprinter->info_2->setuptime = (uint32)setup_time; /* FIXME !! */
1718 printer->year = t->tm_year+1900;
1719 printer->month = t->tm_mon+1;
1720 printer->dayofweek = t->tm_wday;
1721 printer->day = t->tm_mday;
1722 printer->hour = t->tm_hour;
1723 printer->minute = t->tm_min;
1724 printer->second = t->tm_sec;
1725 printer->milliseconds = 0;
1727 printer->global_counter = global_counter;
1728 printer->total_pages = 0;
1729 printer->major_version = 0x0004; /* NT 4 */
1730 printer->build_version = 0x0565; /* build 1381 */
1731 printer->unknown7 = 0x1;
1732 printer->unknown8 = 0x0;
1733 printer->unknown9 = 0x0;
1734 printer->session_counter = session_counter->counter;
1735 printer->unknown11 = 0x0;
1736 printer->printer_errors = 0x0; /* number of print failure */
1737 printer->unknown13 = 0x0;
1738 printer->unknown14 = 0x1;
1739 printer->unknown15 = 0x024a; /* 586 Pentium ? */
1740 printer->unknown16 = 0x0;
1741 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
1742 printer->unknown18 = 0x0;
1743 printer->status = nt_printq_status(status.status);
1744 printer->unknown20 = 0x0;
1745 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
1746 printer->unknown22 = 0x0;
1747 printer->unknown23 = 0x6; /* 6 ???*/
1748 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
1749 printer->unknown25 = 0;
1750 printer->unknown26 = 0;
1751 printer->unknown27 = 0;
1752 printer->unknown28 = 0;
1753 printer->unknown29 = 0;
1756 free_a_printer(&ntprinter,2);
1760 /********************************************************************
1761 * construct_printer_info_1
1762 * fill a printer_info_1 struct
1763 ********************************************************************/
1764 static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum)
1768 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1770 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1773 printer->flags=flags;
1775 if (*ntprinter->info_2->comment == '\0') {
1776 init_unistr(&printer->comment, lp_comment(snum));
1777 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1778 ntprinter->info_2->drivername, lp_comment(snum));
1781 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1782 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1783 ntprinter->info_2->drivername, ntprinter->info_2->comment);
1786 snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter->info_2->printername);
1788 init_unistr(&printer->description, chaine);
1789 init_unistr(&printer->name, chaine2);
1791 free_a_printer(&ntprinter,2);
1796 /****************************************************************************
1797 Free a DEVMODE struct.
1798 ****************************************************************************/
1800 static void free_dev_mode(DEVICEMODE *dev)
1806 safe_free(dev->private);
1811 /****************************************************************************
1812 Create a DEVMODE struct. Returns malloced memory.
1813 ****************************************************************************/
1815 static DEVICEMODE *construct_dev_mode(int snum, char *servername)
1819 NT_PRINTER_INFO_LEVEL *printer = NULL;
1820 NT_DEVICEMODE *ntdevmode = NULL;
1821 DEVICEMODE *devmode = NULL;
1823 DEBUG(7,("construct_dev_mode\n"));
1825 DEBUGADD(8,("getting printer characteristics\n"));
1827 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
1828 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
1832 ZERO_STRUCTP(devmode);
1834 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
1837 if (printer->info_2->devmode)
1838 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
1841 ntdevmode = construct_nt_devicemode(printer->info_2->printername);
1843 if (ntdevmode == NULL)
1846 DEBUGADD(8,("loading DEVICEMODE\n"));
1848 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, printer->info_2->printername);
1849 init_unistr(&devmode->devicename, adevice);
1851 snprintf(aform, sizeof(aform), ntdevmode->formname);
1852 init_unistr(&devmode->formname, aform);
1854 devmode->specversion = ntdevmode->specversion;
1855 devmode->driverversion = ntdevmode->driverversion;
1856 devmode->size = ntdevmode->size;
1857 devmode->driverextra = ntdevmode->driverextra;
1858 devmode->fields = ntdevmode->fields;
1860 devmode->orientation = ntdevmode->orientation;
1861 devmode->papersize = ntdevmode->papersize;
1862 devmode->paperlength = ntdevmode->paperlength;
1863 devmode->paperwidth = ntdevmode->paperwidth;
1864 devmode->scale = ntdevmode->scale;
1865 devmode->copies = ntdevmode->copies;
1866 devmode->defaultsource = ntdevmode->defaultsource;
1867 devmode->printquality = ntdevmode->printquality;
1868 devmode->color = ntdevmode->color;
1869 devmode->duplex = ntdevmode->duplex;
1870 devmode->yresolution = ntdevmode->yresolution;
1871 devmode->ttoption = ntdevmode->ttoption;
1872 devmode->collate = ntdevmode->collate;
1873 devmode->icmmethod = ntdevmode->icmmethod;
1874 devmode->icmintent = ntdevmode->icmintent;
1875 devmode->mediatype = ntdevmode->mediatype;
1876 devmode->dithertype = ntdevmode->dithertype;
1878 if (ntdevmode->private != NULL) {
1879 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
1883 free_nt_devicemode(&ntdevmode);
1884 free_a_printer(&printer,2);
1891 free_nt_devicemode(&ntdevmode);
1893 free_a_printer(&printer,2);
1894 free_dev_mode(devmode);
1899 /********************************************************************
1900 * construct_printer_info_2
1901 * fill a printer_info_2 struct
1902 ********************************************************************/
1904 static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer, int snum)
1910 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1912 print_queue_struct *queue=NULL;
1913 print_status_struct status;
1914 memset(&status, 0, sizeof(status));
1916 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1919 memset(&status, 0, sizeof(status));
1920 count = print_queue_status(snum, &queue, &status);
1922 snprintf(chaine, sizeof(chaine)-1, "%s", servername);
1924 if (strlen(servername)!=0)
1929 snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter->info_2->printername);
1931 init_unistr(&printer->servername, chaine); /* servername*/
1932 init_unistr(&printer->printername, chaine2); /* printername*/
1933 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
1934 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
1935 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
1937 if (*ntprinter->info_2->comment == '\0')
1938 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
1940 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1942 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
1943 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
1944 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
1945 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
1946 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
1948 printer->attributes = ntprinter->info_2->attributes;
1950 printer->priority = ntprinter->info_2->priority; /* priority */
1951 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
1952 printer->starttime = ntprinter->info_2->starttime; /* starttime */
1953 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
1954 printer->status = nt_printq_status(status.status); /* status */
1955 printer->cjobs = count; /* jobs */
1956 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
1958 if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) {
1959 DEBUG(8, ("Returning NULL Devicemode!\n"));
1962 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1963 /* steal the printer info sec_desc structure. [badly done]. */
1964 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1965 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
1966 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
1967 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
1970 printer->secdesc = NULL;
1973 free_a_printer(&ntprinter, 2);
1978 /********************************************************************
1979 * construct_printer_info_3
1980 * fill a printer_info_3 struct
1981 ********************************************************************/
1982 static BOOL construct_printer_info_3(fstring servername,
1983 PRINTER_INFO_3 **pp_printer, int snum)
1985 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1986 PRINTER_INFO_3 *printer = NULL;
1988 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1992 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
1993 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
1997 ZERO_STRUCTP(printer);
1999 printer->flags = 4; /* This is the offset to the SEC_DESC. */
2000 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
2001 /* steal the printer info sec_desc structure. [badly done]. */
2002 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2003 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
2004 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
2005 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
2008 free_a_printer(&ntprinter, 2);
2010 *pp_printer = printer;
2014 /********************************************************************
2015 Spoolss_enumprinters.
2016 ********************************************************************/
2017 static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2021 int n_services=lp_numservices();
2022 PRINTER_INFO_1 *printers=NULL;
2023 PRINTER_INFO_1 current_prt;
2025 DEBUG(4,("enum_all_printers_info_1\n"));
2027 for (snum=0; snum<n_services; snum++) {
2028 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2029 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2031 if (construct_printer_info_1(server, flags, ¤t_prt, snum)) {
2032 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
2034 return ERROR_NOT_ENOUGH_MEMORY;
2036 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2037 memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1));
2043 /* check the required size. */
2044 for (i=0; i<*returned; i++)
2045 (*needed) += spoolss_size_printer_info_1(&(printers[i]));
2047 if (!alloc_buffer_size(buffer, *needed))
2048 return ERROR_INSUFFICIENT_BUFFER;
2050 /* fill the buffer with the structures */
2051 for (i=0; i<*returned; i++)
2052 new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);
2055 safe_free(printers);
2057 if (*needed > offered) {
2059 return ERROR_INSUFFICIENT_BUFFER;
2062 return NT_STATUS_NO_PROBLEMO;
2065 /********************************************************************
2066 enum_all_printers_info_1_local.
2067 *********************************************************************/
2068 static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2071 DEBUG(4,("enum_all_printers_info_1_local\n"));
2073 fstrcpy(temp, "\\\\");
2074 fstrcat(temp, global_myname);
2076 if (!strcmp(name, temp)) {
2077 fstrcat(temp, "\\");
2078 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2081 return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2084 /********************************************************************
2085 enum_all_printers_info_1_name.
2086 *********************************************************************/
2087 static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2090 DEBUG(4,("enum_all_printers_info_1_name\n"));
2092 fstrcpy(temp, "\\\\");
2093 fstrcat(temp, global_myname);
2095 if (!strcmp(name, temp)) {
2096 fstrcat(temp, "\\");
2097 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2100 return ERROR_INVALID_NAME;
2103 /********************************************************************
2104 enum_all_printers_info_1_remote.
2105 *********************************************************************/
2106 static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2108 PRINTER_INFO_1 *printer;
2109 fstring printername;
2112 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2114 /* JFM: currently it's more a place holder than anything else.
2115 * In the spooler world there is a notion of server registration.
2116 * the print servers are registring (sp ?) on the PDC (in the same domain)
2118 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2121 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2122 return ERROR_NOT_ENOUGH_MEMORY;
2126 snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
2127 snprintf(desc, sizeof(desc)-1,"%s", global_myname);
2128 snprintf(comment, sizeof(comment)-1, "Logged on Domain");
2130 init_unistr(&printer->description, desc);
2131 init_unistr(&printer->name, printername);
2132 init_unistr(&printer->comment, comment);
2133 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2135 /* check the required size. */
2136 *needed += spoolss_size_printer_info_1(printer);
2138 if (!alloc_buffer_size(buffer, *needed)) {
2140 return ERROR_INSUFFICIENT_BUFFER;
2143 /* fill the buffer with the structures */
2144 new_smb_io_printer_info_1("", buffer, printer, 0);
2149 if (*needed > offered) {
2151 return ERROR_INSUFFICIENT_BUFFER;
2154 return NT_STATUS_NO_PROBLEMO;
2157 /********************************************************************
2158 enum_all_printers_info_1_network.
2159 *********************************************************************/
2160 static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2163 DEBUG(4,("enum_all_printers_info_1_network\n"));
2165 fstrcpy(temp, "\\\\");
2166 fstrcat(temp, global_myname);
2167 fstrcat(temp, "\\");
2168 return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
2171 /********************************************************************
2172 * api_spoolss_enumprinters
2174 * called from api_spoolss_enumprinters (see this to understand)
2175 ********************************************************************/
2176 static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2180 int n_services=lp_numservices();
2181 PRINTER_INFO_2 *printers=NULL;
2182 PRINTER_INFO_2 current_prt;
2184 for (snum=0; snum<n_services; snum++) {
2185 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2186 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2188 if (construct_printer_info_2(servername, ¤t_prt, snum)) {
2189 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL)
2190 return ERROR_NOT_ENOUGH_MEMORY;
2191 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
2192 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
2198 /* check the required size. */
2199 for (i=0; i<*returned; i++)
2200 (*needed) += spoolss_size_printer_info_2(&printers[i]);
2202 if (!alloc_buffer_size(buffer, *needed)) {
2203 for (i=0; i<*returned; i++) {
2204 free_devmode(printers[i].devmode);
2205 free_sec_desc(&printers[i].secdesc);
2207 safe_free(printers);
2208 return ERROR_INSUFFICIENT_BUFFER;
2211 /* fill the buffer with the structures */
2212 for (i=0; i<*returned; i++)
2213 new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);
2216 for (i=0; i<*returned; i++) {
2217 free_devmode(printers[i].devmode);
2218 free_sec_desc(&printers[i].secdesc);
2220 safe_free(printers);
2222 if (*needed > offered) {
2224 return ERROR_INSUFFICIENT_BUFFER;
2227 return NT_STATUS_NO_PROBLEMO;
2230 /********************************************************************
2231 * handle enumeration of printers at level 1
2232 ********************************************************************/
2233 static uint32 enumprinters_level1( uint32 flags, fstring name,
2234 NEW_BUFFER *buffer, uint32 offered,
2235 uint32 *needed, uint32 *returned)
2237 /* Not all the flags are equals */
2239 if (flags & PRINTER_ENUM_LOCAL)
2240 return enum_all_printers_info_1_local(name, buffer, offered, needed, returned);
2242 if (flags & PRINTER_ENUM_NAME)
2243 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
2245 if (flags & PRINTER_ENUM_REMOTE)
2246 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
2248 if (flags & PRINTER_ENUM_NETWORK)
2249 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
2251 return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
2254 /********************************************************************
2255 * handle enumeration of printers at level 2
2256 ********************************************************************/
2257 static uint32 enumprinters_level2( uint32 flags, fstring servername,
2258 NEW_BUFFER *buffer, uint32 offered,
2259 uint32 *needed, uint32 *returned)
2263 fstrcpy(temp, "\\\\");
2264 fstrcat(temp, global_myname);
2266 if (flags & PRINTER_ENUM_LOCAL) {
2267 if (!strcmp(servername, temp))
2268 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2270 return enum_all_printers_info_2("", buffer, offered, needed, returned);
2273 if (flags & PRINTER_ENUM_NAME) {
2274 if (!strcmp(servername, temp))
2275 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2277 return ERROR_INVALID_NAME;
2280 if (flags & PRINTER_ENUM_REMOTE)
2281 return ERROR_INVALID_LEVEL;
2283 return NT_STATUS_NO_PROBLEMO;
2286 /********************************************************************
2287 * handle enumeration of printers at level 5
2288 ********************************************************************/
2289 static uint32 enumprinters_level5( uint32 flags, fstring servername,
2290 NEW_BUFFER *buffer, uint32 offered,
2291 uint32 *needed, uint32 *returned)
2293 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
2294 return NT_STATUS_NO_PROBLEMO;
2297 /********************************************************************
2298 * api_spoolss_enumprinters
2300 * called from api_spoolss_enumprinters (see this to understand)
2301 ********************************************************************/
2302 uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
2303 NEW_BUFFER *buffer, uint32 offered,
2304 uint32 *needed, uint32 *returned)
2308 DEBUG(4,("_spoolss_enumprinters\n"));
2315 * flags==PRINTER_ENUM_NAME
2316 * if name=="" then enumerates all printers
2317 * if name!="" then enumerate the printer
2318 * flags==PRINTER_ENUM_REMOTE
2319 * name is NULL, enumerate printers
2320 * Level 2: name!="" enumerates printers, name can't be NULL
2321 * Level 3: doesn't exist
2322 * Level 4: does a local registry lookup
2323 * Level 5: same as Level 2
2326 unistr2_to_ascii(name, servername, sizeof(name)-1);
2331 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
2334 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
2337 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
2342 return ERROR_INVALID_LEVEL;
2347 /****************************************************************************
2348 ****************************************************************************/
2349 static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2351 PRINTER_INFO_0 *printer=NULL;
2353 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
2354 return ERROR_NOT_ENOUGH_MEMORY;
2356 construct_printer_info_0(printer, snum, servername);
2358 /* check the required size. */
2359 *needed += spoolss_size_printer_info_0(printer);
2361 if (!alloc_buffer_size(buffer, *needed)) {
2363 return ERROR_INSUFFICIENT_BUFFER;
2366 /* fill the buffer with the structures */
2367 new_smb_io_printer_info_0("", buffer, printer, 0);
2372 if (*needed > offered) {
2373 return ERROR_INSUFFICIENT_BUFFER;
2376 return NT_STATUS_NO_PROBLEMO;
2379 /****************************************************************************
2380 ****************************************************************************/
2381 static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2383 PRINTER_INFO_1 *printer=NULL;
2385 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2386 return ERROR_NOT_ENOUGH_MEMORY;
2388 construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum);
2390 /* check the required size. */
2391 *needed += spoolss_size_printer_info_1(printer);
2393 if (!alloc_buffer_size(buffer, *needed)) {
2395 return ERROR_INSUFFICIENT_BUFFER;
2398 /* fill the buffer with the structures */
2399 new_smb_io_printer_info_1("", buffer, printer, 0);
2404 if (*needed > offered) {
2405 return ERROR_INSUFFICIENT_BUFFER;
2408 return NT_STATUS_NO_PROBLEMO;
2411 /****************************************************************************
2412 ****************************************************************************/
2413 static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2415 PRINTER_INFO_2 *printer=NULL;
2418 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
2419 return ERROR_NOT_ENOUGH_MEMORY;
2421 fstrcpy(temp, "\\\\");
2422 fstrcat(temp, servername);
2423 construct_printer_info_2(temp, printer, snum);
2425 /* check the required size. */
2426 *needed += spoolss_size_printer_info_2(printer);
2428 if (!alloc_buffer_size(buffer, *needed)) {
2429 free_printer_info_2(printer);
2430 return ERROR_INSUFFICIENT_BUFFER;
2433 /* fill the buffer with the structures */
2434 if (!new_smb_io_printer_info_2("", buffer, printer, 0)) {
2435 free_printer_info_2(printer);
2436 return ERROR_NOT_ENOUGH_MEMORY;
2440 free_printer_info_2(printer);
2442 if (*needed > offered) {
2443 return ERROR_INSUFFICIENT_BUFFER;
2446 return NT_STATUS_NO_PROBLEMO;
2449 /****************************************************************************
2450 ****************************************************************************/
2451 static uint32 getprinter_level_3(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2453 PRINTER_INFO_3 *printer=NULL;
2456 fstrcpy(temp, "\\\\");
2457 fstrcat(temp, servername);
2458 if (!construct_printer_info_3(temp, &printer, snum))
2459 return ERROR_NOT_ENOUGH_MEMORY;
2461 /* check the required size. */
2462 *needed += spoolss_size_printer_info_3(printer);
2464 if (!alloc_buffer_size(buffer, *needed)) {
2465 free_printer_info_3(printer);
2466 return ERROR_INSUFFICIENT_BUFFER;
2469 /* fill the buffer with the structures */
2470 new_smb_io_printer_info_3("", buffer, printer, 0);
2473 free_printer_info_3(printer);
2475 if (*needed > offered) {
2476 return ERROR_INSUFFICIENT_BUFFER;
2479 return NT_STATUS_NO_PROBLEMO;
2482 /****************************************************************************
2483 ****************************************************************************/
2484 uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
2485 NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2492 pstrcpy(servername, global_myname);
2494 if (!get_printer_snum(handle, &snum))
2495 return ERROR_INVALID_HANDLE;
2499 return getprinter_level_0(servername, snum, buffer, offered, needed);
2501 return getprinter_level_1(servername,snum, buffer, offered, needed);
2503 return getprinter_level_2(servername,snum, buffer, offered, needed);
2505 return getprinter_level_3(servername,snum, buffer, offered, needed);
2507 return ERROR_INVALID_LEVEL;
2512 /********************************************************************
2513 * fill a DRIVER_INFO_1 struct
2514 ********************************************************************/
2515 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
2517 init_unistr( &info->name, driver.info_3->name);
2520 /********************************************************************
2521 * construct_printer_driver_info_1
2522 ********************************************************************/
2523 static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
2525 NT_PRINTER_INFO_LEVEL *printer = NULL;
2526 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2528 ZERO_STRUCT(driver);
2530 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2531 return ERROR_INVALID_PRINTER_NAME;
2533 if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2534 return ERROR_UNKNOWN_PRINTER_DRIVER;
2536 fill_printer_driver_info_1(info, driver, servername, architecture);
2538 free_a_printer(&printer,2);
2540 return NT_STATUS_NO_PROBLEMO;
2543 /********************************************************************
2544 * construct_printer_driver_info_2
2545 * fill a printer_info_2 struct
2546 ********************************************************************/
2547 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2549 pstring temp_driverpath;
2550 pstring temp_datafile;
2551 pstring temp_configfile;
2553 info->version=driver.info_3->cversion;
2555 init_unistr( &info->name, driver.info_3->name );
2556 init_unistr( &info->architecture, driver.info_3->environment );
2558 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2559 init_unistr( &info->driverpath, temp_driverpath );
2561 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2562 init_unistr( &info->datafile, temp_datafile );
2564 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2565 init_unistr( &info->configfile, temp_configfile );
2568 /********************************************************************
2569 * construct_printer_driver_info_2
2570 * fill a printer_info_2 struct
2571 ********************************************************************/
2572 static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
2574 NT_PRINTER_INFO_LEVEL *printer = NULL;
2575 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2577 ZERO_STRUCT(printer);
2578 ZERO_STRUCT(driver);
2580 if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2581 return ERROR_INVALID_PRINTER_NAME;
2583 if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2584 return ERROR_UNKNOWN_PRINTER_DRIVER;
2586 fill_printer_driver_info_2(info, driver, servername);
2588 free_a_printer(&printer,2);
2590 return NT_STATUS_NO_PROBLEMO;
2593 /********************************************************************
2594 * copy a strings array and convert to UNICODE
2596 * convert an array of ascii string to a UNICODE string
2597 ********************************************************************/
2598 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
2605 DEBUG(6,("init_unistr_array\n"));
2609 if (char_array == NULL)
2613 if (!v) v = ""; /* hack to handle null lists */
2615 if (strlen(v) == 0) break;
2616 snprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
2617 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
2618 if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
2619 DEBUG(0,("init_unistr_array: Realloc error\n" ));
2622 j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
2627 (*uni_array)[j]=0x0000;
2630 DEBUGADD(6,("last one:done\n"));
2633 /********************************************************************
2634 * construct_printer_info_3
2635 * fill a printer_info_3 struct
2636 ********************************************************************/
2637 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2639 pstring temp_driverpath;
2640 pstring temp_datafile;
2641 pstring temp_configfile;
2642 pstring temp_helpfile;
2644 info->version=driver.info_3->cversion;
2646 init_unistr( &info->name, driver.info_3->name );
2647 init_unistr( &info->architecture, driver.info_3->environment );
2649 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2650 init_unistr( &info->driverpath, temp_driverpath );
2652 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2653 init_unistr( &info->datafile, temp_datafile );
2655 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2656 init_unistr( &info->configfile, temp_configfile );
2658 snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
2659 init_unistr( &info->helpfile, temp_helpfile );
2661 init_unistr( &info->monitorname, driver.info_3->monitorname );
2662 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
2664 info->dependentfiles=NULL;
2665 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
2668 /********************************************************************
2669 * construct_printer_info_3
2670 * fill a printer_info_3 struct
2671 ********************************************************************/
2672 static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
2674 NT_PRINTER_INFO_LEVEL *printer = NULL;
2675 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2677 ZERO_STRUCT(driver);
2679 status=get_a_printer(&printer, 2, lp_servicename(snum) );
2680 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2682 return ERROR_INVALID_PRINTER_NAME;
2684 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
2685 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2687 free_a_printer(&printer,2);
2688 return ERROR_UNKNOWN_PRINTER_DRIVER;
2691 fill_printer_driver_info_3(info, driver, servername);
2693 free_a_printer(&printer,2);
2695 return NT_STATUS_NO_PROBLEMO;
2698 /****************************************************************************
2699 ****************************************************************************/
2701 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
2703 safe_free(info->dependentfiles);
2706 /****************************************************************************
2707 ****************************************************************************/
2708 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2710 DRIVER_INFO_1 *info=NULL;
2713 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
2714 return ERROR_NOT_ENOUGH_MEMORY;
2716 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
2717 if (status != NT_STATUS_NO_PROBLEMO) {
2722 /* check the required size. */
2723 *needed += spoolss_size_printer_driver_info_1(info);
2725 if (!alloc_buffer_size(buffer, *needed)) {
2727 return ERROR_INSUFFICIENT_BUFFER;
2730 /* fill the buffer with the structures */
2731 new_smb_io_printer_driver_info_1("", buffer, info, 0);
2736 if (*needed > offered)
2737 return ERROR_INSUFFICIENT_BUFFER;
2739 return NT_STATUS_NO_PROBLEMO;
2742 /****************************************************************************
2743 ****************************************************************************/
2744 static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2746 DRIVER_INFO_2 *info=NULL;
2749 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
2750 return ERROR_NOT_ENOUGH_MEMORY;
2752 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
2753 if (status != NT_STATUS_NO_PROBLEMO) {
2758 /* check the required size. */
2759 *needed += spoolss_size_printer_driver_info_2(info);
2761 if (!alloc_buffer_size(buffer, *needed)) {
2763 return ERROR_INSUFFICIENT_BUFFER;
2766 /* fill the buffer with the structures */
2767 new_smb_io_printer_driver_info_2("", buffer, info, 0);
2772 if (*needed > offered)
2773 return ERROR_INSUFFICIENT_BUFFER;
2775 return NT_STATUS_NO_PROBLEMO;
2778 /****************************************************************************
2779 ****************************************************************************/
2780 static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2787 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
2788 if (status != NT_STATUS_NO_PROBLEMO) {
2792 /* check the required size. */
2793 *needed += spoolss_size_printer_driver_info_3(&info);
2795 if (!alloc_buffer_size(buffer, *needed)) {
2796 free_printer_driver_info_3(&info);
2797 return ERROR_INSUFFICIENT_BUFFER;
2800 /* fill the buffer with the structures */
2801 new_smb_io_printer_driver_info_3("", buffer, &info, 0);
2803 free_printer_driver_info_3(&info);
2805 if (*needed > offered)
2806 return ERROR_INSUFFICIENT_BUFFER;
2808 return NT_STATUS_NO_PROBLEMO;
2811 /****************************************************************************
2812 ****************************************************************************/
2813 uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level,
2814 uint32 clientmajorversion, uint32 clientminorversion,
2815 NEW_BUFFER *buffer, uint32 offered,
2816 uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
2819 fstring architecture;
2822 DEBUG(4,("_spoolss_getprinterdriver2\n"));
2825 *servermajorversion=0;
2826 *serverminorversion=0;
2828 pstrcpy(servername, global_myname);
2829 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
2831 if (!get_printer_snum(handle, &snum))
2832 return ERROR_INVALID_HANDLE;
2836 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2839 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2842 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2845 return ERROR_INVALID_LEVEL;
2850 /****************************************************************************
2851 ****************************************************************************/
2852 uint32 _spoolss_startpageprinter(POLICY_HND *handle)
2854 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2856 if (OPEN_HANDLE(Printer)) {
2857 Printer->page_started=True;
2861 DEBUG(3,("Error in startpageprinter printer handle\n"));
2862 return ERROR_INVALID_HANDLE;
2865 /****************************************************************************
2866 ****************************************************************************/
2867 uint32 _spoolss_endpageprinter(POLICY_HND *handle)
2869 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2871 if (!OPEN_HANDLE(Printer)) {
2872 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
2873 return ERROR_INVALID_HANDLE;
2876 Printer->page_started=False;
2878 return NT_STATUS_NO_PROBLEMO;
2882 /********************************************************************
2883 * api_spoolss_getprinter
2884 * called from the spoolss dispatcher
2886 ********************************************************************/
2887 uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
2888 pipes_struct *p, DOC_INFO *docinfo,
2891 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
2895 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2896 struct current_user user;
2898 if (!OPEN_HANDLE(Printer)) {
2899 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2900 return ERROR_INVALID_HANDLE;
2903 if (p->ntlmssp_auth_validated) {
2904 memcpy(&user, &p->pipe_user, sizeof(user));
2906 extern struct current_user current_user;
2907 memcpy(&user, ¤t_user, sizeof(user));
2911 * a nice thing with NT is it doesn't listen to what you tell it.
2912 * when asked to send _only_ RAW datas, it tries to send datas
2915 * So I add checks like in NT Server ...
2917 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
2918 * there's a bug in NT client-side code, so we'll fix it in the
2919 * server-side code. *nnnnnggggh!*
2922 if (info_1->p_datatype != 0)
2924 unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype));
2925 if (strcmp(datatype, "RAW") != 0)
2928 return ERROR_INVALID_DATATYPE;
2932 /* get the share number of the printer */
2933 if (!get_printer_snum(handle, &snum))
2935 return ERROR_INVALID_HANDLE;
2938 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
2940 Printer->jobid = print_job_start(&user, snum, jobname);
2942 /* need to map error codes properly - for now give out of
2943 memory as I don't know the correct codes (tridge) */
2944 if (Printer->jobid == -1) {
2945 return ERROR_NOT_ENOUGH_MEMORY;
2948 Printer->document_started=True;
2949 (*jobid) = Printer->jobid;
2954 /********************************************************************
2955 * api_spoolss_getprinter
2956 * called from the spoolss dispatcher
2958 ********************************************************************/
2959 uint32 _spoolss_enddocprinter(POLICY_HND *handle)
2961 Printer_entry *Printer=find_printer_index_by_hnd(handle);
2963 if (!OPEN_HANDLE(Printer)) {
2964 DEBUG(0,("_spoolss_enddocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2965 return ERROR_INVALID_HANDLE;
2968 Printer->document_started=False;
2969 print_job_end(Printer->jobid);
2970 /* error codes unhandled so far ... */
2975 /****************************************************************************
2976 ****************************************************************************/
2977 uint32 _spoolss_writeprinter( POLICY_HND *handle,
2980 uint32 *buffer_written)
2982 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2984 if (!OPEN_HANDLE(Printer)) {
2985 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
2986 return ERROR_INVALID_HANDLE;
2989 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer,
2995 /********************************************************************
2996 * api_spoolss_getprinter
2997 * called from the spoolss dispatcher
2999 ********************************************************************/
3000 static uint32 control_printer(POLICY_HND *handle, uint32 command,
3003 struct current_user user;
3005 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3007 if (p->ntlmssp_auth_validated) {
3008 memcpy(&user, &p->pipe_user, sizeof(user));
3010 extern struct current_user current_user;
3011 memcpy(&user, ¤t_user, sizeof(user));
3014 if (!OPEN_HANDLE(Printer)) {
3015 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3016 return ERROR_INVALID_HANDLE;
3019 if (!get_printer_snum(handle, &snum) )
3020 return ERROR_INVALID_HANDLE;
3023 case PRINTER_CONTROL_PAUSE:
3024 if (print_queue_pause(&user, snum)) {
3028 case PRINTER_CONTROL_RESUME:
3029 case PRINTER_CONTROL_UNPAUSE:
3030 if (print_queue_resume(&user, snum)) {
3034 case PRINTER_CONTROL_PURGE:
3035 if (print_queue_purge(&user, snum)) {
3041 return ERROR_INVALID_FUNCTION;
3044 /********************************************************************
3045 * called by spoolss_api_setprinter
3046 * when updating a printer description
3047 ********************************************************************/
3048 static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
3049 const SPOOL_PRINTER_INFO_LEVEL *info,
3050 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
3052 struct current_user user;
3056 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3058 if (!OPEN_HANDLE(Printer) || !get_printer_snum(handle, &snum)) {
3059 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3060 return ERROR_INVALID_HANDLE;
3063 /* Work out which user is performing the operation */
3064 if (p->ntlmssp_auth_validated) {
3065 memcpy(&user, &p->pipe_user, sizeof(user));
3067 extern struct current_user current_user;
3068 memcpy(&user, ¤t_user, sizeof(user));
3071 /* Check the user has permissions to change the security
3072 descriptor. By experimentation with two NT machines, the user
3073 requires Full Access to the printer to change security
3075 if (!print_access_check(&user, snum, PRINTER_ACE_FULL_CONTROL)) {
3076 result = NT_STATUS_ACCESS_DENIED;
3080 result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
3086 /********************************************************************
3087 Do Samba sanity checks on a printer info struct.
3088 ********************************************************************/
3090 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
3093 * Ensure that this printer is shared under the correct name
3094 * as this is what Samba insists upon.
3097 if (!(info->attributes & PRINTER_ATTRIBUTE_SHARED)) {
3098 DEBUG(10,("check_printer_ok: SHARED check failed (%x).\n", (unsigned int)info->attributes ));
3102 if (!(info->attributes & PRINTER_ATTRIBUTE_RAW_ONLY)) {
3103 /* NT forgets to set the raw attribute but sends the correct type. */
3104 if (strequal(info->datatype, "RAW"))
3105 info->attributes |= PRINTER_ATTRIBUTE_RAW_ONLY;
3107 DEBUG(10,("check_printer_ok: RAW check failed (%x).\n", (unsigned int)info->attributes ));
3112 if (!strequal(info->sharename, lp_servicename(snum))) {
3113 DEBUG(10,("check_printer_ok: NAME check failed (%s) (%s).\n", info->sharename, lp_servicename(snum)));
3120 /********************************************************************
3121 * called by spoolss_api_setprinter
3122 * when updating a printer description
3123 ********************************************************************/
3125 static uint32 update_printer(POLICY_HND *handle, uint32 level,
3126 const SPOOL_PRINTER_INFO_LEVEL *info,
3127 DEVICEMODE *devmode)
3130 NT_PRINTER_INFO_LEVEL *printer = NULL;
3131 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3134 DEBUG(8,("update_printer\n"));
3136 result = NT_STATUS_NO_PROBLEMO;
3138 /* Check calling user has permission to update printer description */
3141 DEBUG(0,("Send a mail to samba@samba.org\n"));
3142 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3143 result = ERROR_INVALID_LEVEL;
3147 if (!OPEN_HANDLE(Printer)) {
3148 result = ERROR_INVALID_HANDLE;
3152 if (!get_printer_snum(handle, &snum)) {
3153 result = ERROR_INVALID_HANDLE;
3157 if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
3158 DEBUG(3, ("printer property change denied by security "
3160 result = NT_STATUS_ACCESS_DENIED;
3164 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3165 result = ERROR_INVALID_HANDLE;
3169 DEBUGADD(8,("Converting info_2 struct\n"));
3172 * convert_printer_info converts the incoming
3173 * info from the client and overwrites the info
3174 * just read from the tdb in the pointer 'printer'.
3177 convert_printer_info(info, printer, level);
3179 if (info->info_2->devmode_ptr != 0) {
3180 /* we have a valid devmode
3181 convert it and link it*/
3184 * Ensure printer->info_2->devmode is a valid pointer
3185 * as we will be overwriting it in convert_devicemode().
3188 if (printer->info_2->devmode == NULL)
3189 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3191 DEBUGADD(8,("Converting the devicemode struct\n"));
3192 convert_devicemode(devmode, printer->info_2->devmode);
3195 if (printer->info_2->devmode != NULL)
3196 free_nt_devicemode(&printer->info_2->devmode);
3197 printer->info_2->devmode=NULL;
3201 * Do sanity check on the requested changes for Samba.
3204 if (!check_printer_ok(printer->info_2, snum)) {
3205 result = ERROR_INVALID_PARAMETER;
3209 if (add_a_printer(*printer, 2)!=0) {
3210 /* I don't really know what to return here !!! */
3211 result = ERROR_ACCESS_DENIED;
3216 free_a_printer(&printer, 2);
3221 /****************************************************************************
3222 ****************************************************************************/
3223 uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
3224 const SPOOL_PRINTER_INFO_LEVEL *info,
3225 DEVMODE_CTR devmode_ctr,
3226 SEC_DESC_BUF *secdesc_ctr,
3227 uint32 command, pipes_struct *p)
3229 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3231 if (!OPEN_HANDLE(Printer)) {
3232 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3233 return ERROR_INVALID_HANDLE;
3236 /* check the level */
3239 return control_printer(handle, command, p);
3242 return update_printer(handle, level, info, devmode_ctr.devmode);
3245 return update_printer_sec(handle, level, info, p,
3249 return ERROR_INVALID_LEVEL;
3254 /****************************************************************************
3255 ****************************************************************************/
3256 uint32 _spoolss_fcpn(POLICY_HND *handle)
3258 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3260 if (!OPEN_HANDLE(Printer)) {
3261 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3262 return ERROR_INVALID_HANDLE;
3265 Printer->notify.flags=0;
3266 Printer->notify.options=0;
3267 Printer->notify.localmachine[0]='\0';
3268 Printer->notify.printerlocal=0;
3269 if (Printer->notify.option)
3270 safe_free(Printer->notify.option->ctr.type);
3271 safe_free(Printer->notify.option);
3272 Printer->notify.option=NULL;
3274 return NT_STATUS_NO_PROBLEMO;
3277 /****************************************************************************
3278 ****************************************************************************/
3279 uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
3280 NEW_BUFFER *buffer, uint32 offered)
3282 return NT_STATUS_NO_PROBLEMO;
3285 /****************************************************************************
3286 ****************************************************************************/
3287 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3288 int position, int snum)
3293 time_t unixdate = time(NULL);
3295 t=gmtime(&unixdate);
3296 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3298 job_info->jobid=queue->job;
3299 init_unistr(&job_info->printername, lp_servicename(snum));
3300 init_unistr(&job_info->machinename, temp_name);
3301 init_unistr(&job_info->username, queue->user);
3302 init_unistr(&job_info->document, queue->file);
3303 init_unistr(&job_info->datatype, "RAW");
3304 init_unistr(&job_info->text_status, "");
3305 job_info->status=nt_printj_status(queue->status);
3306 job_info->priority=queue->priority;
3307 job_info->position=position;
3308 job_info->totalpages=0;
3309 job_info->pagesprinted=0;
3311 make_systemtime(&job_info->submitted, t);
3314 /****************************************************************************
3315 ****************************************************************************/
3316 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3317 int position, int snum)
3320 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3324 time_t unixdate = time(NULL);
3326 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3329 t=gmtime(&unixdate);
3330 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3332 job_info->jobid=queue->job;
3334 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3336 init_unistr(&job_info->printername, chaine);
3338 init_unistr(&job_info->machinename, temp_name);
3339 init_unistr(&job_info->username, queue->user);
3340 init_unistr(&job_info->document, queue->file);
3341 init_unistr(&job_info->notifyname, queue->user);
3342 init_unistr(&job_info->datatype, "RAW");
3343 init_unistr(&job_info->printprocessor, "winprint");
3344 init_unistr(&job_info->parameters, "");
3345 init_unistr(&job_info->text_status, "");
3347 /* and here the security descriptor */
3349 job_info->status=nt_printj_status(queue->status);
3350 job_info->priority=queue->priority;
3351 job_info->position=position;
3352 job_info->starttime=0;
3353 job_info->untiltime=0;
3354 job_info->totalpages=0;
3355 job_info->size=queue->size;
3356 make_systemtime(&(job_info->submitted), t);
3357 job_info->timeelapsed=0;
3358 job_info->pagesprinted=0;
3360 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3361 free_a_printer(&ntprinter, 2);
3365 free_a_printer(&ntprinter, 2);
3369 /****************************************************************************
3370 Enumjobs at level 1.
3371 ****************************************************************************/
3372 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3373 NEW_BUFFER *buffer, uint32 offered,
3374 uint32 *needed, uint32 *returned)
3379 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3383 return ERROR_NOT_ENOUGH_MEMORY;
3386 for (i=0; i<*returned; i++)
3387 fill_job_info_1(&info[i], &queue[i], i, snum);
3391 /* check the required size. */
3392 for (i=0; i<*returned; i++)
3393 (*needed) += spoolss_size_job_info_1(&info[i]);
3395 if (!alloc_buffer_size(buffer, *needed)) {
3397 return ERROR_INSUFFICIENT_BUFFER;
3400 /* fill the buffer with the structures */
3401 for (i=0; i<*returned; i++)
3402 new_smb_io_job_info_1("", buffer, &info[i], 0);
3407 if (*needed > offered) {
3409 return ERROR_INSUFFICIENT_BUFFER;
3412 return NT_STATUS_NO_PROBLEMO;
3415 /****************************************************************************
3416 Enumjobs at level 2.
3417 ****************************************************************************/
3418 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3419 NEW_BUFFER *buffer, uint32 offered,
3420 uint32 *needed, uint32 *returned)
3425 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3429 return ERROR_NOT_ENOUGH_MEMORY;
3432 for (i=0; i<*returned; i++)
3433 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3437 /* check the required size. */
3438 for (i=0; i<*returned; i++)
3439 (*needed) += spoolss_size_job_info_2(&info[i]);
3441 if (!alloc_buffer_size(buffer, *needed)) {
3443 return ERROR_INSUFFICIENT_BUFFER;
3446 /* fill the buffer with the structures */
3447 for (i=0; i<*returned; i++)
3448 new_smb_io_job_info_2("", buffer, &info[i], 0);
3453 if (*needed > offered) {
3455 return ERROR_INSUFFICIENT_BUFFER;
3458 return NT_STATUS_NO_PROBLEMO;
3461 /****************************************************************************
3463 ****************************************************************************/
3464 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3465 NEW_BUFFER *buffer, uint32 offered,
3466 uint32 *needed, uint32 *returned)
3469 print_queue_struct *queue=NULL;
3470 print_status_struct prt_status;
3472 DEBUG(4,("_spoolss_enumjobs\n"));
3474 ZERO_STRUCT(prt_status);
3479 if (!get_printer_snum(handle, &snum))
3480 return ERROR_INVALID_HANDLE;
3482 *returned = print_queue_status(snum, &queue, &prt_status);
3483 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3487 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3490 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3495 return ERROR_INVALID_LEVEL;
3501 /****************************************************************************
3502 ****************************************************************************/
3503 uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid)
3508 /****************************************************************************
3509 ****************************************************************************/
3510 uint32 _spoolss_setjob( POLICY_HND *handle,
3518 struct current_user user;
3520 print_status_struct prt_status;
3522 memset(&prt_status, 0, sizeof(prt_status));
3524 if (!get_printer_snum(handle, &snum)) {
3525 return ERROR_INVALID_HANDLE;
3528 if (!print_job_exists(jobid)) {
3529 return ERROR_INVALID_PRINTER_NAME;
3532 if (p->ntlmssp_auth_validated) {
3533 memcpy(&user, &p->pipe_user, sizeof(user));
3535 extern struct current_user current_user;
3536 memcpy(&user, ¤t_user, sizeof(user));
3540 case JOB_CONTROL_CANCEL:
3541 case JOB_CONTROL_DELETE:
3542 if (print_job_delete(&user, jobid)) return 0x0;
3544 case JOB_CONTROL_PAUSE:
3545 if (print_job_pause(&user, jobid)) return 0x0;
3547 case JOB_CONTROL_RESUME:
3548 if (print_job_resume(&user, jobid)) return 0x0;
3551 return ERROR_INVALID_LEVEL;
3554 return ERROR_INVALID_HANDLE;
3557 /****************************************************************************
3558 Enumerates all printer drivers at level 1.
3559 ****************************************************************************/
3560 static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3565 fstring *list = NULL;
3567 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3568 DRIVER_INFO_1 *driver_info_1=NULL;
3572 #define MAX_VERSION 4
3574 for (version=0; version<MAX_VERSION; version++) {
3576 ndrivers=get_ntdrivers(&list, architecture, version);
3577 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3580 return ERROR_NOT_ENOUGH_MEMORY;
3583 if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
3585 return ERROR_NOT_ENOUGH_MEMORY;
3589 for (i=0; i<ndrivers; i++) {
3590 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3591 ZERO_STRUCT(driver);
3592 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3593 fill_printer_driver_info_1(&(driver_info_1[*returned+i]), driver, servername, architecture );
3596 *returned+=ndrivers;
3600 /* check the required size. */
3601 for (i=0; i<*returned; i++) {
3602 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3603 *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
3606 if (!alloc_buffer_size(buffer, *needed)) {
3607 safe_free(driver_info_1);
3608 return ERROR_INSUFFICIENT_BUFFER;
3611 /* fill the buffer with the form structures */
3612 for (i=0; i<*returned; i++) {
3613 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3614 new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
3617 safe_free(driver_info_1);
3619 if (*needed > offered) {
3621 return ERROR_INSUFFICIENT_BUFFER;
3624 return NT_STATUS_NO_PROBLEMO;
3627 /****************************************************************************
3628 Enumerates all printer drivers at level 2.
3629 ****************************************************************************/
3630 static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3635 fstring *list = NULL;
3637 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3638 DRIVER_INFO_2 *driver_info_2=NULL;
3642 #define MAX_VERSION 4
3644 for (version=0; version<MAX_VERSION; version++) {
3646 ndrivers=get_ntdrivers(&list, architecture, version);
3647 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3650 return ERROR_NOT_ENOUGH_MEMORY;
3653 if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
3655 return ERROR_NOT_ENOUGH_MEMORY;
3659 for (i=0; i<ndrivers; i++) {
3660 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3661 ZERO_STRUCT(driver);
3662 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3663 fill_printer_driver_info_2(&(driver_info_2[*returned+i]), driver, servername);
3666 *returned+=ndrivers;
3670 /* check the required size. */
3671 for (i=0; i<*returned; i++) {
3672 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3673 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3676 if (!alloc_buffer_size(buffer, *needed)) {
3677 safe_free(driver_info_2);
3678 return ERROR_INSUFFICIENT_BUFFER;
3681 /* fill the buffer with the form structures */
3682 for (i=0; i<*returned; i++) {
3683 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3684 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3687 safe_free(driver_info_2);
3689 if (*needed > offered) {
3691 return ERROR_INSUFFICIENT_BUFFER;
3694 return NT_STATUS_NO_PROBLEMO;
3697 /****************************************************************************
3698 Enumerates all printer drivers at level 3.
3699 ****************************************************************************/
3700 static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3705 fstring *list = NULL;
3707 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3708 DRIVER_INFO_3 *driver_info_3=NULL;
3712 #define MAX_VERSION 4
3714 for (version=0; version<MAX_VERSION; version++) {
3716 ndrivers=get_ntdrivers(&list, architecture, version);
3717 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3720 return ERROR_NOT_ENOUGH_MEMORY;
3723 if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
3725 return ERROR_NOT_ENOUGH_MEMORY;
3729 for (i=0; i<ndrivers; i++) {
3730 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3731 ZERO_STRUCT(driver);
3732 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3733 fill_printer_driver_info_3(&(driver_info_3[*returned+i]), driver, servername);
3736 *returned+=ndrivers;
3740 /* check the required size. */
3741 for (i=0; i<*returned; i++) {
3742 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3743 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3746 if (!alloc_buffer_size(buffer, *needed)) {
3747 safe_free(driver_info_3);
3748 return ERROR_INSUFFICIENT_BUFFER;
3751 /* fill the buffer with the driver structures */
3752 for (i=0; i<*returned; i++) {
3753 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3754 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
3757 for (i=0; i<*returned; i++)
3758 safe_free(driver_info_3[i].dependentfiles);
3760 safe_free(driver_info_3);
3762 if (*needed > offered) {
3764 return ERROR_INSUFFICIENT_BUFFER;
3767 return NT_STATUS_NO_PROBLEMO;
3770 /****************************************************************************
3771 Enumerates all printer drivers.
3772 ****************************************************************************/
3773 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
3774 NEW_BUFFER *buffer, uint32 offered,
3775 uint32 *needed, uint32 *returned)
3777 fstring *list = NULL;
3779 fstring architecture;
3781 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
3782 fstrcpy(servername, global_myname);
3786 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
3790 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
3793 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
3796 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
3801 return ERROR_INVALID_LEVEL;
3806 /****************************************************************************
3807 ****************************************************************************/
3808 static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
3810 form->flag=list->flag;
3811 init_unistr(&form->name, list->name);
3812 form->width=list->width;
3813 form->length=list->length;
3814 form->left=list->left;
3815 form->top=list->top;
3816 form->right=list->right;
3817 form->bottom=list->bottom;
3820 /****************************************************************************
3821 ****************************************************************************/
3822 uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
3823 NEW_BUFFER *buffer, uint32 offered,
3824 uint32 *needed, uint32 *numofforms)
3826 nt_forms_struct *list=NULL;
3831 DEBUG(4,("_new_spoolss_enumforms\n"));
3832 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3833 DEBUGADD(5,("Info level [%d]\n", level));
3835 *numofforms = get_ntforms(&list);
3836 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
3838 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
3842 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
3844 return ERROR_NOT_ENOUGH_MEMORY;
3847 /* construct the list of form structures */
3848 for (i=0; i<*numofforms; i++) {
3849 DEBUGADD(6,("Filling form number [%d]\n",i));
3850 fill_form_1(&forms_1[i], &list[i], i);
3855 /* check the required size. */
3856 for (i=0; i<*numofforms; i++) {
3857 DEBUGADD(6,("adding form [%d]'s size\n",i));
3858 buffer_size += spoolss_size_form_1(&forms_1[i]);
3861 *needed=buffer_size;
3863 if (!alloc_buffer_size(buffer, buffer_size)){
3865 return ERROR_INSUFFICIENT_BUFFER;
3868 /* fill the buffer with the form structures */
3869 for (i=0; i<*numofforms; i++) {
3870 DEBUGADD(6,("adding form [%d] to buffer\n",i));
3871 new_smb_io_form_1("", buffer, &forms_1[i], 0);
3876 if (*needed > offered) {
3878 return ERROR_INSUFFICIENT_BUFFER;
3881 return NT_STATUS_NO_PROBLEMO;
3885 return ERROR_INVALID_LEVEL;
3890 /****************************************************************************
3891 ****************************************************************************/
3892 static void fill_port_1(PORT_INFO_1 *port, char *name)
3894 init_unistr(&port->port_name, name);
3897 /****************************************************************************
3898 ****************************************************************************/
3899 static void fill_port_2(PORT_INFO_2 *port, char *name)
3901 init_unistr(&port->port_name, name);
3902 init_unistr(&port->monitor_name, "Local Monitor");
3903 init_unistr(&port->description, "Local Port");
3904 #define PORT_TYPE_WRITE 1
3905 port->port_type=PORT_TYPE_WRITE;
3909 /****************************************************************************
3911 ****************************************************************************/
3912 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3914 PORT_INFO_1 *ports=NULL;
3917 if (*lp_enumports_cmd()) {
3918 pid_t local_pid = sys_getpid();
3919 char *cmd = lp_enumports_cmd();
3927 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
3928 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
3932 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
3933 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 1);
3936 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
3937 ret = smbrun(command, tmp_file, False);
3938 DEBUG(10,("Returned [%d]\n", ret));
3941 // Is this the best error to return here?
3942 return ERROR_ACCESS_DENIED;
3946 qlines = file_lines_load(tmp_file, &numlines);
3947 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
3948 DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
3949 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
3953 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
3954 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
3955 file_lines_free(qlines);
3956 return ERROR_NOT_ENOUGH_MEMORY;
3959 for (i=0; i<numlines; i++) {
3960 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
3961 fill_port_1(&ports[i], qlines[i]);
3964 file_lines_free(qlines);
3967 *returned = numlines;
3970 *returned = 1; /* Sole Samba port returned. */
3972 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
3973 return ERROR_NOT_ENOUGH_MEMORY;
3975 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
3977 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
3980 /* check the required size. */
3981 for (i=0; i<*returned; i++) {
3982 DEBUGADD(6,("adding port [%d]'s size\n", i));
3983 *needed += spoolss_size_port_info_1(&ports[i]);
3986 if (!alloc_buffer_size(buffer, *needed)) {
3988 return ERROR_INSUFFICIENT_BUFFER;
3991 /* fill the buffer with the ports structures */
3992 for (i=0; i<*returned; i++) {
3993 DEBUGADD(6,("adding port [%d] to buffer\n", i));
3994 new_smb_io_port_1("", buffer, &ports[i], 0);
3999 if (*needed > offered) {
4001 return ERROR_INSUFFICIENT_BUFFER;
4004 return NT_STATUS_NO_PROBLEMO;
4007 /****************************************************************************
4009 ****************************************************************************/
4011 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4013 PORT_INFO_2 *ports=NULL;
4016 if (*lp_enumports_cmd()) {
4017 pid_t local_pid = sys_getpid();
4018 char *cmd = lp_enumports_cmd();
4026 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4027 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4031 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4032 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 2);
4035 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4036 ret = smbrun(command, tmp_file, False);
4037 DEBUGADD(10,("returned [%d]\n", ret));
4040 // Is this the best error to return here?
4041 return ERROR_ACCESS_DENIED;
4045 qlines = file_lines_load(tmp_file, &numlines);
4046 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4047 DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
4048 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4052 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
4053 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4054 file_lines_free(qlines);
4055 return ERROR_NOT_ENOUGH_MEMORY;
4058 for (i=0; i<numlines; i++) {
4059 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4060 fill_port_2(&(ports[i]), qlines[i]);
4063 file_lines_free(qlines);
4066 *returned = numlines;
4072 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
4073 return ERROR_NOT_ENOUGH_MEMORY;
4075 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4077 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
4080 /* check the required size. */
4081 for (i=0; i<*returned; i++) {
4082 DEBUGADD(6,("adding port [%d]'s size\n", i));
4083 *needed += spoolss_size_port_info_2(&ports[i]);
4086 if (!alloc_buffer_size(buffer, *needed)) {
4088 return ERROR_INSUFFICIENT_BUFFER;
4091 /* fill the buffer with the ports structures */
4092 for (i=0; i<*returned; i++) {
4093 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4094 new_smb_io_port_2("", buffer, &ports[i], 0);
4099 if (*needed > offered) {
4101 return ERROR_INSUFFICIENT_BUFFER;
4104 return NT_STATUS_NO_PROBLEMO;
4107 /****************************************************************************
4109 ****************************************************************************/
4110 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
4111 NEW_BUFFER *buffer, uint32 offered,
4112 uint32 *needed, uint32 *returned)
4114 DEBUG(4,("_spoolss_enumports\n"));
4121 return enumports_level_1(buffer, offered, needed, returned);
4124 return enumports_level_2(buffer, offered, needed, returned);
4127 return ERROR_INVALID_LEVEL;
4132 /****************************************************************************
4133 ****************************************************************************/
4134 static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
4136 pid_t local_pid = sys_getpid();
4137 char *cmd = lp_addprinter_cmd();
4142 pstring driverlocation;
4146 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4147 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4151 /* build driver path... only 9X architecture is needed for legacy reasons */
4152 slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
4154 /* change \ to \\ for the shell */
4155 all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
4157 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4158 slprintf(command, sizeof(command), "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
4159 cmd, printer->info_2->printername, printer->info_2->sharename,
4160 printer->info_2->portname, printer->info_2->drivername,
4161 printer->info_2->location, driverlocation);
4164 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4165 ret = smbrun(command, tmp_file, False);
4166 DEBUGADD(10,("returned [%d]\n", ret));
4170 free_a_printer(&printer,2);
4175 qlines = file_lines_load(tmp_file, &numlines);
4176 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4177 DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
4178 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4182 // Set the portname to what the script says the portname should be
4183 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
4185 // Send SIGHUP to process group... is there a better way?
4190 file_lines_free(qlines);
4194 /****************************************************************************
4195 ****************************************************************************/
4196 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
4197 const SPOOL_PRINTER_INFO_LEVEL *info,
4198 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4199 uint32 user_switch, const SPOOL_USER_CTR *user,
4202 NT_PRINTER_INFO_LEVEL *printer = NULL;
4206 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
4207 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
4208 return ERROR_NOT_ENOUGH_MEMORY;
4211 ZERO_STRUCTP(printer);
4213 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
4214 convert_printer_info(info, printer, 2);
4216 if (*lp_addprinter_cmd() )
4217 if ( !add_printer_hook(printer) )
4218 return ERROR_ACCESS_DENIED;
4220 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
4221 printer->info_2->sharename);
4223 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
4224 free_a_printer(&printer,2);
4225 return ERROR_ACCESS_DENIED;
4228 /* you must be a printer admin to add a new printer */
4229 if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
4230 free_a_printer(&printer,2);
4231 return ERROR_ACCESS_DENIED;
4235 * Do sanity check on the requested changes for Samba.
4238 if (!check_printer_ok(printer->info_2, snum)) {
4239 free_a_printer(&printer,2);
4240 return ERROR_INVALID_PARAMETER;
4243 /* write the ASCII on disk */
4244 if (add_a_printer(*printer, 2) != 0) {
4245 free_a_printer(&printer,2);
4246 return ERROR_ACCESS_DENIED;
4249 if (!open_printer_hnd(handle, name)) {
4250 /* Handle open failed - remove addition. */
4251 del_a_printer(printer->info_2->sharename);
4252 free_a_printer(&printer,2);
4253 return ERROR_ACCESS_DENIED;
4256 free_a_printer(&printer,2);
4257 return NT_STATUS_NO_PROBLEMO;
4260 /****************************************************************************
4261 ****************************************************************************/
4262 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4263 const SPOOL_PRINTER_INFO_LEVEL *info,
4264 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4265 uint32 user_switch, const SPOOL_USER_CTR *user,
4270 /* we don't handle yet */
4271 /* but I know what to do ... */
4272 return ERROR_INVALID_LEVEL;
4275 return spoolss_addprinterex_level_2(uni_srv_name, info,
4276 unk0, unk1, unk2, unk3,
4277 user_switch, user, handle);
4280 return ERROR_INVALID_LEVEL;
4285 /****************************************************************************
4286 ****************************************************************************/
4287 uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
4288 uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4290 uint32 err = NT_STATUS_NO_PROBLEMO;
4291 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4292 struct current_user user;
4294 ZERO_STRUCT(driver);
4296 if (p->ntlmssp_auth_validated) {
4297 memcpy(&user, &p->pipe_user, sizeof(user));
4299 extern struct current_user current_user;
4300 memcpy(&user, ¤t_user, sizeof(user));
4303 convert_printer_driver_info(info, &driver, level);
4305 DEBUG(5,("Cleaning driver's information\n"));
4306 clean_up_driver_struct(driver, level);
4308 DEBUG(5,("Moving driver to final destination\n"));
4309 if(!move_driver_to_download_area(driver, level, &user)) {
4310 err = ERROR_ACCESS_DENIED;
4314 if (add_a_printer_driver(driver, level)!=0) {
4315 err = ERROR_ACCESS_DENIED;
4320 free_a_printer_driver(driver, level);
4324 /****************************************************************************
4325 ****************************************************************************/
4326 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4328 init_unistr(&info->name, name);
4331 /****************************************************************************
4332 ****************************************************************************/
4333 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4337 pstring short_archi;
4338 DRIVER_DIRECTORY_1 *info=NULL;
4340 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4342 if (get_short_archi(short_archi, long_archi)==FALSE)
4343 return ERROR_INVALID_ENVIRONMENT;
4345 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4346 return ERROR_NOT_ENOUGH_MEMORY;
4348 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
4350 DEBUG(4,("printer driver directory: [%s]\n", path));
4352 fill_driverdir_1(info, path);
4354 *needed += spoolss_size_driverdir_info_1(info);
4356 if (!alloc_buffer_size(buffer, *needed)) {
4358 return ERROR_INSUFFICIENT_BUFFER;
4361 new_smb_io_driverdir_1("", buffer, info, 0);
4365 if (*needed > offered)
4366 return ERROR_INSUFFICIENT_BUFFER;
4368 return NT_STATUS_NO_PROBLEMO;
4371 /****************************************************************************
4372 ****************************************************************************/
4373 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4374 NEW_BUFFER *buffer, uint32 offered,
4377 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4383 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4386 return ERROR_INVALID_LEVEL;
4391 /****************************************************************************
4392 ****************************************************************************/
4393 uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
4394 uint32 in_value_len, uint32 in_data_len,
4395 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4397 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4399 NT_PRINTER_INFO_LEVEL *printer = NULL;
4404 uint32 biggest_valuesize;
4405 uint32 biggest_datasize;
4407 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4412 ZERO_STRUCT(printer);
4414 *out_max_value_len=0;
4420 *out_max_data_len=0;
4424 DEBUG(5,("spoolss_enumprinterdata\n"));
4426 if (!OPEN_HANDLE(Printer)) {
4427 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4428 return ERROR_INVALID_HANDLE;
4431 if (!get_printer_snum(handle, &snum))
4432 return ERROR_INVALID_HANDLE;
4434 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4435 return ERROR_INVALID_HANDLE;
4438 * The NT machine wants to know the biggest size of value and data
4440 * cf: MSDN EnumPrinterData remark section
4442 if ( (in_value_len==0) && (in_data_len==0) ) {
4443 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4446 biggest_valuesize=0;
4449 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4450 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4451 if (data_len > biggest_datasize) biggest_datasize=data_len;
4453 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4459 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4460 *out_value_len=2*(1+biggest_valuesize);
4461 *out_data_len=biggest_datasize;
4463 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4465 free_a_printer(&printer, 2);
4466 return NT_STATUS_NO_PROBLEMO;
4470 * the value len is wrong in NT sp3
4471 * that's the number of bytes not the number of unicode chars
4474 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4476 free_a_printer(&printer, 2);
4477 return ERROR_NO_MORE_ITEMS;
4480 free_a_printer(&printer, 2);
4484 * - counted in bytes in the request
4485 * - counted in UNICODE chars in the max reply
4486 * - counted in bytes in the real size
4488 * take a pause *before* coding not *during* coding
4491 *out_max_value_len=(in_value_len/sizeof(uint16));
4492 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4494 return ERROR_NOT_ENOUGH_MEMORY;
4497 ZERO_STRUCTP(*out_value);
4498 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4502 /* the data is counted in bytes */
4503 *out_max_data_len=in_data_len;
4504 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4506 return ERROR_NOT_ENOUGH_MEMORY;
4509 ZERO_STRUCTP(*data_out);
4510 memcpy(*data_out, data, (size_t)data_len);
4511 *out_data_len=data_len;
4515 return NT_STATUS_NO_PROBLEMO;
4518 /****************************************************************************
4519 ****************************************************************************/
4520 uint32 _spoolss_setprinterdata( POLICY_HND *handle,
4521 const UNISTR2 *value,
4526 uint32 numeric_data)
4528 NT_PRINTER_INFO_LEVEL *printer = NULL;
4529 NT_PRINTER_PARAM *param = NULL;
4531 uint32 status = 0x0;
4532 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4534 DEBUG(5,("spoolss_setprinterdata\n"));
4537 if (!OPEN_HANDLE(Printer)) {
4538 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4539 return ERROR_INVALID_HANDLE;
4542 if (!get_printer_snum(handle, &snum))
4543 return ERROR_INVALID_HANDLE;
4545 if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
4546 DEBUG(3, ("security descriptor change denied by existing "
4547 "security descriptor\n"));
4548 return NT_STATUS_ACCESS_DENIED;
4551 status = get_a_printer(&printer, 2, lp_servicename(snum));
4553 return ERROR_INVALID_NAME;
4555 convert_specific_param(¶m, value , type, data, real_len);
4556 unlink_specific_param_if_exist(printer->info_2, param);
4558 if (!add_a_specific_param(printer->info_2, param))
4559 status = ERROR_INVALID_PARAMETER;
4561 status = add_a_printer(*printer, 2);
4563 free_a_printer(&printer, 2);
4567 /****************************************************************************
4568 ****************************************************************************/
4569 uint32 _spoolss_addform( POLICY_HND *handle,
4574 nt_forms_struct *list=NULL;
4575 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4577 DEBUG(5,("spoolss_addform\n"));
4579 if (!OPEN_HANDLE(Printer)) {
4580 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4581 return ERROR_INVALID_HANDLE;
4584 count=get_ntforms(&list);
4585 if(!add_a_form(&list, form, &count))
4586 return ERROR_NOT_ENOUGH_MEMORY;
4587 write_ntforms(&list, count);
4594 /****************************************************************************
4595 ****************************************************************************/
4596 uint32 _spoolss_setform( POLICY_HND *handle,
4597 const UNISTR2 *uni_name,
4602 nt_forms_struct *list=NULL;
4603 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4605 DEBUG(5,("spoolss_setform\n"));
4607 if (!OPEN_HANDLE(Printer)) {
4608 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4609 return ERROR_INVALID_HANDLE;
4611 count=get_ntforms(&list);
4612 update_a_form(&list, form, count);
4613 write_ntforms(&list, count);
4620 /****************************************************************************
4621 enumprintprocessors level 1.
4622 ****************************************************************************/
4623 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4625 PRINTPROCESSOR_1 *info_1=NULL;
4627 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4628 return ERROR_NOT_ENOUGH_MEMORY;
4632 init_unistr(&info_1->name, "winprint");
4634 *needed += spoolss_size_printprocessor_info_1(info_1);
4636 if (!alloc_buffer_size(buffer, *needed))
4637 return ERROR_INSUFFICIENT_BUFFER;
4639 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4643 if (*needed > offered) {
4645 return ERROR_INSUFFICIENT_BUFFER;
4648 return NT_STATUS_NO_PROBLEMO;
4651 /****************************************************************************
4652 ****************************************************************************/
4653 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
4654 NEW_BUFFER *buffer, uint32 offered,
4655 uint32 *needed, uint32 *returned)
4657 DEBUG(5,("spoolss_enumprintprocessors\n"));
4660 * Enumerate the print processors ...
4662 * Just reply with "winprint", to keep NT happy
4663 * and I can use my nice printer checker.
4671 return enumprintprocessors_level_1(buffer, offered, needed, returned);
4674 return ERROR_INVALID_LEVEL;
4679 /****************************************************************************
4680 enumprintprocdatatypes level 1.
4681 ****************************************************************************/
4682 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4684 PRINTPROCDATATYPE_1 *info_1=NULL;
4686 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
4687 return ERROR_NOT_ENOUGH_MEMORY;
4691 init_unistr(&info_1->name, "RAW");
4693 *needed += spoolss_size_printprocdatatype_info_1(info_1);
4695 if (!alloc_buffer_size(buffer, *needed))
4696 return ERROR_INSUFFICIENT_BUFFER;
4698 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
4702 if (*needed > offered) {
4704 return ERROR_INSUFFICIENT_BUFFER;
4707 return NT_STATUS_NO_PROBLEMO;
4710 /****************************************************************************
4711 ****************************************************************************/
4712 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
4713 NEW_BUFFER *buffer, uint32 offered,
4714 uint32 *needed, uint32 *returned)
4716 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
4723 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
4726 return ERROR_INVALID_LEVEL;
4731 /****************************************************************************
4732 enumprintmonitors level 1.
4733 ****************************************************************************/
4734 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4736 PRINTMONITOR_1 *info_1=NULL;
4738 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
4739 return ERROR_NOT_ENOUGH_MEMORY;
4743 init_unistr(&info_1->name, "Local Port");
4745 *needed += spoolss_size_printmonitor_info_1(info_1);
4747 if (!alloc_buffer_size(buffer, *needed))
4748 return ERROR_INSUFFICIENT_BUFFER;
4750 smb_io_printmonitor_info_1("", buffer, info_1, 0);
4754 if (*needed > offered) {
4756 return ERROR_INSUFFICIENT_BUFFER;
4759 return NT_STATUS_NO_PROBLEMO;
4762 /****************************************************************************
4763 enumprintmonitors level 2.
4764 ****************************************************************************/
4765 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4767 PRINTMONITOR_2 *info_2=NULL;
4769 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
4770 return ERROR_NOT_ENOUGH_MEMORY;
4774 init_unistr(&info_2->name, "Local Port");
4775 init_unistr(&info_2->environment, "Windows NT X86");
4776 init_unistr(&info_2->dll_name, "localmon.dll");
4778 *needed += spoolss_size_printmonitor_info_2(info_2);
4780 if (!alloc_buffer_size(buffer, *needed))
4781 return ERROR_INSUFFICIENT_BUFFER;
4783 smb_io_printmonitor_info_2("", buffer, info_2, 0);
4787 if (*needed > offered) {
4789 return ERROR_INSUFFICIENT_BUFFER;
4792 return NT_STATUS_NO_PROBLEMO;
4795 /****************************************************************************
4796 ****************************************************************************/
4797 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
4798 NEW_BUFFER *buffer, uint32 offered,
4799 uint32 *needed, uint32 *returned)
4801 DEBUG(5,("spoolss_enumprintmonitors\n"));
4804 * Enumerate the print monitors ...
4806 * Just reply with "Local Port", to keep NT happy
4807 * and I can use my nice printer checker.
4815 return enumprintmonitors_level_1(buffer, offered, needed, returned);
4818 return enumprintmonitors_level_2(buffer, offered, needed, returned);
4821 return ERROR_INVALID_LEVEL;
4826 /****************************************************************************
4827 ****************************************************************************/
4828 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4832 JOB_INFO_1 *info_1=NULL;
4834 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
4836 if (info_1 == NULL) {
4838 return ERROR_NOT_ENOUGH_MEMORY;
4841 for (i=0; i<count && found==False; i++) {
4842 if (queue[i].job==(int)jobid)
4849 /* I shoud reply something else ... I can't find the good one */
4850 return NT_STATUS_NO_PROBLEMO;
4853 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
4857 *needed += spoolss_size_job_info_1(info_1);
4859 if (!alloc_buffer_size(buffer, *needed)) {
4861 return ERROR_INSUFFICIENT_BUFFER;
4864 new_smb_io_job_info_1("", buffer, info_1, 0);
4868 if (*needed > offered)
4869 return ERROR_INSUFFICIENT_BUFFER;
4871 return NT_STATUS_NO_PROBLEMO;
4875 /****************************************************************************
4876 ****************************************************************************/
4877 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4882 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
4884 ZERO_STRUCTP(info_2);
4886 if (info_2 == NULL) {
4888 return ERROR_NOT_ENOUGH_MEMORY;
4891 for (i=0; i<count && found==False; i++) {
4892 if (queue[i].job==(int)jobid)
4899 /* I shoud reply something else ... I can't find the good one */
4900 return NT_STATUS_NO_PROBLEMO;
4903 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
4907 *needed += spoolss_size_job_info_2(info_2);
4909 if (!alloc_buffer_size(buffer, *needed)) {
4911 return ERROR_INSUFFICIENT_BUFFER;
4914 new_smb_io_job_info_2("", buffer, info_2, 0);
4916 free_dev_mode(info_2->devmode);
4919 if (*needed > offered)
4920 return ERROR_INSUFFICIENT_BUFFER;
4922 return NT_STATUS_NO_PROBLEMO;
4925 /****************************************************************************
4926 ****************************************************************************/
4927 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
4928 NEW_BUFFER *buffer, uint32 offered,
4933 print_queue_struct *queue=NULL;
4934 print_status_struct prt_status;
4936 DEBUG(5,("spoolss_getjob\n"));
4938 memset(&prt_status, 0, sizeof(prt_status));
4942 if (!get_printer_snum(handle, &snum))
4943 return ERROR_INVALID_HANDLE;
4945 count = print_queue_status(snum, &queue, &prt_status);
4947 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
4948 count, prt_status.status, prt_status.message));
4952 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
4955 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
4959 return ERROR_INVALID_LEVEL;