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.
27 extern int DEBUGLEVEL;
28 extern pstring global_myname;
30 #ifndef MAX_OPEN_PRINTER_EXS
31 #define MAX_OPEN_PRINTER_EXS 50
34 #define PRINTER_HANDLE_IS_PRINTER 0
35 #define PRINTER_HANDLE_IS_PRINTSERVER 1
37 /* structure to store the printer handles */
38 /* and a reference to what it's pointing to */
39 /* and the notify info asked about */
40 /* that's the central struct */
41 typedef struct _Printer{
46 BOOL document_started;
48 int jobid; /* jobid in printing backend */
49 POLICY_HND printer_hnd;
53 fstring printerservername;
62 SPOOL_NOTIFY_OPTION *option;
70 typedef struct _counter_printer_0 {
78 static ubi_dlList Printer_list;
79 static ubi_dlList counter_list;
82 #define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False) && (IVAL(pnum->printer_hnd.data,16)==(uint32)sys_getpid()))
83 #define OUR_HANDLE(pnum) ((pnum==NULL)?"NULL":(IVAL(pnum->data,16)==sys_getpid()?"OURS":"OTHER"))
85 /* translate between internal status numbers and NT status numbers */
86 static int nt_printj_status(int v)
90 return PRINTER_STATUS_PAUSED;
99 static int nt_printq_status(int v)
103 return PRINTER_STATUS_PAUSED;
112 /****************************************************************************
113 initialise printer handle states...
114 ****************************************************************************/
115 void init_printer_hnd(void)
117 ubi_dlInitList(&Printer_list);
118 ubi_dlInitList(&counter_list);
121 /****************************************************************************
122 create a unique printer handle
123 ****************************************************************************/
124 static void create_printer_hnd(POLICY_HND *hnd)
126 static uint32 prt_hnd_low = 0;
127 static uint32 prt_hnd_high = 0;
129 if (hnd == NULL) return;
131 /* i severely doubt that prt_hnd_high will ever be non-zero... */
133 if (prt_hnd_low == 0) prt_hnd_high++;
135 SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
136 SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
137 SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
138 SIVAL(hnd->data, 12, time(NULL)); /* something random */
139 SIVAL(hnd->data, 16, sys_getpid()); /* something more random */
142 /****************************************************************************
143 find printer index by handle
144 ****************************************************************************/
145 static Printer_entry *find_printer_index_by_hnd(const POLICY_HND *hnd)
147 Printer_entry *find_printer;
149 find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
151 for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) {
153 if (memcmp(&(find_printer->printer_hnd), hnd, sizeof(*hnd)) == 0) {
154 DEBUG(4,("Found printer handle \n"));
155 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
160 DEBUG(3,("Whoops, Printer handle not found: "));
161 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
165 /****************************************************************************
167 ****************************************************************************/
168 static void clear_handle(POLICY_HND *hnd)
173 /****************************************************************************
174 close printer index by handle
175 ****************************************************************************/
176 static BOOL close_printer_handle(POLICY_HND *hnd)
178 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
180 if (!OPEN_HANDLE(Printer)) {
181 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
186 Printer->notify.flags=0;
187 Printer->notify.options=0;
188 Printer->notify.localmachine[0]='\0';
189 Printer->notify.printerlocal=0;
190 safe_free(Printer->notify.option);
191 Printer->notify.option=NULL;
195 ubi_dlRemThis(&Printer_list, Printer);
202 /****************************************************************************
203 delete a printer given a handle
204 ****************************************************************************/
205 static BOOL delete_printer_handle(POLICY_HND *hnd)
207 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
209 if (!OPEN_HANDLE(Printer)) {
210 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
214 if (del_a_printer(Printer->dev.handlename) != 0) {
215 DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
219 if (*lp_deleteprinter_cmd()) {
221 pid_t local_pid = sys_getpid();
222 char *cmd = lp_deleteprinter_cmd();
229 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
230 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
234 /* Printer->dev.handlename equals portname equals sharename */
235 slprintf(command, sizeof(command), "%s \"%s\"", cmd,
236 Printer->dev.handlename);
237 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
240 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
241 ret = smbrun(command, tmp_file, False);
246 DEBUGADD(10,("returned [%d]\n", ret));
247 DEBUGADD(10,("Unlinking output file [%s]\n", tmp_file));
250 // Send SIGHUP to process group... is there a better way?
253 if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
254 lp_remove_service( i );
264 /****************************************************************************
265 return the snum of a printer corresponding to an handle
266 ****************************************************************************/
267 static BOOL get_printer_snum(POLICY_HND *hnd, int *number)
269 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
271 if (!OPEN_HANDLE(Printer)) {
272 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
276 switch (Printer->printer_type) {
277 case PRINTER_HANDLE_IS_PRINTER:
278 DEBUG(4,("short name:%s\n", Printer->dev.handlename));
279 *number = print_queue_snum(Printer->dev.handlename);
280 return (*number != -1);
281 case PRINTER_HANDLE_IS_PRINTSERVER:
290 /****************************************************************************
291 set printer handle type.
292 ****************************************************************************/
293 static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required)
295 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
297 if (!OPEN_HANDLE(Printer)) {
298 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd)));
302 DEBUG(4,("Setting printer access=%x\n", access_required));
303 Printer->access = access_required;
307 /****************************************************************************
308 Set printer handle type.
309 Check if it's \\server or \\server\printer
310 ****************************************************************************/
312 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
314 DEBUG(3,("Setting printer type=%s\n", handlename));
316 if ( strlen(handlename) < 3 ) {
317 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
321 /* it's a print server */
322 if (!strchr(handlename+2, '\\')) {
323 DEBUGADD(4,("Printer is a print server\n"));
324 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
329 DEBUGADD(4,("Printer is a printer\n"));
330 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
337 /****************************************************************************
338 Set printer handle name.
339 ****************************************************************************/
341 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
343 NT_PRINTER_INFO_LEVEL *printer = NULL;
345 int n_services=lp_numservices();
349 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
351 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
352 ZERO_STRUCT(Printer->dev.printerservername);
353 strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
357 if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
360 aprinter=strchr(handlename+2, '\\');
363 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
366 * store the Samba share name in it
367 * in back we have the long printer name
368 * need to iterate all the snum and do a
369 * get_a_printer each time to find the printer
370 * faster to do it here than later.
373 for (snum=0;snum<n_services && found==False;snum++) {
375 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
378 DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
380 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
383 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
384 printer->info_2->printername, aprinter ));
386 if ( strlen(printer->info_2->printername) != strlen(aprinter) ) {
387 free_a_printer(&printer, 2);
391 if ( strncasecmp(printer->info_2->printername, aprinter, strlen(aprinter))) {
392 free_a_printer(&printer, 2);
400 * if we haven't found a printer with the given handlename
401 * then it can be a share name as you can open both \\server\printer and
406 * we still check if the printer description file exists as NT won't be happy
407 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
411 DEBUGADD(5,("Printer not found, checking for share now\n"));
413 for (snum=0;snum<n_services && found==False;snum++) {
415 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
418 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum)));
420 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
423 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
424 printer->info_2->printername, aprinter ));
426 if ( strlen(lp_servicename(snum)) != strlen(aprinter) ) {
427 free_a_printer(&printer, 2);
431 if ( strncasecmp(lp_servicename(snum), aprinter, strlen(aprinter))) {
432 free_a_printer(&printer, 2);
441 DEBUGADD(4,("Printer not found\n"));
446 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
447 printer->info_2->printername, lp_servicename(snum),snum));
449 ZERO_STRUCT(Printer->dev.handlename);
450 strncpy(Printer->dev.handlename, lp_servicename(snum), strlen(lp_servicename(snum)));
452 free_a_printer(&printer, 2);
457 /****************************************************************************
458 find first available printer slot. creates a printer handle for you.
459 ****************************************************************************/
461 static BOOL open_printer_hnd(POLICY_HND *hnd, char *name)
463 Printer_entry *new_printer;
466 create_printer_hnd(hnd);
468 if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
471 ZERO_STRUCTP(new_printer);
473 new_printer->open = True;
474 new_printer->notify.option=NULL;
476 memcpy(&new_printer->printer_hnd, hnd, sizeof(*hnd));
478 ubi_dlAddHead( &Printer_list, (ubi_dlNode *)new_printer);
480 if (!set_printer_hnd_printertype(new_printer, name)) {
481 close_printer_handle(hnd);
485 if (!set_printer_hnd_name(new_printer, name)) {
486 close_printer_handle(hnd);
493 /********************************************************************
494 Return True is the handle is a print server.
495 ********************************************************************/
496 static BOOL handle_is_printserver(const POLICY_HND *handle)
498 Printer_entry *Printer=find_printer_index_by_hnd(handle);
500 if (!OPEN_HANDLE(Printer))
503 if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
509 /****************************************************************************
510 allocate more memory for a BUFFER.
511 ****************************************************************************/
512 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
520 /* damn, I'm doing the reverse operation of prs_grow() :) */
521 if (buffer_size < prs_data_size(ps))
524 extra_space = buffer_size - prs_data_size(ps);
527 * save the offset and move to the end of the buffer
528 * prs_grow() checks the extra_space against the offset
530 old_offset=prs_offset(ps);
531 prs_set_offset(ps, prs_data_size(ps));
533 if (!prs_grow(ps, extra_space))
536 prs_set_offset(ps, old_offset);
539 buffer->string_at_end = buffer_size;
541 buffer->string_at_end=prs_data_size(ps);
547 /********************************************************************
548 * spoolss_open_printer
550 * called from the spoolss dispatcher
551 ********************************************************************/
552 uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
553 const PRINTER_DEFAULT *printer_default,
554 uint32 user_switch, SPOOL_USER_CTR user_ctr,
559 if (printername == NULL)
560 return ERROR_INVALID_PRINTER_NAME;
562 /* some sanity check because you can open a printer or a print server */
563 /* aka: \\server\printer or \\server */
564 unistr2_to_ascii(name, printername, sizeof(name)-1);
566 DEBUGADD(3,("checking name: %s\n",name));
568 if (!open_printer_hnd(handle, name))
569 return ERROR_INVALID_PRINTER_NAME;
572 if (printer_default->datatype_ptr != NULL)
574 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
575 set_printer_hnd_datatype(handle, datatype);
578 set_printer_hnd_datatype(handle, "");
581 if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
582 close_printer_handle(handle);
583 return ERROR_ACCESS_DENIED;
586 return NT_STATUS_NO_PROBLEMO;
589 /****************************************************************************
590 ****************************************************************************/
591 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
592 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
596 uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
605 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
606 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
610 printer->info_3=NULL;
611 uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3);
614 printer->info_6=NULL;
615 uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6);
624 static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devmode)
626 unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
627 unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
629 nt_devmode->specversion=devmode->specversion;
630 nt_devmode->driverversion=devmode->driverversion;
631 nt_devmode->size=devmode->size;
632 nt_devmode->driverextra=devmode->driverextra;
633 nt_devmode->fields=devmode->fields;
634 nt_devmode->orientation=devmode->orientation;
635 nt_devmode->papersize=devmode->papersize;
636 nt_devmode->paperlength=devmode->paperlength;
637 nt_devmode->paperwidth=devmode->paperwidth;
638 nt_devmode->scale=devmode->scale;
639 nt_devmode->copies=devmode->copies;
640 nt_devmode->defaultsource=devmode->defaultsource;
641 nt_devmode->printquality=devmode->printquality;
642 nt_devmode->color=devmode->color;
643 nt_devmode->duplex=devmode->duplex;
644 nt_devmode->yresolution=devmode->yresolution;
645 nt_devmode->ttoption=devmode->ttoption;
646 nt_devmode->collate=devmode->collate;
648 nt_devmode->logpixels=devmode->logpixels;
649 nt_devmode->bitsperpel=devmode->bitsperpel;
650 nt_devmode->pelswidth=devmode->pelswidth;
651 nt_devmode->pelsheight=devmode->pelsheight;
652 nt_devmode->displayflags=devmode->displayflags;
653 nt_devmode->displayfrequency=devmode->displayfrequency;
654 nt_devmode->icmmethod=devmode->icmmethod;
655 nt_devmode->icmintent=devmode->icmintent;
656 nt_devmode->mediatype=devmode->mediatype;
657 nt_devmode->dithertype=devmode->dithertype;
658 nt_devmode->reserved1=devmode->reserved1;
659 nt_devmode->reserved2=devmode->reserved2;
660 nt_devmode->panningwidth=devmode->panningwidth;
661 nt_devmode->panningheight=devmode->panningheight;
663 if (nt_devmode->driverextra != 0) {
664 /* if we had a previous private delete it and make a new one */
665 safe_free(nt_devmode->private);
666 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
668 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
674 /********************************************************************
675 * api_spoolss_closeprinter
676 ********************************************************************/
677 uint32 _spoolss_closeprinter(POLICY_HND *handle)
679 if (!close_printer_handle(handle))
680 return ERROR_INVALID_HANDLE;
682 return NT_STATUS_NO_PROBLEMO;
685 /********************************************************************
686 * api_spoolss_deleteprinter
687 ********************************************************************/
688 uint32 _spoolss_deleteprinter(POLICY_HND *handle)
690 if (!delete_printer_handle(handle))
691 return ERROR_INVALID_HANDLE;
693 return NT_STATUS_NO_PROBLEMO;
696 /********************************************************************
697 GetPrinterData on a printer server Handle.
698 ********************************************************************/
699 static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
703 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
705 if (!strcmp(value, "BeepEnabled")) {
707 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
709 SIVAL(*data, 0, 0x01);
714 if (!strcmp(value, "EventLog")) {
716 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
718 SIVAL(*data, 0, 0x1B);
723 if (!strcmp(value, "NetPopup")) {
725 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
727 SIVAL(*data, 0, 0x01);
732 if (!strcmp(value, "MajorVersion")) {
734 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
736 SIVAL(*data, 0, 0x02);
741 if (!strcmp(value, "DefaultSpoolDirectory")) {
742 pstring string="You are using a Samba server";
744 *needed = 2*(strlen(string)+1);
745 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
747 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
749 /* it's done by hand ready to go on the wire */
750 for (i=0; i<strlen(string); i++) {
751 (*data)[2*i]=string[i];
757 if (!strcmp(value, "Architecture")) {
758 pstring string="Windows NT x86";
760 *needed = 2*(strlen(string)+1);
761 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
763 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
764 for (i=0; i<strlen(string); i++) {
765 (*data)[2*i]=string[i];
774 /********************************************************************
775 GetPrinterData on a printer Handle.
776 ********************************************************************/
777 static BOOL getprinterdata_printer(POLICY_HND *handle,
778 fstring value, uint32 *type,
779 uint8 **data, uint32 *needed, uint32 in_size )
781 NT_PRINTER_INFO_LEVEL *printer = NULL;
785 Printer_entry *Printer = find_printer_index_by_hnd(handle);
787 DEBUG(5,("getprinterdata_printer\n"));
789 if (!OPEN_HANDLE(Printer)) {
790 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
794 if(!get_printer_snum(handle, &snum))
797 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
800 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
801 free_a_printer(&printer, 2);
805 free_a_printer(&printer, 2);
807 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
810 if((*data = (uint8 *)malloc( in_size *sizeof(uint8) )) == NULL) {
814 memset(*data, 0, in_size *sizeof(uint8));
815 /* copy the min(in_size, len) */
816 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
823 DEBUG(5,("getprinterdata_printer:copy done\n"));
830 /********************************************************************
831 * spoolss_getprinterdata
832 ********************************************************************/
833 uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
842 Printer_entry *Printer = find_printer_index_by_hnd(handle);
845 * Reminder: when it's a string, the length is in BYTES
846 * even if UNICODE is negociated.
853 /* in case of problem, return some default values */
857 DEBUG(4,("_spoolss_getprinterdata\n"));
859 if (!OPEN_HANDLE(Printer)) {
860 if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
861 return ERROR_NOT_ENOUGH_MEMORY;
862 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
863 return ERROR_INVALID_HANDLE;
866 unistr2_to_ascii(value, valuename, sizeof(value)-1);
868 if (handle_is_printserver(handle))
869 found=getprinterdata_printer_server(value, type, data, needed, *out_size);
871 found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
874 DEBUG(5, ("value not found, allocating %d\n", *out_size));
875 /* reply this param doesn't exist */
877 if((*data=(uint8 *)malloc(*out_size*sizeof(uint8))) == NULL)
878 return ERROR_NOT_ENOUGH_MEMORY;
879 memset(*data, '\0', *out_size*sizeof(uint8));
884 return ERROR_INVALID_PARAMETER;
887 if (*needed > *out_size)
888 return ERROR_MORE_DATA;
890 return NT_STATUS_NO_PROBLEMO;
893 /********************************************************************
895 * ReplyFindFirstPrinterChangeNotifyEx
897 * jfmxxxx: before replying OK: status=0
898 * should do a rpc call to the workstation asking ReplyOpenPrinter
899 * have to code it, later.
901 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
902 * called from api_spoolss_rffpcnex
903 ********************************************************************/
904 uint32 _spoolss_rffpcnex(POLICY_HND *handle, uint32 flags, uint32 options,
905 const UNISTR2 *localmachine, uint32 printerlocal,
906 SPOOL_NOTIFY_OPTION *option)
908 /* store the notify value in the printer struct */
910 Printer_entry *Printer=find_printer_index_by_hnd(handle);
912 if (!OPEN_HANDLE(Printer)) {
913 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
914 return ERROR_INVALID_HANDLE;
917 Printer->notify.flags=flags;
918 Printer->notify.options=options;
919 Printer->notify.printerlocal=printerlocal;
920 Printer->notify.option=option;
921 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
923 return NT_STATUS_NO_PROBLEMO;
926 /*******************************************************************
927 * fill a notify_info_data with the servername
928 ********************************************************************/
929 static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
930 NT_PRINTER_INFO_LEVEL *printer)
934 snprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
936 data->notify_data.data.length= (uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
937 temp_name, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
940 /*******************************************************************
941 * fill a notify_info_data with the servicename
942 * jfmxxxx: it's incorrect should be long_printername
943 ********************************************************************/
944 static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
945 NT_PRINTER_INFO_LEVEL *printer)
948 data->notify_data.data.length=strlen(lp_servicename(snum));
949 dos_PutUniCode(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string), True);
951 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
952 printer->info_2->printername, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
955 /*******************************************************************
956 * fill a notify_info_data with the servicename
957 ********************************************************************/
958 static void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
960 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
961 lp_servicename(snum), sizeof(data->notify_data.data.string),True) - sizeof(uint16))/sizeof(uint16));
964 /*******************************************************************
965 * fill a notify_info_data with the port name
966 ********************************************************************/
967 static void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
969 /* even if it's strange, that's consistant in all the code */
971 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
972 lp_servicename(snum), sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
975 /*******************************************************************
976 * fill a notify_info_data with the printername
977 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
978 * but it doesn't exist, have to see what to do
979 ********************************************************************/
980 static void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
982 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
983 printer->info_2->drivername, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
986 /*******************************************************************
987 * fill a notify_info_data with the comment
988 ********************************************************************/
989 static void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
991 if (*printer->info_2->comment == '\0')
992 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
993 lp_comment(snum), sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
995 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
996 printer->info_2->comment, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
999 /*******************************************************************
1000 * fill a notify_info_data with the comment
1001 * jfm:xxxx incorrect, have to create a new smb.conf option
1002 * location = "Room 1, floor 2, building 3"
1003 ********************************************************************/
1004 static void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1006 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1007 printer->info_2->location, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1010 /*******************************************************************
1011 * fill a notify_info_data with the device mode
1012 * jfm:xxxx don't to it for know but that's a real problem !!!
1013 ********************************************************************/
1014 static void spoolss_notify_devmode(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1018 /*******************************************************************
1019 * fill a notify_info_data with the separator file name
1020 * jfm:xxxx just return no file could add an option to smb.conf
1021 * separator file = "separator.txt"
1022 ********************************************************************/
1023 static void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1025 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1026 printer->info_2->sepfile, sizeof(data->notify_data.data.string)-1,True) - sizeof(uint16))/sizeof(uint16));
1029 /*******************************************************************
1030 * fill a notify_info_data with the print processor
1031 * jfm:xxxx return always winprint to indicate we don't do anything to it
1032 ********************************************************************/
1033 static void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1035 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1036 printer->info_2->printprocessor, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1039 /*******************************************************************
1040 * fill a notify_info_data with the print processor options
1041 * jfm:xxxx send an empty string
1042 ********************************************************************/
1043 static void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1045 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1046 printer->info_2->parameters, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1049 /*******************************************************************
1050 * fill a notify_info_data with the data type
1051 * jfm:xxxx always send RAW as data type
1052 ********************************************************************/
1053 static void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1055 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1056 printer->info_2->datatype, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1059 /*******************************************************************
1060 * fill a notify_info_data with the security descriptor
1061 * jfm:xxxx send an null pointer to say no security desc
1062 * have to implement security before !
1063 ********************************************************************/
1064 static void spoolss_notify_security_desc(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1066 data->notify_data.data.length=0;
1067 data->notify_data.data.string[0]=0x00;
1070 /*******************************************************************
1071 * fill a notify_info_data with the attributes
1072 * jfm:xxxx a samba printer is always shared
1073 ********************************************************************/
1074 static void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1076 data->notify_data.value[0] = PRINTER_ATTRIBUTE_SHARED \
1077 | PRINTER_ATTRIBUTE_LOCAL \
1078 | PRINTER_ATTRIBUTE_RAW_ONLY ;
1081 /*******************************************************************
1082 * fill a notify_info_data with the priority
1083 ********************************************************************/
1084 static void spoolss_notify_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1086 data->notify_data.value[0] = printer->info_2->priority;
1089 /*******************************************************************
1090 * fill a notify_info_data with the default priority
1091 ********************************************************************/
1092 static void spoolss_notify_default_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1094 data->notify_data.value[0] = printer->info_2->default_priority;
1097 /*******************************************************************
1098 * fill a notify_info_data with the start time
1099 ********************************************************************/
1100 static void spoolss_notify_start_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1102 data->notify_data.value[0] = printer->info_2->starttime;
1105 /*******************************************************************
1106 * fill a notify_info_data with the until time
1107 ********************************************************************/
1108 static void spoolss_notify_until_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1110 data->notify_data.value[0] = printer->info_2->untiltime;
1113 /*******************************************************************
1114 * fill a notify_info_data with the status
1115 ********************************************************************/
1116 static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1119 print_queue_struct *q=NULL;
1120 print_status_struct status;
1122 memset(&status, 0, sizeof(status));
1123 count = print_queue_status(snum, &q, &status);
1124 data->notify_data.value[0]=(uint32) status.status;
1128 /*******************************************************************
1129 * fill a notify_info_data with the number of jobs queued
1130 ********************************************************************/
1131 static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1133 print_queue_struct *q=NULL;
1134 print_status_struct status;
1136 memset(&status, 0, sizeof(status));
1137 data->notify_data.value[0] = print_queue_status(snum, &q, &status);
1141 /*******************************************************************
1142 * fill a notify_info_data with the average ppm
1143 ********************************************************************/
1144 static void spoolss_notify_average_ppm(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1146 /* always respond 8 pages per minutes */
1147 /* a little hard ! */
1148 data->notify_data.value[0] = printer->info_2->averageppm;
1151 /*******************************************************************
1152 * fill a notify_info_data with
1153 ********************************************************************/
1154 static void spoolss_notify_username(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1156 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1157 queue->user, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1160 /*******************************************************************
1161 * fill a notify_info_data with
1162 ********************************************************************/
1163 static void spoolss_notify_job_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1165 data->notify_data.value[0]=nt_printj_status(queue->status);
1168 /*******************************************************************
1169 * fill a notify_info_data with
1170 ********************************************************************/
1171 static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1173 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1174 queue->file, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1177 /*******************************************************************
1178 * fill a notify_info_data with
1179 ********************************************************************/
1180 static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1182 char *p = "unknown";
1183 switch (queue->status) {
1197 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1198 p, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1201 /*******************************************************************
1202 * fill a notify_info_data with
1203 ********************************************************************/
1204 static void spoolss_notify_job_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1206 data->notify_data.value[0]=0x0;
1209 /*******************************************************************
1210 * fill a notify_info_data with
1211 ********************************************************************/
1212 static void spoolss_notify_job_size(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1214 data->notify_data.value[0]=queue->size;
1217 /*******************************************************************
1218 * fill a notify_info_data with
1219 ********************************************************************/
1220 static void spoolss_notify_job_position(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1222 data->notify_data.value[0]=queue->job;
1227 struct s_notify_info_data_table
1233 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
1234 print_queue_struct *queue,
1235 NT_PRINTER_INFO_LEVEL *printer);
1238 struct s_notify_info_data_table notify_info_data_table[] =
1240 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
1241 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1242 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
1243 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1244 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1245 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
1246 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
1247 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1248 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
1249 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1250 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1251 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1252 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
1253 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
1254 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1255 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
1256 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1257 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1258 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
1259 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
1260 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
1261 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
1262 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
1263 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
1264 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
1265 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
1266 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1267 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
1268 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1269 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
1270 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
1271 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1272 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1273 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1274 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1275 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1276 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
1277 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
1278 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
1279 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
1280 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1281 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
1282 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, NULL },
1283 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1284 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1285 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
1286 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
1287 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
1288 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
1289 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
1290 { END, END, "", END, NULL }
1293 /*******************************************************************
1294 return the size of info_data structure
1295 ********************************************************************/
1296 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
1300 while (notify_info_data_table[i].type != END)
1302 if ( (notify_info_data_table[i].type == type ) &&
1303 (notify_info_data_table[i].field == field ) )
1305 return (notify_info_data_table[i].size);
1313 /*******************************************************************
1314 return the type of notify_info_data
1315 ********************************************************************/
1316 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
1320 while (notify_info_data_table[i].type != END)
1322 if ( (notify_info_data_table[i].type == type ) &&
1323 (notify_info_data_table[i].field == field ) )
1325 if (notify_info_data_table[i].size == POINTER)
1340 /****************************************************************************
1341 ****************************************************************************/
1342 static int search_notify(uint16 type, uint16 field, int *value)
1347 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1349 if ( (notify_info_data_table[j].type == type ) &&
1350 (notify_info_data_table[j].field == field ) )
1355 if ( found && (notify_info_data_table[j].fn != NULL) )
1361 /****************************************************************************
1362 ****************************************************************************/
1363 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1365 info_data->type = type;
1366 info_data->field = field;
1367 info_data->reserved = 0;
1369 info_data->size = size_of_notify_info_data(type, field);
1370 info_data->enc_type = type_of_notify_info_data(type, field);
1374 /*******************************************************************
1376 * fill a notify_info struct with info asked
1378 ********************************************************************/
1379 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1385 SPOOL_NOTIFY_INFO_DATA *current_data;
1386 NT_PRINTER_INFO_LEVEL *printer = NULL;
1387 print_queue_struct *queue=NULL;
1389 DEBUG(4,("construct_notify_printer_info\n"));
1391 type=option_type->type;
1393 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
1394 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1395 option_type->count, lp_servicename(snum)));
1397 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1400 for(field_num=0; field_num<option_type->count; field_num++) {
1401 field = option_type->fields[field_num];
1402 DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field));
1404 if (!search_notify(type, field, &j) )
1407 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1410 current_data=&info->data[info->count];
1412 construct_info_data(current_data, type, field, id);
1413 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1418 free_a_printer(&printer, 2);
1422 /*******************************************************************
1424 * fill a notify_info struct with info asked
1426 ********************************************************************/
1427 static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1433 SPOOL_NOTIFY_INFO_DATA *current_data;
1434 NT_PRINTER_INFO_LEVEL *printer = NULL;
1436 DEBUG(4,("construct_notify_jobs_info\n"));
1438 type = option_type->type;
1440 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
1441 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1442 option_type->count));
1444 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1447 for(field_num=0; field_num<option_type->count; field_num++) {
1448 field = option_type->fields[field_num];
1450 if (!search_notify(type, field, &j) )
1453 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1457 current_data=&(info->data[info->count]);
1459 construct_info_data(current_data, type, field, id);
1460 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1464 free_a_printer(&printer, 2);
1469 * JFM: The enumeration is not that simple, it's even non obvious.
1471 * let's take an example: I want to monitor the PRINTER SERVER for
1472 * the printer's name and the number of jobs currently queued.
1473 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
1474 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
1476 * I have 3 printers on the back of my server.
1478 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
1481 * 1 printer 1 name 1
1482 * 2 printer 1 cjob 1
1483 * 3 printer 2 name 2
1484 * 4 printer 2 cjob 2
1485 * 5 printer 3 name 3
1486 * 6 printer 3 name 3
1488 * that's the print server case, the printer case is even worse.
1493 /*******************************************************************
1495 * enumerate all printers on the printserver
1496 * fill a notify_info struct with info asked
1498 ********************************************************************/
1499 static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1502 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1503 int n_services=lp_numservices();
1506 SPOOL_NOTIFY_OPTION *option;
1507 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1509 DEBUG(4,("printserver_notify_info\n"));
1511 option=Printer->notify.option;
1517 for (i=0; i<option->count; i++) {
1518 option_type=&(option->ctr.type[i]);
1520 if (option_type->type!=PRINTER_NOTIFY_TYPE)
1523 for (snum=0; snum<n_services; snum++)
1524 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1525 if (construct_notify_printer_info(info, snum, option_type, id))
1530 * Debugging information, don't delete.
1533 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1534 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1535 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1537 for (i=0; i<info->count; i++) {
1538 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1539 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1540 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1544 return NT_STATUS_NO_PROBLEMO;
1547 /*******************************************************************
1549 * fill a notify_info struct with info asked
1551 ********************************************************************/
1552 static uint32 printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1555 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1558 SPOOL_NOTIFY_OPTION *option;
1559 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1561 print_queue_struct *queue=NULL;
1562 print_status_struct status;
1564 DEBUG(4,("printer_notify_info\n"));
1566 option=Printer->notify.option;
1572 get_printer_snum(hnd, &snum);
1574 for (i=0; i<option->count; i++) {
1575 option_type=&option->ctr.type[i];
1577 switch ( option_type->type ) {
1578 case PRINTER_NOTIFY_TYPE:
1579 if(construct_notify_printer_info(info, snum, option_type, id))
1583 case JOB_NOTIFY_TYPE:
1584 memset(&status, 0, sizeof(status));
1585 count = print_queue_status(snum, &queue, &status);
1586 for (j=0; j<count; j++)
1587 construct_notify_jobs_info(&queue[j], info, snum, option_type, queue[j].job);
1594 * Debugging information, don't delete.
1597 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1598 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1599 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1601 for (i=0; i<info->count; i++) {
1602 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1603 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1604 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1607 return NT_STATUS_NO_PROBLEMO;
1610 /********************************************************************
1612 ********************************************************************/
1613 uint32 _spoolss_rfnpcnex( POLICY_HND *handle, uint32 change,
1614 SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info)
1616 Printer_entry *Printer=find_printer_index_by_hnd(handle);
1618 if (!OPEN_HANDLE(Printer)) {
1619 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",OUR_HANDLE(handle)));
1620 return ERROR_INVALID_HANDLE;
1623 DEBUG(4,("Printer type %x\n",Printer->printer_type));
1625 /* jfm: the change value isn't used right now.
1626 * we will honour it when
1627 * a) we'll be able to send notification to the client
1628 * b) we'll have a way to communicate between the spoolss process.
1630 * same thing for option->flags
1631 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
1632 * I don't have a global notification system, I'm sending back all the
1633 * informations even when _NOTHING_ has changed.
1636 /* just discard the SPOOL_NOTIFY_OPTION */
1638 safe_free(option->ctr.type);
1640 switch (Printer->printer_type) {
1641 case PRINTER_HANDLE_IS_PRINTSERVER:
1642 return printserver_notify_info(handle, info);
1644 case PRINTER_HANDLE_IS_PRINTER:
1645 return printer_notify_info(handle, info);
1649 return ERROR_INVALID_HANDLE;
1652 /********************************************************************
1653 * construct_printer_info_0
1654 * fill a printer_info_1 struct
1655 ********************************************************************/
1656 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring servername)
1660 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1661 counter_printer_0 *session_counter;
1662 uint32 global_counter;
1664 time_t setup_time = time(NULL);
1666 print_queue_struct *queue=NULL;
1667 print_status_struct status;
1669 memset(&status, 0, sizeof(status));
1671 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1674 count = print_queue_status(snum, &queue, &status);
1676 /* check if we already have a counter for this printer */
1677 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
1679 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
1680 if (session_counter->snum == snum)
1684 /* it's the first time, add it to the list */
1685 if (session_counter==NULL) {
1686 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
1687 free_a_printer(&ntprinter, 2);
1690 ZERO_STRUCTP(session_counter);
1691 session_counter->snum=snum;
1692 session_counter->counter=0;
1693 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
1697 session_counter->counter++;
1700 * the global_counter should be stored in a TDB as it's common to all the clients
1701 * and should be zeroed on samba startup
1703 global_counter=session_counter->counter;
1705 /* the description and the name are of the form \\server\share */
1706 slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter->info_2->printername);
1708 init_unistr(&printer->printername, chaine);
1710 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1711 init_unistr(&printer->servername, chaine);
1713 printer->cjobs = count;
1714 printer->total_jobs = 0;
1715 printer->total_bytes = 0;
1717 t=gmtime(&setup_time);
1718 ntprinter->info_2->setuptime = (uint32)setup_time; /* FIXME !! */
1720 printer->year = t->tm_year+1900;
1721 printer->month = t->tm_mon+1;
1722 printer->dayofweek = t->tm_wday;
1723 printer->day = t->tm_mday;
1724 printer->hour = t->tm_hour;
1725 printer->minute = t->tm_min;
1726 printer->second = t->tm_sec;
1727 printer->milliseconds = 0;
1729 printer->global_counter = global_counter;
1730 printer->total_pages = 0;
1731 printer->major_version = 0x0004; /* NT 4 */
1732 printer->build_version = 0x0565; /* build 1381 */
1733 printer->unknown7 = 0x1;
1734 printer->unknown8 = 0x0;
1735 printer->unknown9 = 0x0;
1736 printer->session_counter = session_counter->counter;
1737 printer->unknown11 = 0x0;
1738 printer->printer_errors = 0x0; /* number of print failure */
1739 printer->unknown13 = 0x0;
1740 printer->unknown14 = 0x1;
1741 printer->unknown15 = 0x024a; /* 586 Pentium ? */
1742 printer->unknown16 = 0x0;
1743 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
1744 printer->unknown18 = 0x0;
1745 printer->status = nt_printq_status(status.status);
1746 printer->unknown20 = 0x0;
1747 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
1748 printer->unknown22 = 0x0;
1749 printer->unknown23 = 0x6; /* 6 ???*/
1750 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
1751 printer->unknown25 = 0;
1752 printer->unknown26 = 0;
1753 printer->unknown27 = 0;
1754 printer->unknown28 = 0;
1755 printer->unknown29 = 0;
1758 free_a_printer(&ntprinter,2);
1762 /********************************************************************
1763 * construct_printer_info_1
1764 * fill a printer_info_1 struct
1765 ********************************************************************/
1766 static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum)
1770 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1772 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1775 printer->flags=flags;
1777 if (*ntprinter->info_2->comment == '\0') {
1778 init_unistr(&printer->comment, lp_comment(snum));
1779 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1780 ntprinter->info_2->drivername, lp_comment(snum));
1783 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1784 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1785 ntprinter->info_2->drivername, ntprinter->info_2->comment);
1788 snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter->info_2->printername);
1790 init_unistr(&printer->description, chaine);
1791 init_unistr(&printer->name, chaine2);
1793 free_a_printer(&ntprinter,2);
1798 /****************************************************************************
1799 Free a DEVMODE struct.
1800 ****************************************************************************/
1802 static void free_dev_mode(DEVICEMODE *dev)
1808 safe_free(dev->private);
1813 /****************************************************************************
1814 Create a DEVMODE struct. Returns malloced memory.
1815 ****************************************************************************/
1817 static DEVICEMODE *construct_dev_mode(int snum, char *servername)
1821 NT_PRINTER_INFO_LEVEL *printer = NULL;
1822 NT_DEVICEMODE *ntdevmode = NULL;
1823 DEVICEMODE *devmode = NULL;
1825 DEBUG(7,("construct_dev_mode\n"));
1827 DEBUGADD(8,("getting printer characteristics\n"));
1829 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
1830 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
1834 ZERO_STRUCTP(devmode);
1836 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
1839 if (printer->info_2->devmode)
1840 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
1843 ntdevmode = construct_nt_devicemode(printer->info_2->printername);
1845 if (ntdevmode == NULL)
1848 DEBUGADD(8,("loading DEVICEMODE\n"));
1850 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, printer->info_2->printername);
1851 init_unistr(&devmode->devicename, adevice);
1853 snprintf(aform, sizeof(aform), ntdevmode->formname);
1854 init_unistr(&devmode->formname, aform);
1856 devmode->specversion = ntdevmode->specversion;
1857 devmode->driverversion = ntdevmode->driverversion;
1858 devmode->size = ntdevmode->size;
1859 devmode->driverextra = ntdevmode->driverextra;
1860 devmode->fields = ntdevmode->fields;
1862 devmode->orientation = ntdevmode->orientation;
1863 devmode->papersize = ntdevmode->papersize;
1864 devmode->paperlength = ntdevmode->paperlength;
1865 devmode->paperwidth = ntdevmode->paperwidth;
1866 devmode->scale = ntdevmode->scale;
1867 devmode->copies = ntdevmode->copies;
1868 devmode->defaultsource = ntdevmode->defaultsource;
1869 devmode->printquality = ntdevmode->printquality;
1870 devmode->color = ntdevmode->color;
1871 devmode->duplex = ntdevmode->duplex;
1872 devmode->yresolution = ntdevmode->yresolution;
1873 devmode->ttoption = ntdevmode->ttoption;
1874 devmode->collate = ntdevmode->collate;
1875 devmode->icmmethod = ntdevmode->icmmethod;
1876 devmode->icmintent = ntdevmode->icmintent;
1877 devmode->mediatype = ntdevmode->mediatype;
1878 devmode->dithertype = ntdevmode->dithertype;
1880 if (ntdevmode->private != NULL) {
1881 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
1885 free_nt_devicemode(&ntdevmode);
1886 free_a_printer(&printer,2);
1893 free_nt_devicemode(&ntdevmode);
1895 free_a_printer(&printer,2);
1896 free_dev_mode(devmode);
1901 /********************************************************************
1902 * construct_printer_info_2
1903 * fill a printer_info_2 struct
1904 ********************************************************************/
1906 static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer, int snum)
1912 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1914 print_queue_struct *queue=NULL;
1915 print_status_struct status;
1916 memset(&status, 0, sizeof(status));
1918 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1921 memset(&status, 0, sizeof(status));
1922 count = print_queue_status(snum, &queue, &status);
1924 snprintf(chaine, sizeof(chaine)-1, "%s", servername);
1926 if (strlen(servername)!=0)
1931 snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter->info_2->printername);
1933 init_unistr(&printer->servername, chaine); /* servername*/
1934 init_unistr(&printer->printername, chaine2); /* printername*/
1935 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
1936 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
1937 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
1939 if (*ntprinter->info_2->comment == '\0')
1940 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
1942 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1944 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
1945 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
1946 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
1947 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
1948 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
1950 printer->attributes = ntprinter->info_2->attributes;
1952 printer->priority = ntprinter->info_2->priority; /* priority */
1953 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
1954 printer->starttime = ntprinter->info_2->starttime; /* starttime */
1955 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
1956 printer->status = nt_printq_status(status.status); /* status */
1957 printer->cjobs = count; /* jobs */
1958 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
1960 if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) {
1961 DEBUG(8, ("Returning NULL Devicemode!\n"));
1964 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1965 /* steal the printer info sec_desc structure. [badly done]. */
1966 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1967 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
1968 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
1969 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
1972 printer->secdesc = NULL;
1975 free_a_printer(&ntprinter, 2);
1980 /********************************************************************
1981 * construct_printer_info_3
1982 * fill a printer_info_3 struct
1983 ********************************************************************/
1984 static BOOL construct_printer_info_3(fstring servername,
1985 PRINTER_INFO_3 **pp_printer, int snum)
1987 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1988 PRINTER_INFO_3 *printer = NULL;
1990 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1994 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
1995 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
1999 ZERO_STRUCTP(printer);
2001 printer->flags = 4; /* This is the offset to the SEC_DESC. */
2002 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
2003 /* steal the printer info sec_desc structure. [badly done]. */
2004 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2005 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
2006 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
2007 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
2010 free_a_printer(&ntprinter, 2);
2012 *pp_printer = printer;
2016 /********************************************************************
2017 Spoolss_enumprinters.
2018 ********************************************************************/
2019 static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2023 int n_services=lp_numservices();
2024 PRINTER_INFO_1 *printers=NULL;
2025 PRINTER_INFO_1 current_prt;
2027 DEBUG(4,("enum_all_printers_info_1\n"));
2029 for (snum=0; snum<n_services; snum++) {
2030 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2031 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2033 if (construct_printer_info_1(server, flags, ¤t_prt, snum)) {
2034 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
2036 return ERROR_NOT_ENOUGH_MEMORY;
2038 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2039 memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1));
2045 /* check the required size. */
2046 for (i=0; i<*returned; i++)
2047 (*needed) += spoolss_size_printer_info_1(&(printers[i]));
2049 if (!alloc_buffer_size(buffer, *needed))
2050 return ERROR_INSUFFICIENT_BUFFER;
2052 /* fill the buffer with the structures */
2053 for (i=0; i<*returned; i++)
2054 new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);
2057 safe_free(printers);
2059 if (*needed > offered) {
2061 return ERROR_INSUFFICIENT_BUFFER;
2064 return NT_STATUS_NO_PROBLEMO;
2067 /********************************************************************
2068 enum_all_printers_info_1_local.
2069 *********************************************************************/
2070 static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2073 DEBUG(4,("enum_all_printers_info_1_local\n"));
2075 fstrcpy(temp, "\\\\");
2076 fstrcat(temp, global_myname);
2078 if (!strcmp(name, temp)) {
2079 fstrcat(temp, "\\");
2080 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2083 return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2086 /********************************************************************
2087 enum_all_printers_info_1_name.
2088 *********************************************************************/
2089 static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2092 DEBUG(4,("enum_all_printers_info_1_name\n"));
2094 fstrcpy(temp, "\\\\");
2095 fstrcat(temp, global_myname);
2097 if (!strcmp(name, temp)) {
2098 fstrcat(temp, "\\");
2099 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2102 return ERROR_INVALID_NAME;
2105 /********************************************************************
2106 enum_all_printers_info_1_remote.
2107 *********************************************************************/
2108 static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2110 PRINTER_INFO_1 *printer;
2111 fstring printername;
2114 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2116 /* JFM: currently it's more a place holder than anything else.
2117 * In the spooler world there is a notion of server registration.
2118 * the print servers are registring (sp ?) on the PDC (in the same domain)
2120 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2123 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2124 return ERROR_NOT_ENOUGH_MEMORY;
2128 snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
2129 snprintf(desc, sizeof(desc)-1,"%s", global_myname);
2130 snprintf(comment, sizeof(comment)-1, "Logged on Domain");
2132 init_unistr(&printer->description, desc);
2133 init_unistr(&printer->name, printername);
2134 init_unistr(&printer->comment, comment);
2135 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2137 /* check the required size. */
2138 *needed += spoolss_size_printer_info_1(printer);
2140 if (!alloc_buffer_size(buffer, *needed)) {
2142 return ERROR_INSUFFICIENT_BUFFER;
2145 /* fill the buffer with the structures */
2146 new_smb_io_printer_info_1("", buffer, printer, 0);
2151 if (*needed > offered) {
2153 return ERROR_INSUFFICIENT_BUFFER;
2156 return NT_STATUS_NO_PROBLEMO;
2159 /********************************************************************
2160 enum_all_printers_info_1_network.
2161 *********************************************************************/
2162 static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2165 DEBUG(4,("enum_all_printers_info_1_network\n"));
2167 fstrcpy(temp, "\\\\");
2168 fstrcat(temp, global_myname);
2169 fstrcat(temp, "\\");
2170 return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
2173 /********************************************************************
2174 * api_spoolss_enumprinters
2176 * called from api_spoolss_enumprinters (see this to understand)
2177 ********************************************************************/
2178 static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2182 int n_services=lp_numservices();
2183 PRINTER_INFO_2 *printers=NULL;
2184 PRINTER_INFO_2 current_prt;
2186 for (snum=0; snum<n_services; snum++) {
2187 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2188 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2190 if (construct_printer_info_2(servername, ¤t_prt, snum)) {
2191 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL)
2192 return ERROR_NOT_ENOUGH_MEMORY;
2193 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
2194 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
2200 /* check the required size. */
2201 for (i=0; i<*returned; i++)
2202 (*needed) += spoolss_size_printer_info_2(&printers[i]);
2204 if (!alloc_buffer_size(buffer, *needed)) {
2205 for (i=0; i<*returned; i++) {
2206 free_devmode(printers[i].devmode);
2207 free_sec_desc(&printers[i].secdesc);
2209 safe_free(printers);
2210 return ERROR_INSUFFICIENT_BUFFER;
2213 /* fill the buffer with the structures */
2214 for (i=0; i<*returned; i++)
2215 new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);
2218 for (i=0; i<*returned; i++) {
2219 free_devmode(printers[i].devmode);
2220 free_sec_desc(&printers[i].secdesc);
2222 safe_free(printers);
2224 if (*needed > offered) {
2226 return ERROR_INSUFFICIENT_BUFFER;
2229 return NT_STATUS_NO_PROBLEMO;
2232 /********************************************************************
2233 * handle enumeration of printers at level 1
2234 ********************************************************************/
2235 static uint32 enumprinters_level1( uint32 flags, fstring name,
2236 NEW_BUFFER *buffer, uint32 offered,
2237 uint32 *needed, uint32 *returned)
2239 /* Not all the flags are equals */
2241 if (flags & PRINTER_ENUM_LOCAL)
2242 return enum_all_printers_info_1_local(name, buffer, offered, needed, returned);
2244 if (flags & PRINTER_ENUM_NAME)
2245 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
2247 if (flags & PRINTER_ENUM_REMOTE)
2248 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
2250 if (flags & PRINTER_ENUM_NETWORK)
2251 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
2253 return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
2256 /********************************************************************
2257 * handle enumeration of printers at level 2
2258 ********************************************************************/
2259 static uint32 enumprinters_level2( uint32 flags, fstring servername,
2260 NEW_BUFFER *buffer, uint32 offered,
2261 uint32 *needed, uint32 *returned)
2265 fstrcpy(temp, "\\\\");
2266 fstrcat(temp, global_myname);
2268 if (flags & PRINTER_ENUM_LOCAL) {
2269 if (!strcmp(servername, temp))
2270 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2272 return enum_all_printers_info_2("", buffer, offered, needed, returned);
2275 if (flags & PRINTER_ENUM_NAME) {
2276 if (!strcmp(servername, temp))
2277 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2279 return ERROR_INVALID_NAME;
2282 if (flags & PRINTER_ENUM_REMOTE)
2283 return ERROR_INVALID_LEVEL;
2285 return NT_STATUS_NO_PROBLEMO;
2288 /********************************************************************
2289 * handle enumeration of printers at level 5
2290 ********************************************************************/
2291 static uint32 enumprinters_level5( uint32 flags, fstring servername,
2292 NEW_BUFFER *buffer, uint32 offered,
2293 uint32 *needed, uint32 *returned)
2295 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
2296 return NT_STATUS_NO_PROBLEMO;
2299 /********************************************************************
2300 * api_spoolss_enumprinters
2302 * called from api_spoolss_enumprinters (see this to understand)
2303 ********************************************************************/
2304 uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
2305 NEW_BUFFER *buffer, uint32 offered,
2306 uint32 *needed, uint32 *returned)
2310 DEBUG(4,("_spoolss_enumprinters\n"));
2317 * flags==PRINTER_ENUM_NAME
2318 * if name=="" then enumerates all printers
2319 * if name!="" then enumerate the printer
2320 * flags==PRINTER_ENUM_REMOTE
2321 * name is NULL, enumerate printers
2322 * Level 2: name!="" enumerates printers, name can't be NULL
2323 * Level 3: doesn't exist
2324 * Level 4: does a local registry lookup
2325 * Level 5: same as Level 2
2328 unistr2_to_ascii(name, servername, sizeof(name)-1);
2333 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
2336 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
2339 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
2344 return ERROR_INVALID_LEVEL;
2349 /****************************************************************************
2350 ****************************************************************************/
2351 static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2353 PRINTER_INFO_0 *printer=NULL;
2355 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
2356 return ERROR_NOT_ENOUGH_MEMORY;
2358 construct_printer_info_0(printer, snum, servername);
2360 /* check the required size. */
2361 *needed += spoolss_size_printer_info_0(printer);
2363 if (!alloc_buffer_size(buffer, *needed)) {
2365 return ERROR_INSUFFICIENT_BUFFER;
2368 /* fill the buffer with the structures */
2369 new_smb_io_printer_info_0("", buffer, printer, 0);
2374 if (*needed > offered) {
2375 return ERROR_INSUFFICIENT_BUFFER;
2378 return NT_STATUS_NO_PROBLEMO;
2381 /****************************************************************************
2382 ****************************************************************************/
2383 static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2385 PRINTER_INFO_1 *printer=NULL;
2387 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2388 return ERROR_NOT_ENOUGH_MEMORY;
2390 construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum);
2392 /* check the required size. */
2393 *needed += spoolss_size_printer_info_1(printer);
2395 if (!alloc_buffer_size(buffer, *needed)) {
2397 return ERROR_INSUFFICIENT_BUFFER;
2400 /* fill the buffer with the structures */
2401 new_smb_io_printer_info_1("", buffer, printer, 0);
2406 if (*needed > offered) {
2407 return ERROR_INSUFFICIENT_BUFFER;
2410 return NT_STATUS_NO_PROBLEMO;
2413 /****************************************************************************
2414 ****************************************************************************/
2415 static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2417 PRINTER_INFO_2 *printer=NULL;
2420 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
2421 return ERROR_NOT_ENOUGH_MEMORY;
2423 fstrcpy(temp, "\\\\");
2424 fstrcat(temp, servername);
2425 construct_printer_info_2(temp, printer, snum);
2427 /* check the required size. */
2428 *needed += spoolss_size_printer_info_2(printer);
2430 if (!alloc_buffer_size(buffer, *needed)) {
2431 free_printer_info_2(printer);
2432 return ERROR_INSUFFICIENT_BUFFER;
2435 /* fill the buffer with the structures */
2436 if (!new_smb_io_printer_info_2("", buffer, printer, 0)) {
2437 free_printer_info_2(printer);
2438 return ERROR_NOT_ENOUGH_MEMORY;
2442 free_printer_info_2(printer);
2444 if (*needed > offered) {
2445 return ERROR_INSUFFICIENT_BUFFER;
2448 return NT_STATUS_NO_PROBLEMO;
2451 /****************************************************************************
2452 ****************************************************************************/
2453 static uint32 getprinter_level_3(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2455 PRINTER_INFO_3 *printer=NULL;
2458 fstrcpy(temp, "\\\\");
2459 fstrcat(temp, servername);
2460 if (!construct_printer_info_3(temp, &printer, snum))
2461 return ERROR_NOT_ENOUGH_MEMORY;
2463 /* check the required size. */
2464 *needed += spoolss_size_printer_info_3(printer);
2466 if (!alloc_buffer_size(buffer, *needed)) {
2467 free_printer_info_3(printer);
2468 return ERROR_INSUFFICIENT_BUFFER;
2471 /* fill the buffer with the structures */
2472 new_smb_io_printer_info_3("", buffer, printer, 0);
2475 free_printer_info_3(printer);
2477 if (*needed > offered) {
2478 return ERROR_INSUFFICIENT_BUFFER;
2481 return NT_STATUS_NO_PROBLEMO;
2484 /****************************************************************************
2485 ****************************************************************************/
2486 uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
2487 NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2494 pstrcpy(servername, global_myname);
2496 if (!get_printer_snum(handle, &snum))
2497 return ERROR_INVALID_HANDLE;
2501 return getprinter_level_0(servername, snum, buffer, offered, needed);
2503 return getprinter_level_1(servername,snum, buffer, offered, needed);
2505 return getprinter_level_2(servername,snum, buffer, offered, needed);
2507 return getprinter_level_3(servername,snum, buffer, offered, needed);
2509 return ERROR_INVALID_LEVEL;
2514 /********************************************************************
2515 * fill a DRIVER_INFO_1 struct
2516 ********************************************************************/
2517 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
2519 init_unistr( &info->name, driver.info_3->name);
2522 /********************************************************************
2523 * construct_printer_driver_info_1
2524 ********************************************************************/
2525 static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
2527 NT_PRINTER_INFO_LEVEL *printer = NULL;
2528 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2530 ZERO_STRUCT(driver);
2532 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2533 return ERROR_INVALID_PRINTER_NAME;
2535 if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2536 return ERROR_UNKNOWN_PRINTER_DRIVER;
2538 fill_printer_driver_info_1(info, driver, servername, architecture);
2540 free_a_printer(&printer,2);
2542 return NT_STATUS_NO_PROBLEMO;
2545 /********************************************************************
2546 * construct_printer_driver_info_2
2547 * fill a printer_info_2 struct
2548 ********************************************************************/
2549 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2551 pstring temp_driverpath;
2552 pstring temp_datafile;
2553 pstring temp_configfile;
2555 info->version=driver.info_3->cversion;
2557 init_unistr( &info->name, driver.info_3->name );
2558 init_unistr( &info->architecture, driver.info_3->environment );
2560 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2561 init_unistr( &info->driverpath, temp_driverpath );
2563 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2564 init_unistr( &info->datafile, temp_datafile );
2566 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2567 init_unistr( &info->configfile, temp_configfile );
2570 /********************************************************************
2571 * construct_printer_driver_info_2
2572 * fill a printer_info_2 struct
2573 ********************************************************************/
2574 static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
2576 NT_PRINTER_INFO_LEVEL *printer = NULL;
2577 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2579 ZERO_STRUCT(printer);
2580 ZERO_STRUCT(driver);
2582 if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2583 return ERROR_INVALID_PRINTER_NAME;
2585 if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2586 return ERROR_UNKNOWN_PRINTER_DRIVER;
2588 fill_printer_driver_info_2(info, driver, servername);
2590 free_a_printer(&printer,2);
2592 return NT_STATUS_NO_PROBLEMO;
2595 /********************************************************************
2596 * copy a strings array and convert to UNICODE
2598 * convert an array of ascii string to a UNICODE string
2599 ********************************************************************/
2600 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
2607 DEBUG(6,("init_unistr_array\n"));
2611 if (char_array == NULL)
2615 if (!v) v = ""; /* hack to handle null lists */
2617 if (strlen(v) == 0) break;
2618 snprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
2619 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
2620 if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
2621 DEBUG(0,("init_unistr_array: Realloc error\n" ));
2624 j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
2629 (*uni_array)[j]=0x0000;
2632 DEBUGADD(6,("last one:done\n"));
2635 /********************************************************************
2636 * construct_printer_info_3
2637 * fill a printer_info_3 struct
2638 ********************************************************************/
2639 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2641 pstring temp_driverpath;
2642 pstring temp_datafile;
2643 pstring temp_configfile;
2644 pstring temp_helpfile;
2646 info->version=driver.info_3->cversion;
2648 init_unistr( &info->name, driver.info_3->name );
2649 init_unistr( &info->architecture, driver.info_3->environment );
2651 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2652 init_unistr( &info->driverpath, temp_driverpath );
2654 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2655 init_unistr( &info->datafile, temp_datafile );
2657 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2658 init_unistr( &info->configfile, temp_configfile );
2660 snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
2661 init_unistr( &info->helpfile, temp_helpfile );
2663 init_unistr( &info->monitorname, driver.info_3->monitorname );
2664 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
2666 info->dependentfiles=NULL;
2667 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
2670 /********************************************************************
2671 * construct_printer_info_3
2672 * fill a printer_info_3 struct
2673 ********************************************************************/
2674 static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
2676 NT_PRINTER_INFO_LEVEL *printer = NULL;
2677 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2679 ZERO_STRUCT(driver);
2681 status=get_a_printer(&printer, 2, lp_servicename(snum) );
2682 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2684 return ERROR_INVALID_PRINTER_NAME;
2686 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
2687 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2689 free_a_printer(&printer,2);
2690 return ERROR_UNKNOWN_PRINTER_DRIVER;
2693 fill_printer_driver_info_3(info, driver, servername);
2695 free_a_printer(&printer,2);
2697 return NT_STATUS_NO_PROBLEMO;
2700 /****************************************************************************
2701 ****************************************************************************/
2703 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
2705 safe_free(info->dependentfiles);
2708 /****************************************************************************
2709 ****************************************************************************/
2710 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2712 DRIVER_INFO_1 *info=NULL;
2715 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
2716 return ERROR_NOT_ENOUGH_MEMORY;
2718 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
2719 if (status != NT_STATUS_NO_PROBLEMO) {
2724 /* check the required size. */
2725 *needed += spoolss_size_printer_driver_info_1(info);
2727 if (!alloc_buffer_size(buffer, *needed)) {
2729 return ERROR_INSUFFICIENT_BUFFER;
2732 /* fill the buffer with the structures */
2733 new_smb_io_printer_driver_info_1("", buffer, info, 0);
2738 if (*needed > offered)
2739 return ERROR_INSUFFICIENT_BUFFER;
2741 return NT_STATUS_NO_PROBLEMO;
2744 /****************************************************************************
2745 ****************************************************************************/
2746 static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2748 DRIVER_INFO_2 *info=NULL;
2751 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
2752 return ERROR_NOT_ENOUGH_MEMORY;
2754 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
2755 if (status != NT_STATUS_NO_PROBLEMO) {
2760 /* check the required size. */
2761 *needed += spoolss_size_printer_driver_info_2(info);
2763 if (!alloc_buffer_size(buffer, *needed)) {
2765 return ERROR_INSUFFICIENT_BUFFER;
2768 /* fill the buffer with the structures */
2769 new_smb_io_printer_driver_info_2("", buffer, info, 0);
2774 if (*needed > offered)
2775 return ERROR_INSUFFICIENT_BUFFER;
2777 return NT_STATUS_NO_PROBLEMO;
2780 /****************************************************************************
2781 ****************************************************************************/
2782 static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2789 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
2790 if (status != NT_STATUS_NO_PROBLEMO) {
2794 /* check the required size. */
2795 *needed += spoolss_size_printer_driver_info_3(&info);
2797 if (!alloc_buffer_size(buffer, *needed)) {
2798 free_printer_driver_info_3(&info);
2799 return ERROR_INSUFFICIENT_BUFFER;
2802 /* fill the buffer with the structures */
2803 new_smb_io_printer_driver_info_3("", buffer, &info, 0);
2805 free_printer_driver_info_3(&info);
2807 if (*needed > offered)
2808 return ERROR_INSUFFICIENT_BUFFER;
2810 return NT_STATUS_NO_PROBLEMO;
2813 /****************************************************************************
2814 ****************************************************************************/
2815 uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level,
2816 uint32 clientmajorversion, uint32 clientminorversion,
2817 NEW_BUFFER *buffer, uint32 offered,
2818 uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
2821 fstring architecture;
2824 DEBUG(4,("_spoolss_getprinterdriver2\n"));
2827 *servermajorversion=0;
2828 *serverminorversion=0;
2830 pstrcpy(servername, global_myname);
2831 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
2833 if (!get_printer_snum(handle, &snum))
2834 return ERROR_INVALID_HANDLE;
2838 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2841 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2844 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2847 return ERROR_INVALID_LEVEL;
2852 /****************************************************************************
2853 ****************************************************************************/
2854 uint32 _spoolss_startpageprinter(POLICY_HND *handle)
2856 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2858 if (OPEN_HANDLE(Printer)) {
2859 Printer->page_started=True;
2863 DEBUG(3,("Error in startpageprinter printer handle\n"));
2864 return ERROR_INVALID_HANDLE;
2867 /****************************************************************************
2868 ****************************************************************************/
2869 uint32 _spoolss_endpageprinter(POLICY_HND *handle)
2871 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2873 if (!OPEN_HANDLE(Printer)) {
2874 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
2875 return ERROR_INVALID_HANDLE;
2878 Printer->page_started=False;
2880 return NT_STATUS_NO_PROBLEMO;
2884 /********************************************************************
2885 * api_spoolss_getprinter
2886 * called from the spoolss dispatcher
2888 ********************************************************************/
2889 uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
2890 pipes_struct *p, DOC_INFO *docinfo,
2893 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
2897 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2898 struct current_user user;
2900 if (!OPEN_HANDLE(Printer)) {
2901 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2902 return ERROR_INVALID_HANDLE;
2905 if (p->ntlmssp_auth_validated) {
2906 memcpy(&user, &p->pipe_user, sizeof(user));
2908 extern struct current_user current_user;
2909 memcpy(&user, ¤t_user, sizeof(user));
2913 * a nice thing with NT is it doesn't listen to what you tell it.
2914 * when asked to send _only_ RAW datas, it tries to send datas
2917 * So I add checks like in NT Server ...
2919 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
2920 * there's a bug in NT client-side code, so we'll fix it in the
2921 * server-side code. *nnnnnggggh!*
2924 if (info_1->p_datatype != 0) {
2925 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
2926 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)) {
2934 return ERROR_INVALID_HANDLE;
2937 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
2939 Printer->jobid = print_job_start(&user, snum, jobname);
2941 /* An error occured in print_job_start() so return an appropriate
2944 if (Printer->jobid == -1) {
2945 return map_nt_error_from_unix(errno);
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;
3006 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3008 if (p->ntlmssp_auth_validated) {
3009 memcpy(&user, &p->pipe_user, sizeof(user));
3011 extern struct current_user current_user;
3012 memcpy(&user, ¤t_user, sizeof(user));
3015 if (!OPEN_HANDLE(Printer)) {
3016 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3017 return ERROR_INVALID_HANDLE;
3020 if (!get_printer_snum(handle, &snum) )
3021 return ERROR_INVALID_HANDLE;
3024 case PRINTER_CONTROL_PAUSE:
3025 if (print_queue_pause(&user, snum, &errcode)) {
3029 case PRINTER_CONTROL_RESUME:
3030 case PRINTER_CONTROL_UNPAUSE:
3031 if (print_queue_resume(&user, snum, &errcode)) {
3035 case PRINTER_CONTROL_PURGE:
3036 if (print_queue_purge(&user, snum, &errcode)) {
3043 return (uint32)errcode;
3045 return ERROR_INVALID_FUNCTION;
3048 /********************************************************************
3049 * api_spoolss_abortprinter
3050 ********************************************************************/
3052 uint32 _spoolss_abortprinter(POLICY_HND *handle, pipes_struct *p)
3054 return control_printer(handle, PRINTER_CONTROL_PURGE, p);
3057 /********************************************************************
3058 * called by spoolss_api_setprinter
3059 * when updating a printer description
3060 ********************************************************************/
3061 static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
3062 const SPOOL_PRINTER_INFO_LEVEL *info,
3063 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
3065 struct current_user user;
3069 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3071 if (!OPEN_HANDLE(Printer) || !get_printer_snum(handle, &snum)) {
3072 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3073 return ERROR_INVALID_HANDLE;
3076 /* Work out which user is performing the operation */
3077 if (p->ntlmssp_auth_validated) {
3078 memcpy(&user, &p->pipe_user, sizeof(user));
3080 extern struct current_user current_user;
3081 memcpy(&user, ¤t_user, sizeof(user));
3084 /* Check the user has permissions to change the security
3085 descriptor. By experimentation with two NT machines, the user
3086 requires Full Access to the printer to change security
3088 if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
3089 result = ERROR_ACCESS_DENIED;
3093 result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
3099 /********************************************************************
3100 Do Samba sanity checks on a printer info struct.
3101 ********************************************************************/
3103 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
3106 * Ensure that this printer is shared under the correct name
3107 * as this is what Samba insists upon.
3110 if (!(info->attributes & PRINTER_ATTRIBUTE_SHARED)) {
3111 DEBUG(10,("check_printer_ok: SHARED check failed (%x).\n", (unsigned int)info->attributes ));
3115 if (!(info->attributes & PRINTER_ATTRIBUTE_RAW_ONLY)) {
3116 /* NT forgets to set the raw attribute but sends the correct type. */
3117 if (strequal(info->datatype, "RAW"))
3118 info->attributes |= PRINTER_ATTRIBUTE_RAW_ONLY;
3120 DEBUG(10,("check_printer_ok: RAW check failed (%x).\n", (unsigned int)info->attributes ));
3125 if (!strequal(info->sharename, lp_servicename(snum))) {
3126 DEBUG(10,("check_printer_ok: NAME check failed (%s) (%s).\n", info->sharename, lp_servicename(snum)));
3133 /****************************************************************************
3134 ****************************************************************************/
3135 static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
3137 pid_t local_pid = sys_getpid();
3138 char *cmd = lp_addprinter_cmd();
3143 pstring driverlocation;
3147 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
3148 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
3152 /* build driver path... only 9X architecture is needed for legacy reasons */
3153 slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
3155 /* change \ to \\ for the shell */
3156 all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
3158 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
3159 slprintf(command, sizeof(command), "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
3160 cmd, printer->info_2->printername, printer->info_2->sharename,
3161 printer->info_2->portname, printer->info_2->drivername,
3162 printer->info_2->location, driverlocation);
3165 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
3166 ret = smbrun(command, tmp_file, False);
3167 DEBUGADD(10,("returned [%d]\n", ret));
3175 qlines = file_lines_load(tmp_file, &numlines);
3176 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
3177 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
3181 // Set the portname to what the script says the portname should be
3182 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
3183 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
3185 // Send SIGHUP to process group... is there a better way?
3190 file_lines_free(qlines);
3194 /********************************************************************
3195 * called by spoolss_api_setprinter
3196 * when updating a printer description
3197 ********************************************************************/
3199 static uint32 update_printer(POLICY_HND *handle, uint32 level,
3200 const SPOOL_PRINTER_INFO_LEVEL *info,
3201 DEVICEMODE *devmode)
3204 NT_PRINTER_INFO_LEVEL *printer = NULL;
3205 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3208 DEBUG(8,("update_printer\n"));
3210 result = NT_STATUS_NO_PROBLEMO;
3212 /* Check calling user has permission to update printer description */
3215 DEBUG(0,("Send a mail to samba@samba.org\n"));
3216 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3217 result = ERROR_INVALID_LEVEL;
3221 if (!OPEN_HANDLE(Printer)) {
3222 result = ERROR_INVALID_HANDLE;
3226 if (!get_printer_snum(handle, &snum)) {
3227 result = ERROR_INVALID_HANDLE;
3231 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
3232 DEBUG(3, ("printer property change denied by security "
3234 result = ERROR_ACCESS_DENIED;
3238 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3239 result = ERROR_INVALID_HANDLE;
3243 DEBUGADD(8,("Converting info_2 struct\n"));
3246 * convert_printer_info converts the incoming
3247 * info from the client and overwrites the info
3248 * just read from the tdb in the pointer 'printer'.
3251 convert_printer_info(info, printer, level);
3253 if (info->info_2->devmode_ptr != 0) {
3254 /* we have a valid devmode
3255 convert it and link it*/
3258 * Ensure printer->info_2->devmode is a valid pointer
3259 * as we will be overwriting it in convert_devicemode().
3262 if (printer->info_2->devmode == NULL)
3263 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3265 DEBUGADD(8,("Converting the devicemode struct\n"));
3266 convert_devicemode(devmode, printer->info_2->devmode);
3269 if (printer->info_2->devmode != NULL)
3270 free_nt_devicemode(&printer->info_2->devmode);
3271 printer->info_2->devmode=NULL;
3275 * Do sanity check on the requested changes for Samba.
3278 if (!check_printer_ok(printer->info_2, snum)) {
3279 result = ERROR_INVALID_PARAMETER;
3283 if (*lp_addprinter_cmd() )
3284 if ( !add_printer_hook(printer) ) {
3285 result = ERROR_ACCESS_DENIED;
3289 if (add_a_printer(*printer, 2)!=0) {
3290 /* I don't really know what to return here !!! */
3291 result = ERROR_ACCESS_DENIED;
3296 free_a_printer(&printer, 2);
3301 /****************************************************************************
3302 ****************************************************************************/
3303 uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
3304 const SPOOL_PRINTER_INFO_LEVEL *info,
3305 DEVMODE_CTR devmode_ctr,
3306 SEC_DESC_BUF *secdesc_ctr,
3307 uint32 command, pipes_struct *p)
3309 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3311 if (!OPEN_HANDLE(Printer)) {
3312 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3313 return ERROR_INVALID_HANDLE;
3316 /* check the level */
3319 return control_printer(handle, command, p);
3322 return update_printer(handle, level, info, devmode_ctr.devmode);
3325 return update_printer_sec(handle, level, info, p,
3329 return ERROR_INVALID_LEVEL;
3334 /****************************************************************************
3335 ****************************************************************************/
3336 uint32 _spoolss_fcpn(POLICY_HND *handle)
3338 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3340 if (!OPEN_HANDLE(Printer)) {
3341 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3342 return ERROR_INVALID_HANDLE;
3345 Printer->notify.flags=0;
3346 Printer->notify.options=0;
3347 Printer->notify.localmachine[0]='\0';
3348 Printer->notify.printerlocal=0;
3349 if (Printer->notify.option)
3350 safe_free(Printer->notify.option->ctr.type);
3351 safe_free(Printer->notify.option);
3352 Printer->notify.option=NULL;
3354 return NT_STATUS_NO_PROBLEMO;
3357 /****************************************************************************
3358 ****************************************************************************/
3359 uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
3360 NEW_BUFFER *buffer, uint32 offered,
3364 return ERROR_INVALID_PARAMETER; /* this is what a NT server
3365 returns for AddJob. AddJob
3366 must fail on non-local
3370 /****************************************************************************
3371 ****************************************************************************/
3372 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3373 int position, int snum)
3378 time_t unixdate = time(NULL);
3380 t=gmtime(&unixdate);
3381 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3383 job_info->jobid=queue->job;
3384 init_unistr(&job_info->printername, lp_servicename(snum));
3385 init_unistr(&job_info->machinename, temp_name);
3386 init_unistr(&job_info->username, queue->user);
3387 init_unistr(&job_info->document, queue->file);
3388 init_unistr(&job_info->datatype, "RAW");
3389 init_unistr(&job_info->text_status, "");
3390 job_info->status=nt_printj_status(queue->status);
3391 job_info->priority=queue->priority;
3392 job_info->position=position;
3393 job_info->totalpages=0;
3394 job_info->pagesprinted=0;
3396 make_systemtime(&job_info->submitted, t);
3399 /****************************************************************************
3400 ****************************************************************************/
3401 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3402 int position, int snum)
3405 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3409 time_t unixdate = time(NULL);
3411 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3414 t=gmtime(&unixdate);
3415 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3417 job_info->jobid=queue->job;
3419 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3421 init_unistr(&job_info->printername, chaine);
3423 init_unistr(&job_info->machinename, temp_name);
3424 init_unistr(&job_info->username, queue->user);
3425 init_unistr(&job_info->document, queue->file);
3426 init_unistr(&job_info->notifyname, queue->user);
3427 init_unistr(&job_info->datatype, "RAW");
3428 init_unistr(&job_info->printprocessor, "winprint");
3429 init_unistr(&job_info->parameters, "");
3430 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
3431 init_unistr(&job_info->text_status, "");
3433 /* and here the security descriptor */
3435 job_info->status=nt_printj_status(queue->status);
3436 job_info->priority=queue->priority;
3437 job_info->position=position;
3438 job_info->starttime=0;
3439 job_info->untiltime=0;
3440 job_info->totalpages=0;
3441 job_info->size=queue->size;
3442 make_systemtime(&(job_info->submitted), t);
3443 job_info->timeelapsed=0;
3444 job_info->pagesprinted=0;
3446 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3447 free_a_printer(&ntprinter, 2);
3451 free_a_printer(&ntprinter, 2);
3455 /****************************************************************************
3456 Enumjobs at level 1.
3457 ****************************************************************************/
3458 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3459 NEW_BUFFER *buffer, uint32 offered,
3460 uint32 *needed, uint32 *returned)
3465 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3469 return ERROR_NOT_ENOUGH_MEMORY;
3472 for (i=0; i<*returned; i++)
3473 fill_job_info_1(&info[i], &queue[i], i, snum);
3477 /* check the required size. */
3478 for (i=0; i<*returned; i++)
3479 (*needed) += spoolss_size_job_info_1(&info[i]);
3481 if (!alloc_buffer_size(buffer, *needed)) {
3483 return ERROR_INSUFFICIENT_BUFFER;
3486 /* fill the buffer with the structures */
3487 for (i=0; i<*returned; i++)
3488 new_smb_io_job_info_1("", buffer, &info[i], 0);
3493 if (*needed > offered) {
3495 return ERROR_INSUFFICIENT_BUFFER;
3498 return NT_STATUS_NO_PROBLEMO;
3501 /****************************************************************************
3502 Enumjobs at level 2.
3503 ****************************************************************************/
3504 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3505 NEW_BUFFER *buffer, uint32 offered,
3506 uint32 *needed, uint32 *returned)
3511 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3515 return ERROR_NOT_ENOUGH_MEMORY;
3518 for (i=0; i<*returned; i++)
3519 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3523 /* check the required size. */
3524 for (i=0; i<*returned; i++)
3525 (*needed) += spoolss_size_job_info_2(&info[i]);
3527 if (!alloc_buffer_size(buffer, *needed)) {
3529 return ERROR_INSUFFICIENT_BUFFER;
3532 /* fill the buffer with the structures */
3533 for (i=0; i<*returned; i++)
3534 new_smb_io_job_info_2("", buffer, &info[i], 0);
3539 if (*needed > offered) {
3541 return ERROR_INSUFFICIENT_BUFFER;
3544 return NT_STATUS_NO_PROBLEMO;
3547 /****************************************************************************
3549 ****************************************************************************/
3550 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3551 NEW_BUFFER *buffer, uint32 offered,
3552 uint32 *needed, uint32 *returned)
3555 print_queue_struct *queue=NULL;
3556 print_status_struct prt_status;
3558 DEBUG(4,("_spoolss_enumjobs\n"));
3560 ZERO_STRUCT(prt_status);
3565 if (!get_printer_snum(handle, &snum))
3566 return ERROR_INVALID_HANDLE;
3568 *returned = print_queue_status(snum, &queue, &prt_status);
3569 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3571 if (*returned == 0) {
3573 return NT_STATUS_NO_PROBLEMO;
3578 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3581 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3586 return ERROR_INVALID_LEVEL;
3592 /****************************************************************************
3593 ****************************************************************************/
3594 uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid)
3599 /****************************************************************************
3600 ****************************************************************************/
3601 uint32 _spoolss_setjob( POLICY_HND *handle,
3609 struct current_user user;
3611 print_status_struct prt_status;
3613 memset(&prt_status, 0, sizeof(prt_status));
3615 if (!get_printer_snum(handle, &snum)) {
3616 return ERROR_INVALID_HANDLE;
3619 if (!print_job_exists(jobid)) {
3620 return ERROR_INVALID_PRINTER_NAME;
3623 if (p->ntlmssp_auth_validated) {
3624 memcpy(&user, &p->pipe_user, sizeof(user));
3626 extern struct current_user current_user;
3627 memcpy(&user, ¤t_user, sizeof(user));
3631 case JOB_CONTROL_CANCEL:
3632 case JOB_CONTROL_DELETE:
3633 if (print_job_delete(&user, jobid)) return 0x0;
3635 case JOB_CONTROL_PAUSE:
3636 if (print_job_pause(&user, jobid)) return 0x0;
3638 case JOB_CONTROL_RESUME:
3639 if (print_job_resume(&user, jobid)) return 0x0;
3642 return ERROR_INVALID_LEVEL;
3645 return ERROR_INVALID_HANDLE;
3648 /****************************************************************************
3649 Enumerates all printer drivers at level 1.
3650 ****************************************************************************/
3651 static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3656 fstring *list = NULL;
3658 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3659 DRIVER_INFO_1 *driver_info_1=NULL;
3663 #define MAX_VERSION 4
3665 for (version=0; version<MAX_VERSION; version++) {
3667 ndrivers=get_ntdrivers(&list, architecture, version);
3668 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3671 return ERROR_NOT_ENOUGH_MEMORY;
3674 if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
3676 return ERROR_NOT_ENOUGH_MEMORY;
3680 for (i=0; i<ndrivers; i++) {
3681 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3682 ZERO_STRUCT(driver);
3683 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3684 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
3685 free_a_printer_driver(driver, 3);
3688 *returned+=ndrivers;
3692 /* check the required size. */
3693 for (i=0; i<*returned; i++) {
3694 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3695 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
3698 if (!alloc_buffer_size(buffer, *needed)) {
3699 safe_free(driver_info_1);
3700 return ERROR_INSUFFICIENT_BUFFER;
3703 /* fill the buffer with the form structures */
3704 for (i=0; i<*returned; i++) {
3705 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3706 new_smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
3709 safe_free(driver_info_1);
3711 if (*needed > offered) {
3713 return ERROR_INSUFFICIENT_BUFFER;
3716 return NT_STATUS_NO_PROBLEMO;
3719 /****************************************************************************
3720 Enumerates all printer drivers at level 2.
3721 ****************************************************************************/
3722 static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3727 fstring *list = NULL;
3729 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3730 DRIVER_INFO_2 *driver_info_2=NULL;
3734 #define MAX_VERSION 4
3736 for (version=0; version<MAX_VERSION; version++) {
3738 ndrivers=get_ntdrivers(&list, architecture, version);
3739 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3742 return ERROR_NOT_ENOUGH_MEMORY;
3745 if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
3747 return ERROR_NOT_ENOUGH_MEMORY;
3751 for (i=0; i<ndrivers; i++) {
3752 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3753 ZERO_STRUCT(driver);
3754 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3755 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
3756 free_a_printer_driver(driver, 3);
3759 *returned+=ndrivers;
3763 /* check the required size. */
3764 for (i=0; i<*returned; i++) {
3765 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3766 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3769 if (!alloc_buffer_size(buffer, *needed)) {
3770 safe_free(driver_info_2);
3771 return ERROR_INSUFFICIENT_BUFFER;
3774 /* fill the buffer with the form structures */
3775 for (i=0; i<*returned; i++) {
3776 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3777 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3780 safe_free(driver_info_2);
3782 if (*needed > offered) {
3784 return ERROR_INSUFFICIENT_BUFFER;
3787 return NT_STATUS_NO_PROBLEMO;
3790 /****************************************************************************
3791 Enumerates all printer drivers at level 3.
3792 ****************************************************************************/
3793 static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3798 fstring *list = NULL;
3800 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3801 DRIVER_INFO_3 *driver_info_3=NULL;
3805 #define MAX_VERSION 4
3807 for (version=0; version<MAX_VERSION; version++) {
3809 ndrivers=get_ntdrivers(&list, architecture, version);
3810 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3813 return ERROR_NOT_ENOUGH_MEMORY;
3816 if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
3818 return ERROR_NOT_ENOUGH_MEMORY;
3822 for (i=0; i<ndrivers; i++) {
3823 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3824 ZERO_STRUCT(driver);
3825 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3826 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
3827 free_a_printer_driver(driver, 3);
3830 *returned+=ndrivers;
3834 /* check the required size. */
3835 for (i=0; i<*returned; i++) {
3836 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3837 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3840 if (!alloc_buffer_size(buffer, *needed)) {
3841 safe_free(driver_info_3);
3842 return ERROR_INSUFFICIENT_BUFFER;
3845 /* fill the buffer with the driver structures */
3846 for (i=0; i<*returned; i++) {
3847 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3848 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
3851 for (i=0; i<*returned; i++)
3852 safe_free(driver_info_3[i].dependentfiles);
3854 safe_free(driver_info_3);
3856 if (*needed > offered) {
3858 return ERROR_INSUFFICIENT_BUFFER;
3861 return NT_STATUS_NO_PROBLEMO;
3864 /****************************************************************************
3865 Enumerates all printer drivers.
3866 ****************************************************************************/
3867 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
3868 NEW_BUFFER *buffer, uint32 offered,
3869 uint32 *needed, uint32 *returned)
3871 fstring *list = NULL;
3873 fstring architecture;
3875 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
3876 fstrcpy(servername, global_myname);
3880 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
3884 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
3887 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
3890 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
3895 return ERROR_INVALID_LEVEL;
3900 /****************************************************************************
3901 ****************************************************************************/
3902 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
3904 form->flag=list->flag;
3905 init_unistr(&form->name, list->name);
3906 form->width=list->width;
3907 form->length=list->length;
3908 form->left=list->left;
3909 form->top=list->top;
3910 form->right=list->right;
3911 form->bottom=list->bottom;
3914 /****************************************************************************
3915 ****************************************************************************/
3916 uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
3917 NEW_BUFFER *buffer, uint32 offered,
3918 uint32 *needed, uint32 *numofforms)
3920 nt_forms_struct *list=NULL;
3925 DEBUG(4,("_new_spoolss_enumforms\n"));
3926 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3927 DEBUGADD(5,("Info level [%d]\n", level));
3929 *numofforms = get_ntforms(&list);
3930 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
3932 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
3936 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
3938 return ERROR_NOT_ENOUGH_MEMORY;
3941 /* construct the list of form structures */
3942 for (i=0; i<*numofforms; i++) {
3943 DEBUGADD(6,("Filling form number [%d]\n",i));
3944 fill_form_1(&forms_1[i], &list[i]);
3949 /* check the required size. */
3950 for (i=0; i<*numofforms; i++) {
3951 DEBUGADD(6,("adding form [%d]'s size\n",i));
3952 buffer_size += spoolss_size_form_1(&forms_1[i]);
3955 *needed=buffer_size;
3957 if (!alloc_buffer_size(buffer, buffer_size)){
3959 return ERROR_INSUFFICIENT_BUFFER;
3962 /* fill the buffer with the form structures */
3963 for (i=0; i<*numofforms; i++) {
3964 DEBUGADD(6,("adding form [%d] to buffer\n",i));
3965 new_smb_io_form_1("", buffer, &forms_1[i], 0);
3970 if (*needed > offered) {
3972 return ERROR_INSUFFICIENT_BUFFER;
3975 return NT_STATUS_NO_PROBLEMO;
3979 return ERROR_INVALID_LEVEL;
3984 /****************************************************************************
3985 ****************************************************************************/
3986 uint32 _spoolss_getform( POLICY_HND *handle, uint32 level, UNISTR2 *uni_formname, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3988 nt_forms_struct *list=NULL;
3994 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
3996 DEBUG(4,("_spoolss_getform\n"));
3997 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3998 DEBUGADD(5,("Info level [%d]\n", level));
4000 numofforms = get_ntforms(&list);
4001 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
4003 if (numofforms == 0)
4004 return ERROR_NO_MORE_ITEMS;
4009 /* Check if the requested name is in the list of form structures */
4010 for (i=0; i<numofforms; i++) {
4012 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
4014 if (strequal(form_name, list[i].name)) {
4015 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
4016 fill_form_1(&form_1, &list[i]);
4023 /* check the required size. */
4025 *needed=spoolss_size_form_1(&form_1);
4027 if (!alloc_buffer_size(buffer, buffer_size)){
4028 return ERROR_INSUFFICIENT_BUFFER;
4031 if (*needed > offered) {
4032 return ERROR_INSUFFICIENT_BUFFER;
4035 /* fill the buffer with the form structures */
4036 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
4037 new_smb_io_form_1("", buffer, &form_1, 0);
4039 return NT_STATUS_NO_PROBLEMO;
4043 return ERROR_INVALID_LEVEL;
4047 /****************************************************************************
4048 ****************************************************************************/
4049 static void fill_port_1(PORT_INFO_1 *port, char *name)
4051 init_unistr(&port->port_name, name);
4054 /****************************************************************************
4055 ****************************************************************************/
4056 static void fill_port_2(PORT_INFO_2 *port, char *name)
4058 init_unistr(&port->port_name, name);
4059 init_unistr(&port->monitor_name, "Local Monitor");
4060 init_unistr(&port->description, "Local Port");
4061 #define PORT_TYPE_WRITE 1
4062 port->port_type=PORT_TYPE_WRITE;
4066 /****************************************************************************
4068 ****************************************************************************/
4069 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4071 PORT_INFO_1 *ports=NULL;
4074 if (*lp_enumports_cmd()) {
4075 pid_t local_pid = sys_getpid();
4076 char *cmd = lp_enumports_cmd();
4084 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4085 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4089 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4090 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 1);
4093 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4094 ret = smbrun(command, tmp_file, False);
4095 DEBUG(10,("Returned [%d]\n", ret));
4098 // Is this the best error to return here?
4099 return ERROR_ACCESS_DENIED;
4103 qlines = file_lines_load(tmp_file, &numlines);
4104 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4105 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4109 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
4110 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4111 file_lines_free(qlines);
4112 return ERROR_NOT_ENOUGH_MEMORY;
4115 for (i=0; i<numlines; i++) {
4116 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4117 fill_port_1(&ports[i], qlines[i]);
4120 file_lines_free(qlines);
4123 *returned = numlines;
4126 *returned = 1; /* Sole Samba port returned. */
4128 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
4129 return ERROR_NOT_ENOUGH_MEMORY;
4131 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4133 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
4136 /* check the required size. */
4137 for (i=0; i<*returned; i++) {
4138 DEBUGADD(6,("adding port [%d]'s size\n", i));
4139 *needed += spoolss_size_port_info_1(&ports[i]);
4142 if (!alloc_buffer_size(buffer, *needed)) {
4144 return ERROR_INSUFFICIENT_BUFFER;
4147 /* fill the buffer with the ports structures */
4148 for (i=0; i<*returned; i++) {
4149 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4150 new_smb_io_port_1("", buffer, &ports[i], 0);
4155 if (*needed > offered) {
4157 return ERROR_INSUFFICIENT_BUFFER;
4160 return NT_STATUS_NO_PROBLEMO;
4163 /****************************************************************************
4165 ****************************************************************************/
4167 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4169 PORT_INFO_2 *ports=NULL;
4172 if (*lp_enumports_cmd()) {
4173 pid_t local_pid = sys_getpid();
4174 char *cmd = lp_enumports_cmd();
4182 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4183 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4187 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4188 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 2);
4191 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4192 ret = smbrun(command, tmp_file, False);
4193 DEBUGADD(10,("returned [%d]\n", ret));
4196 // Is this the best error to return here?
4197 return ERROR_ACCESS_DENIED;
4201 qlines = file_lines_load(tmp_file, &numlines);
4202 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4203 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4207 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
4208 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4209 file_lines_free(qlines);
4210 return ERROR_NOT_ENOUGH_MEMORY;
4213 for (i=0; i<numlines; i++) {
4214 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4215 fill_port_2(&(ports[i]), qlines[i]);
4218 file_lines_free(qlines);
4221 *returned = numlines;
4227 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
4228 return ERROR_NOT_ENOUGH_MEMORY;
4230 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4232 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
4235 /* check the required size. */
4236 for (i=0; i<*returned; i++) {
4237 DEBUGADD(6,("adding port [%d]'s size\n", i));
4238 *needed += spoolss_size_port_info_2(&ports[i]);
4241 if (!alloc_buffer_size(buffer, *needed)) {
4243 return ERROR_INSUFFICIENT_BUFFER;
4246 /* fill the buffer with the ports structures */
4247 for (i=0; i<*returned; i++) {
4248 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4249 new_smb_io_port_2("", buffer, &ports[i], 0);
4254 if (*needed > offered) {
4256 return ERROR_INSUFFICIENT_BUFFER;
4259 return NT_STATUS_NO_PROBLEMO;
4262 /****************************************************************************
4264 ****************************************************************************/
4265 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
4266 NEW_BUFFER *buffer, uint32 offered,
4267 uint32 *needed, uint32 *returned)
4269 DEBUG(4,("_spoolss_enumports\n"));
4276 return enumports_level_1(buffer, offered, needed, returned);
4279 return enumports_level_2(buffer, offered, needed, returned);
4282 return ERROR_INVALID_LEVEL;
4287 /****************************************************************************
4288 ****************************************************************************/
4289 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
4290 const SPOOL_PRINTER_INFO_LEVEL *info,
4291 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4292 uint32 user_switch, const SPOOL_USER_CTR *user,
4295 NT_PRINTER_INFO_LEVEL *printer = NULL;
4299 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
4300 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
4301 return ERROR_NOT_ENOUGH_MEMORY;
4304 ZERO_STRUCTP(printer);
4306 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
4307 convert_printer_info(info, printer, 2);
4309 if (*lp_addprinter_cmd() )
4310 if ( !add_printer_hook(printer) ) {
4311 free_a_printer(&printer,2);
4312 return ERROR_ACCESS_DENIED;
4315 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
4316 printer->info_2->sharename);
4318 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
4319 free_a_printer(&printer,2);
4320 return ERROR_ACCESS_DENIED;
4323 /* you must be a printer admin to add a new printer */
4324 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4325 free_a_printer(&printer,2);
4326 return ERROR_ACCESS_DENIED;
4330 * Do sanity check on the requested changes for Samba.
4333 if (!check_printer_ok(printer->info_2, snum)) {
4334 free_a_printer(&printer,2);
4335 return ERROR_INVALID_PARAMETER;
4338 /* write the ASCII on disk */
4339 if (add_a_printer(*printer, 2) != 0) {
4340 free_a_printer(&printer,2);
4341 return ERROR_ACCESS_DENIED;
4344 if (!open_printer_hnd(handle, name)) {
4345 /* Handle open failed - remove addition. */
4346 del_a_printer(printer->info_2->sharename);
4347 free_a_printer(&printer,2);
4348 return ERROR_ACCESS_DENIED;
4351 free_a_printer(&printer,2);
4352 return NT_STATUS_NO_PROBLEMO;
4355 /****************************************************************************
4356 ****************************************************************************/
4357 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4358 const SPOOL_PRINTER_INFO_LEVEL *info,
4359 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4360 uint32 user_switch, const SPOOL_USER_CTR *user,
4365 /* we don't handle yet */
4366 /* but I know what to do ... */
4367 return ERROR_INVALID_LEVEL;
4370 return spoolss_addprinterex_level_2(uni_srv_name, info,
4371 unk0, unk1, unk2, unk3,
4372 user_switch, user, handle);
4375 return ERROR_INVALID_LEVEL;
4380 /****************************************************************************
4381 ****************************************************************************/
4382 uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
4383 uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4385 uint32 err = NT_STATUS_NO_PROBLEMO;
4386 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4387 struct current_user user;
4389 ZERO_STRUCT(driver);
4391 if (p->ntlmssp_auth_validated) {
4392 memcpy(&user, &p->pipe_user, sizeof(user));
4394 extern struct current_user current_user;
4395 memcpy(&user, ¤t_user, sizeof(user));
4398 convert_printer_driver_info(info, &driver, level);
4400 DEBUG(5,("Cleaning driver's information\n"));
4401 clean_up_driver_struct(driver, level);
4403 DEBUG(5,("Moving driver to final destination\n"));
4404 if(!move_driver_to_download_area(driver, level, &user, &err)) {
4406 err = ERROR_ACCESS_DENIED;
4410 if (add_a_printer_driver(driver, level)!=0) {
4411 err = ERROR_ACCESS_DENIED;
4416 free_a_printer_driver(driver, level);
4420 /****************************************************************************
4421 ****************************************************************************/
4422 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4424 init_unistr(&info->name, name);
4427 /****************************************************************************
4428 ****************************************************************************/
4429 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4433 pstring short_archi;
4434 DRIVER_DIRECTORY_1 *info=NULL;
4436 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4438 if (get_short_archi(short_archi, long_archi)==FALSE)
4439 return ERROR_INVALID_ENVIRONMENT;
4441 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4442 return ERROR_NOT_ENOUGH_MEMORY;
4444 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
4446 DEBUG(4,("printer driver directory: [%s]\n", path));
4448 fill_driverdir_1(info, path);
4450 *needed += spoolss_size_driverdir_info_1(info);
4452 if (!alloc_buffer_size(buffer, *needed)) {
4454 return ERROR_INSUFFICIENT_BUFFER;
4457 new_smb_io_driverdir_1("", buffer, info, 0);
4461 if (*needed > offered)
4462 return ERROR_INSUFFICIENT_BUFFER;
4464 return NT_STATUS_NO_PROBLEMO;
4467 /****************************************************************************
4468 ****************************************************************************/
4469 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4470 NEW_BUFFER *buffer, uint32 offered,
4473 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4479 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4482 return ERROR_INVALID_LEVEL;
4487 /****************************************************************************
4488 ****************************************************************************/
4489 uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
4490 uint32 in_value_len, uint32 in_data_len,
4491 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4493 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4495 NT_PRINTER_INFO_LEVEL *printer = NULL;
4500 uint32 biggest_valuesize;
4501 uint32 biggest_datasize;
4503 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4508 ZERO_STRUCT(printer);
4510 *out_max_value_len=0;
4516 *out_max_data_len=0;
4520 DEBUG(5,("spoolss_enumprinterdata\n"));
4522 if (!OPEN_HANDLE(Printer)) {
4523 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4524 return ERROR_INVALID_HANDLE;
4527 if (!get_printer_snum(handle, &snum))
4528 return ERROR_INVALID_HANDLE;
4530 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4531 return ERROR_INVALID_HANDLE;
4534 * The NT machine wants to know the biggest size of value and data
4536 * cf: MSDN EnumPrinterData remark section
4538 if ( (in_value_len==0) && (in_data_len==0) ) {
4539 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4542 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
4543 * if this parameter size doesn't exist.
4544 * Ok - my opinion here is that the client is not asking for the greatest
4545 * possible size of all the parameters, but is asking specifically for the size needed
4546 * for this specific parameter. In that case we can remove the loop below and
4547 * simplify this lookup code considerably. JF - comments welcome. JRA.
4550 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4552 free_a_printer(&printer, 2);
4553 return ERROR_NO_MORE_ITEMS;
4560 biggest_valuesize=0;
4563 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4564 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4565 if (data_len > biggest_datasize) biggest_datasize=data_len;
4567 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4575 * I think this is correct, it doesn't break APW and
4576 * allows Gerald's Win32 test programs to work correctly,
4577 * but may need altering.... JRA.
4580 if (param_index == 0) {
4581 /* No parameters found. */
4582 free_a_printer(&printer, 2);
4583 return ERROR_NO_MORE_ITEMS;
4586 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4587 *out_value_len=2*(1+biggest_valuesize);
4588 *out_data_len=biggest_datasize;
4590 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4592 free_a_printer(&printer, 2);
4593 return NT_STATUS_NO_PROBLEMO;
4597 * the value len is wrong in NT sp3
4598 * that's the number of bytes not the number of unicode chars
4601 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4603 free_a_printer(&printer, 2);
4604 return ERROR_NO_MORE_ITEMS;
4607 free_a_printer(&printer, 2);
4611 * - counted in bytes in the request
4612 * - counted in UNICODE chars in the max reply
4613 * - counted in bytes in the real size
4615 * take a pause *before* coding not *during* coding
4618 *out_max_value_len=(in_value_len/sizeof(uint16));
4619 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4621 return ERROR_NOT_ENOUGH_MEMORY;
4624 ZERO_STRUCTP(*out_value);
4625 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4629 /* the data is counted in bytes */
4630 *out_max_data_len=in_data_len;
4631 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4633 return ERROR_NOT_ENOUGH_MEMORY;
4636 ZERO_STRUCTP(*data_out);
4637 memcpy(*data_out, data, (size_t)data_len);
4638 *out_data_len=data_len;
4642 return NT_STATUS_NO_PROBLEMO;
4645 /****************************************************************************
4646 ****************************************************************************/
4647 uint32 _spoolss_setprinterdata( POLICY_HND *handle,
4648 const UNISTR2 *value,
4653 uint32 numeric_data)
4655 NT_PRINTER_INFO_LEVEL *printer = NULL;
4656 NT_PRINTER_PARAM *param = NULL;
4658 uint32 status = 0x0;
4659 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4661 DEBUG(5,("spoolss_setprinterdata\n"));
4664 if (!OPEN_HANDLE(Printer)) {
4665 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4666 return ERROR_INVALID_HANDLE;
4669 if (!get_printer_snum(handle, &snum))
4670 return ERROR_INVALID_HANDLE;
4672 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4673 DEBUG(3, ("security descriptor change denied by existing "
4674 "security descriptor\n"));
4675 return ERROR_ACCESS_DENIED;
4678 status = get_a_printer(&printer, 2, lp_servicename(snum));
4680 return ERROR_INVALID_NAME;
4682 convert_specific_param(¶m, value , type, data, real_len);
4683 unlink_specific_param_if_exist(printer->info_2, param);
4685 if (!add_a_specific_param(printer->info_2, param))
4686 status = ERROR_INVALID_PARAMETER;
4688 status = add_a_printer(*printer, 2);
4690 free_a_printer(&printer, 2);
4694 /****************************************************************************
4695 ****************************************************************************/
4696 uint32 _spoolss_deleteprinterdata( POLICY_HND *handle, const UNISTR2 *value)
4698 NT_PRINTER_INFO_LEVEL *printer = NULL;
4699 NT_PRINTER_PARAM param;
4701 uint32 status = 0x0;
4702 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4704 DEBUG(5,("spoolss_deleteprinterdata\n"));
4706 if (!OPEN_HANDLE(Printer)) {
4707 DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4708 return ERROR_INVALID_HANDLE;
4711 if (!get_printer_snum(handle, &snum))
4712 return ERROR_INVALID_HANDLE;
4714 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4715 DEBUG(3, ("_spoolss_deleteprinterdata: security descriptor change denied by existing "
4716 "security descriptor\n"));
4717 return ERROR_ACCESS_DENIED;
4720 status = get_a_printer(&printer, 2, lp_servicename(snum));
4722 return ERROR_INVALID_NAME;
4724 ZERO_STRUCTP(¶m);
4725 unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
4727 if(!unlink_specific_param_if_exist(printer->info_2, ¶m))
4728 status = ERROR_INVALID_PARAMETER;
4730 status = add_a_printer(*printer, 2);
4732 free_a_printer(&printer, 2);
4736 /****************************************************************************
4737 ****************************************************************************/
4738 uint32 _spoolss_addform( POLICY_HND *handle,
4743 nt_forms_struct *list=NULL;
4744 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4746 DEBUG(5,("spoolss_addform\n"));
4748 if (!OPEN_HANDLE(Printer)) {
4749 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4750 return ERROR_INVALID_HANDLE;
4753 count=get_ntforms(&list);
4754 if(!add_a_form(&list, form, &count))
4755 return ERROR_NOT_ENOUGH_MEMORY;
4756 write_ntforms(&list, count);
4763 /****************************************************************************
4764 ****************************************************************************/
4765 uint32 _spoolss_deleteform( POLICY_HND *handle, UNISTR2 *form_name)
4769 nt_forms_struct *list=NULL;
4770 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4772 DEBUG(5,("spoolss_deleteform\n"));
4774 if (!OPEN_HANDLE(Printer)) {
4775 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4776 return ERROR_INVALID_HANDLE;
4779 count = get_ntforms(&list);
4780 if(!delete_a_form(&list, form_name, &count, &ret))
4781 return ERROR_INVALID_PARAMETER;
4788 /****************************************************************************
4789 ****************************************************************************/
4790 uint32 _spoolss_setform( POLICY_HND *handle,
4791 const UNISTR2 *uni_name,
4796 nt_forms_struct *list=NULL;
4797 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4799 DEBUG(5,("spoolss_setform\n"));
4801 if (!OPEN_HANDLE(Printer)) {
4802 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4803 return ERROR_INVALID_HANDLE;
4805 count=get_ntforms(&list);
4806 update_a_form(&list, form, count);
4807 write_ntforms(&list, count);
4814 /****************************************************************************
4815 enumprintprocessors level 1.
4816 ****************************************************************************/
4817 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4819 PRINTPROCESSOR_1 *info_1=NULL;
4821 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4822 return ERROR_NOT_ENOUGH_MEMORY;
4826 init_unistr(&info_1->name, "winprint");
4828 *needed += spoolss_size_printprocessor_info_1(info_1);
4830 if (!alloc_buffer_size(buffer, *needed))
4831 return ERROR_INSUFFICIENT_BUFFER;
4833 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4837 if (*needed > offered) {
4839 return ERROR_INSUFFICIENT_BUFFER;
4842 return NT_STATUS_NO_PROBLEMO;
4845 /****************************************************************************
4846 ****************************************************************************/
4847 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
4848 NEW_BUFFER *buffer, uint32 offered,
4849 uint32 *needed, uint32 *returned)
4851 DEBUG(5,("spoolss_enumprintprocessors\n"));
4854 * Enumerate the print processors ...
4856 * Just reply with "winprint", to keep NT happy
4857 * and I can use my nice printer checker.
4865 return enumprintprocessors_level_1(buffer, offered, needed, returned);
4868 return ERROR_INVALID_LEVEL;
4873 /****************************************************************************
4874 enumprintprocdatatypes level 1.
4875 ****************************************************************************/
4876 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4878 PRINTPROCDATATYPE_1 *info_1=NULL;
4880 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
4881 return ERROR_NOT_ENOUGH_MEMORY;
4885 init_unistr(&info_1->name, "RAW");
4887 *needed += spoolss_size_printprocdatatype_info_1(info_1);
4889 if (!alloc_buffer_size(buffer, *needed))
4890 return ERROR_INSUFFICIENT_BUFFER;
4892 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
4896 if (*needed > offered) {
4898 return ERROR_INSUFFICIENT_BUFFER;
4901 return NT_STATUS_NO_PROBLEMO;
4904 /****************************************************************************
4905 ****************************************************************************/
4906 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
4907 NEW_BUFFER *buffer, uint32 offered,
4908 uint32 *needed, uint32 *returned)
4910 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
4917 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
4920 return ERROR_INVALID_LEVEL;
4925 /****************************************************************************
4926 enumprintmonitors level 1.
4927 ****************************************************************************/
4928 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4930 PRINTMONITOR_1 *info_1=NULL;
4932 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
4933 return ERROR_NOT_ENOUGH_MEMORY;
4937 init_unistr(&info_1->name, "Local Port");
4939 *needed += spoolss_size_printmonitor_info_1(info_1);
4941 if (!alloc_buffer_size(buffer, *needed))
4942 return ERROR_INSUFFICIENT_BUFFER;
4944 smb_io_printmonitor_info_1("", buffer, info_1, 0);
4948 if (*needed > offered) {
4950 return ERROR_INSUFFICIENT_BUFFER;
4953 return NT_STATUS_NO_PROBLEMO;
4956 /****************************************************************************
4957 enumprintmonitors level 2.
4958 ****************************************************************************/
4959 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4961 PRINTMONITOR_2 *info_2=NULL;
4963 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
4964 return ERROR_NOT_ENOUGH_MEMORY;
4968 init_unistr(&info_2->name, "Local Port");
4969 init_unistr(&info_2->environment, "Windows NT X86");
4970 init_unistr(&info_2->dll_name, "localmon.dll");
4972 *needed += spoolss_size_printmonitor_info_2(info_2);
4974 if (!alloc_buffer_size(buffer, *needed))
4975 return ERROR_INSUFFICIENT_BUFFER;
4977 smb_io_printmonitor_info_2("", buffer, info_2, 0);
4981 if (*needed > offered) {
4983 return ERROR_INSUFFICIENT_BUFFER;
4986 return NT_STATUS_NO_PROBLEMO;
4989 /****************************************************************************
4990 ****************************************************************************/
4991 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
4992 NEW_BUFFER *buffer, uint32 offered,
4993 uint32 *needed, uint32 *returned)
4995 DEBUG(5,("spoolss_enumprintmonitors\n"));
4998 * Enumerate the print monitors ...
5000 * Just reply with "Local Port", to keep NT happy
5001 * and I can use my nice printer checker.
5009 return enumprintmonitors_level_1(buffer, offered, needed, returned);
5012 return enumprintmonitors_level_2(buffer, offered, needed, returned);
5015 return ERROR_INVALID_LEVEL;
5020 /****************************************************************************
5021 ****************************************************************************/
5022 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
5026 JOB_INFO_1 *info_1=NULL;
5028 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
5030 if (info_1 == NULL) {
5032 return ERROR_NOT_ENOUGH_MEMORY;
5035 for (i=0; i<count && found==False; i++) {
5036 if (queue[i].job==(int)jobid)
5043 /* I shoud reply something else ... I can't find the good one */
5044 return NT_STATUS_NO_PROBLEMO;
5047 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
5051 *needed += spoolss_size_job_info_1(info_1);
5053 if (!alloc_buffer_size(buffer, *needed)) {
5055 return ERROR_INSUFFICIENT_BUFFER;
5058 new_smb_io_job_info_1("", buffer, info_1, 0);
5062 if (*needed > offered)
5063 return ERROR_INSUFFICIENT_BUFFER;
5065 return NT_STATUS_NO_PROBLEMO;
5069 /****************************************************************************
5070 ****************************************************************************/
5071 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
5076 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
5078 ZERO_STRUCTP(info_2);
5080 if (info_2 == NULL) {
5082 return ERROR_NOT_ENOUGH_MEMORY;
5085 for (i=0; i<count && found==False; i++) {
5086 if (queue[i].job==(int)jobid)
5093 /* I shoud reply something else ... I can't find the good one */
5094 return NT_STATUS_NO_PROBLEMO;
5097 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
5101 *needed += spoolss_size_job_info_2(info_2);
5103 if (!alloc_buffer_size(buffer, *needed)) {
5105 return ERROR_INSUFFICIENT_BUFFER;
5108 new_smb_io_job_info_2("", buffer, info_2, 0);
5110 free_dev_mode(info_2->devmode);
5113 if (*needed > offered)
5114 return ERROR_INSUFFICIENT_BUFFER;
5116 return NT_STATUS_NO_PROBLEMO;
5119 /****************************************************************************
5120 ****************************************************************************/
5121 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
5122 NEW_BUFFER *buffer, uint32 offered,
5127 print_queue_struct *queue=NULL;
5128 print_status_struct prt_status;
5130 DEBUG(5,("spoolss_getjob\n"));
5132 memset(&prt_status, 0, sizeof(prt_status));
5136 if (!get_printer_snum(handle, &snum))
5137 return ERROR_INVALID_HANDLE;
5139 count = print_queue_status(snum, &queue, &prt_status);
5141 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
5142 count, prt_status.status, prt_status.message));
5146 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
5149 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
5153 return ERROR_INVALID_LEVEL;