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);
538 buffer->string_at_end=prs_data_size(ps);
543 /********************************************************************
544 * spoolss_open_printer
546 * called from the spoolss dispatcher
547 ********************************************************************/
548 uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
549 const PRINTER_DEFAULT *printer_default,
550 uint32 user_switch, SPOOL_USER_CTR user_ctr,
555 if (printername == NULL)
556 return ERROR_INVALID_PRINTER_NAME;
558 /* some sanity check because you can open a printer or a print server */
559 /* aka: \\server\printer or \\server */
560 unistr2_to_ascii(name, printername, sizeof(name)-1);
562 DEBUGADD(3,("checking name: %s\n",name));
564 if (!open_printer_hnd(handle, name))
565 return ERROR_INVALID_PRINTER_NAME;
568 if (printer_default->datatype_ptr != NULL)
570 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
571 set_printer_hnd_datatype(handle, datatype);
574 set_printer_hnd_datatype(handle, "");
577 if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
578 close_printer_handle(handle);
579 return ERROR_ACCESS_DENIED;
582 return NT_STATUS_NO_PROBLEMO;
585 /****************************************************************************
586 ****************************************************************************/
587 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
588 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
592 uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
601 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
602 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
606 printer->info_3=NULL;
607 uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3);
610 printer->info_6=NULL;
611 uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6);
620 static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devmode)
622 unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
623 unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
625 nt_devmode->specversion=devmode->specversion;
626 nt_devmode->driverversion=devmode->driverversion;
627 nt_devmode->size=devmode->size;
628 nt_devmode->driverextra=devmode->driverextra;
629 nt_devmode->fields=devmode->fields;
630 nt_devmode->orientation=devmode->orientation;
631 nt_devmode->papersize=devmode->papersize;
632 nt_devmode->paperlength=devmode->paperlength;
633 nt_devmode->paperwidth=devmode->paperwidth;
634 nt_devmode->scale=devmode->scale;
635 nt_devmode->copies=devmode->copies;
636 nt_devmode->defaultsource=devmode->defaultsource;
637 nt_devmode->printquality=devmode->printquality;
638 nt_devmode->color=devmode->color;
639 nt_devmode->duplex=devmode->duplex;
640 nt_devmode->yresolution=devmode->yresolution;
641 nt_devmode->ttoption=devmode->ttoption;
642 nt_devmode->collate=devmode->collate;
644 nt_devmode->logpixels=devmode->logpixels;
645 nt_devmode->bitsperpel=devmode->bitsperpel;
646 nt_devmode->pelswidth=devmode->pelswidth;
647 nt_devmode->pelsheight=devmode->pelsheight;
648 nt_devmode->displayflags=devmode->displayflags;
649 nt_devmode->displayfrequency=devmode->displayfrequency;
650 nt_devmode->icmmethod=devmode->icmmethod;
651 nt_devmode->icmintent=devmode->icmintent;
652 nt_devmode->mediatype=devmode->mediatype;
653 nt_devmode->dithertype=devmode->dithertype;
654 nt_devmode->reserved1=devmode->reserved1;
655 nt_devmode->reserved2=devmode->reserved2;
656 nt_devmode->panningwidth=devmode->panningwidth;
657 nt_devmode->panningheight=devmode->panningheight;
659 if (nt_devmode->driverextra != 0) {
660 /* if we had a previous private delete it and make a new one */
661 safe_free(nt_devmode->private);
662 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
664 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
670 /********************************************************************
671 * api_spoolss_closeprinter
672 ********************************************************************/
673 uint32 _spoolss_closeprinter(POLICY_HND *handle)
675 if (!close_printer_handle(handle))
676 return ERROR_INVALID_HANDLE;
678 return NT_STATUS_NO_PROBLEMO;
681 /********************************************************************
682 * api_spoolss_deleteprinter
683 ********************************************************************/
684 uint32 _spoolss_deleteprinter(POLICY_HND *handle)
686 if (!delete_printer_handle(handle))
687 return ERROR_INVALID_HANDLE;
689 return NT_STATUS_NO_PROBLEMO;
692 /********************************************************************
693 GetPrinterData on a printer server Handle.
694 ********************************************************************/
695 static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
699 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
701 if (!strcmp(value, "BeepEnabled")) {
703 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
705 SIVAL(*data, 0, 0x01);
710 if (!strcmp(value, "EventLog")) {
712 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
714 SIVAL(*data, 0, 0x1B);
719 if (!strcmp(value, "NetPopup")) {
721 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
723 SIVAL(*data, 0, 0x01);
728 if (!strcmp(value, "MajorVersion")) {
730 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
732 SIVAL(*data, 0, 0x02);
737 if (!strcmp(value, "DefaultSpoolDirectory")) {
738 pstring string="You are using a Samba server";
740 *needed = 2*(strlen(string)+1);
741 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
743 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
745 /* it's done by hand ready to go on the wire */
746 for (i=0; i<strlen(string); i++) {
747 (*data)[2*i]=string[i];
753 if (!strcmp(value, "Architecture")) {
754 pstring string="Windows NT x86";
756 *needed = 2*(strlen(string)+1);
757 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
759 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
760 for (i=0; i<strlen(string); i++) {
761 (*data)[2*i]=string[i];
770 /********************************************************************
771 GetPrinterData on a printer Handle.
772 ********************************************************************/
773 static BOOL getprinterdata_printer(POLICY_HND *handle,
774 fstring value, uint32 *type,
775 uint8 **data, uint32 *needed, uint32 in_size )
777 NT_PRINTER_INFO_LEVEL *printer = NULL;
781 Printer_entry *Printer = find_printer_index_by_hnd(handle);
783 DEBUG(5,("getprinterdata_printer\n"));
785 if (!OPEN_HANDLE(Printer)) {
786 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
790 if(!get_printer_snum(handle, &snum))
793 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
796 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
797 free_a_printer(&printer, 2);
801 free_a_printer(&printer, 2);
803 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
806 if((*data = (uint8 *)malloc( in_size *sizeof(uint8) )) == NULL) {
810 memset(*data, 0, in_size *sizeof(uint8));
811 /* copy the min(in_size, len) */
812 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
819 DEBUG(5,("getprinterdata_printer:copy done\n"));
826 /********************************************************************
827 * spoolss_getprinterdata
828 ********************************************************************/
829 uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
838 Printer_entry *Printer = find_printer_index_by_hnd(handle);
841 * Reminder: when it's a string, the length is in BYTES
842 * even if UNICODE is negociated.
849 /* in case of problem, return some default values */
853 DEBUG(4,("_spoolss_getprinterdata\n"));
855 if (!OPEN_HANDLE(Printer)) {
856 if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
857 return ERROR_NOT_ENOUGH_MEMORY;
858 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
859 return ERROR_INVALID_HANDLE;
862 unistr2_to_ascii(value, valuename, sizeof(value)-1);
864 if (handle_is_printserver(handle))
865 found=getprinterdata_printer_server(value, type, data, needed, *out_size);
867 found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
870 DEBUG(5, ("value not found, allocating %d\n", *out_size));
871 /* reply this param doesn't exist */
873 if((*data=(uint8 *)malloc(*out_size*sizeof(uint8))) == NULL)
874 return ERROR_NOT_ENOUGH_MEMORY;
875 memset(*data, '\0', *out_size*sizeof(uint8));
880 return ERROR_INVALID_PARAMETER;
883 if (*needed > *out_size)
884 return ERROR_MORE_DATA;
886 return NT_STATUS_NO_PROBLEMO;
889 /********************************************************************
891 * ReplyFindFirstPrinterChangeNotifyEx
893 * jfmxxxx: before replying OK: status=0
894 * should do a rpc call to the workstation asking ReplyOpenPrinter
895 * have to code it, later.
897 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
898 * called from api_spoolss_rffpcnex
899 ********************************************************************/
900 uint32 _spoolss_rffpcnex(POLICY_HND *handle, uint32 flags, uint32 options,
901 const UNISTR2 *localmachine, uint32 printerlocal,
902 SPOOL_NOTIFY_OPTION *option)
904 /* store the notify value in the printer struct */
906 Printer_entry *Printer=find_printer_index_by_hnd(handle);
908 if (!OPEN_HANDLE(Printer)) {
909 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
910 return ERROR_INVALID_HANDLE;
913 Printer->notify.flags=flags;
914 Printer->notify.options=options;
915 Printer->notify.printerlocal=printerlocal;
916 Printer->notify.option=option;
917 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
919 return NT_STATUS_NO_PROBLEMO;
922 /*******************************************************************
923 * fill a notify_info_data with the servername
924 ********************************************************************/
925 static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
926 NT_PRINTER_INFO_LEVEL *printer)
930 snprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
932 data->notify_data.data.length= (uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
933 temp_name, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
936 /*******************************************************************
937 * fill a notify_info_data with the servicename
938 * jfmxxxx: it's incorrect should be long_printername
939 ********************************************************************/
940 static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
941 NT_PRINTER_INFO_LEVEL *printer)
944 data->notify_data.data.length=strlen(lp_servicename(snum));
945 dos_PutUniCode(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string), True);
947 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
948 printer->info_2->printername, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
951 /*******************************************************************
952 * fill a notify_info_data with the servicename
953 ********************************************************************/
954 static void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
956 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
957 lp_servicename(snum), sizeof(data->notify_data.data.string),True) - sizeof(uint16))/sizeof(uint16));
960 /*******************************************************************
961 * fill a notify_info_data with the port name
962 ********************************************************************/
963 static void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
965 /* even if it's strange, that's consistant in all the code */
967 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
968 lp_servicename(snum), sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
971 /*******************************************************************
972 * fill a notify_info_data with the printername
973 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
974 * but it doesn't exist, have to see what to do
975 ********************************************************************/
976 static void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
978 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
979 printer->info_2->drivername, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
982 /*******************************************************************
983 * fill a notify_info_data with the comment
984 ********************************************************************/
985 static void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
987 if (*printer->info_2->comment == '\0')
988 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
989 lp_comment(snum), sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
991 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
992 printer->info_2->comment, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
995 /*******************************************************************
996 * fill a notify_info_data with the comment
997 * jfm:xxxx incorrect, have to create a new smb.conf option
998 * location = "Room 1, floor 2, building 3"
999 ********************************************************************/
1000 static void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1002 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1003 printer->info_2->location, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1006 /*******************************************************************
1007 * fill a notify_info_data with the device mode
1008 * jfm:xxxx don't to it for know but that's a real problem !!!
1009 ********************************************************************/
1010 static void spoolss_notify_devmode(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1014 /*******************************************************************
1015 * fill a notify_info_data with the separator file name
1016 * jfm:xxxx just return no file could add an option to smb.conf
1017 * separator file = "separator.txt"
1018 ********************************************************************/
1019 static void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1021 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1022 printer->info_2->sepfile, sizeof(data->notify_data.data.string)-1,True) - sizeof(uint16))/sizeof(uint16));
1025 /*******************************************************************
1026 * fill a notify_info_data with the print processor
1027 * jfm:xxxx return always winprint to indicate we don't do anything to it
1028 ********************************************************************/
1029 static void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1031 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1032 printer->info_2->printprocessor, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1035 /*******************************************************************
1036 * fill a notify_info_data with the print processor options
1037 * jfm:xxxx send an empty string
1038 ********************************************************************/
1039 static void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1041 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1042 printer->info_2->parameters, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1045 /*******************************************************************
1046 * fill a notify_info_data with the data type
1047 * jfm:xxxx always send RAW as data type
1048 ********************************************************************/
1049 static void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1051 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1052 printer->info_2->datatype, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1055 /*******************************************************************
1056 * fill a notify_info_data with the security descriptor
1057 * jfm:xxxx send an null pointer to say no security desc
1058 * have to implement security before !
1059 ********************************************************************/
1060 static void spoolss_notify_security_desc(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1062 data->notify_data.data.length=0;
1063 data->notify_data.data.string[0]=0x00;
1066 /*******************************************************************
1067 * fill a notify_info_data with the attributes
1068 * jfm:xxxx a samba printer is always shared
1069 ********************************************************************/
1070 static void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1072 data->notify_data.value[0] = PRINTER_ATTRIBUTE_SHARED \
1073 | PRINTER_ATTRIBUTE_LOCAL \
1074 | PRINTER_ATTRIBUTE_RAW_ONLY ;
1077 /*******************************************************************
1078 * fill a notify_info_data with the priority
1079 ********************************************************************/
1080 static void spoolss_notify_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1082 data->notify_data.value[0] = printer->info_2->priority;
1085 /*******************************************************************
1086 * fill a notify_info_data with the default priority
1087 ********************************************************************/
1088 static void spoolss_notify_default_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1090 data->notify_data.value[0] = printer->info_2->default_priority;
1093 /*******************************************************************
1094 * fill a notify_info_data with the start time
1095 ********************************************************************/
1096 static void spoolss_notify_start_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1098 data->notify_data.value[0] = printer->info_2->starttime;
1101 /*******************************************************************
1102 * fill a notify_info_data with the until time
1103 ********************************************************************/
1104 static void spoolss_notify_until_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1106 data->notify_data.value[0] = printer->info_2->untiltime;
1109 /*******************************************************************
1110 * fill a notify_info_data with the status
1111 ********************************************************************/
1112 static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1115 print_queue_struct *q=NULL;
1116 print_status_struct status;
1118 memset(&status, 0, sizeof(status));
1119 count = print_queue_status(snum, &q, &status);
1120 data->notify_data.value[0]=(uint32) status.status;
1124 /*******************************************************************
1125 * fill a notify_info_data with the number of jobs queued
1126 ********************************************************************/
1127 static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1129 print_queue_struct *q=NULL;
1130 print_status_struct status;
1132 memset(&status, 0, sizeof(status));
1133 data->notify_data.value[0] = print_queue_status(snum, &q, &status);
1137 /*******************************************************************
1138 * fill a notify_info_data with the average ppm
1139 ********************************************************************/
1140 static void spoolss_notify_average_ppm(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1142 /* always respond 8 pages per minutes */
1143 /* a little hard ! */
1144 data->notify_data.value[0] = printer->info_2->averageppm;
1147 /*******************************************************************
1148 * fill a notify_info_data with
1149 ********************************************************************/
1150 static void spoolss_notify_username(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1152 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1153 queue->user, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1156 /*******************************************************************
1157 * fill a notify_info_data with
1158 ********************************************************************/
1159 static void spoolss_notify_job_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1161 data->notify_data.value[0]=nt_printj_status(queue->status);
1164 /*******************************************************************
1165 * fill a notify_info_data with
1166 ********************************************************************/
1167 static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1169 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1170 queue->file, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1173 /*******************************************************************
1174 * fill a notify_info_data with
1175 ********************************************************************/
1176 static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1178 char *p = "unknown";
1179 switch (queue->status) {
1193 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1194 p, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1197 /*******************************************************************
1198 * fill a notify_info_data with
1199 ********************************************************************/
1200 static void spoolss_notify_job_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1202 data->notify_data.value[0]=0x0;
1205 /*******************************************************************
1206 * fill a notify_info_data with
1207 ********************************************************************/
1208 static void spoolss_notify_job_size(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1210 data->notify_data.value[0]=queue->size;
1213 /*******************************************************************
1214 * fill a notify_info_data with
1215 ********************************************************************/
1216 static void spoolss_notify_job_position(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1218 data->notify_data.value[0]=queue->job;
1223 struct s_notify_info_data_table
1229 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
1230 print_queue_struct *queue,
1231 NT_PRINTER_INFO_LEVEL *printer);
1234 struct s_notify_info_data_table notify_info_data_table[] =
1236 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
1237 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1238 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
1239 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1240 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1241 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
1242 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
1243 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1244 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
1245 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1246 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1247 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1248 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
1249 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
1250 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1251 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
1252 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1253 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1254 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
1255 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
1256 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
1257 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
1258 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
1259 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
1260 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
1261 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
1262 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1263 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
1264 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1265 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
1266 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
1267 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1268 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1269 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1270 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1271 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1272 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
1273 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
1274 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
1275 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
1276 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1277 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
1278 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, NULL },
1279 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1280 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1281 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
1282 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
1283 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
1284 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
1285 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
1286 { END, END, "", END, NULL }
1289 /*******************************************************************
1290 return the size of info_data structure
1291 ********************************************************************/
1292 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
1296 while (notify_info_data_table[i].type != END)
1298 if ( (notify_info_data_table[i].type == type ) &&
1299 (notify_info_data_table[i].field == field ) )
1301 return (notify_info_data_table[i].size);
1309 /*******************************************************************
1310 return the type of notify_info_data
1311 ********************************************************************/
1312 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
1316 while (notify_info_data_table[i].type != END)
1318 if ( (notify_info_data_table[i].type == type ) &&
1319 (notify_info_data_table[i].field == field ) )
1321 if (notify_info_data_table[i].size == POINTER)
1336 /****************************************************************************
1337 ****************************************************************************/
1338 static int search_notify(uint16 type, uint16 field, int *value)
1343 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1345 if ( (notify_info_data_table[j].type == type ) &&
1346 (notify_info_data_table[j].field == field ) )
1351 if ( found && (notify_info_data_table[j].fn != NULL) )
1357 /****************************************************************************
1358 ****************************************************************************/
1359 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1361 info_data->type = type;
1362 info_data->field = field;
1363 info_data->reserved = 0;
1365 info_data->size = size_of_notify_info_data(type, field);
1366 info_data->enc_type = type_of_notify_info_data(type, field);
1370 /*******************************************************************
1372 * fill a notify_info struct with info asked
1374 ********************************************************************/
1375 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1381 SPOOL_NOTIFY_INFO_DATA *current_data;
1382 NT_PRINTER_INFO_LEVEL *printer = NULL;
1383 print_queue_struct *queue=NULL;
1385 DEBUG(4,("construct_notify_printer_info\n"));
1387 type=option_type->type;
1389 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
1390 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1391 option_type->count, lp_servicename(snum)));
1393 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1396 for(field_num=0; field_num<option_type->count; field_num++) {
1397 field = option_type->fields[field_num];
1398 DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field));
1400 if (!search_notify(type, field, &j) )
1403 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1406 current_data=&info->data[info->count];
1408 construct_info_data(current_data, type, field, id);
1409 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1414 free_a_printer(&printer, 2);
1418 /*******************************************************************
1420 * fill a notify_info struct with info asked
1422 ********************************************************************/
1423 static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1429 SPOOL_NOTIFY_INFO_DATA *current_data;
1430 NT_PRINTER_INFO_LEVEL *printer = NULL;
1432 DEBUG(4,("construct_notify_jobs_info\n"));
1434 type = option_type->type;
1436 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
1437 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1438 option_type->count));
1440 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1443 for(field_num=0; field_num<option_type->count; field_num++) {
1444 field = option_type->fields[field_num];
1446 if (!search_notify(type, field, &j) )
1449 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1453 current_data=&(info->data[info->count]);
1455 construct_info_data(current_data, type, field, id);
1456 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1460 free_a_printer(&printer, 2);
1465 * JFM: The enumeration is not that simple, it's even non obvious.
1467 * let's take an example: I want to monitor the PRINTER SERVER for
1468 * the printer's name and the number of jobs currently queued.
1469 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
1470 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
1472 * I have 3 printers on the back of my server.
1474 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
1477 * 1 printer 1 name 1
1478 * 2 printer 1 cjob 1
1479 * 3 printer 2 name 2
1480 * 4 printer 2 cjob 2
1481 * 5 printer 3 name 3
1482 * 6 printer 3 name 3
1484 * that's the print server case, the printer case is even worse.
1489 /*******************************************************************
1491 * enumerate all printers on the printserver
1492 * fill a notify_info struct with info asked
1494 ********************************************************************/
1495 static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1498 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1499 int n_services=lp_numservices();
1502 SPOOL_NOTIFY_OPTION *option;
1503 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1505 DEBUG(4,("printserver_notify_info\n"));
1507 option=Printer->notify.option;
1513 for (i=0; i<option->count; i++) {
1514 option_type=&(option->ctr.type[i]);
1516 if (option_type->type!=PRINTER_NOTIFY_TYPE)
1519 for (snum=0; snum<n_services; snum++)
1520 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1521 if (construct_notify_printer_info(info, snum, option_type, id))
1526 * Debugging information, don't delete.
1529 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1530 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1531 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1533 for (i=0; i<info->count; i++) {
1534 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1535 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1536 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1540 return NT_STATUS_NO_PROBLEMO;
1543 /*******************************************************************
1545 * fill a notify_info struct with info asked
1547 ********************************************************************/
1548 static uint32 printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1551 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1554 SPOOL_NOTIFY_OPTION *option;
1555 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1557 print_queue_struct *queue=NULL;
1558 print_status_struct status;
1560 DEBUG(4,("printer_notify_info\n"));
1562 option=Printer->notify.option;
1568 get_printer_snum(hnd, &snum);
1570 for (i=0; i<option->count; i++) {
1571 option_type=&option->ctr.type[i];
1573 switch ( option_type->type ) {
1574 case PRINTER_NOTIFY_TYPE:
1575 if(construct_notify_printer_info(info, snum, option_type, id))
1579 case JOB_NOTIFY_TYPE:
1580 memset(&status, 0, sizeof(status));
1581 count = print_queue_status(snum, &queue, &status);
1582 for (j=0; j<count; j++)
1583 construct_notify_jobs_info(&queue[j], info, snum, option_type, queue[j].job);
1590 * Debugging information, don't delete.
1593 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1594 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1595 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1597 for (i=0; i<info->count; i++) {
1598 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1599 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1600 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1603 return NT_STATUS_NO_PROBLEMO;
1606 /********************************************************************
1608 ********************************************************************/
1609 uint32 _spoolss_rfnpcnex( POLICY_HND *handle, uint32 change,
1610 SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info)
1612 Printer_entry *Printer=find_printer_index_by_hnd(handle);
1614 if (!OPEN_HANDLE(Printer)) {
1615 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",OUR_HANDLE(handle)));
1616 return ERROR_INVALID_HANDLE;
1619 DEBUG(4,("Printer type %x\n",Printer->printer_type));
1621 /* jfm: the change value isn't used right now.
1622 * we will honour it when
1623 * a) we'll be able to send notification to the client
1624 * b) we'll have a way to communicate between the spoolss process.
1626 * same thing for option->flags
1627 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
1628 * I don't have a global notification system, I'm sending back all the
1629 * informations even when _NOTHING_ has changed.
1632 /* just discard the SPOOL_NOTIFY_OPTION */
1634 safe_free(option->ctr.type);
1636 switch (Printer->printer_type) {
1637 case PRINTER_HANDLE_IS_PRINTSERVER:
1638 return printserver_notify_info(handle, info);
1640 case PRINTER_HANDLE_IS_PRINTER:
1641 return printer_notify_info(handle, info);
1645 return ERROR_INVALID_HANDLE;
1648 /********************************************************************
1649 * construct_printer_info_0
1650 * fill a printer_info_1 struct
1651 ********************************************************************/
1652 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring servername)
1656 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1657 counter_printer_0 *session_counter;
1658 uint32 global_counter;
1660 time_t setup_time = time(NULL);
1662 print_queue_struct *queue=NULL;
1663 print_status_struct status;
1665 memset(&status, 0, sizeof(status));
1667 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1670 count = print_queue_status(snum, &queue, &status);
1672 /* check if we already have a counter for this printer */
1673 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
1675 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
1676 if (session_counter->snum == snum)
1680 /* it's the first time, add it to the list */
1681 if (session_counter==NULL) {
1682 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
1683 free_a_printer(&ntprinter, 2);
1686 ZERO_STRUCTP(session_counter);
1687 session_counter->snum=snum;
1688 session_counter->counter=0;
1689 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
1693 session_counter->counter++;
1696 * the global_counter should be stored in a TDB as it's common to all the clients
1697 * and should be zeroed on samba startup
1699 global_counter=session_counter->counter;
1701 /* the description and the name are of the form \\server\share */
1702 slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter->info_2->printername);
1704 init_unistr(&printer->printername, chaine);
1706 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1707 init_unistr(&printer->servername, chaine);
1709 printer->cjobs = count;
1710 printer->total_jobs = 0;
1711 printer->total_bytes = 0;
1713 t=gmtime(&setup_time);
1714 ntprinter->info_2->setuptime = (uint32)setup_time; /* FIXME !! */
1716 printer->year = t->tm_year+1900;
1717 printer->month = t->tm_mon+1;
1718 printer->dayofweek = t->tm_wday;
1719 printer->day = t->tm_mday;
1720 printer->hour = t->tm_hour;
1721 printer->minute = t->tm_min;
1722 printer->second = t->tm_sec;
1723 printer->milliseconds = 0;
1725 printer->global_counter = global_counter;
1726 printer->total_pages = 0;
1727 printer->major_version = 0x0004; /* NT 4 */
1728 printer->build_version = 0x0565; /* build 1381 */
1729 printer->unknown7 = 0x1;
1730 printer->unknown8 = 0x0;
1731 printer->unknown9 = 0x0;
1732 printer->session_counter = session_counter->counter;
1733 printer->unknown11 = 0x0;
1734 printer->printer_errors = 0x0; /* number of print failure */
1735 printer->unknown13 = 0x0;
1736 printer->unknown14 = 0x1;
1737 printer->unknown15 = 0x024a; /* 586 Pentium ? */
1738 printer->unknown16 = 0x0;
1739 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
1740 printer->unknown18 = 0x0;
1741 printer->status = nt_printq_status(status.status);
1742 printer->unknown20 = 0x0;
1743 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
1744 printer->unknown22 = 0x0;
1745 printer->unknown23 = 0x6; /* 6 ???*/
1746 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
1747 printer->unknown25 = 0;
1748 printer->unknown26 = 0;
1749 printer->unknown27 = 0;
1750 printer->unknown28 = 0;
1751 printer->unknown29 = 0;
1754 free_a_printer(&ntprinter,2);
1758 /********************************************************************
1759 * construct_printer_info_1
1760 * fill a printer_info_1 struct
1761 ********************************************************************/
1762 static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum)
1766 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1768 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1771 printer->flags=flags;
1773 if (*ntprinter->info_2->comment == '\0') {
1774 init_unistr(&printer->comment, lp_comment(snum));
1775 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1776 ntprinter->info_2->drivername, lp_comment(snum));
1779 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1780 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1781 ntprinter->info_2->drivername, ntprinter->info_2->comment);
1784 snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter->info_2->printername);
1786 init_unistr(&printer->description, chaine);
1787 init_unistr(&printer->name, chaine2);
1789 free_a_printer(&ntprinter,2);
1794 /****************************************************************************
1795 Free a DEVMODE struct.
1796 ****************************************************************************/
1798 static void free_dev_mode(DEVICEMODE *dev)
1804 safe_free(dev->private);
1809 /****************************************************************************
1810 Create a DEVMODE struct. Returns malloced memory.
1811 ****************************************************************************/
1813 static DEVICEMODE *construct_dev_mode(int snum, char *servername)
1817 NT_PRINTER_INFO_LEVEL *printer = NULL;
1818 NT_DEVICEMODE *ntdevmode = NULL;
1819 DEVICEMODE *devmode = NULL;
1821 DEBUG(7,("construct_dev_mode\n"));
1823 DEBUGADD(8,("getting printer characteristics\n"));
1825 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
1826 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
1830 ZERO_STRUCTP(devmode);
1832 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
1835 if (printer->info_2->devmode)
1836 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
1838 if (ntdevmode == NULL)
1841 DEBUGADD(8,("loading DEVICEMODE\n"));
1843 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, printer->info_2->printername);
1844 init_unistr(&devmode->devicename, adevice);
1846 snprintf(aform, sizeof(aform), ntdevmode->formname);
1847 init_unistr(&devmode->formname, aform);
1849 devmode->specversion = ntdevmode->specversion;
1850 devmode->driverversion = ntdevmode->driverversion;
1851 devmode->size = ntdevmode->size;
1852 devmode->driverextra = ntdevmode->driverextra;
1853 devmode->fields = ntdevmode->fields;
1855 devmode->orientation = ntdevmode->orientation;
1856 devmode->papersize = ntdevmode->papersize;
1857 devmode->paperlength = ntdevmode->paperlength;
1858 devmode->paperwidth = ntdevmode->paperwidth;
1859 devmode->scale = ntdevmode->scale;
1860 devmode->copies = ntdevmode->copies;
1861 devmode->defaultsource = ntdevmode->defaultsource;
1862 devmode->printquality = ntdevmode->printquality;
1863 devmode->color = ntdevmode->color;
1864 devmode->duplex = ntdevmode->duplex;
1865 devmode->yresolution = ntdevmode->yresolution;
1866 devmode->ttoption = ntdevmode->ttoption;
1867 devmode->collate = ntdevmode->collate;
1868 devmode->icmmethod = ntdevmode->icmmethod;
1869 devmode->icmintent = ntdevmode->icmintent;
1870 devmode->mediatype = ntdevmode->mediatype;
1871 devmode->dithertype = ntdevmode->dithertype;
1873 if (ntdevmode->private != NULL) {
1874 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
1878 free_nt_devicemode(&ntdevmode);
1879 free_a_printer(&printer,2);
1886 free_nt_devicemode(&ntdevmode);
1888 free_a_printer(&printer,2);
1889 free_dev_mode(devmode);
1894 /********************************************************************
1895 * construct_printer_info_2
1896 * fill a printer_info_2 struct
1897 ********************************************************************/
1899 static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer, int snum)
1905 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1907 print_queue_struct *queue=NULL;
1908 print_status_struct status;
1909 memset(&status, 0, sizeof(status));
1911 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1914 memset(&status, 0, sizeof(status));
1915 count = print_queue_status(snum, &queue, &status);
1917 snprintf(chaine, sizeof(chaine)-1, "%s", servername);
1919 if (strlen(servername)!=0)
1924 snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter->info_2->printername);
1926 init_unistr(&printer->servername, chaine); /* servername*/
1927 init_unistr(&printer->printername, chaine2); /* printername*/
1928 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
1929 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
1930 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
1932 if (*ntprinter->info_2->comment == '\0')
1933 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
1935 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1937 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
1938 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
1939 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
1940 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
1941 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
1943 printer->attributes = ntprinter->info_2->attributes;
1945 printer->priority = ntprinter->info_2->priority; /* priority */
1946 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
1947 printer->starttime = ntprinter->info_2->starttime; /* starttime */
1948 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
1949 printer->status = nt_printq_status(status.status); /* status */
1950 printer->cjobs = count; /* jobs */
1951 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
1953 if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) {
1954 DEBUG(8, ("Returning NULL Devicemode!\n"));
1957 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1958 /* steal the printer info sec_desc structure. [badly done]. */
1959 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1960 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
1961 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
1962 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
1965 printer->secdesc = NULL;
1968 free_a_printer(&ntprinter, 2);
1973 /********************************************************************
1974 * construct_printer_info_3
1975 * fill a printer_info_3 struct
1976 ********************************************************************/
1977 static BOOL construct_printer_info_3(fstring servername,
1978 PRINTER_INFO_3 **pp_printer, int snum)
1980 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1981 PRINTER_INFO_3 *printer = NULL;
1983 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1987 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
1988 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
1992 ZERO_STRUCTP(printer);
1994 printer->flags = 4; /* These are the components of the SD we are returning. */
1995 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1996 /* steal the printer info sec_desc structure. [badly done]. */
1997 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2001 * Set the flags for the components we are returning.
2004 if (printer->secdesc->owner_sid)
2005 printer->flags |= OWNER_SECURITY_INFORMATION;
2007 if (printer->secdesc->grp_sid)
2008 printer->flags |= GROUP_SECURITY_INFORMATION;
2010 if (printer->secdesc->dacl)
2011 printer->flags |= DACL_SECURITY_INFORMATION;
2013 if (printer->secdesc->sacl)
2014 printer->flags |= SACL_SECURITY_INFORMATION;
2017 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
2018 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
2019 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
2022 free_a_printer(&ntprinter, 2);
2024 *pp_printer = printer;
2028 /********************************************************************
2029 Spoolss_enumprinters.
2030 ********************************************************************/
2031 static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2035 int n_services=lp_numservices();
2036 PRINTER_INFO_1 *printers=NULL;
2037 PRINTER_INFO_1 current_prt;
2039 DEBUG(4,("enum_all_printers_info_1\n"));
2041 for (snum=0; snum<n_services; snum++) {
2042 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2043 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2045 if (construct_printer_info_1(server, flags, ¤t_prt, snum)) {
2046 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
2048 return ERROR_NOT_ENOUGH_MEMORY;
2050 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2051 memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1));
2057 /* check the required size. */
2058 for (i=0; i<*returned; i++)
2059 (*needed) += spoolss_size_printer_info_1(&(printers[i]));
2061 if (!alloc_buffer_size(buffer, *needed))
2062 return ERROR_INSUFFICIENT_BUFFER;
2064 /* fill the buffer with the structures */
2065 for (i=0; i<*returned; i++)
2066 new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);
2069 safe_free(printers);
2071 if (*needed > offered) {
2073 return ERROR_INSUFFICIENT_BUFFER;
2076 return NT_STATUS_NO_PROBLEMO;
2079 /********************************************************************
2080 enum_all_printers_info_1_local.
2081 *********************************************************************/
2082 static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2085 DEBUG(4,("enum_all_printers_info_1_local\n"));
2087 fstrcpy(temp, "\\\\");
2088 fstrcat(temp, global_myname);
2090 if (!strcmp(name, temp)) {
2091 fstrcat(temp, "\\");
2092 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2095 return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2098 /********************************************************************
2099 enum_all_printers_info_1_name.
2100 *********************************************************************/
2101 static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2104 DEBUG(4,("enum_all_printers_info_1_name\n"));
2106 fstrcpy(temp, "\\\\");
2107 fstrcat(temp, global_myname);
2109 if (!strcmp(name, temp)) {
2110 fstrcat(temp, "\\");
2111 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2114 return ERROR_INVALID_NAME;
2117 /********************************************************************
2118 enum_all_printers_info_1_remote.
2119 *********************************************************************/
2120 static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2122 PRINTER_INFO_1 *printer;
2123 fstring printername;
2126 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2128 /* JFM: currently it's more a place holder than anything else.
2129 * In the spooler world there is a notion of server registration.
2130 * the print servers are registring (sp ?) on the PDC (in the same domain)
2132 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2135 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2136 return ERROR_NOT_ENOUGH_MEMORY;
2140 snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
2141 snprintf(desc, sizeof(desc)-1,"%s", global_myname);
2142 snprintf(comment, sizeof(comment)-1, "Logged on Domain");
2144 init_unistr(&printer->description, desc);
2145 init_unistr(&printer->name, printername);
2146 init_unistr(&printer->comment, comment);
2147 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2149 /* check the required size. */
2150 *needed += spoolss_size_printer_info_1(printer);
2152 if (!alloc_buffer_size(buffer, *needed)) {
2154 return ERROR_INSUFFICIENT_BUFFER;
2157 /* fill the buffer with the structures */
2158 new_smb_io_printer_info_1("", buffer, printer, 0);
2163 if (*needed > offered) {
2165 return ERROR_INSUFFICIENT_BUFFER;
2168 return NT_STATUS_NO_PROBLEMO;
2171 /********************************************************************
2172 enum_all_printers_info_1_network.
2173 *********************************************************************/
2174 static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2177 DEBUG(4,("enum_all_printers_info_1_network\n"));
2179 fstrcpy(temp, "\\\\");
2180 fstrcat(temp, global_myname);
2181 fstrcat(temp, "\\");
2182 return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
2185 /********************************************************************
2186 * api_spoolss_enumprinters
2188 * called from api_spoolss_enumprinters (see this to understand)
2189 ********************************************************************/
2190 static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2194 int n_services=lp_numservices();
2195 PRINTER_INFO_2 *printers=NULL;
2196 PRINTER_INFO_2 current_prt;
2198 for (snum=0; snum<n_services; snum++) {
2199 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2200 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2202 if (construct_printer_info_2(servername, ¤t_prt, snum)) {
2203 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL)
2204 return ERROR_NOT_ENOUGH_MEMORY;
2205 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
2206 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
2212 /* check the required size. */
2213 for (i=0; i<*returned; i++)
2214 (*needed) += spoolss_size_printer_info_2(&printers[i]);
2216 if (!alloc_buffer_size(buffer, *needed)) {
2217 for (i=0; i<*returned; i++) {
2218 free_devmode(printers[i].devmode);
2219 free_sec_desc(&printers[i].secdesc);
2221 safe_free(printers);
2222 return ERROR_INSUFFICIENT_BUFFER;
2225 /* fill the buffer with the structures */
2226 for (i=0; i<*returned; i++)
2227 new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);
2230 for (i=0; i<*returned; i++) {
2231 free_devmode(printers[i].devmode);
2232 free_sec_desc(&printers[i].secdesc);
2234 safe_free(printers);
2236 if (*needed > offered) {
2238 return ERROR_INSUFFICIENT_BUFFER;
2241 return NT_STATUS_NO_PROBLEMO;
2244 /********************************************************************
2245 * handle enumeration of printers at level 1
2246 ********************************************************************/
2247 static uint32 enumprinters_level1( uint32 flags, fstring name,
2248 NEW_BUFFER *buffer, uint32 offered,
2249 uint32 *needed, uint32 *returned)
2251 /* Not all the flags are equals */
2253 if (flags & PRINTER_ENUM_LOCAL)
2254 return enum_all_printers_info_1_local(name, buffer, offered, needed, returned);
2256 if (flags & PRINTER_ENUM_NAME)
2257 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
2259 if (flags & PRINTER_ENUM_REMOTE)
2260 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
2262 if (flags & PRINTER_ENUM_NETWORK)
2263 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
2265 return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
2268 /********************************************************************
2269 * handle enumeration of printers at level 2
2270 ********************************************************************/
2271 static uint32 enumprinters_level2( uint32 flags, fstring servername,
2272 NEW_BUFFER *buffer, uint32 offered,
2273 uint32 *needed, uint32 *returned)
2277 fstrcpy(temp, "\\\\");
2278 fstrcat(temp, global_myname);
2280 if (flags & PRINTER_ENUM_LOCAL) {
2281 if (!strcmp(servername, temp))
2282 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2284 return enum_all_printers_info_2("", buffer, offered, needed, returned);
2287 if (flags & PRINTER_ENUM_NAME) {
2288 if (!strcmp(servername, temp))
2289 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2291 return ERROR_INVALID_NAME;
2294 if (flags & PRINTER_ENUM_REMOTE)
2295 return ERROR_INVALID_LEVEL;
2297 return NT_STATUS_NO_PROBLEMO;
2300 /********************************************************************
2301 * handle enumeration of printers at level 5
2302 ********************************************************************/
2303 static uint32 enumprinters_level5( uint32 flags, fstring servername,
2304 NEW_BUFFER *buffer, uint32 offered,
2305 uint32 *needed, uint32 *returned)
2307 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
2308 return NT_STATUS_NO_PROBLEMO;
2311 /********************************************************************
2312 * api_spoolss_enumprinters
2314 * called from api_spoolss_enumprinters (see this to understand)
2315 ********************************************************************/
2316 uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
2317 NEW_BUFFER *buffer, uint32 offered,
2318 uint32 *needed, uint32 *returned)
2322 DEBUG(4,("_spoolss_enumprinters\n"));
2329 * flags==PRINTER_ENUM_NAME
2330 * if name=="" then enumerates all printers
2331 * if name!="" then enumerate the printer
2332 * flags==PRINTER_ENUM_REMOTE
2333 * name is NULL, enumerate printers
2334 * Level 2: name!="" enumerates printers, name can't be NULL
2335 * Level 3: doesn't exist
2336 * Level 4: does a local registry lookup
2337 * Level 5: same as Level 2
2340 unistr2_to_ascii(name, servername, sizeof(name)-1);
2345 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
2348 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
2351 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
2356 return ERROR_INVALID_LEVEL;
2361 /****************************************************************************
2362 ****************************************************************************/
2363 static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2365 PRINTER_INFO_0 *printer=NULL;
2367 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
2368 return ERROR_NOT_ENOUGH_MEMORY;
2370 construct_printer_info_0(printer, snum, servername);
2372 /* check the required size. */
2373 *needed += spoolss_size_printer_info_0(printer);
2375 if (!alloc_buffer_size(buffer, *needed)) {
2377 return ERROR_INSUFFICIENT_BUFFER;
2380 /* fill the buffer with the structures */
2381 new_smb_io_printer_info_0("", buffer, printer, 0);
2386 if (*needed > offered) {
2387 return ERROR_INSUFFICIENT_BUFFER;
2390 return NT_STATUS_NO_PROBLEMO;
2393 /****************************************************************************
2394 ****************************************************************************/
2395 static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2397 PRINTER_INFO_1 *printer=NULL;
2399 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2400 return ERROR_NOT_ENOUGH_MEMORY;
2402 construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum);
2404 /* check the required size. */
2405 *needed += spoolss_size_printer_info_1(printer);
2407 if (!alloc_buffer_size(buffer, *needed)) {
2409 return ERROR_INSUFFICIENT_BUFFER;
2412 /* fill the buffer with the structures */
2413 new_smb_io_printer_info_1("", buffer, printer, 0);
2418 if (*needed > offered) {
2419 return ERROR_INSUFFICIENT_BUFFER;
2422 return NT_STATUS_NO_PROBLEMO;
2425 /****************************************************************************
2426 ****************************************************************************/
2427 static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2429 PRINTER_INFO_2 *printer=NULL;
2432 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
2433 return ERROR_NOT_ENOUGH_MEMORY;
2435 fstrcpy(temp, "\\\\");
2436 fstrcat(temp, servername);
2437 construct_printer_info_2(temp, printer, snum);
2439 /* check the required size. */
2440 *needed += spoolss_size_printer_info_2(printer);
2442 if (!alloc_buffer_size(buffer, *needed)) {
2443 free_printer_info_2(printer);
2444 return ERROR_INSUFFICIENT_BUFFER;
2447 /* fill the buffer with the structures */
2448 if (!new_smb_io_printer_info_2("", buffer, printer, 0)) {
2449 free_printer_info_2(printer);
2450 return ERROR_NOT_ENOUGH_MEMORY;
2454 free_printer_info_2(printer);
2456 if (*needed > offered) {
2457 return ERROR_INSUFFICIENT_BUFFER;
2460 return NT_STATUS_NO_PROBLEMO;
2463 /****************************************************************************
2464 ****************************************************************************/
2465 static uint32 getprinter_level_3(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2467 PRINTER_INFO_3 *printer=NULL;
2470 fstrcpy(temp, "\\\\");
2471 fstrcat(temp, servername);
2472 if (!construct_printer_info_3(temp, &printer, snum))
2473 return ERROR_NOT_ENOUGH_MEMORY;
2475 /* check the required size. */
2476 *needed += spoolss_size_printer_info_3(printer);
2478 if (!alloc_buffer_size(buffer, *needed)) {
2479 free_printer_info_3(printer);
2480 return ERROR_INSUFFICIENT_BUFFER;
2483 /* fill the buffer with the structures */
2484 new_smb_io_printer_info_3("", buffer, printer, 0);
2487 free_printer_info_3(printer);
2489 if (*needed > offered) {
2490 return ERROR_INSUFFICIENT_BUFFER;
2493 return NT_STATUS_NO_PROBLEMO;
2496 /****************************************************************************
2497 ****************************************************************************/
2498 uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
2499 NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2506 pstrcpy(servername, global_myname);
2508 if (!get_printer_snum(handle, &snum))
2509 return ERROR_INVALID_HANDLE;
2513 return getprinter_level_0(servername, snum, buffer, offered, needed);
2515 return getprinter_level_1(servername,snum, buffer, offered, needed);
2517 return getprinter_level_2(servername,snum, buffer, offered, needed);
2519 return getprinter_level_3(servername,snum, buffer, offered, needed);
2521 return ERROR_INVALID_LEVEL;
2526 /********************************************************************
2527 * fill a DRIVER_INFO_1 struct
2528 ********************************************************************/
2529 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
2531 init_unistr( &info->name, driver.info_3->name);
2534 /********************************************************************
2535 * construct_printer_driver_info_1
2536 ********************************************************************/
2537 static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
2539 NT_PRINTER_INFO_LEVEL *printer = NULL;
2540 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2542 ZERO_STRUCT(driver);
2544 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2545 return ERROR_INVALID_PRINTER_NAME;
2547 if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2548 return ERROR_UNKNOWN_PRINTER_DRIVER;
2550 fill_printer_driver_info_1(info, driver, servername, architecture);
2552 free_a_printer(&printer,2);
2554 return NT_STATUS_NO_PROBLEMO;
2557 /********************************************************************
2558 * construct_printer_driver_info_2
2559 * fill a printer_info_2 struct
2560 ********************************************************************/
2561 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2563 pstring temp_driverpath;
2564 pstring temp_datafile;
2565 pstring temp_configfile;
2567 info->version=driver.info_3->cversion;
2569 init_unistr( &info->name, driver.info_3->name );
2570 init_unistr( &info->architecture, driver.info_3->environment );
2572 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2573 init_unistr( &info->driverpath, temp_driverpath );
2575 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2576 init_unistr( &info->datafile, temp_datafile );
2578 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2579 init_unistr( &info->configfile, temp_configfile );
2582 /********************************************************************
2583 * construct_printer_driver_info_2
2584 * fill a printer_info_2 struct
2585 ********************************************************************/
2586 static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
2588 NT_PRINTER_INFO_LEVEL *printer = NULL;
2589 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2591 ZERO_STRUCT(printer);
2592 ZERO_STRUCT(driver);
2594 if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2595 return ERROR_INVALID_PRINTER_NAME;
2597 if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2598 return ERROR_UNKNOWN_PRINTER_DRIVER;
2600 fill_printer_driver_info_2(info, driver, servername);
2602 free_a_printer(&printer,2);
2604 return NT_STATUS_NO_PROBLEMO;
2607 /********************************************************************
2608 * copy a strings array and convert to UNICODE
2610 * convert an array of ascii string to a UNICODE string
2611 ********************************************************************/
2612 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
2619 DEBUG(6,("init_unistr_array\n"));
2623 if (char_array == NULL)
2627 if (!v) v = ""; /* hack to handle null lists */
2629 if (strlen(v) == 0) break;
2630 snprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
2631 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
2632 if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
2633 DEBUG(0,("init_unistr_array: Realloc error\n" ));
2636 j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
2641 (*uni_array)[j]=0x0000;
2644 DEBUGADD(6,("last one:done\n"));
2647 /********************************************************************
2648 * construct_printer_info_3
2649 * fill a printer_info_3 struct
2650 ********************************************************************/
2651 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2653 pstring temp_driverpath;
2654 pstring temp_datafile;
2655 pstring temp_configfile;
2656 pstring temp_helpfile;
2660 info->version=driver.info_3->cversion;
2662 init_unistr( &info->name, driver.info_3->name );
2663 init_unistr( &info->architecture, driver.info_3->environment );
2665 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2666 init_unistr( &info->driverpath, temp_driverpath );
2668 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2669 init_unistr( &info->datafile, temp_datafile );
2671 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2672 init_unistr( &info->configfile, temp_configfile );
2674 snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
2675 init_unistr( &info->helpfile, temp_helpfile );
2677 init_unistr( &info->monitorname, driver.info_3->monitorname );
2678 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
2680 info->dependentfiles=NULL;
2681 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
2684 /********************************************************************
2685 * construct_printer_info_3
2686 * fill a printer_info_3 struct
2687 ********************************************************************/
2688 static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
2690 NT_PRINTER_INFO_LEVEL *printer = NULL;
2691 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2693 ZERO_STRUCT(driver);
2695 status=get_a_printer(&printer, 2, lp_servicename(snum) );
2696 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2698 return ERROR_INVALID_PRINTER_NAME;
2700 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
2701 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2703 free_a_printer(&printer,2);
2704 return ERROR_UNKNOWN_PRINTER_DRIVER;
2707 fill_printer_driver_info_3(info, driver, servername);
2709 free_a_printer(&printer,2);
2711 return NT_STATUS_NO_PROBLEMO;
2714 /********************************************************************
2715 * construct_printer_info_6
2716 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
2717 ********************************************************************/
2719 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2721 pstring temp_driverpath;
2722 pstring temp_datafile;
2723 pstring temp_configfile;
2724 pstring temp_helpfile;
2728 memset(&nullstr, '\0', sizeof(fstring));
2730 info->version=driver.info_3->cversion;
2732 init_unistr( &info->name, driver.info_3->name );
2733 init_unistr( &info->architecture, driver.info_3->environment );
2735 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2736 init_unistr( &info->driverpath, temp_driverpath );
2738 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2739 init_unistr( &info->datafile, temp_datafile );
2741 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2742 init_unistr( &info->configfile, temp_configfile );
2744 snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
2745 init_unistr( &info->helpfile, temp_helpfile );
2747 init_unistr( &info->monitorname, driver.info_3->monitorname );
2748 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
2750 info->dependentfiles=NULL;
2751 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
2753 info->previousdrivernames=NULL;
2754 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
2756 init_unistr( &info->mfgname, "");
2757 init_unistr( &info->oem_url, "");
2758 init_unistr( &info->hardware_id, "");
2759 init_unistr( &info->provider, "");
2762 /********************************************************************
2763 * construct_printer_info_6
2764 * fill a printer_info_6 struct
2765 ********************************************************************/
2766 static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
2768 NT_PRINTER_INFO_LEVEL *printer = NULL;
2769 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2771 ZERO_STRUCT(driver);
2773 status=get_a_printer(&printer, 2, lp_servicename(snum) );
2774 DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
2776 return ERROR_INVALID_PRINTER_NAME;
2778 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
2779 DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
2781 free_a_printer(&printer,2);
2782 return ERROR_UNKNOWN_PRINTER_DRIVER;
2785 fill_printer_driver_info_6(info, driver, servername);
2787 free_a_printer(&printer,2);
2789 return NT_STATUS_NO_PROBLEMO;
2792 /****************************************************************************
2793 ****************************************************************************/
2795 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
2797 safe_free(info->dependentfiles);
2800 /****************************************************************************
2801 ****************************************************************************/
2803 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
2805 safe_free(info->dependentfiles);
2809 /****************************************************************************
2810 ****************************************************************************/
2811 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2813 DRIVER_INFO_1 *info=NULL;
2816 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
2817 return ERROR_NOT_ENOUGH_MEMORY;
2819 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
2820 if (status != NT_STATUS_NO_PROBLEMO) {
2825 /* check the required size. */
2826 *needed += spoolss_size_printer_driver_info_1(info);
2828 if (!alloc_buffer_size(buffer, *needed)) {
2830 return ERROR_INSUFFICIENT_BUFFER;
2833 /* fill the buffer with the structures */
2834 new_smb_io_printer_driver_info_1("", buffer, info, 0);
2839 if (*needed > offered)
2840 return ERROR_INSUFFICIENT_BUFFER;
2842 return NT_STATUS_NO_PROBLEMO;
2845 /****************************************************************************
2846 ****************************************************************************/
2847 static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2849 DRIVER_INFO_2 *info=NULL;
2852 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
2853 return ERROR_NOT_ENOUGH_MEMORY;
2855 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
2856 if (status != NT_STATUS_NO_PROBLEMO) {
2861 /* check the required size. */
2862 *needed += spoolss_size_printer_driver_info_2(info);
2864 if (!alloc_buffer_size(buffer, *needed)) {
2866 return ERROR_INSUFFICIENT_BUFFER;
2869 /* fill the buffer with the structures */
2870 new_smb_io_printer_driver_info_2("", buffer, info, 0);
2875 if (*needed > offered)
2876 return ERROR_INSUFFICIENT_BUFFER;
2878 return NT_STATUS_NO_PROBLEMO;
2881 /****************************************************************************
2882 ****************************************************************************/
2883 static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2890 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
2891 if (status != NT_STATUS_NO_PROBLEMO) {
2895 /* check the required size. */
2896 *needed += spoolss_size_printer_driver_info_3(&info);
2898 if (!alloc_buffer_size(buffer, *needed)) {
2899 free_printer_driver_info_3(&info);
2900 return ERROR_INSUFFICIENT_BUFFER;
2903 /* fill the buffer with the structures */
2904 new_smb_io_printer_driver_info_3("", buffer, &info, 0);
2906 free_printer_driver_info_3(&info);
2908 if (*needed > offered)
2909 return ERROR_INSUFFICIENT_BUFFER;
2911 return NT_STATUS_NO_PROBLEMO;
2914 /****************************************************************************
2915 ****************************************************************************/
2916 static uint32 getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2923 status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
2924 if (status != NT_STATUS_NO_PROBLEMO) {
2928 /* check the required size. */
2929 *needed += spoolss_size_printer_driver_info_6(&info);
2931 if (!alloc_buffer_size(buffer, *needed)) {
2932 free_printer_driver_info_3(&info);
2933 return ERROR_INSUFFICIENT_BUFFER;
2936 /* fill the buffer with the structures */
2937 new_smb_io_printer_driver_info_6("", buffer, &info, 0);
2939 free_printer_driver_info_6(&info);
2941 if (*needed > offered)
2942 return ERROR_INSUFFICIENT_BUFFER;
2944 return NT_STATUS_NO_PROBLEMO;
2947 /****************************************************************************
2948 ****************************************************************************/
2949 uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level,
2950 uint32 clientmajorversion, uint32 clientminorversion,
2951 NEW_BUFFER *buffer, uint32 offered,
2952 uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
2955 fstring architecture;
2958 DEBUG(4,("_spoolss_getprinterdriver2\n"));
2961 *servermajorversion=0;
2962 *serverminorversion=0;
2964 pstrcpy(servername, global_myname);
2965 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
2967 if (!get_printer_snum(handle, &snum))
2968 return ERROR_INVALID_HANDLE;
2972 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2975 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2978 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2981 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2984 return ERROR_INVALID_LEVEL;
2989 /****************************************************************************
2990 ****************************************************************************/
2991 uint32 _spoolss_startpageprinter(POLICY_HND *handle)
2993 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2995 if (OPEN_HANDLE(Printer)) {
2996 Printer->page_started=True;
3000 DEBUG(3,("Error in startpageprinter printer handle\n"));
3001 return ERROR_INVALID_HANDLE;
3004 /****************************************************************************
3005 ****************************************************************************/
3006 uint32 _spoolss_endpageprinter(POLICY_HND *handle)
3008 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3010 if (!OPEN_HANDLE(Printer)) {
3011 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
3012 return ERROR_INVALID_HANDLE;
3015 Printer->page_started=False;
3017 return NT_STATUS_NO_PROBLEMO;
3021 /********************************************************************
3022 * api_spoolss_getprinter
3023 * called from the spoolss dispatcher
3025 ********************************************************************/
3026 uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
3027 pipes_struct *p, DOC_INFO *docinfo,
3030 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
3034 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3035 struct current_user user;
3037 if (!OPEN_HANDLE(Printer)) {
3038 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3039 return ERROR_INVALID_HANDLE;
3042 if (p->ntlmssp_auth_validated) {
3043 memcpy(&user, &p->pipe_user, sizeof(user));
3045 extern struct current_user current_user;
3046 memcpy(&user, ¤t_user, sizeof(user));
3050 * a nice thing with NT is it doesn't listen to what you tell it.
3051 * when asked to send _only_ RAW datas, it tries to send datas
3054 * So I add checks like in NT Server ...
3056 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
3057 * there's a bug in NT client-side code, so we'll fix it in the
3058 * server-side code. *nnnnnggggh!*
3061 if (info_1->p_datatype != 0) {
3062 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
3063 if (strcmp(datatype, "RAW") != 0) {
3065 return ERROR_INVALID_DATATYPE;
3069 /* get the share number of the printer */
3070 if (!get_printer_snum(handle, &snum)) {
3071 return ERROR_INVALID_HANDLE;
3074 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
3076 Printer->jobid = print_job_start(&user, snum, jobname);
3078 /* An error occured in print_job_start() so return an appropriate
3081 if (Printer->jobid == -1) {
3082 return map_nt_error_from_unix(errno);
3085 Printer->document_started=True;
3086 (*jobid) = Printer->jobid;
3091 /********************************************************************
3092 * api_spoolss_getprinter
3093 * called from the spoolss dispatcher
3095 ********************************************************************/
3096 uint32 _spoolss_enddocprinter(POLICY_HND *handle)
3098 Printer_entry *Printer=find_printer_index_by_hnd(handle);
3100 if (!OPEN_HANDLE(Printer)) {
3101 DEBUG(0,("_spoolss_enddocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3102 return ERROR_INVALID_HANDLE;
3105 Printer->document_started=False;
3106 print_job_end(Printer->jobid);
3107 /* error codes unhandled so far ... */
3112 /****************************************************************************
3113 ****************************************************************************/
3114 uint32 _spoolss_writeprinter( POLICY_HND *handle,
3117 uint32 *buffer_written)
3119 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3121 if (!OPEN_HANDLE(Printer)) {
3122 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
3123 return ERROR_INVALID_HANDLE;
3126 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer,
3132 /********************************************************************
3133 * api_spoolss_getprinter
3134 * called from the spoolss dispatcher
3136 ********************************************************************/
3137 static uint32 control_printer(POLICY_HND *handle, uint32 command,
3140 struct current_user user;
3143 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3145 if (p->ntlmssp_auth_validated) {
3146 memcpy(&user, &p->pipe_user, sizeof(user));
3148 extern struct current_user current_user;
3149 memcpy(&user, ¤t_user, sizeof(user));
3152 if (!OPEN_HANDLE(Printer)) {
3153 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3154 return ERROR_INVALID_HANDLE;
3157 if (!get_printer_snum(handle, &snum) )
3158 return ERROR_INVALID_HANDLE;
3161 case PRINTER_CONTROL_PAUSE:
3162 if (print_queue_pause(&user, snum, &errcode)) {
3166 case PRINTER_CONTROL_RESUME:
3167 case PRINTER_CONTROL_UNPAUSE:
3168 if (print_queue_resume(&user, snum, &errcode)) {
3172 case PRINTER_CONTROL_PURGE:
3173 if (print_queue_purge(&user, snum, &errcode)) {
3180 return (uint32)errcode;
3182 return ERROR_INVALID_FUNCTION;
3185 /********************************************************************
3186 * api_spoolss_abortprinter
3187 ********************************************************************/
3189 uint32 _spoolss_abortprinter(POLICY_HND *handle, pipes_struct *p)
3191 return control_printer(handle, PRINTER_CONTROL_PURGE, p);
3194 /********************************************************************
3195 * called by spoolss_api_setprinter
3196 * when updating a printer description
3197 ********************************************************************/
3198 static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
3199 const SPOOL_PRINTER_INFO_LEVEL *info,
3200 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
3202 struct current_user user;
3206 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3208 if (!OPEN_HANDLE(Printer) || !get_printer_snum(handle, &snum)) {
3209 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3210 return ERROR_INVALID_HANDLE;
3213 /* Work out which user is performing the operation */
3214 if (p->ntlmssp_auth_validated) {
3215 memcpy(&user, &p->pipe_user, sizeof(user));
3217 extern struct current_user current_user;
3218 memcpy(&user, ¤t_user, sizeof(user));
3221 /* Check the user has permissions to change the security
3222 descriptor. By experimentation with two NT machines, the user
3223 requires Full Access to the printer to change security
3225 if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
3226 result = ERROR_ACCESS_DENIED;
3230 result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
3236 /********************************************************************
3237 Do Samba sanity checks on a printer info struct.
3238 ********************************************************************/
3240 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
3243 * Ensure that this printer is shared under the correct name
3244 * as this is what Samba insists upon.
3247 if (!(info->attributes & PRINTER_ATTRIBUTE_SHARED)) {
3248 DEBUG(10,("check_printer_ok: SHARED check failed (%x).\n", (unsigned int)info->attributes ));
3252 if (!(info->attributes & PRINTER_ATTRIBUTE_RAW_ONLY)) {
3253 /* NT forgets to set the raw attribute but sends the correct type. */
3254 if (strequal(info->datatype, "RAW"))
3255 info->attributes |= PRINTER_ATTRIBUTE_RAW_ONLY;
3257 DEBUG(10,("check_printer_ok: RAW check failed (%x).\n", (unsigned int)info->attributes ));
3262 if (!strequal(info->sharename, lp_servicename(snum))) {
3263 DEBUG(10,("check_printer_ok: NAME check failed (%s) (%s).\n", info->sharename, lp_servicename(snum)));
3270 /****************************************************************************
3271 ****************************************************************************/
3272 static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
3274 pid_t local_pid = sys_getpid();
3275 char *cmd = lp_addprinter_cmd();
3280 pstring driverlocation;
3284 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
3285 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
3289 /* build driver path... only 9X architecture is needed for legacy reasons */
3290 slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
3292 /* change \ to \\ for the shell */
3293 all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
3295 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
3296 slprintf(command, sizeof(command), "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
3297 cmd, printer->info_2->printername, printer->info_2->sharename,
3298 printer->info_2->portname, printer->info_2->drivername,
3299 printer->info_2->location, driverlocation);
3302 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
3303 ret = smbrun(command, tmp_file, False);
3304 DEBUGADD(10,("returned [%d]\n", ret));
3312 qlines = file_lines_load(tmp_file, &numlines);
3313 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
3314 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
3318 // Set the portname to what the script says the portname should be
3319 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
3320 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
3322 // Send SIGHUP to process group... is there a better way?
3327 file_lines_free(qlines);
3331 /********************************************************************
3332 * called by spoolss_api_setprinter
3333 * when updating a printer description
3334 ********************************************************************/
3336 static uint32 update_printer(POLICY_HND *handle, uint32 level,
3337 const SPOOL_PRINTER_INFO_LEVEL *info,
3338 DEVICEMODE *devmode)
3341 NT_PRINTER_INFO_LEVEL *printer = NULL;
3342 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3345 DEBUG(8,("update_printer\n"));
3347 result = NT_STATUS_NO_PROBLEMO;
3349 /* Check calling user has permission to update printer description */
3352 DEBUG(0,("Send a mail to samba@samba.org\n"));
3353 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3354 result = ERROR_INVALID_LEVEL;
3358 if (!OPEN_HANDLE(Printer)) {
3359 result = ERROR_INVALID_HANDLE;
3363 if (!get_printer_snum(handle, &snum)) {
3364 result = ERROR_INVALID_HANDLE;
3368 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
3369 DEBUG(3, ("printer property change denied by security "
3371 result = ERROR_ACCESS_DENIED;
3375 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3376 result = ERROR_INVALID_HANDLE;
3380 DEBUGADD(8,("Converting info_2 struct\n"));
3383 * convert_printer_info converts the incoming
3384 * info from the client and overwrites the info
3385 * just read from the tdb in the pointer 'printer'.
3388 convert_printer_info(info, printer, level);
3390 if (info->info_2->devmode_ptr != 0) {
3391 /* we have a valid devmode
3392 convert it and link it*/
3395 * Ensure printer->info_2->devmode is a valid pointer
3396 * as we will be overwriting it in convert_devicemode().
3399 if (printer->info_2->devmode == NULL)
3400 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3402 DEBUGADD(8,("Converting the devicemode struct\n"));
3403 convert_devicemode(devmode, printer->info_2->devmode);
3406 if (printer->info_2->devmode != NULL)
3407 free_nt_devicemode(&printer->info_2->devmode);
3408 printer->info_2->devmode=NULL;
3412 * Do sanity check on the requested changes for Samba.
3415 if (!check_printer_ok(printer->info_2, snum)) {
3416 result = ERROR_INVALID_PARAMETER;
3420 if (*lp_addprinter_cmd() )
3421 if ( !add_printer_hook(printer) ) {
3422 result = ERROR_ACCESS_DENIED;
3426 if (add_a_printer(*printer, 2)!=0) {
3427 /* I don't really know what to return here !!! */
3428 result = ERROR_ACCESS_DENIED;
3433 free_a_printer(&printer, 2);
3438 /****************************************************************************
3439 ****************************************************************************/
3440 uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
3441 const SPOOL_PRINTER_INFO_LEVEL *info,
3442 DEVMODE_CTR devmode_ctr,
3443 SEC_DESC_BUF *secdesc_ctr,
3444 uint32 command, pipes_struct *p)
3446 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3448 if (!OPEN_HANDLE(Printer)) {
3449 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3450 return ERROR_INVALID_HANDLE;
3453 /* check the level */
3456 return control_printer(handle, command, p);
3459 return update_printer(handle, level, info, devmode_ctr.devmode);
3462 return update_printer_sec(handle, level, info, p,
3466 return ERROR_INVALID_LEVEL;
3471 /****************************************************************************
3472 ****************************************************************************/
3473 uint32 _spoolss_fcpn(POLICY_HND *handle)
3475 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3477 if (!OPEN_HANDLE(Printer)) {
3478 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3479 return ERROR_INVALID_HANDLE;
3482 Printer->notify.flags=0;
3483 Printer->notify.options=0;
3484 Printer->notify.localmachine[0]='\0';
3485 Printer->notify.printerlocal=0;
3486 if (Printer->notify.option)
3487 safe_free(Printer->notify.option->ctr.type);
3488 safe_free(Printer->notify.option);
3489 Printer->notify.option=NULL;
3491 return NT_STATUS_NO_PROBLEMO;
3494 /****************************************************************************
3495 ****************************************************************************/
3496 uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
3497 NEW_BUFFER *buffer, uint32 offered,
3501 return ERROR_INVALID_PARAMETER; /* this is what a NT server
3502 returns for AddJob. AddJob
3503 must fail on non-local
3507 /****************************************************************************
3508 ****************************************************************************/
3509 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3510 int position, int snum)
3515 time_t unixdate = time(NULL);
3517 t=gmtime(&unixdate);
3518 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3520 job_info->jobid=queue->job;
3521 init_unistr(&job_info->printername, lp_servicename(snum));
3522 init_unistr(&job_info->machinename, temp_name);
3523 init_unistr(&job_info->username, queue->user);
3524 init_unistr(&job_info->document, queue->file);
3525 init_unistr(&job_info->datatype, "RAW");
3526 init_unistr(&job_info->text_status, "");
3527 job_info->status=nt_printj_status(queue->status);
3528 job_info->priority=queue->priority;
3529 job_info->position=position;
3530 job_info->totalpages=0;
3531 job_info->pagesprinted=0;
3533 make_systemtime(&job_info->submitted, t);
3536 /****************************************************************************
3537 ****************************************************************************/
3538 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3539 int position, int snum)
3542 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3546 time_t unixdate = time(NULL);
3548 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3551 t=gmtime(&unixdate);
3552 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3554 job_info->jobid=queue->job;
3556 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3558 init_unistr(&job_info->printername, chaine);
3560 init_unistr(&job_info->machinename, temp_name);
3561 init_unistr(&job_info->username, queue->user);
3562 init_unistr(&job_info->document, queue->file);
3563 init_unistr(&job_info->notifyname, queue->user);
3564 init_unistr(&job_info->datatype, "RAW");
3565 init_unistr(&job_info->printprocessor, "winprint");
3566 init_unistr(&job_info->parameters, "");
3567 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
3568 init_unistr(&job_info->text_status, "");
3570 /* and here the security descriptor */
3572 job_info->status=nt_printj_status(queue->status);
3573 job_info->priority=queue->priority;
3574 job_info->position=position;
3575 job_info->starttime=0;
3576 job_info->untiltime=0;
3577 job_info->totalpages=0;
3578 job_info->size=queue->size;
3579 make_systemtime(&(job_info->submitted), t);
3580 job_info->timeelapsed=0;
3581 job_info->pagesprinted=0;
3583 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3584 free_a_printer(&ntprinter, 2);
3588 free_a_printer(&ntprinter, 2);
3592 /****************************************************************************
3593 Enumjobs at level 1.
3594 ****************************************************************************/
3595 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3596 NEW_BUFFER *buffer, uint32 offered,
3597 uint32 *needed, uint32 *returned)
3602 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3606 return ERROR_NOT_ENOUGH_MEMORY;
3609 for (i=0; i<*returned; i++)
3610 fill_job_info_1(&info[i], &queue[i], i, snum);
3614 /* check the required size. */
3615 for (i=0; i<*returned; i++)
3616 (*needed) += spoolss_size_job_info_1(&info[i]);
3618 if (!alloc_buffer_size(buffer, *needed)) {
3620 return ERROR_INSUFFICIENT_BUFFER;
3623 /* fill the buffer with the structures */
3624 for (i=0; i<*returned; i++)
3625 new_smb_io_job_info_1("", buffer, &info[i], 0);
3630 if (*needed > offered) {
3632 return ERROR_INSUFFICIENT_BUFFER;
3635 return NT_STATUS_NO_PROBLEMO;
3638 /****************************************************************************
3639 Enumjobs at level 2.
3640 ****************************************************************************/
3641 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3642 NEW_BUFFER *buffer, uint32 offered,
3643 uint32 *needed, uint32 *returned)
3648 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3652 return ERROR_NOT_ENOUGH_MEMORY;
3655 for (i=0; i<*returned; i++)
3656 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3660 /* check the required size. */
3661 for (i=0; i<*returned; i++)
3662 (*needed) += spoolss_size_job_info_2(&info[i]);
3664 if (!alloc_buffer_size(buffer, *needed)) {
3666 return ERROR_INSUFFICIENT_BUFFER;
3669 /* fill the buffer with the structures */
3670 for (i=0; i<*returned; i++)
3671 new_smb_io_job_info_2("", buffer, &info[i], 0);
3676 if (*needed > offered) {
3678 return ERROR_INSUFFICIENT_BUFFER;
3681 return NT_STATUS_NO_PROBLEMO;
3684 /****************************************************************************
3686 ****************************************************************************/
3687 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3688 NEW_BUFFER *buffer, uint32 offered,
3689 uint32 *needed, uint32 *returned)
3692 print_queue_struct *queue=NULL;
3693 print_status_struct prt_status;
3695 DEBUG(4,("_spoolss_enumjobs\n"));
3697 ZERO_STRUCT(prt_status);
3702 if (!get_printer_snum(handle, &snum))
3703 return ERROR_INVALID_HANDLE;
3705 *returned = print_queue_status(snum, &queue, &prt_status);
3706 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3708 if (*returned == 0) {
3710 return NT_STATUS_NO_PROBLEMO;
3715 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3718 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3723 return ERROR_INVALID_LEVEL;
3729 /****************************************************************************
3730 ****************************************************************************/
3731 uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid)
3736 /****************************************************************************
3737 ****************************************************************************/
3738 uint32 _spoolss_setjob( POLICY_HND *handle,
3746 struct current_user user;
3748 print_status_struct prt_status;
3750 memset(&prt_status, 0, sizeof(prt_status));
3752 if (!get_printer_snum(handle, &snum)) {
3753 return ERROR_INVALID_HANDLE;
3756 if (!print_job_exists(jobid)) {
3757 return ERROR_INVALID_PRINTER_NAME;
3760 if (p->ntlmssp_auth_validated) {
3761 memcpy(&user, &p->pipe_user, sizeof(user));
3763 extern struct current_user current_user;
3764 memcpy(&user, ¤t_user, sizeof(user));
3768 case JOB_CONTROL_CANCEL:
3769 case JOB_CONTROL_DELETE:
3770 if (print_job_delete(&user, jobid)) return 0x0;
3772 case JOB_CONTROL_PAUSE:
3773 if (print_job_pause(&user, jobid)) return 0x0;
3775 case JOB_CONTROL_RESUME:
3776 if (print_job_resume(&user, jobid)) return 0x0;
3779 return ERROR_INVALID_LEVEL;
3782 return ERROR_INVALID_HANDLE;
3785 /****************************************************************************
3786 Enumerates all printer drivers at level 1.
3787 ****************************************************************************/
3788 static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3793 fstring *list = NULL;
3795 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3796 DRIVER_INFO_1 *driver_info_1=NULL;
3800 #define MAX_VERSION 4
3802 for (version=0; version<MAX_VERSION; version++) {
3804 ndrivers=get_ntdrivers(&list, architecture, version);
3805 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3808 return ERROR_NOT_ENOUGH_MEMORY;
3811 if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
3813 return ERROR_NOT_ENOUGH_MEMORY;
3817 for (i=0; i<ndrivers; i++) {
3819 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3820 ZERO_STRUCT(driver);
3821 if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
3825 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
3826 free_a_printer_driver(driver, 3);
3829 *returned+=ndrivers;
3833 /* check the required size. */
3834 for (i=0; i<*returned; i++) {
3835 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3836 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
3839 if (!alloc_buffer_size(buffer, *needed)) {
3840 safe_free(driver_info_1);
3841 return ERROR_INSUFFICIENT_BUFFER;
3844 /* fill the buffer with the form structures */
3845 for (i=0; i<*returned; i++) {
3846 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3847 new_smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
3850 safe_free(driver_info_1);
3852 if (*needed > offered) {
3854 return ERROR_INSUFFICIENT_BUFFER;
3857 return NT_STATUS_NO_PROBLEMO;
3860 /****************************************************************************
3861 Enumerates all printer drivers at level 2.
3862 ****************************************************************************/
3863 static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3868 fstring *list = NULL;
3870 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3871 DRIVER_INFO_2 *driver_info_2=NULL;
3875 #define MAX_VERSION 4
3877 for (version=0; version<MAX_VERSION; version++) {
3879 ndrivers=get_ntdrivers(&list, architecture, version);
3880 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3883 return ERROR_NOT_ENOUGH_MEMORY;
3886 if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
3888 return ERROR_NOT_ENOUGH_MEMORY;
3892 for (i=0; i<ndrivers; i++) {
3895 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3896 ZERO_STRUCT(driver);
3897 if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
3901 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
3902 free_a_printer_driver(driver, 3);
3905 *returned+=ndrivers;
3909 /* check the required size. */
3910 for (i=0; i<*returned; i++) {
3911 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3912 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3915 if (!alloc_buffer_size(buffer, *needed)) {
3916 safe_free(driver_info_2);
3917 return ERROR_INSUFFICIENT_BUFFER;
3920 /* fill the buffer with the form structures */
3921 for (i=0; i<*returned; i++) {
3922 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3923 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3926 safe_free(driver_info_2);
3928 if (*needed > offered) {
3930 return ERROR_INSUFFICIENT_BUFFER;
3933 return NT_STATUS_NO_PROBLEMO;
3936 /****************************************************************************
3937 Enumerates all printer drivers at level 3.
3938 ****************************************************************************/
3939 static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3944 fstring *list = NULL;
3946 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3947 DRIVER_INFO_3 *driver_info_3=NULL;
3951 #define MAX_VERSION 4
3953 for (version=0; version<MAX_VERSION; version++) {
3955 ndrivers=get_ntdrivers(&list, architecture, version);
3956 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3959 return ERROR_NOT_ENOUGH_MEMORY;
3962 if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
3964 return ERROR_NOT_ENOUGH_MEMORY;
3968 for (i=0; i<ndrivers; i++) {
3971 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3972 ZERO_STRUCT(driver);
3973 if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
3977 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
3978 free_a_printer_driver(driver, 3);
3981 *returned+=ndrivers;
3985 /* check the required size. */
3986 for (i=0; i<*returned; i++) {
3987 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3988 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3991 if (!alloc_buffer_size(buffer, *needed)) {
3992 safe_free(driver_info_3);
3993 return ERROR_INSUFFICIENT_BUFFER;
3996 /* fill the buffer with the driver structures */
3997 for (i=0; i<*returned; i++) {
3998 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3999 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
4002 for (i=0; i<*returned; i++)
4003 safe_free(driver_info_3[i].dependentfiles);
4005 safe_free(driver_info_3);
4007 if (*needed > offered) {
4009 return ERROR_INSUFFICIENT_BUFFER;
4012 return NT_STATUS_NO_PROBLEMO;
4015 /****************************************************************************
4016 Enumerates all printer drivers.
4017 ****************************************************************************/
4018 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
4019 NEW_BUFFER *buffer, uint32 offered,
4020 uint32 *needed, uint32 *returned)
4022 fstring *list = NULL;
4024 fstring architecture;
4026 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
4027 fstrcpy(servername, global_myname);
4031 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
4035 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
4038 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
4041 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
4046 return ERROR_INVALID_LEVEL;
4051 /****************************************************************************
4052 ****************************************************************************/
4053 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
4055 form->flag=list->flag;
4056 init_unistr(&form->name, list->name);
4057 form->width=list->width;
4058 form->length=list->length;
4059 form->left=list->left;
4060 form->top=list->top;
4061 form->right=list->right;
4062 form->bottom=list->bottom;
4065 /****************************************************************************
4066 ****************************************************************************/
4067 uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
4068 NEW_BUFFER *buffer, uint32 offered,
4069 uint32 *needed, uint32 *numofforms)
4071 nt_forms_struct *list=NULL;
4076 DEBUG(4,("_new_spoolss_enumforms\n"));
4077 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
4078 DEBUGADD(5,("Info level [%d]\n", level));
4080 *numofforms = get_ntforms(&list);
4081 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
4083 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
4087 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
4089 return ERROR_NOT_ENOUGH_MEMORY;
4092 /* construct the list of form structures */
4093 for (i=0; i<*numofforms; i++) {
4094 DEBUGADD(6,("Filling form number [%d]\n",i));
4095 fill_form_1(&forms_1[i], &list[i]);
4100 /* check the required size. */
4101 for (i=0; i<*numofforms; i++) {
4102 DEBUGADD(6,("adding form [%d]'s size\n",i));
4103 buffer_size += spoolss_size_form_1(&forms_1[i]);
4106 *needed=buffer_size;
4108 if (!alloc_buffer_size(buffer, buffer_size)){
4110 return ERROR_INSUFFICIENT_BUFFER;
4113 /* fill the buffer with the form structures */
4114 for (i=0; i<*numofforms; i++) {
4115 DEBUGADD(6,("adding form [%d] to buffer\n",i));
4116 new_smb_io_form_1("", buffer, &forms_1[i], 0);
4121 if (*needed > offered) {
4123 return ERROR_INSUFFICIENT_BUFFER;
4126 return NT_STATUS_NO_PROBLEMO;
4130 return ERROR_INVALID_LEVEL;
4135 /****************************************************************************
4136 ****************************************************************************/
4137 uint32 _spoolss_getform( POLICY_HND *handle, uint32 level, UNISTR2 *uni_formname, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4139 nt_forms_struct *list=NULL;
4145 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
4147 DEBUG(4,("_spoolss_getform\n"));
4148 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
4149 DEBUGADD(5,("Info level [%d]\n", level));
4151 numofforms = get_ntforms(&list);
4152 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
4154 if (numofforms == 0)
4155 return ERROR_NO_MORE_ITEMS;
4160 /* Check if the requested name is in the list of form structures */
4161 for (i=0; i<numofforms; i++) {
4163 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
4165 if (strequal(form_name, list[i].name)) {
4166 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
4167 fill_form_1(&form_1, &list[i]);
4174 /* check the required size. */
4176 *needed=spoolss_size_form_1(&form_1);
4178 if (!alloc_buffer_size(buffer, buffer_size)){
4179 return ERROR_INSUFFICIENT_BUFFER;
4182 if (*needed > offered) {
4183 return ERROR_INSUFFICIENT_BUFFER;
4186 /* fill the buffer with the form structures */
4187 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
4188 new_smb_io_form_1("", buffer, &form_1, 0);
4190 return NT_STATUS_NO_PROBLEMO;
4194 return ERROR_INVALID_LEVEL;
4198 /****************************************************************************
4199 ****************************************************************************/
4200 static void fill_port_1(PORT_INFO_1 *port, char *name)
4202 init_unistr(&port->port_name, name);
4205 /****************************************************************************
4206 ****************************************************************************/
4207 static void fill_port_2(PORT_INFO_2 *port, char *name)
4209 init_unistr(&port->port_name, name);
4210 init_unistr(&port->monitor_name, "Local Monitor");
4211 init_unistr(&port->description, "Local Port");
4212 #define PORT_TYPE_WRITE 1
4213 port->port_type=PORT_TYPE_WRITE;
4217 /****************************************************************************
4219 ****************************************************************************/
4220 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4222 PORT_INFO_1 *ports=NULL;
4225 if (*lp_enumports_cmd()) {
4226 pid_t local_pid = sys_getpid();
4227 char *cmd = lp_enumports_cmd();
4235 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4236 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4240 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4241 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 1);
4244 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4245 ret = smbrun(command, tmp_file, False);
4246 DEBUG(10,("Returned [%d]\n", ret));
4249 // Is this the best error to return here?
4250 return ERROR_ACCESS_DENIED;
4254 qlines = file_lines_load(tmp_file, &numlines);
4255 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4256 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4260 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
4261 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4262 file_lines_free(qlines);
4263 return ERROR_NOT_ENOUGH_MEMORY;
4266 for (i=0; i<numlines; i++) {
4267 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4268 fill_port_1(&ports[i], qlines[i]);
4271 file_lines_free(qlines);
4274 *returned = numlines;
4277 *returned = 1; /* Sole Samba port returned. */
4279 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
4280 return ERROR_NOT_ENOUGH_MEMORY;
4282 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4284 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
4287 /* check the required size. */
4288 for (i=0; i<*returned; i++) {
4289 DEBUGADD(6,("adding port [%d]'s size\n", i));
4290 *needed += spoolss_size_port_info_1(&ports[i]);
4293 if (!alloc_buffer_size(buffer, *needed)) {
4295 return ERROR_INSUFFICIENT_BUFFER;
4298 /* fill the buffer with the ports structures */
4299 for (i=0; i<*returned; i++) {
4300 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4301 new_smb_io_port_1("", buffer, &ports[i], 0);
4306 if (*needed > offered) {
4308 return ERROR_INSUFFICIENT_BUFFER;
4311 return NT_STATUS_NO_PROBLEMO;
4314 /****************************************************************************
4316 ****************************************************************************/
4318 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4320 PORT_INFO_2 *ports=NULL;
4323 if (*lp_enumports_cmd()) {
4324 pid_t local_pid = sys_getpid();
4325 char *cmd = lp_enumports_cmd();
4333 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4334 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4338 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4339 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 2);
4342 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4343 ret = smbrun(command, tmp_file, False);
4344 DEBUGADD(10,("returned [%d]\n", ret));
4347 // Is this the best error to return here?
4348 return ERROR_ACCESS_DENIED;
4352 qlines = file_lines_load(tmp_file, &numlines);
4353 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4354 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4358 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
4359 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4360 file_lines_free(qlines);
4361 return ERROR_NOT_ENOUGH_MEMORY;
4364 for (i=0; i<numlines; i++) {
4365 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4366 fill_port_2(&(ports[i]), qlines[i]);
4369 file_lines_free(qlines);
4372 *returned = numlines;
4378 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
4379 return ERROR_NOT_ENOUGH_MEMORY;
4381 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4383 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
4386 /* check the required size. */
4387 for (i=0; i<*returned; i++) {
4388 DEBUGADD(6,("adding port [%d]'s size\n", i));
4389 *needed += spoolss_size_port_info_2(&ports[i]);
4392 if (!alloc_buffer_size(buffer, *needed)) {
4394 return ERROR_INSUFFICIENT_BUFFER;
4397 /* fill the buffer with the ports structures */
4398 for (i=0; i<*returned; i++) {
4399 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4400 new_smb_io_port_2("", buffer, &ports[i], 0);
4405 if (*needed > offered) {
4407 return ERROR_INSUFFICIENT_BUFFER;
4410 return NT_STATUS_NO_PROBLEMO;
4413 /****************************************************************************
4415 ****************************************************************************/
4416 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
4417 NEW_BUFFER *buffer, uint32 offered,
4418 uint32 *needed, uint32 *returned)
4420 DEBUG(4,("_spoolss_enumports\n"));
4427 return enumports_level_1(buffer, offered, needed, returned);
4430 return enumports_level_2(buffer, offered, needed, returned);
4433 return ERROR_INVALID_LEVEL;
4438 /****************************************************************************
4439 ****************************************************************************/
4440 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
4441 const SPOOL_PRINTER_INFO_LEVEL *info,
4442 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4443 uint32 user_switch, const SPOOL_USER_CTR *user,
4446 NT_PRINTER_INFO_LEVEL *printer = NULL;
4450 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
4451 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
4452 return ERROR_NOT_ENOUGH_MEMORY;
4455 ZERO_STRUCTP(printer);
4457 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
4458 convert_printer_info(info, printer, 2);
4460 if (*lp_addprinter_cmd() )
4461 if ( !add_printer_hook(printer) ) {
4462 free_a_printer(&printer,2);
4463 return ERROR_ACCESS_DENIED;
4466 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
4467 printer->info_2->sharename);
4469 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
4470 free_a_printer(&printer,2);
4471 return ERROR_ACCESS_DENIED;
4474 /* you must be a printer admin to add a new printer */
4475 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4476 free_a_printer(&printer,2);
4477 return ERROR_ACCESS_DENIED;
4481 * Do sanity check on the requested changes for Samba.
4484 if (!check_printer_ok(printer->info_2, snum)) {
4485 free_a_printer(&printer,2);
4486 return ERROR_INVALID_PARAMETER;
4489 /* write the ASCII on disk */
4490 if (add_a_printer(*printer, 2) != 0) {
4491 free_a_printer(&printer,2);
4492 return ERROR_ACCESS_DENIED;
4495 if (!open_printer_hnd(handle, name)) {
4496 /* Handle open failed - remove addition. */
4497 del_a_printer(printer->info_2->sharename);
4498 free_a_printer(&printer,2);
4499 return ERROR_ACCESS_DENIED;
4502 free_a_printer(&printer,2);
4503 return NT_STATUS_NO_PROBLEMO;
4506 /****************************************************************************
4507 ****************************************************************************/
4508 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4509 const SPOOL_PRINTER_INFO_LEVEL *info,
4510 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4511 uint32 user_switch, const SPOOL_USER_CTR *user,
4516 /* we don't handle yet */
4517 /* but I know what to do ... */
4518 return ERROR_INVALID_LEVEL;
4521 return spoolss_addprinterex_level_2(uni_srv_name, info,
4522 unk0, unk1, unk2, unk3,
4523 user_switch, user, handle);
4526 return ERROR_INVALID_LEVEL;
4531 /****************************************************************************
4532 ****************************************************************************/
4533 uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
4534 uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4536 uint32 err = NT_STATUS_NO_PROBLEMO;
4537 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4538 struct current_user user;
4540 ZERO_STRUCT(driver);
4542 if (p->ntlmssp_auth_validated) {
4543 memcpy(&user, &p->pipe_user, sizeof(user));
4545 extern struct current_user current_user;
4546 memcpy(&user, ¤t_user, sizeof(user));
4549 convert_printer_driver_info(info, &driver, level);
4551 DEBUG(5,("Cleaning driver's information\n"));
4552 clean_up_driver_struct(driver, level);
4554 DEBUG(5,("Moving driver to final destination\n"));
4555 if(!move_driver_to_download_area(driver, level, &user, &err)) {
4557 err = ERROR_ACCESS_DENIED;
4561 if (add_a_printer_driver(driver, level)!=0) {
4562 err = ERROR_ACCESS_DENIED;
4567 free_a_printer_driver(driver, level);
4571 /****************************************************************************
4572 ****************************************************************************/
4573 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4575 init_unistr(&info->name, name);
4578 /****************************************************************************
4579 ****************************************************************************/
4580 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4584 pstring short_archi;
4585 DRIVER_DIRECTORY_1 *info=NULL;
4587 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4589 if (get_short_archi(short_archi, long_archi)==FALSE)
4590 return ERROR_INVALID_ENVIRONMENT;
4592 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4593 return ERROR_NOT_ENOUGH_MEMORY;
4595 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
4597 DEBUG(4,("printer driver directory: [%s]\n", path));
4599 fill_driverdir_1(info, path);
4601 *needed += spoolss_size_driverdir_info_1(info);
4603 if (!alloc_buffer_size(buffer, *needed)) {
4605 return ERROR_INSUFFICIENT_BUFFER;
4608 new_smb_io_driverdir_1("", buffer, info, 0);
4612 if (*needed > offered)
4613 return ERROR_INSUFFICIENT_BUFFER;
4615 return NT_STATUS_NO_PROBLEMO;
4618 /****************************************************************************
4619 ****************************************************************************/
4620 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4621 NEW_BUFFER *buffer, uint32 offered,
4624 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4630 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4633 return ERROR_INVALID_LEVEL;
4638 /****************************************************************************
4639 ****************************************************************************/
4640 uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
4641 uint32 in_value_len, uint32 in_data_len,
4642 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4644 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4646 NT_PRINTER_INFO_LEVEL *printer = NULL;
4651 uint32 biggest_valuesize;
4652 uint32 biggest_datasize;
4654 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4659 ZERO_STRUCT(printer);
4661 *out_max_value_len=0;
4667 *out_max_data_len=0;
4671 DEBUG(5,("spoolss_enumprinterdata\n"));
4673 if (!OPEN_HANDLE(Printer)) {
4674 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4675 return ERROR_INVALID_HANDLE;
4678 if (!get_printer_snum(handle, &snum))
4679 return ERROR_INVALID_HANDLE;
4681 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4682 return ERROR_INVALID_HANDLE;
4685 * The NT machine wants to know the biggest size of value and data
4687 * cf: MSDN EnumPrinterData remark section
4689 if ( (in_value_len==0) && (in_data_len==0) ) {
4690 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4694 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
4695 * if this parameter size doesn't exist.
4696 * Ok - my opinion here is that the client is not asking for the greatest
4697 * possible size of all the parameters, but is asking specifically for the size needed
4698 * for this specific parameter. In that case we can remove the loop below and
4699 * simplify this lookup code considerably. JF - comments welcome. JRA.
4702 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4704 free_a_printer(&printer, 2);
4705 return ERROR_NO_MORE_ITEMS;
4713 biggest_valuesize=0;
4716 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4717 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4718 if (data_len > biggest_datasize) biggest_datasize=data_len;
4720 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4728 * I think this is correct, it doesn't break APW and
4729 * allows Gerald's Win32 test programs to work correctly,
4730 * but may need altering.... JRA.
4733 if (param_index == 0) {
4734 /* No parameters found. */
4735 free_a_printer(&printer, 2);
4736 return ERROR_NO_MORE_ITEMS;
4739 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4740 *out_value_len=2*(1+biggest_valuesize);
4741 *out_data_len=biggest_datasize;
4743 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4745 free_a_printer(&printer, 2);
4746 return NT_STATUS_NO_PROBLEMO;
4750 * the value len is wrong in NT sp3
4751 * that's the number of bytes not the number of unicode chars
4754 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4756 free_a_printer(&printer, 2);
4757 return ERROR_NO_MORE_ITEMS;
4760 free_a_printer(&printer, 2);
4764 * - counted in bytes in the request
4765 * - counted in UNICODE chars in the max reply
4766 * - counted in bytes in the real size
4768 * take a pause *before* coding not *during* coding
4771 *out_max_value_len=(in_value_len/sizeof(uint16));
4772 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4774 return ERROR_NOT_ENOUGH_MEMORY;
4777 ZERO_STRUCTP(*out_value);
4778 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4782 /* the data is counted in bytes */
4783 *out_max_data_len=in_data_len;
4784 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4786 return ERROR_NOT_ENOUGH_MEMORY;
4789 ZERO_STRUCTP(*data_out);
4790 memcpy(*data_out, data, (size_t)data_len);
4791 *out_data_len=data_len;
4795 return NT_STATUS_NO_PROBLEMO;
4798 /****************************************************************************
4799 ****************************************************************************/
4800 uint32 _spoolss_setprinterdata( POLICY_HND *handle,
4801 const UNISTR2 *value,
4806 uint32 numeric_data)
4808 NT_PRINTER_INFO_LEVEL *printer = NULL;
4809 NT_PRINTER_PARAM *param = NULL;
4811 uint32 status = 0x0;
4812 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4814 DEBUG(5,("spoolss_setprinterdata\n"));
4817 if (!OPEN_HANDLE(Printer)) {
4818 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4819 return ERROR_INVALID_HANDLE;
4822 if (!get_printer_snum(handle, &snum))
4823 return ERROR_INVALID_HANDLE;
4825 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4826 DEBUG(3, ("security descriptor change denied by existing "
4827 "security descriptor\n"));
4828 return ERROR_ACCESS_DENIED;
4831 status = get_a_printer(&printer, 2, lp_servicename(snum));
4833 return ERROR_INVALID_NAME;
4835 convert_specific_param(¶m, value , type, data, real_len);
4836 unlink_specific_param_if_exist(printer->info_2, param);
4838 if (!add_a_specific_param(printer->info_2, param))
4839 status = ERROR_INVALID_PARAMETER;
4841 status = add_a_printer(*printer, 2);
4843 free_a_printer(&printer, 2);
4847 /****************************************************************************
4848 ****************************************************************************/
4849 uint32 _spoolss_deleteprinterdata( POLICY_HND *handle, const UNISTR2 *value)
4851 NT_PRINTER_INFO_LEVEL *printer = NULL;
4852 NT_PRINTER_PARAM param;
4854 uint32 status = 0x0;
4855 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4857 DEBUG(5,("spoolss_deleteprinterdata\n"));
4859 if (!OPEN_HANDLE(Printer)) {
4860 DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4861 return ERROR_INVALID_HANDLE;
4864 if (!get_printer_snum(handle, &snum))
4865 return ERROR_INVALID_HANDLE;
4867 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4868 DEBUG(3, ("_spoolss_deleteprinterdata: security descriptor change denied by existing "
4869 "security descriptor\n"));
4870 return ERROR_ACCESS_DENIED;
4873 status = get_a_printer(&printer, 2, lp_servicename(snum));
4875 return ERROR_INVALID_NAME;
4877 ZERO_STRUCTP(¶m);
4878 unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
4880 if(!unlink_specific_param_if_exist(printer->info_2, ¶m))
4881 status = ERROR_INVALID_PARAMETER;
4883 status = add_a_printer(*printer, 2);
4885 free_a_printer(&printer, 2);
4889 /****************************************************************************
4890 ****************************************************************************/
4891 uint32 _spoolss_addform( POLICY_HND *handle,
4896 nt_forms_struct *list=NULL;
4897 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4899 DEBUG(5,("spoolss_addform\n"));
4901 if (!OPEN_HANDLE(Printer)) {
4902 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4903 return ERROR_INVALID_HANDLE;
4906 count=get_ntforms(&list);
4907 if(!add_a_form(&list, form, &count))
4908 return ERROR_NOT_ENOUGH_MEMORY;
4909 write_ntforms(&list, count);
4916 /****************************************************************************
4917 ****************************************************************************/
4918 uint32 _spoolss_deleteform( POLICY_HND *handle, UNISTR2 *form_name)
4922 nt_forms_struct *list=NULL;
4923 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4925 DEBUG(5,("spoolss_deleteform\n"));
4927 if (!OPEN_HANDLE(Printer)) {
4928 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4929 return ERROR_INVALID_HANDLE;
4932 count = get_ntforms(&list);
4933 if(!delete_a_form(&list, form_name, &count, &ret))
4934 return ERROR_INVALID_PARAMETER;
4941 /****************************************************************************
4942 ****************************************************************************/
4943 uint32 _spoolss_setform( POLICY_HND *handle,
4944 const UNISTR2 *uni_name,
4949 nt_forms_struct *list=NULL;
4950 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4952 DEBUG(5,("spoolss_setform\n"));
4954 if (!OPEN_HANDLE(Printer)) {
4955 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4956 return ERROR_INVALID_HANDLE;
4958 count=get_ntforms(&list);
4959 update_a_form(&list, form, count);
4960 write_ntforms(&list, count);
4967 /****************************************************************************
4968 enumprintprocessors level 1.
4969 ****************************************************************************/
4970 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4972 PRINTPROCESSOR_1 *info_1=NULL;
4974 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4975 return ERROR_NOT_ENOUGH_MEMORY;
4979 init_unistr(&info_1->name, "winprint");
4981 *needed += spoolss_size_printprocessor_info_1(info_1);
4983 if (!alloc_buffer_size(buffer, *needed))
4984 return ERROR_INSUFFICIENT_BUFFER;
4986 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4990 if (*needed > offered) {
4992 return ERROR_INSUFFICIENT_BUFFER;
4995 return NT_STATUS_NO_PROBLEMO;
4998 /****************************************************************************
4999 ****************************************************************************/
5000 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
5001 NEW_BUFFER *buffer, uint32 offered,
5002 uint32 *needed, uint32 *returned)
5004 DEBUG(5,("spoolss_enumprintprocessors\n"));
5007 * Enumerate the print processors ...
5009 * Just reply with "winprint", to keep NT happy
5010 * and I can use my nice printer checker.
5018 return enumprintprocessors_level_1(buffer, offered, needed, returned);
5021 return ERROR_INVALID_LEVEL;
5026 /****************************************************************************
5027 enumprintprocdatatypes level 1.
5028 ****************************************************************************/
5029 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5031 PRINTPROCDATATYPE_1 *info_1=NULL;
5033 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
5034 return ERROR_NOT_ENOUGH_MEMORY;
5038 init_unistr(&info_1->name, "RAW");
5040 *needed += spoolss_size_printprocdatatype_info_1(info_1);
5042 if (!alloc_buffer_size(buffer, *needed))
5043 return ERROR_INSUFFICIENT_BUFFER;
5045 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
5049 if (*needed > offered) {
5051 return ERROR_INSUFFICIENT_BUFFER;
5054 return NT_STATUS_NO_PROBLEMO;
5057 /****************************************************************************
5058 ****************************************************************************/
5059 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
5060 NEW_BUFFER *buffer, uint32 offered,
5061 uint32 *needed, uint32 *returned)
5063 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
5070 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
5073 return ERROR_INVALID_LEVEL;
5078 /****************************************************************************
5079 enumprintmonitors level 1.
5080 ****************************************************************************/
5081 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5083 PRINTMONITOR_1 *info_1=NULL;
5085 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
5086 return ERROR_NOT_ENOUGH_MEMORY;
5090 init_unistr(&info_1->name, "Local Port");
5092 *needed += spoolss_size_printmonitor_info_1(info_1);
5094 if (!alloc_buffer_size(buffer, *needed))
5095 return ERROR_INSUFFICIENT_BUFFER;
5097 smb_io_printmonitor_info_1("", buffer, info_1, 0);
5101 if (*needed > offered) {
5103 return ERROR_INSUFFICIENT_BUFFER;
5106 return NT_STATUS_NO_PROBLEMO;
5109 /****************************************************************************
5110 enumprintmonitors level 2.
5111 ****************************************************************************/
5112 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
5114 PRINTMONITOR_2 *info_2=NULL;
5116 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
5117 return ERROR_NOT_ENOUGH_MEMORY;
5121 init_unistr(&info_2->name, "Local Port");
5122 init_unistr(&info_2->environment, "Windows NT X86");
5123 init_unistr(&info_2->dll_name, "localmon.dll");
5125 *needed += spoolss_size_printmonitor_info_2(info_2);
5127 if (!alloc_buffer_size(buffer, *needed))
5128 return ERROR_INSUFFICIENT_BUFFER;
5130 smb_io_printmonitor_info_2("", buffer, info_2, 0);
5134 if (*needed > offered) {
5136 return ERROR_INSUFFICIENT_BUFFER;
5139 return NT_STATUS_NO_PROBLEMO;
5142 /****************************************************************************
5143 ****************************************************************************/
5144 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
5145 NEW_BUFFER *buffer, uint32 offered,
5146 uint32 *needed, uint32 *returned)
5148 DEBUG(5,("spoolss_enumprintmonitors\n"));
5151 * Enumerate the print monitors ...
5153 * Just reply with "Local Port", to keep NT happy
5154 * and I can use my nice printer checker.
5162 return enumprintmonitors_level_1(buffer, offered, needed, returned);
5165 return enumprintmonitors_level_2(buffer, offered, needed, returned);
5168 return ERROR_INVALID_LEVEL;
5173 /****************************************************************************
5174 ****************************************************************************/
5175 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
5179 JOB_INFO_1 *info_1=NULL;
5181 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
5183 if (info_1 == NULL) {
5185 return ERROR_NOT_ENOUGH_MEMORY;
5188 for (i=0; i<count && found==False; i++) {
5189 if (queue[i].job==(int)jobid)
5196 /* I shoud reply something else ... I can't find the good one */
5197 return NT_STATUS_NO_PROBLEMO;
5200 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
5204 *needed += spoolss_size_job_info_1(info_1);
5206 if (!alloc_buffer_size(buffer, *needed)) {
5208 return ERROR_INSUFFICIENT_BUFFER;
5211 new_smb_io_job_info_1("", buffer, info_1, 0);
5215 if (*needed > offered)
5216 return ERROR_INSUFFICIENT_BUFFER;
5218 return NT_STATUS_NO_PROBLEMO;
5222 /****************************************************************************
5223 ****************************************************************************/
5224 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
5229 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
5231 ZERO_STRUCTP(info_2);
5233 if (info_2 == NULL) {
5235 return ERROR_NOT_ENOUGH_MEMORY;
5238 for (i=0; i<count && found==False; i++) {
5239 if (queue[i].job==(int)jobid)
5246 /* I shoud reply something else ... I can't find the good one */
5247 return NT_STATUS_NO_PROBLEMO;
5250 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
5254 *needed += spoolss_size_job_info_2(info_2);
5256 if (!alloc_buffer_size(buffer, *needed)) {
5258 return ERROR_INSUFFICIENT_BUFFER;
5261 new_smb_io_job_info_2("", buffer, info_2, 0);
5263 free_dev_mode(info_2->devmode);
5266 if (*needed > offered)
5267 return ERROR_INSUFFICIENT_BUFFER;
5269 return NT_STATUS_NO_PROBLEMO;
5272 /****************************************************************************
5273 ****************************************************************************/
5274 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
5275 NEW_BUFFER *buffer, uint32 offered,
5280 print_queue_struct *queue=NULL;
5281 print_status_struct prt_status;
5283 DEBUG(5,("spoolss_getjob\n"));
5285 memset(&prt_status, 0, sizeof(prt_status));
5289 if (!get_printer_snum(handle, &snum))
5290 return ERROR_INVALID_HANDLE;
5292 count = print_queue_status(snum, &queue, &prt_status);
5294 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
5295 count, prt_status.status, prt_status.message));
5299 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
5302 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
5306 return ERROR_INVALID_LEVEL;