3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-2000,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
8 * Copyright (C) Jean François Micouleau 1998-2000.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern int DEBUGLEVEL;
29 extern pstring global_myname;
31 #ifndef MAX_OPEN_PRINTER_EXS
32 #define MAX_OPEN_PRINTER_EXS 50
35 #define PRINTER_HANDLE_IS_PRINTER 0
36 #define PRINTER_HANDLE_IS_PRINTSERVER 1
38 /* structure to store the printer handles */
39 /* and a reference to what it's pointing to */
40 /* and the notify info asked about */
41 /* that's the central struct */
42 typedef struct _Printer{
47 BOOL document_started;
49 int jobid; /* jobid in printing backend */
50 POLICY_HND printer_hnd;
54 fstring printerservername;
63 SPOOL_NOTIFY_OPTION *option;
71 typedef struct _counter_printer_0 {
79 static ubi_dlList Printer_list;
80 static ubi_dlList counter_list;
83 #define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False) && (IVAL(pnum->printer_hnd.data,16)==(uint32)sys_getpid()))
84 #define OUR_HANDLE(pnum) ((pnum==NULL)?"NULL":(IVAL(pnum->data,16)==sys_getpid()?"OURS":"OTHER"))
86 /* translate between internal status numbers and NT status numbers */
87 static int nt_printj_status(int v)
91 return PRINTER_STATUS_PAUSED;
100 static int nt_printq_status(int v)
104 return PRINTER_STATUS_ERROR;
113 /****************************************************************************
114 initialise printer handle states...
115 ****************************************************************************/
116 void init_printer_hnd(void)
118 ubi_dlInitList(&Printer_list);
119 ubi_dlInitList(&counter_list);
122 /****************************************************************************
123 create a unique printer handle
124 ****************************************************************************/
125 static void create_printer_hnd(POLICY_HND *hnd)
127 static uint32 prt_hnd_low = 0;
128 static uint32 prt_hnd_high = 0;
130 if (hnd == NULL) return;
132 /* i severely doubt that prt_hnd_high will ever be non-zero... */
134 if (prt_hnd_low == 0) prt_hnd_high++;
136 SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
137 SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
138 SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
139 SIVAL(hnd->data, 12, time(NULL)); /* something random */
140 SIVAL(hnd->data, 16, sys_getpid()); /* something more random */
143 /****************************************************************************
144 find printer index by handle
145 ****************************************************************************/
146 static Printer_entry *find_printer_index_by_hnd(const POLICY_HND *hnd)
148 Printer_entry *find_printer;
150 find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
152 for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) {
154 if (memcmp(&(find_printer->printer_hnd), hnd, sizeof(*hnd)) == 0) {
155 DEBUG(4,("Found printer handle \n"));
156 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
161 DEBUG(3,("Whoops, Printer handle not found: "));
162 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
166 /****************************************************************************
168 ****************************************************************************/
169 static void clear_handle(POLICY_HND *hnd)
174 /****************************************************************************
175 close printer index by handle
176 ****************************************************************************/
177 static BOOL close_printer_handle(POLICY_HND *hnd)
179 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
181 if (!OPEN_HANDLE(Printer)) {
182 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
187 Printer->notify.flags=0;
188 Printer->notify.options=0;
189 Printer->notify.localmachine[0]='\0';
190 Printer->notify.printerlocal=0;
191 safe_free(Printer->notify.option);
192 Printer->notify.option=NULL;
196 ubi_dlRemThis(&Printer_list, Printer);
203 /****************************************************************************
204 delete a printer given a handle
205 ****************************************************************************/
206 static BOOL delete_printer_handle(POLICY_HND *hnd)
208 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
210 if (!OPEN_HANDLE(Printer)) {
211 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
215 if (del_a_printer(Printer->dev.handlename) != 0) {
216 DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
223 /****************************************************************************
224 return the snum of a printer corresponding to an handle
225 ****************************************************************************/
226 static BOOL get_printer_snum(POLICY_HND *hnd, int *number)
228 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
230 if (!OPEN_HANDLE(Printer)) {
231 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
235 switch (Printer->printer_type) {
236 case PRINTER_HANDLE_IS_PRINTER:
237 DEBUG(4,("short name:%s\n", Printer->dev.handlename));
238 *number = print_queue_snum(Printer->dev.handlename);
239 return (*number != -1);
240 case PRINTER_HANDLE_IS_PRINTSERVER:
249 /****************************************************************************
250 set printer handle type.
251 ****************************************************************************/
252 static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required)
254 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
256 if (!OPEN_HANDLE(Printer)) {
257 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd)));
261 DEBUG(4,("Setting printer access=%x\n", access_required));
262 Printer->access = access_required;
266 /****************************************************************************
267 Set printer handle type.
268 Check if it's \\server or \\server\printer
269 ****************************************************************************/
271 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
273 DEBUG(3,("Setting printer type=%s\n", handlename));
275 if ( strlen(handlename) < 3 ) {
276 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
280 /* it's a print server */
281 if (!strchr(handlename+2, '\\')) {
282 DEBUGADD(4,("Printer is a print server\n"));
283 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
288 DEBUGADD(4,("Printer is a printer\n"));
289 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
296 /****************************************************************************
297 Set printer handle name.
298 ****************************************************************************/
300 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
302 NT_PRINTER_INFO_LEVEL *printer = NULL;
304 int n_services=lp_numservices();
308 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
310 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
311 ZERO_STRUCT(Printer->dev.printerservername);
312 strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
316 if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
319 aprinter=strchr(handlename+2, '\\');
322 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
325 * store the Samba share name in it
326 * in back we have the long printer name
327 * need to iterate all the snum and do a
328 * get_a_printer each time to find the printer
329 * faster to do it here than later.
332 for (snum=0;snum<n_services && found==False;snum++) {
334 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
337 DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
339 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
342 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
343 printer->info_2->printername, aprinter ));
345 if ( strlen(printer->info_2->printername) != strlen(aprinter) ) {
346 free_a_printer(&printer, 2);
350 if ( strncasecmp(printer->info_2->printername, aprinter, strlen(aprinter))) {
351 free_a_printer(&printer, 2);
359 * if we haven't found a printer with the given handlename
360 * then it can be a share name as you can open both \\server\printer and
365 * we still check if the printer description file exists as NT won't be happy
366 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
370 DEBUGADD(5,("Printer not found, checking for share now\n"));
372 for (snum=0;snum<n_services && found==False;snum++) {
374 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
377 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum)));
379 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
382 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
383 printer->info_2->printername, aprinter ));
385 if ( strlen(lp_servicename(snum)) != strlen(aprinter) ) {
386 free_a_printer(&printer, 2);
390 if ( strncasecmp(lp_servicename(snum), aprinter, strlen(aprinter))) {
391 free_a_printer(&printer, 2);
400 DEBUGADD(4,("Printer not found\n"));
405 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
406 printer->info_2->printername, lp_servicename(snum),snum));
408 ZERO_STRUCT(Printer->dev.handlename);
409 strncpy(Printer->dev.handlename, lp_servicename(snum), strlen(lp_servicename(snum)));
411 free_a_printer(&printer, 2);
416 /****************************************************************************
417 find first available printer slot. creates a printer handle for you.
418 ****************************************************************************/
420 static BOOL open_printer_hnd(POLICY_HND *hnd, char *name)
422 Printer_entry *new_printer;
425 create_printer_hnd(hnd);
427 if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
430 ZERO_STRUCTP(new_printer);
432 new_printer->open = True;
433 new_printer->notify.option=NULL;
435 memcpy(&new_printer->printer_hnd, hnd, sizeof(*hnd));
437 ubi_dlAddHead( &Printer_list, (ubi_dlNode *)new_printer);
439 if (!set_printer_hnd_printertype(new_printer, name)) {
440 close_printer_handle(hnd);
444 if (!set_printer_hnd_name(new_printer, name)) {
445 close_printer_handle(hnd);
452 /********************************************************************
453 Return True is the handle is a print server.
454 ********************************************************************/
455 static BOOL handle_is_printserver(const POLICY_HND *handle)
457 Printer_entry *Printer=find_printer_index_by_hnd(handle);
459 if (!OPEN_HANDLE(Printer))
462 if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
468 /****************************************************************************
469 allocate more memory for a BUFFER.
470 ****************************************************************************/
471 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
479 /* damn, I'm doing the reverse operation of prs_grow() :) */
480 if (buffer_size < prs_data_size(ps))
483 extra_space = buffer_size - prs_data_size(ps);
486 * save the offset and move to the end of the buffer
487 * prs_grow() checks the extra_space against the offset
489 old_offset=prs_offset(ps);
490 prs_set_offset(ps, prs_data_size(ps));
492 if (!prs_grow(ps, extra_space))
495 prs_set_offset(ps, old_offset);
498 buffer->string_at_end = buffer_size;
500 buffer->string_at_end=prs_data_size(ps);
506 /********************************************************************
507 * spoolss_open_printer
509 * called from the spoolss dispatcher
510 ********************************************************************/
511 uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
512 const PRINTER_DEFAULT *printer_default,
513 uint32 user_switch, SPOOL_USER_CTR user_ctr,
518 if (printername == NULL)
519 return ERROR_INVALID_PRINTER_NAME;
521 /* some sanity check because you can open a printer or a print server */
522 /* aka: \\server\printer or \\server */
523 unistr2_to_ascii(name, printername, sizeof(name)-1);
525 DEBUGADD(3,("checking name: %s\n",name));
527 if (!open_printer_hnd(handle, name))
528 return ERROR_INVALID_PRINTER_NAME;
531 if (printer_default->datatype_ptr != NULL)
533 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
534 set_printer_hnd_datatype(handle, datatype);
537 set_printer_hnd_datatype(handle, "");
540 if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
541 close_printer_handle(handle);
542 return ERROR_ACCESS_DENIED;
545 return NT_STATUS_NO_PROBLEMO;
548 /****************************************************************************
549 ****************************************************************************/
550 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
551 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
555 uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
564 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
565 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
569 printer->info_3=NULL;
570 uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3);
573 printer->info_6=NULL;
574 uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6);
583 static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devmode)
585 unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
586 unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
588 nt_devmode->specversion=devmode->specversion;
589 nt_devmode->driverversion=devmode->driverversion;
590 nt_devmode->size=devmode->size;
591 nt_devmode->driverextra=devmode->driverextra;
592 nt_devmode->fields=devmode->fields;
593 nt_devmode->orientation=devmode->orientation;
594 nt_devmode->papersize=devmode->papersize;
595 nt_devmode->paperlength=devmode->paperlength;
596 nt_devmode->paperwidth=devmode->paperwidth;
597 nt_devmode->scale=devmode->scale;
598 nt_devmode->copies=devmode->copies;
599 nt_devmode->defaultsource=devmode->defaultsource;
600 nt_devmode->printquality=devmode->printquality;
601 nt_devmode->color=devmode->color;
602 nt_devmode->duplex=devmode->duplex;
603 nt_devmode->yresolution=devmode->yresolution;
604 nt_devmode->ttoption=devmode->ttoption;
605 nt_devmode->collate=devmode->collate;
607 nt_devmode->logpixels=devmode->logpixels;
608 nt_devmode->bitsperpel=devmode->bitsperpel;
609 nt_devmode->pelswidth=devmode->pelswidth;
610 nt_devmode->pelsheight=devmode->pelsheight;
611 nt_devmode->displayflags=devmode->displayflags;
612 nt_devmode->displayfrequency=devmode->displayfrequency;
613 nt_devmode->icmmethod=devmode->icmmethod;
614 nt_devmode->icmintent=devmode->icmintent;
615 nt_devmode->mediatype=devmode->mediatype;
616 nt_devmode->dithertype=devmode->dithertype;
617 nt_devmode->reserved1=devmode->reserved1;
618 nt_devmode->reserved2=devmode->reserved2;
619 nt_devmode->panningwidth=devmode->panningwidth;
620 nt_devmode->panningheight=devmode->panningheight;
622 if (nt_devmode->driverextra != 0) {
623 /* if we had a previous private delete it and make a new one */
624 safe_free(nt_devmode->private);
625 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
627 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
633 /********************************************************************
634 * api_spoolss_closeprinter
635 ********************************************************************/
636 uint32 _spoolss_closeprinter(POLICY_HND *handle)
638 if (!close_printer_handle(handle))
639 return ERROR_INVALID_HANDLE;
641 return NT_STATUS_NO_PROBLEMO;
644 /********************************************************************
645 * api_spoolss_deleteprinter
646 ********************************************************************/
647 uint32 _spoolss_deleteprinter(POLICY_HND *handle)
649 if (!delete_printer_handle(handle))
650 return ERROR_INVALID_HANDLE;
652 return NT_STATUS_NO_PROBLEMO;
655 /********************************************************************
656 GetPrinterData on a printer server Handle.
657 ********************************************************************/
658 static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
662 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
664 if (!strcmp(value, "BeepEnabled")) {
666 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
668 SIVAL(*data, 0, 0x01);
673 if (!strcmp(value, "EventLog")) {
675 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
677 SIVAL(*data, 0, 0x1B);
682 if (!strcmp(value, "NetPopup")) {
684 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
686 SIVAL(*data, 0, 0x01);
691 if (!strcmp(value, "MajorVersion")) {
693 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
695 SIVAL(*data, 0, 0x02);
700 if (!strcmp(value, "DefaultSpoolDirectory")) {
701 pstring string="You are using a Samba server";
703 *needed = 2*(strlen(string)+1);
704 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
706 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
708 /* it's done by hand ready to go on the wire */
709 for (i=0; i<strlen(string); i++) {
710 (*data)[2*i]=string[i];
716 if (!strcmp(value, "Architecture")) {
717 pstring string="Windows NT x86";
719 *needed = 2*(strlen(string)+1);
720 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
722 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
723 for (i=0; i<strlen(string); i++) {
724 (*data)[2*i]=string[i];
733 /********************************************************************
734 GetPrinterData on a printer Handle.
735 ********************************************************************/
736 static BOOL getprinterdata_printer(POLICY_HND *handle,
737 fstring value, uint32 *type,
738 uint8 **data, uint32 *needed, uint32 in_size )
740 NT_PRINTER_INFO_LEVEL *printer = NULL;
744 Printer_entry *Printer = find_printer_index_by_hnd(handle);
746 DEBUG(5,("getprinterdata_printer\n"));
748 if (!OPEN_HANDLE(Printer)) {
749 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
753 if(!get_printer_snum(handle, &snum))
756 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
759 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
760 free_a_printer(&printer, 2);
764 free_a_printer(&printer, 2);
766 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
769 if((*data = (uint8 *)malloc( in_size *sizeof(uint8) )) == NULL) {
773 memset(*data, 0, in_size *sizeof(uint8));
774 /* copy the min(in_size, len) */
775 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
782 DEBUG(5,("getprinterdata_printer:copy done\n"));
789 /********************************************************************
790 * spoolss_getprinterdata
791 ********************************************************************/
792 uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
801 Printer_entry *Printer = find_printer_index_by_hnd(handle);
804 * Reminder: when it's a string, the length is in BYTES
805 * even if UNICODE is negociated.
812 /* in case of problem, return some default values */
816 DEBUG(4,("_spoolss_getprinterdata\n"));
818 if (!OPEN_HANDLE(Printer)) {
819 if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
820 return ERROR_NOT_ENOUGH_MEMORY;
821 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
822 return ERROR_INVALID_HANDLE;
825 unistr2_to_ascii(value, valuename, sizeof(value)-1);
827 if (handle_is_printserver(handle))
828 found=getprinterdata_printer_server(value, type, data, needed, *out_size);
830 found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
833 DEBUG(5, ("value not found, allocating %d\n", *out_size));
834 /* reply this param doesn't exist */
836 if((*data=(uint8 *)malloc(*out_size*sizeof(uint8))) == NULL)
837 return ERROR_NOT_ENOUGH_MEMORY;
838 memset(*data, '\0', *out_size*sizeof(uint8));
843 return ERROR_INVALID_PARAMETER;
846 if (*needed > *out_size)
847 return ERROR_INSUFFICIENT_BUFFER;
849 return NT_STATUS_NO_PROBLEMO;
852 /********************************************************************
854 * ReplyFindFirstPrinterChangeNotifyEx
856 * jfmxxxx: before replying OK: status=0
857 * should do a rpc call to the workstation asking ReplyOpenPrinter
858 * have to code it, later.
860 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
861 * called from api_spoolss_rffpcnex
862 ********************************************************************/
863 uint32 _spoolss_rffpcnex(POLICY_HND *handle, uint32 flags, uint32 options,
864 const UNISTR2 *localmachine, uint32 printerlocal,
865 SPOOL_NOTIFY_OPTION *option)
867 /* store the notify value in the printer struct */
869 Printer_entry *Printer=find_printer_index_by_hnd(handle);
871 if (!OPEN_HANDLE(Printer)) {
872 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
873 return ERROR_INVALID_HANDLE;
876 Printer->notify.flags=flags;
877 Printer->notify.options=options;
878 Printer->notify.printerlocal=printerlocal;
879 Printer->notify.option=option;
880 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
882 return NT_STATUS_NO_PROBLEMO;
885 /*******************************************************************
886 * fill a notify_info_data with the servername
887 ********************************************************************/
888 static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
889 NT_PRINTER_INFO_LEVEL *printer)
893 snprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
895 data->notify_data.data.length= (uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
896 temp_name, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
899 /*******************************************************************
900 * fill a notify_info_data with the servicename
901 * jfmxxxx: it's incorrect should be long_printername
902 ********************************************************************/
903 static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
904 NT_PRINTER_INFO_LEVEL *printer)
907 data->notify_data.data.length=strlen(lp_servicename(snum));
908 dos_PutUniCode(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string), True);
910 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
911 printer->info_2->printername, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
914 /*******************************************************************
915 * fill a notify_info_data with the servicename
916 ********************************************************************/
917 static void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
919 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
920 lp_servicename(snum), sizeof(data->notify_data.data.string),True) - sizeof(uint16))/sizeof(uint16));
923 /*******************************************************************
924 * fill a notify_info_data with the port name
925 ********************************************************************/
926 static void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
928 /* even if it's strange, that's consistant in all the code */
930 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
931 lp_servicename(snum), sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
934 /*******************************************************************
935 * fill a notify_info_data with the printername
936 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
937 * but it doesn't exist, have to see what to do
938 ********************************************************************/
939 static void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
941 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
942 printer->info_2->drivername, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
945 /*******************************************************************
946 * fill a notify_info_data with the comment
947 ********************************************************************/
948 static void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
950 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
951 lp_comment(snum), sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
954 /*******************************************************************
955 * fill a notify_info_data with the comment
956 * jfm:xxxx incorrect, have to create a new smb.conf option
957 * location = "Room 1, floor 2, building 3"
958 ********************************************************************/
959 static void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
961 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
962 printer->info_2->location, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
965 /*******************************************************************
966 * fill a notify_info_data with the device mode
967 * jfm:xxxx don't to it for know but that's a real problem !!!
968 ********************************************************************/
969 static void spoolss_notify_devmode(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
973 /*******************************************************************
974 * fill a notify_info_data with the separator file name
975 * jfm:xxxx just return no file could add an option to smb.conf
976 * separator file = "separator.txt"
977 ********************************************************************/
978 static void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
980 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
981 printer->info_2->sepfile, sizeof(data->notify_data.data.string)-1,True) - sizeof(uint16))/sizeof(uint16));
984 /*******************************************************************
985 * fill a notify_info_data with the print processor
986 * jfm:xxxx return always winprint to indicate we don't do anything to it
987 ********************************************************************/
988 static void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
990 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
991 printer->info_2->printprocessor, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
994 /*******************************************************************
995 * fill a notify_info_data with the print processor options
996 * jfm:xxxx send an empty string
997 ********************************************************************/
998 static void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1000 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1001 printer->info_2->parameters, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1004 /*******************************************************************
1005 * fill a notify_info_data with the data type
1006 * jfm:xxxx always send RAW as data type
1007 ********************************************************************/
1008 static void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1010 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1011 printer->info_2->datatype, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1014 /*******************************************************************
1015 * fill a notify_info_data with the security descriptor
1016 * jfm:xxxx send an null pointer to say no security desc
1017 * have to implement security before !
1018 ********************************************************************/
1019 static void spoolss_notify_security_desc(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1021 data->notify_data.data.length=0;
1022 data->notify_data.data.string[0]=0x00;
1025 /*******************************************************************
1026 * fill a notify_info_data with the attributes
1027 * jfm:xxxx a samba printer is always shared
1028 ********************************************************************/
1029 static void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1031 data->notify_data.value[0] = PRINTER_ATTRIBUTE_SHARED \
1032 | PRINTER_ATTRIBUTE_LOCAL \
1033 | PRINTER_ATTRIBUTE_RAW_ONLY ;
1036 /*******************************************************************
1037 * fill a notify_info_data with the priority
1038 ********************************************************************/
1039 static void spoolss_notify_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1041 data->notify_data.value[0] = printer->info_2->priority;
1044 /*******************************************************************
1045 * fill a notify_info_data with the default priority
1046 ********************************************************************/
1047 static void spoolss_notify_default_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1049 data->notify_data.value[0] = printer->info_2->default_priority;
1052 /*******************************************************************
1053 * fill a notify_info_data with the start time
1054 ********************************************************************/
1055 static void spoolss_notify_start_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1057 data->notify_data.value[0] = printer->info_2->starttime;
1060 /*******************************************************************
1061 * fill a notify_info_data with the until time
1062 ********************************************************************/
1063 static void spoolss_notify_until_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1065 data->notify_data.value[0] = printer->info_2->untiltime;
1068 /*******************************************************************
1069 * fill a notify_info_data with the status
1070 ********************************************************************/
1071 static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1074 print_queue_struct *q=NULL;
1075 print_status_struct status;
1077 memset(&status, 0, sizeof(status));
1078 count = print_queue_status(snum, &q, &status);
1079 data->notify_data.value[0]=(uint32) status.status;
1083 /*******************************************************************
1084 * fill a notify_info_data with the number of jobs queued
1085 ********************************************************************/
1086 static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1088 print_queue_struct *q=NULL;
1089 print_status_struct status;
1091 memset(&status, 0, sizeof(status));
1092 data->notify_data.value[0] = print_queue_status(snum, &q, &status);
1096 /*******************************************************************
1097 * fill a notify_info_data with the average ppm
1098 ********************************************************************/
1099 static void spoolss_notify_average_ppm(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1101 /* always respond 8 pages per minutes */
1102 /* a little hard ! */
1103 data->notify_data.value[0] = printer->info_2->averageppm;
1106 /*******************************************************************
1107 * fill a notify_info_data with
1108 ********************************************************************/
1109 static void spoolss_notify_username(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1111 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1112 queue->user, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1115 /*******************************************************************
1116 * fill a notify_info_data with
1117 ********************************************************************/
1118 static void spoolss_notify_job_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1120 data->notify_data.value[0]=nt_printj_status(queue->status);
1123 /*******************************************************************
1124 * fill a notify_info_data with
1125 ********************************************************************/
1126 static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1128 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1129 queue->file, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1132 /*******************************************************************
1133 * fill a notify_info_data with
1134 ********************************************************************/
1135 static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1137 char *p = "unknown";
1138 switch (queue->status) {
1152 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1153 p, 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_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1161 data->notify_data.value[0]=0x0;
1164 /*******************************************************************
1165 * fill a notify_info_data with
1166 ********************************************************************/
1167 static void spoolss_notify_job_size(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1169 data->notify_data.value[0]=queue->size;
1172 /*******************************************************************
1173 * fill a notify_info_data with
1174 ********************************************************************/
1175 static void spoolss_notify_job_position(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1177 data->notify_data.value[0]=queue->job;
1182 struct s_notify_info_data_table
1188 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
1189 print_queue_struct *queue,
1190 NT_PRINTER_INFO_LEVEL *printer);
1193 struct s_notify_info_data_table notify_info_data_table[] =
1195 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
1196 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1197 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
1198 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1199 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1200 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
1201 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
1202 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1203 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
1204 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1205 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1206 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1207 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
1208 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
1209 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1210 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
1211 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1212 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1213 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
1214 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
1215 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
1216 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
1217 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
1218 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
1219 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
1220 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
1221 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1222 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
1223 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1224 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
1225 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
1226 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1227 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1228 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1229 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1230 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1231 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
1232 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
1233 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
1234 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
1235 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1236 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
1237 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, NULL },
1238 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1239 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1240 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
1241 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
1242 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
1243 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
1244 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
1245 { END, END, "", END, NULL }
1248 /*******************************************************************
1249 return the size of info_data structure
1250 ********************************************************************/
1251 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
1255 while (notify_info_data_table[i].type != END)
1257 if ( (notify_info_data_table[i].type == type ) &&
1258 (notify_info_data_table[i].field == field ) )
1260 return (notify_info_data_table[i].size);
1268 /*******************************************************************
1269 return the type of notify_info_data
1270 ********************************************************************/
1271 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
1275 while (notify_info_data_table[i].type != END)
1277 if ( (notify_info_data_table[i].type == type ) &&
1278 (notify_info_data_table[i].field == field ) )
1280 if (notify_info_data_table[i].size == POINTER)
1295 /****************************************************************************
1296 ****************************************************************************/
1297 static int search_notify(uint16 type, uint16 field, int *value)
1302 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1304 if ( (notify_info_data_table[j].type == type ) &&
1305 (notify_info_data_table[j].field == field ) )
1310 if ( found && (notify_info_data_table[j].fn != NULL) )
1316 /****************************************************************************
1317 ****************************************************************************/
1318 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1320 info_data->type = type;
1321 info_data->field = field;
1322 info_data->reserved = 0;
1324 info_data->size = size_of_notify_info_data(type, field);
1325 info_data->enc_type = type_of_notify_info_data(type, field);
1329 /*******************************************************************
1331 * fill a notify_info struct with info asked
1333 ********************************************************************/
1334 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1340 SPOOL_NOTIFY_INFO_DATA *current_data;
1341 NT_PRINTER_INFO_LEVEL *printer = NULL;
1342 print_queue_struct *queue=NULL;
1344 DEBUG(4,("construct_notify_printer_info\n"));
1346 type=option_type->type;
1348 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
1349 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1350 option_type->count, lp_servicename(snum)));
1352 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1355 for(field_num=0; field_num<option_type->count; field_num++) {
1356 field = option_type->fields[field_num];
1357 DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field));
1359 if (!search_notify(type, field, &j) )
1362 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1365 current_data=&info->data[info->count];
1367 construct_info_data(current_data, type, field, id);
1368 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1373 free_a_printer(&printer, 2);
1377 /*******************************************************************
1379 * fill a notify_info struct with info asked
1381 ********************************************************************/
1382 static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1388 SPOOL_NOTIFY_INFO_DATA *current_data;
1389 NT_PRINTER_INFO_LEVEL *printer = NULL;
1391 DEBUG(4,("construct_notify_jobs_info\n"));
1393 type = option_type->type;
1395 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
1396 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1397 option_type->count));
1399 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1402 for(field_num=0; field_num<option_type->count; field_num++) {
1403 field = option_type->fields[field_num];
1405 if (!search_notify(type, field, &j) )
1408 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1412 current_data=&(info->data[info->count]);
1414 construct_info_data(current_data, type, field, id);
1415 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1419 free_a_printer(&printer, 2);
1424 * JFM: The enumeration is not that simple, it's even non obvious.
1426 * let's take an example: I want to monitor the PRINTER SERVER for
1427 * the printer's name and the number of jobs currently queued.
1428 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
1429 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
1431 * I have 3 printers on the back of my server.
1433 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
1436 * 1 printer 1 name 1
1437 * 2 printer 1 cjob 1
1438 * 3 printer 2 name 2
1439 * 4 printer 2 cjob 2
1440 * 5 printer 3 name 3
1441 * 6 printer 3 name 3
1443 * that's the print server case, the printer case is even worse.
1448 /*******************************************************************
1450 * enumerate all printers on the printserver
1451 * fill a notify_info struct with info asked
1453 ********************************************************************/
1454 static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1457 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1458 int n_services=lp_numservices();
1461 SPOOL_NOTIFY_OPTION *option;
1462 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1464 DEBUG(4,("printserver_notify_info\n"));
1466 option=Printer->notify.option;
1472 for (i=0; i<option->count; i++) {
1473 option_type=&(option->ctr.type[i]);
1475 if (option_type->type!=PRINTER_NOTIFY_TYPE)
1478 for (snum=0; snum<n_services; snum++)
1479 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1480 if (construct_notify_printer_info(info, snum, option_type, id))
1485 * Debugging information, don't delete.
1488 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1489 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1490 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1492 for (i=0; i<info->count; i++) {
1493 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1494 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1495 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1499 return NT_STATUS_NO_PROBLEMO;
1502 /*******************************************************************
1504 * fill a notify_info struct with info asked
1506 ********************************************************************/
1507 static uint32 printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1510 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1513 SPOOL_NOTIFY_OPTION *option;
1514 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1516 print_queue_struct *queue=NULL;
1517 print_status_struct status;
1519 DEBUG(4,("printer_notify_info\n"));
1521 option=Printer->notify.option;
1527 get_printer_snum(hnd, &snum);
1529 for (i=0; i<option->count; i++) {
1530 option_type=&option->ctr.type[i];
1532 switch ( option_type->type ) {
1533 case PRINTER_NOTIFY_TYPE:
1534 if(construct_notify_printer_info(info, snum, option_type, id))
1538 case JOB_NOTIFY_TYPE:
1539 memset(&status, 0, sizeof(status));
1540 count = print_queue_status(snum, &queue, &status);
1541 for (j=0; j<count; j++)
1542 construct_notify_jobs_info(&queue[j], info, snum, option_type, queue[j].job);
1549 * Debugging information, don't delete.
1552 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1553 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1554 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1556 for (i=0; i<info->count; i++) {
1557 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1558 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1559 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1562 return NT_STATUS_NO_PROBLEMO;
1565 /********************************************************************
1567 ********************************************************************/
1568 uint32 _spoolss_rfnpcnex( POLICY_HND *handle, uint32 change,
1569 SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info)
1571 Printer_entry *Printer=find_printer_index_by_hnd(handle);
1573 if (!OPEN_HANDLE(Printer)) {
1574 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",OUR_HANDLE(handle)));
1575 return ERROR_INVALID_HANDLE;
1578 DEBUG(4,("Printer type %x\n",Printer->printer_type));
1580 /* jfm: the change value isn't used right now.
1581 * we will honour it when
1582 * a) we'll be able to send notification to the client
1583 * b) we'll have a way to communicate between the spoolss process.
1585 * same thing for option->flags
1586 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
1587 * I don't have a global notification system, I'm sending back all the
1588 * informations even when _NOTHING_ has changed.
1591 /* just discard the SPOOL_NOTIFY_OPTION */
1593 safe_free(option->ctr.type);
1595 switch (Printer->printer_type) {
1596 case PRINTER_HANDLE_IS_PRINTSERVER:
1597 return printserver_notify_info(handle, info);
1599 case PRINTER_HANDLE_IS_PRINTER:
1600 return printer_notify_info(handle, info);
1604 return ERROR_INVALID_HANDLE;
1607 /********************************************************************
1608 * construct_printer_info_0
1609 * fill a printer_info_1 struct
1610 ********************************************************************/
1611 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring servername)
1615 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1616 counter_printer_0 *session_counter;
1617 uint32 global_counter;
1619 time_t setup_time = time(NULL);
1621 print_queue_struct *queue=NULL;
1622 print_status_struct status;
1624 memset(&status, 0, sizeof(status));
1626 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1629 count = print_queue_status(snum, &queue, &status);
1631 /* check if we already have a counter for this printer */
1632 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
1634 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
1635 if (session_counter->snum == snum)
1639 /* it's the first time, add it to the list */
1640 if (session_counter==NULL) {
1641 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
1642 free_a_printer(&ntprinter, 2);
1645 ZERO_STRUCTP(session_counter);
1646 session_counter->snum=snum;
1647 session_counter->counter=0;
1648 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
1652 session_counter->counter++;
1655 * the global_counter should be stored in a TDB as it's common to all the clients
1656 * and should be zeroed on samba startup
1658 global_counter=session_counter->counter;
1660 /* the description and the name are of the form \\server\share */
1661 slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter->info_2->printername);
1663 init_unistr(&printer->printername, chaine);
1665 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1666 init_unistr(&printer->servername, chaine);
1668 printer->cjobs = count;
1669 printer->total_jobs = 0;
1670 printer->total_bytes = 0;
1672 t=gmtime(&setup_time);
1673 ntprinter->info_2->setuptime = (uint32)setup_time; /* FIXME !! */
1675 printer->year = t->tm_year+1900;
1676 printer->month = t->tm_mon+1;
1677 printer->dayofweek = t->tm_wday;
1678 printer->day = t->tm_mday;
1679 printer->hour = t->tm_hour;
1680 printer->minute = t->tm_min;
1681 printer->second = t->tm_sec;
1682 printer->milliseconds = 0;
1684 printer->global_counter = global_counter;
1685 printer->total_pages = 0;
1686 printer->major_version = 0x0004; /* NT 4 */
1687 printer->build_version = 0x0565; /* build 1381 */
1688 printer->unknown7 = 0x1;
1689 printer->unknown8 = 0x0;
1690 printer->unknown9 = 0x0;
1691 printer->session_counter = session_counter->counter;
1692 printer->unknown11 = 0x0;
1693 printer->printer_errors = 0x0; /* number of print failure */
1694 printer->unknown13 = 0x0;
1695 printer->unknown14 = 0x1;
1696 printer->unknown15 = 0x024a; /* 586 Pentium ? */
1697 printer->unknown16 = 0x0;
1698 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
1699 printer->unknown18 = 0x0;
1700 printer->status = nt_printq_status(status.status);
1701 printer->unknown20 = 0x0;
1702 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
1703 printer->unknown22 = 0x0;
1704 printer->unknown23 = 0x6; /* 6 ???*/
1705 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
1706 printer->unknown25 = 0;
1707 printer->unknown26 = 0;
1708 printer->unknown27 = 0;
1709 printer->unknown28 = 0;
1710 printer->unknown29 = 0;
1713 free_a_printer(&ntprinter,2);
1717 /********************************************************************
1718 * construct_printer_info_1
1719 * fill a printer_info_1 struct
1720 ********************************************************************/
1721 static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum)
1725 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1727 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1730 printer->flags=flags;
1732 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1733 ntprinter->info_2->drivername, lp_comment(snum));
1735 snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter->info_2->printername);
1737 init_unistr(&printer->description, chaine);
1738 init_unistr(&printer->name, chaine2);
1739 init_unistr(&printer->comment, lp_comment(snum));
1741 free_a_printer(&ntprinter,2);
1746 /****************************************************************************
1747 Free a DEVMODE struct.
1748 ****************************************************************************/
1750 static void free_dev_mode(DEVICEMODE *dev)
1756 safe_free(dev->private);
1761 /****************************************************************************
1762 Create a DEVMODE struct. Returns malloced memory.
1763 ****************************************************************************/
1765 static DEVICEMODE *construct_dev_mode(int snum, char *servername)
1769 NT_PRINTER_INFO_LEVEL *printer = NULL;
1770 NT_DEVICEMODE *ntdevmode = NULL;
1771 DEVICEMODE *devmode = NULL;
1773 DEBUG(7,("construct_dev_mode\n"));
1775 DEBUGADD(8,("getting printer characteristics\n"));
1777 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
1778 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
1782 ZERO_STRUCTP(devmode);
1784 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
1787 if (printer->info_2->devmode)
1788 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
1791 ntdevmode = construct_nt_devicemode(printer->info_2->printername);
1793 if (ntdevmode == NULL)
1796 DEBUGADD(8,("loading DEVICEMODE\n"));
1798 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, printer->info_2->printername);
1799 init_unistr(&devmode->devicename, adevice);
1801 snprintf(aform, sizeof(aform), ntdevmode->formname);
1802 init_unistr(&devmode->formname, aform);
1804 devmode->specversion = ntdevmode->specversion;
1805 devmode->driverversion = ntdevmode->driverversion;
1806 devmode->size = ntdevmode->size;
1807 devmode->driverextra = ntdevmode->driverextra;
1808 devmode->fields = ntdevmode->fields;
1810 devmode->orientation = ntdevmode->orientation;
1811 devmode->papersize = ntdevmode->papersize;
1812 devmode->paperlength = ntdevmode->paperlength;
1813 devmode->paperwidth = ntdevmode->paperwidth;
1814 devmode->scale = ntdevmode->scale;
1815 devmode->copies = ntdevmode->copies;
1816 devmode->defaultsource = ntdevmode->defaultsource;
1817 devmode->printquality = ntdevmode->printquality;
1818 devmode->color = ntdevmode->color;
1819 devmode->duplex = ntdevmode->duplex;
1820 devmode->yresolution = ntdevmode->yresolution;
1821 devmode->ttoption = ntdevmode->ttoption;
1822 devmode->collate = ntdevmode->collate;
1823 devmode->icmmethod = ntdevmode->icmmethod;
1824 devmode->icmintent = ntdevmode->icmintent;
1825 devmode->mediatype = ntdevmode->mediatype;
1826 devmode->dithertype = ntdevmode->dithertype;
1828 if (ntdevmode->private != NULL) {
1829 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
1833 free_nt_devicemode(&ntdevmode);
1834 free_a_printer(&printer,2);
1841 free_nt_devicemode(&ntdevmode);
1843 free_a_printer(&printer,2);
1844 free_dev_mode(devmode);
1849 /********************************************************************
1850 * construct_printer_info_2
1851 * fill a printer_info_2 struct
1852 ********************************************************************/
1854 static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer, int snum)
1860 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1862 print_queue_struct *queue=NULL;
1863 print_status_struct status;
1864 memset(&status, 0, sizeof(status));
1866 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1869 memset(&status, 0, sizeof(status));
1870 count = print_queue_status(snum, &queue, &status);
1872 snprintf(chaine, sizeof(chaine)-1, "%s", servername);
1874 if (strlen(servername)!=0)
1879 snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter->info_2->printername);
1881 init_unistr(&printer->servername, chaine); /* servername*/
1882 init_unistr(&printer->printername, chaine2); /* printername*/
1883 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
1885 /* We need to determine the correct model for this..... */
1886 init_unistr(&printer->portname, lp_printername(snum)); /* port */
1888 init_unistr(&printer->portname, lp_servicename(snum)); /* port */
1890 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
1892 if (*ntprinter->info_2->comment == '\0')
1893 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
1895 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1897 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
1898 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
1899 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
1900 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
1901 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
1903 printer->attributes = ntprinter->info_2->attributes;
1905 printer->priority = ntprinter->info_2->priority; /* priority */
1906 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
1907 printer->starttime = ntprinter->info_2->starttime; /* starttime */
1908 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
1909 printer->status = nt_printq_status(status.status); /* status */
1910 printer->cjobs = count; /* jobs */
1911 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
1913 if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) {
1914 DEBUG(8, ("Returning NULL Devicemode!\n"));
1920 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1921 /* steal the printer info sec_desc structure. [badly done]. */
1922 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1923 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
1924 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
1925 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
1928 printer->secdesc = NULL;
1931 free_a_printer(&ntprinter, 2);
1938 free_a_printer(&ntprinter, 2);
1943 /********************************************************************
1944 * construct_printer_info_3
1945 * fill a printer_info_3 struct
1946 ********************************************************************/
1947 static BOOL construct_printer_info_3(fstring servername,
1948 PRINTER_INFO_3 **pp_printer, int snum)
1950 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1951 PRINTER_INFO_3 *printer = NULL;
1953 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1957 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
1958 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
1962 ZERO_STRUCTP(printer);
1964 printer->flags = 4; /* This is the offset to the SEC_DESC. */
1965 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1966 /* steal the printer info sec_desc structure. [badly done]. */
1967 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1968 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
1969 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
1970 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
1973 free_a_printer(&ntprinter, 2);
1975 *pp_printer = printer;
1979 /********************************************************************
1980 Spoolss_enumprinters.
1981 ********************************************************************/
1982 static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
1986 int n_services=lp_numservices();
1987 PRINTER_INFO_1 *printers=NULL;
1988 PRINTER_INFO_1 current_prt;
1990 DEBUG(4,("enum_all_printers_info_1\n"));
1992 for (snum=0; snum<n_services; snum++) {
1993 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
1994 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
1996 if (construct_printer_info_1(server, flags, ¤t_prt, snum)) {
1997 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
1999 return ERROR_NOT_ENOUGH_MEMORY;
2001 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2002 memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1));
2008 /* check the required size. */
2009 for (i=0; i<*returned; i++)
2010 (*needed) += spoolss_size_printer_info_1(&(printers[i]));
2012 if (!alloc_buffer_size(buffer, *needed))
2013 return ERROR_INSUFFICIENT_BUFFER;
2015 /* fill the buffer with the structures */
2016 for (i=0; i<*returned; i++)
2017 new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);
2020 safe_free(printers);
2022 if (*needed > offered) {
2024 return ERROR_INSUFFICIENT_BUFFER;
2027 return NT_STATUS_NO_PROBLEMO;
2030 /********************************************************************
2031 enum_all_printers_info_1_local.
2032 *********************************************************************/
2033 static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2036 DEBUG(4,("enum_all_printers_info_1_local\n"));
2038 fstrcpy(temp, "\\\\");
2039 fstrcat(temp, global_myname);
2041 if (!strcmp(name, temp)) {
2042 fstrcat(temp, "\\");
2043 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2046 return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2049 /********************************************************************
2050 enum_all_printers_info_1_name.
2051 *********************************************************************/
2052 static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2055 DEBUG(4,("enum_all_printers_info_1_name\n"));
2057 fstrcpy(temp, "\\\\");
2058 fstrcat(temp, global_myname);
2060 if (!strcmp(name, temp)) {
2061 fstrcat(temp, "\\");
2062 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2065 return ERROR_INVALID_NAME;
2068 /********************************************************************
2069 enum_all_printers_info_1_remote.
2070 *********************************************************************/
2071 static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2073 PRINTER_INFO_1 *printer;
2074 fstring printername;
2077 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2079 /* JFM: currently it's more a place holder than anything else.
2080 * In the spooler world there is a notion of server registration.
2081 * the print servers are registring (sp ?) on the PDC (in the same domain)
2083 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2086 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2087 return ERROR_NOT_ENOUGH_MEMORY;
2091 snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
2092 snprintf(desc, sizeof(desc)-1,"%s", global_myname);
2093 snprintf(comment, sizeof(comment)-1, "Logged on Domain");
2095 init_unistr(&printer->description, desc);
2096 init_unistr(&printer->name, printername);
2097 init_unistr(&printer->comment, comment);
2098 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2100 /* check the required size. */
2101 *needed += spoolss_size_printer_info_1(printer);
2103 if (!alloc_buffer_size(buffer, *needed)) {
2105 return ERROR_INSUFFICIENT_BUFFER;
2108 /* fill the buffer with the structures */
2109 new_smb_io_printer_info_1("", buffer, printer, 0);
2114 if (*needed > offered) {
2116 return ERROR_INSUFFICIENT_BUFFER;
2119 return NT_STATUS_NO_PROBLEMO;
2122 /********************************************************************
2123 enum_all_printers_info_1_network.
2124 *********************************************************************/
2125 static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2128 DEBUG(4,("enum_all_printers_info_1_network\n"));
2130 fstrcpy(temp, "\\\\");
2131 fstrcat(temp, global_myname);
2132 fstrcat(temp, "\\");
2133 return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
2136 /********************************************************************
2137 * api_spoolss_enumprinters
2139 * called from api_spoolss_enumprinters (see this to understand)
2140 ********************************************************************/
2141 static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2145 int n_services=lp_numservices();
2146 PRINTER_INFO_2 *printers=NULL;
2147 PRINTER_INFO_2 current_prt;
2149 for (snum=0; snum<n_services; snum++) {
2150 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2151 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2153 if (construct_printer_info_2(servername, ¤t_prt, snum)) {
2154 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL)
2155 return ERROR_NOT_ENOUGH_MEMORY;
2156 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
2157 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
2163 /* check the required size. */
2164 for (i=0; i<*returned; i++)
2165 (*needed) += spoolss_size_printer_info_2(&printers[i]);
2167 if (!alloc_buffer_size(buffer, *needed)) {
2168 for (i=0; i<*returned; i++) {
2169 free_devmode(printers[i].devmode);
2170 free_sec_desc(&printers[i].secdesc);
2172 safe_free(printers);
2173 return ERROR_INSUFFICIENT_BUFFER;
2176 /* fill the buffer with the structures */
2177 for (i=0; i<*returned; i++)
2178 new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);
2181 for (i=0; i<*returned; i++) {
2182 free_devmode(printers[i].devmode);
2183 free_sec_desc(&printers[i].secdesc);
2185 safe_free(printers);
2187 if (*needed > offered) {
2189 return ERROR_INSUFFICIENT_BUFFER;
2192 return NT_STATUS_NO_PROBLEMO;
2195 /********************************************************************
2196 * handle enumeration of printers at level 1
2197 ********************************************************************/
2198 static uint32 enumprinters_level1( uint32 flags, fstring name,
2199 NEW_BUFFER *buffer, uint32 offered,
2200 uint32 *needed, uint32 *returned)
2202 /* Not all the flags are equals */
2204 if (flags & PRINTER_ENUM_LOCAL)
2205 return enum_all_printers_info_1_local(name, buffer, offered, needed, returned);
2207 if (flags & PRINTER_ENUM_NAME)
2208 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
2210 if (flags & PRINTER_ENUM_REMOTE)
2211 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
2213 if (flags & PRINTER_ENUM_NETWORK)
2214 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
2216 return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
2219 /********************************************************************
2220 * handle enumeration of printers at level 2
2221 ********************************************************************/
2222 static uint32 enumprinters_level2( uint32 flags, fstring servername,
2223 NEW_BUFFER *buffer, uint32 offered,
2224 uint32 *needed, uint32 *returned)
2228 fstrcpy(temp, "\\\\");
2229 fstrcat(temp, global_myname);
2231 if (flags & PRINTER_ENUM_LOCAL) {
2232 if (!strcmp(servername, temp))
2233 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2235 return enum_all_printers_info_2("", buffer, offered, needed, returned);
2238 if (flags & PRINTER_ENUM_NAME) {
2239 if (!strcmp(servername, temp))
2240 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2242 return ERROR_INVALID_NAME;
2245 if (flags & PRINTER_ENUM_REMOTE)
2246 return ERROR_INVALID_LEVEL;
2248 return NT_STATUS_NO_PROBLEMO;
2251 /********************************************************************
2252 * handle enumeration of printers at level 5
2253 ********************************************************************/
2254 static uint32 enumprinters_level5( uint32 flags, fstring servername,
2255 NEW_BUFFER *buffer, uint32 offered,
2256 uint32 *needed, uint32 *returned)
2258 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
2259 return NT_STATUS_NO_PROBLEMO;
2262 /********************************************************************
2263 * api_spoolss_enumprinters
2265 * called from api_spoolss_enumprinters (see this to understand)
2266 ********************************************************************/
2267 uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
2268 NEW_BUFFER *buffer, uint32 offered,
2269 uint32 *needed, uint32 *returned)
2273 DEBUG(4,("_spoolss_enumprinters\n"));
2280 * flags==PRINTER_ENUM_NAME
2281 * if name=="" then enumerates all printers
2282 * if name!="" then enumerate the printer
2283 * flags==PRINTER_ENUM_REMOTE
2284 * name is NULL, enumerate printers
2285 * Level 2: name!="" enumerates printers, name can't be NULL
2286 * Level 3: doesn't exist
2287 * Level 4: does a local registry lookup
2288 * Level 5: same as Level 2
2291 unistr2_to_ascii(name, servername, sizeof(name)-1);
2296 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
2299 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
2302 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
2307 return ERROR_INVALID_LEVEL;
2312 /****************************************************************************
2313 ****************************************************************************/
2314 static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2316 PRINTER_INFO_0 *printer=NULL;
2318 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
2319 return ERROR_NOT_ENOUGH_MEMORY;
2321 construct_printer_info_0(printer, snum, servername);
2323 /* check the required size. */
2324 *needed += spoolss_size_printer_info_0(printer);
2326 if (!alloc_buffer_size(buffer, *needed)) {
2328 return ERROR_INSUFFICIENT_BUFFER;
2331 /* fill the buffer with the structures */
2332 new_smb_io_printer_info_0("", buffer, printer, 0);
2337 if (*needed > offered) {
2338 return ERROR_INSUFFICIENT_BUFFER;
2341 return NT_STATUS_NO_PROBLEMO;
2344 /****************************************************************************
2345 ****************************************************************************/
2346 static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2348 PRINTER_INFO_1 *printer=NULL;
2350 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2351 return ERROR_NOT_ENOUGH_MEMORY;
2353 construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum);
2355 /* check the required size. */
2356 *needed += spoolss_size_printer_info_1(printer);
2358 if (!alloc_buffer_size(buffer, *needed)) {
2360 return ERROR_INSUFFICIENT_BUFFER;
2363 /* fill the buffer with the structures */
2364 new_smb_io_printer_info_1("", buffer, printer, 0);
2369 if (*needed > offered) {
2370 return ERROR_INSUFFICIENT_BUFFER;
2373 return NT_STATUS_NO_PROBLEMO;
2376 /****************************************************************************
2377 ****************************************************************************/
2378 static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2380 PRINTER_INFO_2 *printer=NULL;
2383 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
2384 return ERROR_NOT_ENOUGH_MEMORY;
2386 fstrcpy(temp, "\\\\");
2387 fstrcat(temp, servername);
2388 construct_printer_info_2(temp, printer, snum);
2390 /* check the required size. */
2391 *needed += spoolss_size_printer_info_2(printer);
2393 if (!alloc_buffer_size(buffer, *needed)) {
2394 free_printer_info_2(printer);
2395 return ERROR_INSUFFICIENT_BUFFER;
2398 /* fill the buffer with the structures */
2399 if (!new_smb_io_printer_info_2("", buffer, printer, 0)) {
2400 free_printer_info_2(printer);
2401 return ERROR_NOT_ENOUGH_MEMORY;
2405 free_printer_info_2(printer);
2407 if (*needed > offered) {
2408 return ERROR_INSUFFICIENT_BUFFER;
2411 return NT_STATUS_NO_PROBLEMO;
2414 /****************************************************************************
2415 ****************************************************************************/
2416 static uint32 getprinter_level_3(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2418 PRINTER_INFO_3 *printer=NULL;
2421 fstrcpy(temp, "\\\\");
2422 fstrcat(temp, servername);
2423 if (!construct_printer_info_3(temp, &printer, snum))
2424 return ERROR_NOT_ENOUGH_MEMORY;
2426 /* check the required size. */
2427 *needed += spoolss_size_printer_info_3(printer);
2429 if (!alloc_buffer_size(buffer, *needed)) {
2430 free_printer_info_3(printer);
2431 return ERROR_INSUFFICIENT_BUFFER;
2434 /* fill the buffer with the structures */
2435 new_smb_io_printer_info_3("", buffer, printer, 0);
2438 free_printer_info_3(printer);
2440 if (*needed > offered) {
2441 return ERROR_INSUFFICIENT_BUFFER;
2444 return NT_STATUS_NO_PROBLEMO;
2447 /****************************************************************************
2448 ****************************************************************************/
2449 uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
2450 NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2457 pstrcpy(servername, global_myname);
2459 if (!get_printer_snum(handle, &snum))
2460 return ERROR_INVALID_HANDLE;
2464 return getprinter_level_0(servername, snum, buffer, offered, needed);
2466 return getprinter_level_1(servername,snum, buffer, offered, needed);
2468 return getprinter_level_2(servername,snum, buffer, offered, needed);
2470 return getprinter_level_3(servername,snum, buffer, offered, needed);
2472 return ERROR_INVALID_LEVEL;
2477 /********************************************************************
2478 * fill a DRIVER_INFO_1 struct
2479 ********************************************************************/
2480 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
2482 init_unistr( &(info->name), driver.info_3->name);
2485 /********************************************************************
2486 * construct_printer_driver_info_1
2487 ********************************************************************/
2488 static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
2490 NT_PRINTER_INFO_LEVEL *printer = NULL;
2491 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2493 ZERO_STRUCT(driver);
2495 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2496 return ERROR_INVALID_PRINTER_NAME;
2498 if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2499 return ERROR_UNKNOWN_PRINTER_DRIVER;
2501 fill_printer_driver_info_1(info, driver, servername, architecture);
2503 free_a_printer(&printer,2);
2505 return NT_STATUS_NO_PROBLEMO;
2508 /********************************************************************
2509 * construct_printer_driver_info_2
2510 * fill a printer_info_2 struct
2511 ********************************************************************/
2512 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2514 pstring temp_driverpath;
2515 pstring temp_datafile;
2516 pstring temp_configfile;
2518 info->version=driver.info_3->cversion;
2520 init_unistr( &info->name, driver.info_3->name );
2521 init_unistr( &info->architecture, driver.info_3->environment );
2523 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2524 init_unistr( &info->driverpath, temp_driverpath );
2526 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2527 init_unistr( &info->datafile, temp_datafile );
2529 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2530 init_unistr( &info->configfile, temp_configfile );
2533 /********************************************************************
2534 * construct_printer_driver_info_2
2535 * fill a printer_info_2 struct
2536 ********************************************************************/
2537 static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *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(printer);
2543 ZERO_STRUCT(driver);
2545 if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2546 return ERROR_INVALID_PRINTER_NAME;
2548 if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2549 return ERROR_UNKNOWN_PRINTER_DRIVER;
2551 fill_printer_driver_info_2(info, driver, servername);
2553 free_a_printer(&printer,2);
2555 return NT_STATUS_NO_PROBLEMO;
2558 /********************************************************************
2559 * copy a strings array and convert to UNICODE
2561 * convert an array of ascii string to a UNICODE string
2562 ********************************************************************/
2563 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
2570 DEBUG(6,("init_unistr_array\n"));
2574 if (char_array == NULL)
2578 if (!v) v = ""; /* hack to handle null lists */
2580 if (strlen(v) == 0) break;
2581 snprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
2582 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
2583 if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
2584 DEBUG(0,("init_unistr_array: Realloc error\n" ));
2587 j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
2592 (*uni_array)[j]=0x0000;
2595 DEBUGADD(6,("last one:done\n"));
2598 /********************************************************************
2599 * construct_printer_info_3
2600 * fill a printer_info_3 struct
2601 ********************************************************************/
2602 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2604 pstring temp_driverpath;
2605 pstring temp_datafile;
2606 pstring temp_configfile;
2607 pstring temp_helpfile;
2609 info->version=driver.info_3->cversion;
2611 init_unistr( &info->name, driver.info_3->name );
2612 init_unistr( &info->architecture, driver.info_3->environment );
2614 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2615 init_unistr( &info->driverpath, temp_driverpath );
2617 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2618 init_unistr( &info->datafile, temp_datafile );
2620 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2621 init_unistr( &info->configfile, temp_configfile );
2623 snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
2624 init_unistr( &info->helpfile, temp_helpfile );
2626 init_unistr( &info->monitorname, driver.info_3->monitorname );
2627 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
2629 info->dependentfiles=NULL;
2630 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
2633 /********************************************************************
2634 * construct_printer_info_3
2635 * fill a printer_info_3 struct
2636 ********************************************************************/
2637 static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
2639 NT_PRINTER_INFO_LEVEL *printer = NULL;
2640 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2642 ZERO_STRUCT(driver);
2644 status=get_a_printer(&printer, 2, lp_servicename(snum) );
2645 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2647 return ERROR_INVALID_PRINTER_NAME;
2649 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
2650 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2652 return ERROR_UNKNOWN_PRINTER_DRIVER;
2654 fill_printer_driver_info_3(info, driver, servername);
2656 free_a_printer(&printer,2);
2658 return NT_STATUS_NO_PROBLEMO;
2661 /****************************************************************************
2662 ****************************************************************************/
2664 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
2666 safe_free(info->dependentfiles);
2669 /****************************************************************************
2670 ****************************************************************************/
2671 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2673 DRIVER_INFO_1 *info=NULL;
2676 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
2677 return ERROR_NOT_ENOUGH_MEMORY;
2679 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
2680 if (status != NT_STATUS_NO_PROBLEMO) {
2685 /* check the required size. */
2686 *needed += spoolss_size_printer_driver_info_1(info);
2688 if (!alloc_buffer_size(buffer, *needed)) {
2690 return ERROR_INSUFFICIENT_BUFFER;
2693 /* fill the buffer with the structures */
2694 new_smb_io_printer_driver_info_1("", buffer, info, 0);
2699 if (*needed > offered)
2700 return ERROR_INSUFFICIENT_BUFFER;
2702 return NT_STATUS_NO_PROBLEMO;
2705 /****************************************************************************
2706 ****************************************************************************/
2707 static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2709 DRIVER_INFO_2 *info=NULL;
2712 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
2713 return ERROR_NOT_ENOUGH_MEMORY;
2715 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
2716 if (status != NT_STATUS_NO_PROBLEMO) {
2721 /* check the required size. */
2722 *needed += spoolss_size_printer_driver_info_2(info);
2724 if (!alloc_buffer_size(buffer, *needed)) {
2726 return ERROR_INSUFFICIENT_BUFFER;
2729 /* fill the buffer with the structures */
2730 new_smb_io_printer_driver_info_2("", buffer, info, 0);
2735 if (*needed > offered)
2736 return ERROR_INSUFFICIENT_BUFFER;
2738 return NT_STATUS_NO_PROBLEMO;
2741 /****************************************************************************
2742 ****************************************************************************/
2743 static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2750 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
2751 if (status != NT_STATUS_NO_PROBLEMO) {
2755 /* check the required size. */
2756 *needed += spoolss_size_printer_driver_info_3(&info);
2758 if (!alloc_buffer_size(buffer, *needed)) {
2759 free_printer_driver_info_3(&info);
2760 return ERROR_INSUFFICIENT_BUFFER;
2763 /* fill the buffer with the structures */
2764 new_smb_io_printer_driver_info_3("", buffer, &info, 0);
2766 free_printer_driver_info_3(&info);
2768 if (*needed > offered)
2769 return ERROR_INSUFFICIENT_BUFFER;
2771 return NT_STATUS_NO_PROBLEMO;
2774 /****************************************************************************
2775 ****************************************************************************/
2776 uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level,
2777 uint32 clientmajorversion, uint32 clientminorversion,
2778 NEW_BUFFER *buffer, uint32 offered,
2779 uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
2782 fstring architecture;
2785 DEBUG(4,("_spoolss_getprinterdriver2\n"));
2788 *servermajorversion=0;
2789 *serverminorversion=0;
2791 pstrcpy(servername, global_myname);
2792 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
2794 if (!get_printer_snum(handle, &snum))
2795 return ERROR_INVALID_HANDLE;
2799 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2802 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2805 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2808 return ERROR_INVALID_LEVEL;
2813 /****************************************************************************
2814 ****************************************************************************/
2815 uint32 _spoolss_startpageprinter(POLICY_HND *handle)
2817 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2819 if (OPEN_HANDLE(Printer)) {
2820 Printer->page_started=True;
2824 DEBUG(3,("Error in startpageprinter printer handle\n"));
2825 return ERROR_INVALID_HANDLE;
2828 /****************************************************************************
2829 ****************************************************************************/
2830 uint32 _spoolss_endpageprinter(POLICY_HND *handle)
2832 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2834 if (!OPEN_HANDLE(Printer)) {
2835 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
2836 return ERROR_INVALID_HANDLE;
2839 Printer->page_started=False;
2841 return NT_STATUS_NO_PROBLEMO;
2845 /********************************************************************
2846 * api_spoolss_getprinter
2847 * called from the spoolss dispatcher
2849 ********************************************************************/
2850 uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
2851 pipes_struct *p, DOC_INFO *docinfo,
2854 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
2858 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2859 struct current_user user;
2861 if (!OPEN_HANDLE(Printer)) {
2862 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2863 return ERROR_INVALID_HANDLE;
2866 if (p->ntlmssp_auth_validated) {
2867 memcpy(&user, &p->pipe_user, sizeof(user));
2869 extern struct current_user current_user;
2870 memcpy(&user, ¤t_user, sizeof(user));
2874 * a nice thing with NT is it doesn't listen to what you tell it.
2875 * when asked to send _only_ RAW datas, it tries to send datas
2878 * So I add checks like in NT Server ...
2880 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
2881 * there's a bug in NT client-side code, so we'll fix it in the
2882 * server-side code. *nnnnnggggh!*
2885 if (info_1->p_datatype != 0)
2887 unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype));
2888 if (strcmp(datatype, "RAW") != 0)
2891 return ERROR_INVALID_DATATYPE;
2895 /* get the share number of the printer */
2896 if (!get_printer_snum(handle, &snum))
2898 return ERROR_INVALID_HANDLE;
2901 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
2903 Printer->jobid = print_job_start(&user, snum, jobname);
2905 /* need to map error codes properly - for now give out of
2906 memory as I don't know the correct codes (tridge) */
2907 if (Printer->jobid == -1) {
2908 return ERROR_NOT_ENOUGH_MEMORY;
2911 Printer->document_started=True;
2912 (*jobid) = Printer->jobid;
2917 /********************************************************************
2918 * api_spoolss_getprinter
2919 * called from the spoolss dispatcher
2921 ********************************************************************/
2922 uint32 _spoolss_enddocprinter(POLICY_HND *handle)
2924 Printer_entry *Printer=find_printer_index_by_hnd(handle);
2926 if (!OPEN_HANDLE(Printer)) {
2927 DEBUG(0,("_spoolss_enddocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2928 return ERROR_INVALID_HANDLE;
2931 Printer->document_started=False;
2932 print_job_end(Printer->jobid);
2933 /* error codes unhandled so far ... */
2938 /****************************************************************************
2939 ****************************************************************************/
2940 uint32 _spoolss_writeprinter( POLICY_HND *handle,
2943 uint32 *buffer_written)
2945 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2947 if (!OPEN_HANDLE(Printer)) {
2948 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
2949 return ERROR_INVALID_HANDLE;
2952 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer,
2958 /********************************************************************
2959 * api_spoolss_getprinter
2960 * called from the spoolss dispatcher
2962 ********************************************************************/
2963 static uint32 control_printer(POLICY_HND *handle, uint32 command,
2966 struct current_user user;
2968 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2970 if (p->ntlmssp_auth_validated) {
2971 memcpy(&user, &p->pipe_user, sizeof(user));
2973 extern struct current_user current_user;
2974 memcpy(&user, ¤t_user, sizeof(user));
2977 if (!OPEN_HANDLE(Printer)) {
2978 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2979 return ERROR_INVALID_HANDLE;
2982 if (!get_printer_snum(handle, &snum) )
2983 return ERROR_INVALID_HANDLE;
2986 case PRINTER_CONTROL_PAUSE:
2987 if (print_queue_pause(&user, snum)) {
2991 case PRINTER_CONTROL_RESUME:
2992 case PRINTER_CONTROL_UNPAUSE:
2993 if (print_queue_resume(&user, snum)) {
2997 case PRINTER_CONTROL_PURGE:
2998 if (print_queue_purge(&user, snum)) {
3004 return ERROR_INVALID_FUNCTION;
3007 /********************************************************************
3008 * called by spoolss_api_setprinter
3009 * when updating a printer description
3010 ********************************************************************/
3011 static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
3012 const SPOOL_PRINTER_INFO_LEVEL *info,
3013 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
3015 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3016 struct current_user user;
3017 uint32 acc_granted, status, result;
3019 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3021 if (!OPEN_HANDLE(Printer)) {
3022 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3023 return ERROR_INVALID_HANDLE;
3026 /* Work out which user is performing the operation */
3028 if (p->ntlmssp_auth_validated) {
3029 memcpy(&user, &p->pipe_user, sizeof(user));
3031 extern struct current_user current_user;
3032 memcpy(&user, ¤t_user, sizeof(user));
3035 /* Get old security descriptor */
3037 if (!nt_printing_getsec(Printer->dev.handlename, &old_secdesc_ctr)) {
3038 DEBUG(3, ("could not get old security descriptor for "
3039 "printer %s", Printer->dev.handlename));
3040 return ERROR_INVALID_FUNCTION;
3043 /* Check the user has permissions to change the security
3044 descriptor. By experimentation with two NT machines, the user
3045 requires Full Access to the printer to change security
3048 if (!se_access_check(old_secdesc_ctr->sec, &user,
3049 PRINTER_ACE_FULL_CONTROL, &acc_granted,
3051 DEBUG(3, ("security descriptor change denied by existing "
3052 "security descriptor\n"));
3057 result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
3060 free_sec_desc_buf(&old_secdesc_ctr);
3064 /********************************************************************
3065 Do Samba sanity checks on a printer info struct.
3066 ********************************************************************/
3068 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
3071 * Ensure that this printer is shared under the correct name
3072 * as this is what Samba insists upon.
3075 if (!(info->attributes & PRINTER_ATTRIBUTE_SHARED)) {
3076 DEBUG(10,("check_printer_ok: SHARED check failed (%x).\n", (unsigned int)info->attributes ));
3080 if (!(info->attributes & PRINTER_ATTRIBUTE_RAW_ONLY)) {
3081 /* NT forgets to set the raw attribute but sends the correct type. */
3082 if (strequal(info->datatype, "RAW"))
3083 info->attributes |= PRINTER_ATTRIBUTE_RAW_ONLY;
3085 DEBUG(10,("check_printer_ok: RAW check failed (%x).\n", (unsigned int)info->attributes ));
3090 if (!strequal(info->sharename, lp_servicename(snum))) {
3091 DEBUG(10,("check_printer_ok: NAME check failed (%s) (%s).\n", info->sharename, lp_servicename(snum)));
3098 /********************************************************************
3099 * called by spoolss_api_setprinter
3100 * when updating a printer description
3101 ********************************************************************/
3103 static uint32 update_printer(POLICY_HND *handle, uint32 level,
3104 const SPOOL_PRINTER_INFO_LEVEL *info,
3105 DEVICEMODE *devmode)
3108 NT_PRINTER_INFO_LEVEL *printer = NULL;
3109 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3110 SEC_DESC_BUF *sd = NULL;
3111 uint32 result, acc_granted;
3112 extern struct current_user current_user;
3114 DEBUG(8,("update_printer\n"));
3116 result = NT_STATUS_NO_PROBLEMO;
3118 /* Check calling user has permission to update printer description */
3121 if (!nt_printing_getsec(Printer->dev.handlename, &sd)) {
3122 DEBUG(3, ("Could not get security descriptor for printer %s",
3123 Printer->dev.handlename));
3124 result = ERROR_INVALID_FUNCTION;
3128 if (!se_access_check(sd->sec, ¤t_user,
3129 PRINTER_ACE_FULL_CONTROL, &acc_granted,
3131 DEBUG(3, ("printer property change denied by security "
3137 DEBUG(0,("Send a mail to samba@samba.org\n"));
3138 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3139 result = ERROR_INVALID_LEVEL;
3143 if (!OPEN_HANDLE(Printer)) {
3144 result = ERROR_INVALID_HANDLE;
3148 if (!get_printer_snum(handle, &snum)) {
3149 result = ERROR_INVALID_HANDLE;
3153 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3154 result = ERROR_INVALID_HANDLE;
3158 DEBUGADD(8,("Converting info_2 struct\n"));
3161 * convert_printer_info converts the incoming
3162 * info from the client and overwrites the info
3163 * just read from the tdb in the pointer 'printer'.
3166 convert_printer_info(info, printer, level);
3168 if (info->info_2->devmode_ptr != 0) {
3169 /* we have a valid devmode
3170 convert it and link it*/
3173 * Ensure printer->info_2->devmode is a valid pointer
3174 * as we will be overwriting it in convert_devicemode().
3177 if (printer->info_2->devmode == NULL)
3178 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3180 DEBUGADD(8,("Converting the devicemode struct\n"));
3181 convert_devicemode(devmode, printer->info_2->devmode);
3184 if (printer->info_2->devmode != NULL)
3185 free_nt_devicemode(&printer->info_2->devmode);
3186 printer->info_2->devmode=NULL;
3190 * Do sanity check on the requested changes for Samba.
3193 if (!check_printer_ok(printer->info_2, snum)) {
3194 result = ERROR_ACCESS_DENIED;
3198 if (add_a_printer(*printer, 2)!=0) {
3199 /* I don't really know what to return here !!! */
3200 result = ERROR_ACCESS_DENIED;
3205 free_a_printer(&printer, 2);
3206 free_sec_desc_buf(&sd);
3211 /****************************************************************************
3212 ****************************************************************************/
3213 uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
3214 const SPOOL_PRINTER_INFO_LEVEL *info,
3215 DEVMODE_CTR devmode_ctr,
3216 SEC_DESC_BUF *secdesc_ctr,
3217 uint32 command, pipes_struct *p)
3219 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3221 if (!OPEN_HANDLE(Printer)) {
3222 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3223 return ERROR_INVALID_HANDLE;
3226 /* check the level */
3229 return control_printer(handle, command, p);
3232 return update_printer(handle, level, info, devmode_ctr.devmode);
3235 return update_printer_sec(handle, level, info, p,
3239 return ERROR_INVALID_LEVEL;
3244 /****************************************************************************
3245 ****************************************************************************/
3246 uint32 _spoolss_fcpn(POLICY_HND *handle)
3248 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3250 if (!OPEN_HANDLE(Printer)) {
3251 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3252 return ERROR_INVALID_HANDLE;
3255 Printer->notify.flags=0;
3256 Printer->notify.options=0;
3257 Printer->notify.localmachine[0]='\0';
3258 Printer->notify.printerlocal=0;
3259 if (Printer->notify.option)
3260 safe_free(Printer->notify.option->ctr.type);
3261 safe_free(Printer->notify.option);
3262 Printer->notify.option=NULL;
3264 return NT_STATUS_NO_PROBLEMO;
3267 /****************************************************************************
3268 ****************************************************************************/
3269 uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
3270 NEW_BUFFER *buffer, uint32 offered)
3272 return NT_STATUS_NO_PROBLEMO;
3275 /****************************************************************************
3276 ****************************************************************************/
3277 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3278 int position, int snum)
3283 time_t unixdate = time(NULL);
3285 t=gmtime(&unixdate);
3286 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3288 job_info->jobid=queue->job;
3289 init_unistr(&job_info->printername, lp_servicename(snum));
3290 init_unistr(&job_info->machinename, temp_name);
3291 init_unistr(&job_info->username, queue->user);
3292 init_unistr(&job_info->document, queue->file);
3293 init_unistr(&job_info->datatype, "RAW");
3294 init_unistr(&job_info->text_status, "");
3295 job_info->status=nt_printj_status(queue->status);
3296 job_info->priority=queue->priority;
3297 job_info->position=position;
3298 job_info->totalpages=0;
3299 job_info->pagesprinted=0;
3301 make_systemtime(&(job_info->submitted), t);
3304 /****************************************************************************
3305 ****************************************************************************/
3306 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3307 int position, int snum)
3310 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3314 time_t unixdate = time(NULL);
3316 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3319 t=gmtime(&unixdate);
3320 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3322 job_info->jobid=queue->job;
3324 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3326 init_unistr(&(job_info->printername), chaine);
3328 init_unistr(&job_info->machinename, temp_name);
3329 init_unistr(&job_info->username, queue->user);
3330 init_unistr(&job_info->document, queue->file);
3331 init_unistr(&job_info->notifyname, queue->user);
3332 init_unistr(&job_info->datatype, "RAW");
3333 init_unistr(&job_info->printprocessor, "winprint");
3334 init_unistr(&job_info->parameters, "");
3335 init_unistr(&job_info->text_status, "");
3337 /* and here the security descriptor */
3339 job_info->status=nt_printj_status(queue->status);
3340 job_info->priority=queue->priority;
3341 job_info->position=position;
3342 job_info->starttime=0;
3343 job_info->untiltime=0;
3344 job_info->totalpages=0;
3345 job_info->size=queue->size;
3346 make_systemtime(&(job_info->submitted), t);
3347 job_info->timeelapsed=0;
3348 job_info->pagesprinted=0;
3350 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3351 free_a_printer(&ntprinter, 2);
3355 free_a_printer(&ntprinter, 2);
3359 /****************************************************************************
3360 Enumjobs at level 1.
3361 ****************************************************************************/
3362 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3363 NEW_BUFFER *buffer, uint32 offered,
3364 uint32 *needed, uint32 *returned)
3369 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3373 return ERROR_NOT_ENOUGH_MEMORY;
3376 for (i=0; i<*returned; i++)
3377 fill_job_info_1(&info[i], &queue[i], i, snum);
3381 /* check the required size. */
3382 for (i=0; i<*returned; i++)
3383 (*needed) += spoolss_size_job_info_1(&info[i]);
3385 if (!alloc_buffer_size(buffer, *needed)) {
3387 return ERROR_INSUFFICIENT_BUFFER;
3390 /* fill the buffer with the structures */
3391 for (i=0; i<*returned; i++)
3392 new_smb_io_job_info_1("", buffer, &info[i], 0);
3397 if (*needed > offered) {
3399 return ERROR_INSUFFICIENT_BUFFER;
3402 return NT_STATUS_NO_PROBLEMO;
3405 /****************************************************************************
3406 Enumjobs at level 2.
3407 ****************************************************************************/
3408 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3409 NEW_BUFFER *buffer, uint32 offered,
3410 uint32 *needed, uint32 *returned)
3415 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3419 return ERROR_NOT_ENOUGH_MEMORY;
3422 for (i=0; i<*returned; i++)
3423 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3427 /* check the required size. */
3428 for (i=0; i<*returned; i++)
3429 (*needed) += spoolss_size_job_info_2(&info[i]);
3431 if (!alloc_buffer_size(buffer, *needed)) {
3433 return ERROR_INSUFFICIENT_BUFFER;
3436 /* fill the buffer with the structures */
3437 for (i=0; i<*returned; i++)
3438 new_smb_io_job_info_2("", buffer, &info[i], 0);
3443 if (*needed > offered) {
3445 return ERROR_INSUFFICIENT_BUFFER;
3448 return NT_STATUS_NO_PROBLEMO;
3451 /****************************************************************************
3453 ****************************************************************************/
3454 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3455 NEW_BUFFER *buffer, uint32 offered,
3456 uint32 *needed, uint32 *returned)
3459 print_queue_struct *queue=NULL;
3460 print_status_struct prt_status;
3462 DEBUG(4,("_spoolss_enumjobs\n"));
3464 ZERO_STRUCT(prt_status);
3469 if (!get_printer_snum(handle, &snum))
3470 return ERROR_INVALID_HANDLE;
3472 *returned = print_queue_status(snum, &queue, &prt_status);
3473 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3477 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3480 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3485 return ERROR_INVALID_LEVEL;
3491 /****************************************************************************
3492 ****************************************************************************/
3493 uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid)
3498 /****************************************************************************
3499 ****************************************************************************/
3500 uint32 _spoolss_setjob( POLICY_HND *handle,
3508 struct current_user user;
3510 print_status_struct prt_status;
3512 memset(&prt_status, 0, sizeof(prt_status));
3514 if (!get_printer_snum(handle, &snum)) {
3515 return ERROR_INVALID_HANDLE;
3518 if (!print_job_exists(jobid)) {
3519 return ERROR_INVALID_PRINTER_NAME;
3522 if (p->ntlmssp_auth_validated) {
3523 memcpy(&user, &p->pipe_user, sizeof(user));
3525 extern struct current_user current_user;
3526 memcpy(&user, ¤t_user, sizeof(user));
3530 case JOB_CONTROL_CANCEL:
3531 case JOB_CONTROL_DELETE:
3532 if (print_job_delete(&user, jobid)) return 0x0;
3534 case JOB_CONTROL_PAUSE:
3535 if (print_job_pause(&user, jobid)) return 0x0;
3537 case JOB_CONTROL_RESUME:
3538 if (print_job_resume(&user, jobid)) return 0x0;
3541 return ERROR_INVALID_LEVEL;
3544 return ERROR_INVALID_HANDLE;
3547 /****************************************************************************
3548 Enumerates all printer drivers at level 1.
3549 ****************************************************************************/
3550 static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3555 fstring *list = NULL;
3557 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3558 DRIVER_INFO_1 *driver_info_1=NULL;
3562 #define MAX_VERSION 4
3564 for (version=0; version<MAX_VERSION; version++) {
3566 ndrivers=get_ntdrivers(&list, architecture, version);
3567 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3570 return ERROR_NOT_ENOUGH_MEMORY;
3573 if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
3575 return ERROR_NOT_ENOUGH_MEMORY;
3579 for (i=0; i<ndrivers; i++) {
3580 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3581 ZERO_STRUCT(driver);
3582 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3583 fill_printer_driver_info_1(&(driver_info_1[*returned+i]), driver, servername, architecture );
3586 *returned+=ndrivers;
3590 /* check the required size. */
3591 for (i=0; i<*returned; i++) {
3592 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3593 *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
3596 if (!alloc_buffer_size(buffer, *needed)) {
3597 safe_free(driver_info_1);
3598 return ERROR_INSUFFICIENT_BUFFER;
3601 /* fill the buffer with the form structures */
3602 for (i=0; i<*returned; i++) {
3603 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3604 new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
3607 safe_free(driver_info_1);
3609 if (*needed > offered) {
3611 return ERROR_INSUFFICIENT_BUFFER;
3614 return NT_STATUS_NO_PROBLEMO;
3617 /****************************************************************************
3618 Enumerates all printer drivers at level 2.
3619 ****************************************************************************/
3620 static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3625 fstring *list = NULL;
3627 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3628 DRIVER_INFO_2 *driver_info_2=NULL;
3632 #define MAX_VERSION 4
3634 for (version=0; version<MAX_VERSION; version++) {
3636 ndrivers=get_ntdrivers(&list, architecture, version);
3637 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3640 return ERROR_NOT_ENOUGH_MEMORY;
3643 if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
3645 return ERROR_NOT_ENOUGH_MEMORY;
3649 for (i=0; i<ndrivers; i++) {
3650 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3651 ZERO_STRUCT(driver);
3652 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3653 fill_printer_driver_info_2(&(driver_info_2[*returned+i]), driver, servername);
3656 *returned+=ndrivers;
3660 /* check the required size. */
3661 for (i=0; i<*returned; i++) {
3662 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3663 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3666 if (!alloc_buffer_size(buffer, *needed)) {
3667 safe_free(driver_info_2);
3668 return ERROR_INSUFFICIENT_BUFFER;
3671 /* fill the buffer with the form structures */
3672 for (i=0; i<*returned; i++) {
3673 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3674 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3677 safe_free(driver_info_2);
3679 if (*needed > offered) {
3681 return ERROR_INSUFFICIENT_BUFFER;
3684 return NT_STATUS_NO_PROBLEMO;
3687 /****************************************************************************
3688 Enumerates all printer drivers at level 3.
3689 ****************************************************************************/
3690 static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3695 fstring *list = NULL;
3697 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3698 DRIVER_INFO_3 *driver_info_3=NULL;
3702 #define MAX_VERSION 4
3704 for (version=0; version<MAX_VERSION; version++) {
3706 ndrivers=get_ntdrivers(&list, architecture, version);
3707 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3710 return ERROR_NOT_ENOUGH_MEMORY;
3713 if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
3715 return ERROR_NOT_ENOUGH_MEMORY;
3719 for (i=0; i<ndrivers; i++) {
3720 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3721 ZERO_STRUCT(driver);
3722 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3723 fill_printer_driver_info_3(&(driver_info_3[*returned+i]), driver, servername);
3726 *returned+=ndrivers;
3730 /* check the required size. */
3731 for (i=0; i<*returned; i++) {
3732 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3733 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3736 if (!alloc_buffer_size(buffer, *needed)) {
3737 safe_free(driver_info_3);
3738 return ERROR_INSUFFICIENT_BUFFER;
3741 /* fill the buffer with the driver structures */
3742 for (i=0; i<*returned; i++) {
3743 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3744 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
3747 for (i=0; i<*returned; i++)
3748 safe_free(driver_info_3[i].dependentfiles);
3750 safe_free(driver_info_3);
3752 if (*needed > offered) {
3754 return ERROR_INSUFFICIENT_BUFFER;
3757 return NT_STATUS_NO_PROBLEMO;
3760 /****************************************************************************
3761 Enumerates all printer drivers.
3762 ****************************************************************************/
3763 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
3764 NEW_BUFFER *buffer, uint32 offered,
3765 uint32 *needed, uint32 *returned)
3768 fstring *list = NULL;
3770 fstring architecture;
3772 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
3773 fstrcpy(servername, global_myname);
3777 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
3781 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
3784 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
3787 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
3792 return ERROR_INVALID_LEVEL;
3797 /****************************************************************************
3798 ****************************************************************************/
3799 static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
3801 form->flag=list->flag;
3802 init_unistr(&form->name, list->name);
3803 form->width=list->width;
3804 form->length=list->length;
3805 form->left=list->left;
3806 form->top=list->top;
3807 form->right=list->right;
3808 form->bottom=list->bottom;
3811 /****************************************************************************
3812 ****************************************************************************/
3813 uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
3814 NEW_BUFFER *buffer, uint32 offered,
3815 uint32 *needed, uint32 *numofforms)
3817 nt_forms_struct *list=NULL;
3822 DEBUG(4,("_new_spoolss_enumforms\n"));
3823 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3824 DEBUGADD(5,("Info level [%d]\n", level));
3826 *numofforms = get_ntforms(&list);
3827 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
3829 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
3833 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
3835 return ERROR_NOT_ENOUGH_MEMORY;
3838 /* construct the list of form structures */
3839 for (i=0; i<*numofforms; i++) {
3840 DEBUGADD(6,("Filling form number [%d]\n",i));
3841 fill_form_1(&forms_1[i], &list[i], i);
3846 /* check the required size. */
3847 for (i=0; i<*numofforms; i++) {
3848 DEBUGADD(6,("adding form [%d]'s size\n",i));
3849 buffer_size += spoolss_size_form_1(&forms_1[i]);
3852 *needed=buffer_size;
3854 if (!alloc_buffer_size(buffer, buffer_size)){
3856 return ERROR_INSUFFICIENT_BUFFER;
3859 /* fill the buffer with the form structures */
3860 for (i=0; i<*numofforms; i++) {
3861 DEBUGADD(6,("adding form [%d] to buffer\n",i));
3862 new_smb_io_form_1("", buffer, &forms_1[i], 0);
3867 if (*needed > offered) {
3869 return ERROR_INSUFFICIENT_BUFFER;
3872 return NT_STATUS_NO_PROBLEMO;
3876 return ERROR_INVALID_LEVEL;
3881 /****************************************************************************
3882 ****************************************************************************/
3883 static void fill_port_1(PORT_INFO_1 *port, char *name)
3885 init_unistr(&port->port_name, name);
3888 /****************************************************************************
3889 ****************************************************************************/
3890 static void fill_port_2(PORT_INFO_2 *port, char *name)
3892 init_unistr(&port->port_name, name);
3893 init_unistr(&port->monitor_name, "Local Monitor");
3894 init_unistr(&port->description, "Local Port");
3895 #define PORT_TYPE_WRITE 1
3896 port->port_type=PORT_TYPE_WRITE;
3900 /****************************************************************************
3902 ****************************************************************************/
3903 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3905 int n_services=lp_numservices();
3909 PORT_INFO_1 *ports=NULL;
3911 for (snum=0; snum<n_services; snum++)
3912 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3915 if((ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) )) == NULL)
3916 return ERROR_NOT_ENOUGH_MEMORY;
3918 for (snum=0; snum<n_services; snum++) {
3919 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3921 * Ensure this port name is unique.
3925 DEBUG(10,("enumports_level_1: port name %s\n", PRINTERNAME(snum)));
3927 for(j = 0; j < i; j++) {
3929 unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
3931 if (strequal(port_name, PRINTERNAME(snum)))
3938 DEBUGADD(6,("Filling port number [%d]\n", i));
3939 fill_port_1(&ports[i], PRINTERNAME(snum));
3946 /* check the required size. */
3947 for (i=0; i<*returned; i++) {
3948 DEBUGADD(6,("adding port [%d]'s size\n", i));
3949 *needed += spoolss_size_port_info_1(&ports[i]);
3952 if (!alloc_buffer_size(buffer, *needed)) {
3954 return ERROR_INSUFFICIENT_BUFFER;
3957 /* fill the buffer with the ports structures */
3958 for (i=0; i<*returned; i++) {
3959 DEBUGADD(6,("adding port [%d] to buffer\n", i));
3960 new_smb_io_port_1("", buffer, &ports[i], 0);
3965 if (*needed > offered) {
3967 return ERROR_INSUFFICIENT_BUFFER;
3970 return NT_STATUS_NO_PROBLEMO;
3973 /****************************************************************************
3975 ****************************************************************************/
3977 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3979 int n_services=lp_numservices();
3983 PORT_INFO_2 *ports=NULL;
3985 for (snum=0; snum<n_services; snum++)
3986 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3989 if((ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) )) == NULL)
3990 return ERROR_NOT_ENOUGH_MEMORY;
3992 for (snum=0; snum<n_services; snum++) {
3993 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3995 * Ensure this port name is unique.
3999 DEBUG(10,("enumports_level_2: port name %s\n", PRINTERNAME(snum)));
4001 for(j = 0; j < i; j++) {
4003 unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
4005 if (strequal(port_name, PRINTERNAME(snum)))
4012 DEBUGADD(6,("Filling port number [%d]\n", i));
4013 fill_port_2(&ports[i], PRINTERNAME(snum));
4020 /* check the required size. */
4021 for (i=0; i<*returned; i++) {
4022 DEBUGADD(6,("adding port [%d]'s size\n", i));
4023 *needed += spoolss_size_port_info_2(&ports[i]);
4026 if (!alloc_buffer_size(buffer, *needed)) {
4028 return ERROR_INSUFFICIENT_BUFFER;
4031 /* fill the buffer with the ports structures */
4032 for (i=0; i<*returned; i++) {
4033 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4034 new_smb_io_port_2("", buffer, &ports[i], 0);
4039 if (*needed > offered) {
4041 return ERROR_INSUFFICIENT_BUFFER;
4044 return NT_STATUS_NO_PROBLEMO;
4047 /****************************************************************************
4049 ****************************************************************************/
4050 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
4051 NEW_BUFFER *buffer, uint32 offered,
4052 uint32 *needed, uint32 *returned)
4054 DEBUG(4,("_spoolss_enumports\n"));
4061 return enumports_level_1(buffer, offered, needed, returned);
4064 return enumports_level_2(buffer, offered, needed, returned);
4067 return ERROR_INVALID_LEVEL;
4072 /****************************************************************************
4073 ****************************************************************************/
4074 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
4075 const SPOOL_PRINTER_INFO_LEVEL *info,
4076 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4077 uint32 user_switch, const SPOOL_USER_CTR *user,
4080 NT_PRINTER_INFO_LEVEL *printer = NULL;
4085 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
4086 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
4087 return ERROR_NOT_ENOUGH_MEMORY;
4090 ZERO_STRUCTP(printer);
4092 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
4093 convert_printer_info(info, printer, 2);
4095 unistr2_to_ascii(share_name, &info->info_2->sharename, sizeof(share_name)-1);
4097 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
4099 if ((snum = print_queue_snum(share_name)) == -1) {
4100 free_a_printer(&printer,2);
4101 return ERROR_ACCESS_DENIED;
4105 * Do sanity check on the requested changes for Samba.
4108 if (!check_printer_ok(printer->info_2, snum)) {
4109 free_a_printer(&printer,2);
4110 return ERROR_ACCESS_DENIED;
4113 /* write the ASCII on disk */
4114 if (add_a_printer(*printer, 2) != 0) {
4115 free_a_printer(&printer,2);
4116 return ERROR_ACCESS_DENIED;
4119 if (!open_printer_hnd(handle, name)) {
4120 /* Handle open failed - remove addition. */
4121 del_a_printer(share_name);
4122 free_a_printer(&printer,2);
4123 return ERROR_ACCESS_DENIED;
4126 free_a_printer(&printer,2);
4127 return NT_STATUS_NO_PROBLEMO;
4130 /****************************************************************************
4131 ****************************************************************************/
4132 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4133 const SPOOL_PRINTER_INFO_LEVEL *info,
4134 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4135 uint32 user_switch, const SPOOL_USER_CTR *user,
4140 /* we don't handle yet */
4141 /* but I know what to do ... */
4142 return ERROR_INVALID_LEVEL;
4145 return spoolss_addprinterex_level_2(uni_srv_name, info,
4146 unk0, unk1, unk2, unk3,
4147 user_switch, user, handle);
4150 return ERROR_INVALID_LEVEL;
4155 /****************************************************************************
4156 ****************************************************************************/
4157 uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
4158 uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4160 uint32 err = NT_STATUS_NO_PROBLEMO;
4161 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4162 struct current_user user;
4164 ZERO_STRUCT(driver);
4166 if (p->ntlmssp_auth_validated) {
4167 memcpy(&user, &p->pipe_user, sizeof(user));
4169 extern struct current_user current_user;
4170 memcpy(&user, ¤t_user, sizeof(user));
4173 convert_printer_driver_info(info, &driver, level);
4175 DEBUG(5,("Cleaning driver's information\n"));
4176 clean_up_driver_struct(driver, level);
4178 DEBUG(5,("Moving driver to final destination\n"));
4179 if(!move_driver_to_download_area(driver, level, &user))
4180 return ERROR_ACCESS_DENIED;
4182 if (add_a_printer_driver(driver, level)!=0)
4183 return ERROR_ACCESS_DENIED;
4185 free_a_printer_driver(driver, level);
4190 /****************************************************************************
4191 ****************************************************************************/
4192 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4194 init_unistr(&info->name, name);
4197 /****************************************************************************
4198 ****************************************************************************/
4199 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4203 pstring short_archi;
4204 DRIVER_DIRECTORY_1 *info=NULL;
4206 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4208 if (get_short_archi(short_archi, long_archi)==FALSE)
4209 return ERROR_INVALID_ENVIRONMENT;
4211 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4212 return ERROR_NOT_ENOUGH_MEMORY;
4214 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
4216 DEBUG(4,("printer driver directory: [%s]\n", path));
4218 fill_driverdir_1(info, path);
4220 *needed += spoolss_size_driverdir_info_1(info);
4222 if (!alloc_buffer_size(buffer, *needed)) {
4224 return ERROR_INSUFFICIENT_BUFFER;
4227 new_smb_io_driverdir_1("", buffer, info, 0);
4231 if (*needed > offered)
4232 return ERROR_INSUFFICIENT_BUFFER;
4234 return NT_STATUS_NO_PROBLEMO;
4237 /****************************************************************************
4238 ****************************************************************************/
4239 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4240 NEW_BUFFER *buffer, uint32 offered,
4243 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4249 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4252 return ERROR_INVALID_LEVEL;
4257 /****************************************************************************
4258 ****************************************************************************/
4259 uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
4260 uint32 in_value_len, uint32 in_data_len,
4261 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4263 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4265 NT_PRINTER_INFO_LEVEL *printer = NULL;
4270 uint32 biggest_valuesize;
4271 uint32 biggest_datasize;
4273 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4278 ZERO_STRUCT(printer);
4280 *out_max_value_len=0;
4286 *out_max_data_len=0;
4290 DEBUG(5,("spoolss_enumprinterdata\n"));
4292 if (!OPEN_HANDLE(Printer)) {
4293 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4294 return ERROR_INVALID_HANDLE;
4297 if (!get_printer_snum(handle, &snum))
4298 return ERROR_INVALID_HANDLE;
4300 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4301 return ERROR_INVALID_HANDLE;
4304 * The NT machine wants to know the biggest size of value and data
4306 * cf: MSDN EnumPrinterData remark section
4308 if ( (in_value_len==0) && (in_data_len==0) ) {
4309 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4312 biggest_valuesize=0;
4315 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4316 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4317 if (data_len > biggest_datasize) biggest_datasize=data_len;
4319 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4325 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4326 *out_value_len=2*(1+biggest_valuesize);
4327 *out_data_len=biggest_datasize;
4329 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4331 free_a_printer(&printer, 2);
4332 return NT_STATUS_NO_PROBLEMO;
4336 * the value len is wrong in NT sp3
4337 * that's the number of bytes not the number of unicode chars
4340 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4342 free_a_printer(&printer, 2);
4343 return ERROR_NO_MORE_ITEMS;
4346 free_a_printer(&printer, 2);
4350 * - counted in bytes in the request
4351 * - counted in UNICODE chars in the max reply
4352 * - counted in bytes in the real size
4354 * take a pause *before* coding not *during* coding
4357 *out_max_value_len=(in_value_len/sizeof(uint16));
4358 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4360 return ERROR_NOT_ENOUGH_MEMORY;
4363 ZERO_STRUCTP(*out_value);
4364 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4368 /* the data is counted in bytes */
4369 *out_max_data_len=in_data_len;
4370 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4372 return ERROR_NOT_ENOUGH_MEMORY;
4375 ZERO_STRUCTP(*data_out);
4376 memcpy(*data_out, data, (size_t)data_len);
4377 *out_data_len=data_len;
4381 return NT_STATUS_NO_PROBLEMO;
4384 /****************************************************************************
4385 ****************************************************************************/
4386 uint32 _spoolss_setprinterdata( POLICY_HND *handle,
4387 const UNISTR2 *value,
4392 uint32 numeric_data)
4394 NT_PRINTER_INFO_LEVEL *printer = NULL;
4395 NT_PRINTER_PARAM *param = NULL;
4398 uint32 status = 0x0;
4399 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4401 DEBUG(5,("spoolss_setprinterdata\n"));
4404 if (!OPEN_HANDLE(Printer)) {
4405 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4406 return ERROR_INVALID_HANDLE;
4409 if (!get_printer_snum(handle, &snum))
4410 return ERROR_INVALID_HANDLE;
4412 status = get_a_printer(&printer, 2, lp_servicename(snum));
4414 return ERROR_INVALID_NAME;
4416 convert_specific_param(¶m, value , type, data, real_len);
4417 unlink_specific_param_if_exist(printer->info_2, param);
4419 if (!add_a_specific_param(printer->info_2, param))
4420 status = ERROR_INVALID_PARAMETER;
4422 status = add_a_printer(*printer, 2);
4424 free_a_printer(&printer, 2);
4428 /****************************************************************************
4429 ****************************************************************************/
4430 uint32 _spoolss_addform( POLICY_HND *handle,
4435 nt_forms_struct *list=NULL;
4436 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4438 DEBUG(5,("spoolss_addform\n"));
4440 if (!OPEN_HANDLE(Printer)) {
4441 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4442 return ERROR_INVALID_HANDLE;
4445 count=get_ntforms(&list);
4446 if(!add_a_form(&list, form, &count))
4447 return ERROR_NOT_ENOUGH_MEMORY;
4448 write_ntforms(&list, count);
4455 /****************************************************************************
4456 ****************************************************************************/
4457 uint32 _spoolss_setform( POLICY_HND *handle,
4458 const UNISTR2 *uni_name,
4463 nt_forms_struct *list=NULL;
4464 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4466 DEBUG(5,("spoolss_setform\n"));
4468 if (!OPEN_HANDLE(Printer)) {
4469 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4470 return ERROR_INVALID_HANDLE;
4472 count=get_ntforms(&list);
4473 update_a_form(&list, form, count);
4474 write_ntforms(&list, count);
4481 /****************************************************************************
4482 enumprintprocessors level 1.
4483 ****************************************************************************/
4484 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4486 PRINTPROCESSOR_1 *info_1=NULL;
4488 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4489 return ERROR_NOT_ENOUGH_MEMORY;
4493 init_unistr(&(info_1->name), "winprint");
4495 *needed += spoolss_size_printprocessor_info_1(info_1);
4497 if (!alloc_buffer_size(buffer, *needed))
4498 return ERROR_INSUFFICIENT_BUFFER;
4500 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4504 if (*needed > offered) {
4506 return ERROR_INSUFFICIENT_BUFFER;
4509 return NT_STATUS_NO_PROBLEMO;
4512 /****************************************************************************
4513 ****************************************************************************/
4514 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
4515 NEW_BUFFER *buffer, uint32 offered,
4516 uint32 *needed, uint32 *returned)
4518 DEBUG(5,("spoolss_enumprintprocessors\n"));
4521 * Enumerate the print processors ...
4523 * Just reply with "winprint", to keep NT happy
4524 * and I can use my nice printer checker.
4532 return enumprintprocessors_level_1(buffer, offered, needed, returned);
4535 return ERROR_INVALID_LEVEL;
4540 /****************************************************************************
4541 enumprintprocdatatypes level 1.
4542 ****************************************************************************/
4543 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4545 PRINTPROCDATATYPE_1 *info_1=NULL;
4547 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
4548 return ERROR_NOT_ENOUGH_MEMORY;
4552 init_unistr(&(info_1->name), "RAW");
4554 *needed += spoolss_size_printprocdatatype_info_1(info_1);
4556 if (!alloc_buffer_size(buffer, *needed))
4557 return ERROR_INSUFFICIENT_BUFFER;
4559 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
4563 if (*needed > offered) {
4565 return ERROR_INSUFFICIENT_BUFFER;
4568 return NT_STATUS_NO_PROBLEMO;
4571 /****************************************************************************
4572 ****************************************************************************/
4573 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
4574 NEW_BUFFER *buffer, uint32 offered,
4575 uint32 *needed, uint32 *returned)
4577 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
4584 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
4587 return ERROR_INVALID_LEVEL;
4592 /****************************************************************************
4593 enumprintmonitors level 1.
4594 ****************************************************************************/
4595 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4597 PRINTMONITOR_1 *info_1=NULL;
4599 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
4600 return ERROR_NOT_ENOUGH_MEMORY;
4604 init_unistr(&(info_1->name), "Local Port");
4606 *needed += spoolss_size_printmonitor_info_1(info_1);
4608 if (!alloc_buffer_size(buffer, *needed))
4609 return ERROR_INSUFFICIENT_BUFFER;
4611 smb_io_printmonitor_info_1("", buffer, info_1, 0);
4615 if (*needed > offered) {
4617 return ERROR_INSUFFICIENT_BUFFER;
4620 return NT_STATUS_NO_PROBLEMO;
4623 /****************************************************************************
4624 enumprintmonitors level 2.
4625 ****************************************************************************/
4626 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4628 PRINTMONITOR_2 *info_2=NULL;
4630 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
4631 return ERROR_NOT_ENOUGH_MEMORY;
4635 init_unistr(&(info_2->name), "Local Port");
4636 init_unistr(&(info_2->environment), "Windows NT X86");
4637 init_unistr(&(info_2->dll_name), "localmon.dll");
4639 *needed += spoolss_size_printmonitor_info_2(info_2);
4641 if (!alloc_buffer_size(buffer, *needed))
4642 return ERROR_INSUFFICIENT_BUFFER;
4644 smb_io_printmonitor_info_2("", buffer, info_2, 0);
4648 if (*needed > offered) {
4650 return ERROR_INSUFFICIENT_BUFFER;
4653 return NT_STATUS_NO_PROBLEMO;
4656 /****************************************************************************
4657 ****************************************************************************/
4658 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
4659 NEW_BUFFER *buffer, uint32 offered,
4660 uint32 *needed, uint32 *returned)
4662 DEBUG(5,("spoolss_enumprintmonitors\n"));
4665 * Enumerate the print monitors ...
4667 * Just reply with "Local Port", to keep NT happy
4668 * and I can use my nice printer checker.
4676 return enumprintmonitors_level_1(buffer, offered, needed, returned);
4679 return enumprintmonitors_level_2(buffer, offered, needed, returned);
4682 return ERROR_INVALID_LEVEL;
4687 /****************************************************************************
4688 ****************************************************************************/
4689 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4693 JOB_INFO_1 *info_1=NULL;
4695 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
4697 if (info_1 == NULL) {
4699 return ERROR_NOT_ENOUGH_MEMORY;
4702 for (i=0; i<count && found==False; i++) {
4703 if (queue[i].job==(int)jobid)
4710 /* I shoud reply something else ... I can't find the good one */
4711 return NT_STATUS_NO_PROBLEMO;
4714 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
4718 *needed += spoolss_size_job_info_1(info_1);
4720 if (!alloc_buffer_size(buffer, *needed)) {
4722 return ERROR_INSUFFICIENT_BUFFER;
4725 new_smb_io_job_info_1("", buffer, info_1, 0);
4729 if (*needed > offered)
4730 return ERROR_INSUFFICIENT_BUFFER;
4732 return NT_STATUS_NO_PROBLEMO;
4736 /****************************************************************************
4737 ****************************************************************************/
4738 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4743 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
4745 ZERO_STRUCTP(info_2);
4747 if (info_2 == NULL) {
4749 return ERROR_NOT_ENOUGH_MEMORY;
4752 for (i=0; i<count && found==False; i++) {
4753 if (queue[i].job==(int)jobid)
4760 /* I shoud reply something else ... I can't find the good one */
4761 return NT_STATUS_NO_PROBLEMO;
4764 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
4768 *needed += spoolss_size_job_info_2(info_2);
4770 if (!alloc_buffer_size(buffer, *needed)) {
4772 return ERROR_INSUFFICIENT_BUFFER;
4775 new_smb_io_job_info_2("", buffer, info_2, 0);
4777 free_dev_mode(info_2->devmode);
4780 if (*needed > offered)
4781 return ERROR_INSUFFICIENT_BUFFER;
4783 return NT_STATUS_NO_PROBLEMO;
4786 /****************************************************************************
4787 ****************************************************************************/
4788 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
4789 NEW_BUFFER *buffer, uint32 offered,
4794 print_queue_struct *queue=NULL;
4795 print_status_struct prt_status;
4797 DEBUG(5,("spoolss_getjob\n"));
4799 memset(&prt_status, 0, sizeof(prt_status));
4803 if (!get_printer_snum(handle, &snum))
4804 return ERROR_INVALID_HANDLE;
4806 count = print_queue_status(snum, &queue, &prt_status);
4808 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
4809 count, prt_status.status, prt_status.message));
4813 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
4816 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
4820 return ERROR_INVALID_LEVEL;