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 free_a_printer(&printer,2);
2653 return ERROR_UNKNOWN_PRINTER_DRIVER;
2656 fill_printer_driver_info_3(info, driver, servername);
2658 free_a_printer(&printer,2);
2660 return NT_STATUS_NO_PROBLEMO;
2663 /****************************************************************************
2664 ****************************************************************************/
2666 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
2668 safe_free(info->dependentfiles);
2671 /****************************************************************************
2672 ****************************************************************************/
2673 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2675 DRIVER_INFO_1 *info=NULL;
2678 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
2679 return ERROR_NOT_ENOUGH_MEMORY;
2681 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
2682 if (status != NT_STATUS_NO_PROBLEMO) {
2687 /* check the required size. */
2688 *needed += spoolss_size_printer_driver_info_1(info);
2690 if (!alloc_buffer_size(buffer, *needed)) {
2692 return ERROR_INSUFFICIENT_BUFFER;
2695 /* fill the buffer with the structures */
2696 new_smb_io_printer_driver_info_1("", buffer, info, 0);
2701 if (*needed > offered)
2702 return ERROR_INSUFFICIENT_BUFFER;
2704 return NT_STATUS_NO_PROBLEMO;
2707 /****************************************************************************
2708 ****************************************************************************/
2709 static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2711 DRIVER_INFO_2 *info=NULL;
2714 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
2715 return ERROR_NOT_ENOUGH_MEMORY;
2717 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
2718 if (status != NT_STATUS_NO_PROBLEMO) {
2723 /* check the required size. */
2724 *needed += spoolss_size_printer_driver_info_2(info);
2726 if (!alloc_buffer_size(buffer, *needed)) {
2728 return ERROR_INSUFFICIENT_BUFFER;
2731 /* fill the buffer with the structures */
2732 new_smb_io_printer_driver_info_2("", buffer, info, 0);
2737 if (*needed > offered)
2738 return ERROR_INSUFFICIENT_BUFFER;
2740 return NT_STATUS_NO_PROBLEMO;
2743 /****************************************************************************
2744 ****************************************************************************/
2745 static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2752 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
2753 if (status != NT_STATUS_NO_PROBLEMO) {
2757 /* check the required size. */
2758 *needed += spoolss_size_printer_driver_info_3(&info);
2760 if (!alloc_buffer_size(buffer, *needed)) {
2761 free_printer_driver_info_3(&info);
2762 return ERROR_INSUFFICIENT_BUFFER;
2765 /* fill the buffer with the structures */
2766 new_smb_io_printer_driver_info_3("", buffer, &info, 0);
2768 free_printer_driver_info_3(&info);
2770 if (*needed > offered)
2771 return ERROR_INSUFFICIENT_BUFFER;
2773 return NT_STATUS_NO_PROBLEMO;
2776 /****************************************************************************
2777 ****************************************************************************/
2778 uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level,
2779 uint32 clientmajorversion, uint32 clientminorversion,
2780 NEW_BUFFER *buffer, uint32 offered,
2781 uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
2784 fstring architecture;
2787 DEBUG(4,("_spoolss_getprinterdriver2\n"));
2790 *servermajorversion=0;
2791 *serverminorversion=0;
2793 pstrcpy(servername, global_myname);
2794 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
2796 if (!get_printer_snum(handle, &snum))
2797 return ERROR_INVALID_HANDLE;
2801 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2804 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2807 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2810 return ERROR_INVALID_LEVEL;
2815 /****************************************************************************
2816 ****************************************************************************/
2817 uint32 _spoolss_startpageprinter(POLICY_HND *handle)
2819 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2821 if (OPEN_HANDLE(Printer)) {
2822 Printer->page_started=True;
2826 DEBUG(3,("Error in startpageprinter printer handle\n"));
2827 return ERROR_INVALID_HANDLE;
2830 /****************************************************************************
2831 ****************************************************************************/
2832 uint32 _spoolss_endpageprinter(POLICY_HND *handle)
2834 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2836 if (!OPEN_HANDLE(Printer)) {
2837 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
2838 return ERROR_INVALID_HANDLE;
2841 Printer->page_started=False;
2843 return NT_STATUS_NO_PROBLEMO;
2847 /********************************************************************
2848 * api_spoolss_getprinter
2849 * called from the spoolss dispatcher
2851 ********************************************************************/
2852 uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
2853 pipes_struct *p, DOC_INFO *docinfo,
2856 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
2860 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2861 struct current_user user;
2863 if (!OPEN_HANDLE(Printer)) {
2864 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2865 return ERROR_INVALID_HANDLE;
2868 if (p->ntlmssp_auth_validated) {
2869 memcpy(&user, &p->pipe_user, sizeof(user));
2871 extern struct current_user current_user;
2872 memcpy(&user, ¤t_user, sizeof(user));
2876 * a nice thing with NT is it doesn't listen to what you tell it.
2877 * when asked to send _only_ RAW datas, it tries to send datas
2880 * So I add checks like in NT Server ...
2882 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
2883 * there's a bug in NT client-side code, so we'll fix it in the
2884 * server-side code. *nnnnnggggh!*
2887 if (info_1->p_datatype != 0)
2889 unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype));
2890 if (strcmp(datatype, "RAW") != 0)
2893 return ERROR_INVALID_DATATYPE;
2897 /* get the share number of the printer */
2898 if (!get_printer_snum(handle, &snum))
2900 return ERROR_INVALID_HANDLE;
2903 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
2905 Printer->jobid = print_job_start(&user, snum, jobname);
2907 /* need to map error codes properly - for now give out of
2908 memory as I don't know the correct codes (tridge) */
2909 if (Printer->jobid == -1) {
2910 return ERROR_NOT_ENOUGH_MEMORY;
2913 Printer->document_started=True;
2914 (*jobid) = Printer->jobid;
2919 /********************************************************************
2920 * api_spoolss_getprinter
2921 * called from the spoolss dispatcher
2923 ********************************************************************/
2924 uint32 _spoolss_enddocprinter(POLICY_HND *handle)
2926 Printer_entry *Printer=find_printer_index_by_hnd(handle);
2928 if (!OPEN_HANDLE(Printer)) {
2929 DEBUG(0,("_spoolss_enddocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2930 return ERROR_INVALID_HANDLE;
2933 Printer->document_started=False;
2934 print_job_end(Printer->jobid);
2935 /* error codes unhandled so far ... */
2940 /****************************************************************************
2941 ****************************************************************************/
2942 uint32 _spoolss_writeprinter( POLICY_HND *handle,
2945 uint32 *buffer_written)
2947 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2949 if (!OPEN_HANDLE(Printer)) {
2950 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
2951 return ERROR_INVALID_HANDLE;
2954 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer,
2960 /********************************************************************
2961 * api_spoolss_getprinter
2962 * called from the spoolss dispatcher
2964 ********************************************************************/
2965 static uint32 control_printer(POLICY_HND *handle, uint32 command,
2968 struct current_user user;
2970 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2972 if (p->ntlmssp_auth_validated) {
2973 memcpy(&user, &p->pipe_user, sizeof(user));
2975 extern struct current_user current_user;
2976 memcpy(&user, ¤t_user, sizeof(user));
2979 if (!OPEN_HANDLE(Printer)) {
2980 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2981 return ERROR_INVALID_HANDLE;
2984 if (!get_printer_snum(handle, &snum) )
2985 return ERROR_INVALID_HANDLE;
2988 case PRINTER_CONTROL_PAUSE:
2989 if (print_queue_pause(&user, snum)) {
2993 case PRINTER_CONTROL_RESUME:
2994 case PRINTER_CONTROL_UNPAUSE:
2995 if (print_queue_resume(&user, snum)) {
2999 case PRINTER_CONTROL_PURGE:
3000 if (print_queue_purge(&user, snum)) {
3006 return ERROR_INVALID_FUNCTION;
3009 /********************************************************************
3010 * called by spoolss_api_setprinter
3011 * when updating a printer description
3012 ********************************************************************/
3013 static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
3014 const SPOOL_PRINTER_INFO_LEVEL *info,
3015 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
3017 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3018 struct current_user user;
3019 uint32 acc_granted, status, result;
3021 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3023 if (!OPEN_HANDLE(Printer)) {
3024 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3025 return ERROR_INVALID_HANDLE;
3028 /* Work out which user is performing the operation */
3030 if (p->ntlmssp_auth_validated) {
3031 memcpy(&user, &p->pipe_user, sizeof(user));
3033 extern struct current_user current_user;
3034 memcpy(&user, ¤t_user, sizeof(user));
3037 /* Get old security descriptor */
3039 if (!nt_printing_getsec(Printer->dev.handlename, &old_secdesc_ctr)) {
3040 DEBUG(3, ("could not get old security descriptor for "
3041 "printer %s", Printer->dev.handlename));
3042 return ERROR_INVALID_FUNCTION;
3045 /* Check the user has permissions to change the security
3046 descriptor. By experimentation with two NT machines, the user
3047 requires Full Access to the printer to change security
3050 if (!se_access_check(old_secdesc_ctr->sec, &user,
3051 PRINTER_ACE_FULL_CONTROL, &acc_granted,
3053 DEBUG(3, ("security descriptor change denied by existing "
3054 "security descriptor\n"));
3059 result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
3062 free_sec_desc_buf(&old_secdesc_ctr);
3066 /********************************************************************
3067 Do Samba sanity checks on a printer info struct.
3068 ********************************************************************/
3070 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
3073 * Ensure that this printer is shared under the correct name
3074 * as this is what Samba insists upon.
3077 if (!(info->attributes & PRINTER_ATTRIBUTE_SHARED)) {
3078 DEBUG(10,("check_printer_ok: SHARED check failed (%x).\n", (unsigned int)info->attributes ));
3082 if (!(info->attributes & PRINTER_ATTRIBUTE_RAW_ONLY)) {
3083 /* NT forgets to set the raw attribute but sends the correct type. */
3084 if (strequal(info->datatype, "RAW"))
3085 info->attributes |= PRINTER_ATTRIBUTE_RAW_ONLY;
3087 DEBUG(10,("check_printer_ok: RAW check failed (%x).\n", (unsigned int)info->attributes ));
3092 if (!strequal(info->sharename, lp_servicename(snum))) {
3093 DEBUG(10,("check_printer_ok: NAME check failed (%s) (%s).\n", info->sharename, lp_servicename(snum)));
3100 /********************************************************************
3101 * called by spoolss_api_setprinter
3102 * when updating a printer description
3103 ********************************************************************/
3105 static uint32 update_printer(POLICY_HND *handle, uint32 level,
3106 const SPOOL_PRINTER_INFO_LEVEL *info,
3107 DEVICEMODE *devmode)
3110 NT_PRINTER_INFO_LEVEL *printer = NULL;
3111 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3112 SEC_DESC_BUF *sd = NULL;
3113 uint32 result, acc_granted;
3114 extern struct current_user current_user;
3116 DEBUG(8,("update_printer\n"));
3118 result = NT_STATUS_NO_PROBLEMO;
3120 /* Check calling user has permission to update printer description */
3123 if (!nt_printing_getsec(Printer->dev.handlename, &sd)) {
3124 DEBUG(3, ("Could not get security descriptor for printer %s",
3125 Printer->dev.handlename));
3126 result = ERROR_INVALID_FUNCTION;
3130 if (!se_access_check(sd->sec, ¤t_user,
3131 PRINTER_ACE_FULL_CONTROL, &acc_granted,
3133 DEBUG(3, ("printer property change denied by security "
3139 DEBUG(0,("Send a mail to samba@samba.org\n"));
3140 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3141 result = ERROR_INVALID_LEVEL;
3145 if (!OPEN_HANDLE(Printer)) {
3146 result = ERROR_INVALID_HANDLE;
3150 if (!get_printer_snum(handle, &snum)) {
3151 result = ERROR_INVALID_HANDLE;
3155 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3156 result = ERROR_INVALID_HANDLE;
3160 DEBUGADD(8,("Converting info_2 struct\n"));
3163 * convert_printer_info converts the incoming
3164 * info from the client and overwrites the info
3165 * just read from the tdb in the pointer 'printer'.
3168 convert_printer_info(info, printer, level);
3170 if (info->info_2->devmode_ptr != 0) {
3171 /* we have a valid devmode
3172 convert it and link it*/
3175 * Ensure printer->info_2->devmode is a valid pointer
3176 * as we will be overwriting it in convert_devicemode().
3179 if (printer->info_2->devmode == NULL)
3180 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3182 DEBUGADD(8,("Converting the devicemode struct\n"));
3183 convert_devicemode(devmode, printer->info_2->devmode);
3186 if (printer->info_2->devmode != NULL)
3187 free_nt_devicemode(&printer->info_2->devmode);
3188 printer->info_2->devmode=NULL;
3192 * Do sanity check on the requested changes for Samba.
3195 if (!check_printer_ok(printer->info_2, snum)) {
3196 result = ERROR_ACCESS_DENIED;
3200 if (add_a_printer(*printer, 2)!=0) {
3201 /* I don't really know what to return here !!! */
3202 result = ERROR_ACCESS_DENIED;
3207 free_a_printer(&printer, 2);
3208 free_sec_desc_buf(&sd);
3213 /****************************************************************************
3214 ****************************************************************************/
3215 uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
3216 const SPOOL_PRINTER_INFO_LEVEL *info,
3217 DEVMODE_CTR devmode_ctr,
3218 SEC_DESC_BUF *secdesc_ctr,
3219 uint32 command, pipes_struct *p)
3221 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3223 if (!OPEN_HANDLE(Printer)) {
3224 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3225 return ERROR_INVALID_HANDLE;
3228 /* check the level */
3231 return control_printer(handle, command, p);
3234 return update_printer(handle, level, info, devmode_ctr.devmode);
3237 return update_printer_sec(handle, level, info, p,
3241 return ERROR_INVALID_LEVEL;
3246 /****************************************************************************
3247 ****************************************************************************/
3248 uint32 _spoolss_fcpn(POLICY_HND *handle)
3250 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3252 if (!OPEN_HANDLE(Printer)) {
3253 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3254 return ERROR_INVALID_HANDLE;
3257 Printer->notify.flags=0;
3258 Printer->notify.options=0;
3259 Printer->notify.localmachine[0]='\0';
3260 Printer->notify.printerlocal=0;
3261 if (Printer->notify.option)
3262 safe_free(Printer->notify.option->ctr.type);
3263 safe_free(Printer->notify.option);
3264 Printer->notify.option=NULL;
3266 return NT_STATUS_NO_PROBLEMO;
3269 /****************************************************************************
3270 ****************************************************************************/
3271 uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
3272 NEW_BUFFER *buffer, uint32 offered)
3274 return NT_STATUS_NO_PROBLEMO;
3277 /****************************************************************************
3278 ****************************************************************************/
3279 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3280 int position, int snum)
3285 time_t unixdate = time(NULL);
3287 t=gmtime(&unixdate);
3288 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3290 job_info->jobid=queue->job;
3291 init_unistr(&job_info->printername, lp_servicename(snum));
3292 init_unistr(&job_info->machinename, temp_name);
3293 init_unistr(&job_info->username, queue->user);
3294 init_unistr(&job_info->document, queue->file);
3295 init_unistr(&job_info->datatype, "RAW");
3296 init_unistr(&job_info->text_status, "");
3297 job_info->status=nt_printj_status(queue->status);
3298 job_info->priority=queue->priority;
3299 job_info->position=position;
3300 job_info->totalpages=0;
3301 job_info->pagesprinted=0;
3303 make_systemtime(&(job_info->submitted), t);
3306 /****************************************************************************
3307 ****************************************************************************/
3308 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3309 int position, int snum)
3312 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3316 time_t unixdate = time(NULL);
3318 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3321 t=gmtime(&unixdate);
3322 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3324 job_info->jobid=queue->job;
3326 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3328 init_unistr(&(job_info->printername), chaine);
3330 init_unistr(&job_info->machinename, temp_name);
3331 init_unistr(&job_info->username, queue->user);
3332 init_unistr(&job_info->document, queue->file);
3333 init_unistr(&job_info->notifyname, queue->user);
3334 init_unistr(&job_info->datatype, "RAW");
3335 init_unistr(&job_info->printprocessor, "winprint");
3336 init_unistr(&job_info->parameters, "");
3337 init_unistr(&job_info->text_status, "");
3339 /* and here the security descriptor */
3341 job_info->status=nt_printj_status(queue->status);
3342 job_info->priority=queue->priority;
3343 job_info->position=position;
3344 job_info->starttime=0;
3345 job_info->untiltime=0;
3346 job_info->totalpages=0;
3347 job_info->size=queue->size;
3348 make_systemtime(&(job_info->submitted), t);
3349 job_info->timeelapsed=0;
3350 job_info->pagesprinted=0;
3352 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3353 free_a_printer(&ntprinter, 2);
3357 free_a_printer(&ntprinter, 2);
3361 /****************************************************************************
3362 Enumjobs at level 1.
3363 ****************************************************************************/
3364 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3365 NEW_BUFFER *buffer, uint32 offered,
3366 uint32 *needed, uint32 *returned)
3371 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3375 return ERROR_NOT_ENOUGH_MEMORY;
3378 for (i=0; i<*returned; i++)
3379 fill_job_info_1(&info[i], &queue[i], i, snum);
3383 /* check the required size. */
3384 for (i=0; i<*returned; i++)
3385 (*needed) += spoolss_size_job_info_1(&info[i]);
3387 if (!alloc_buffer_size(buffer, *needed)) {
3389 return ERROR_INSUFFICIENT_BUFFER;
3392 /* fill the buffer with the structures */
3393 for (i=0; i<*returned; i++)
3394 new_smb_io_job_info_1("", buffer, &info[i], 0);
3399 if (*needed > offered) {
3401 return ERROR_INSUFFICIENT_BUFFER;
3404 return NT_STATUS_NO_PROBLEMO;
3407 /****************************************************************************
3408 Enumjobs at level 2.
3409 ****************************************************************************/
3410 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3411 NEW_BUFFER *buffer, uint32 offered,
3412 uint32 *needed, uint32 *returned)
3417 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3421 return ERROR_NOT_ENOUGH_MEMORY;
3424 for (i=0; i<*returned; i++)
3425 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3429 /* check the required size. */
3430 for (i=0; i<*returned; i++)
3431 (*needed) += spoolss_size_job_info_2(&info[i]);
3433 if (!alloc_buffer_size(buffer, *needed)) {
3435 return ERROR_INSUFFICIENT_BUFFER;
3438 /* fill the buffer with the structures */
3439 for (i=0; i<*returned; i++)
3440 new_smb_io_job_info_2("", buffer, &info[i], 0);
3445 if (*needed > offered) {
3447 return ERROR_INSUFFICIENT_BUFFER;
3450 return NT_STATUS_NO_PROBLEMO;
3453 /****************************************************************************
3455 ****************************************************************************/
3456 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3457 NEW_BUFFER *buffer, uint32 offered,
3458 uint32 *needed, uint32 *returned)
3461 print_queue_struct *queue=NULL;
3462 print_status_struct prt_status;
3464 DEBUG(4,("_spoolss_enumjobs\n"));
3466 ZERO_STRUCT(prt_status);
3471 if (!get_printer_snum(handle, &snum))
3472 return ERROR_INVALID_HANDLE;
3474 *returned = print_queue_status(snum, &queue, &prt_status);
3475 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3479 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3482 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3487 return ERROR_INVALID_LEVEL;
3493 /****************************************************************************
3494 ****************************************************************************/
3495 uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid)
3500 /****************************************************************************
3501 ****************************************************************************/
3502 uint32 _spoolss_setjob( POLICY_HND *handle,
3510 struct current_user user;
3512 print_status_struct prt_status;
3514 memset(&prt_status, 0, sizeof(prt_status));
3516 if (!get_printer_snum(handle, &snum)) {
3517 return ERROR_INVALID_HANDLE;
3520 if (!print_job_exists(jobid)) {
3521 return ERROR_INVALID_PRINTER_NAME;
3524 if (p->ntlmssp_auth_validated) {
3525 memcpy(&user, &p->pipe_user, sizeof(user));
3527 extern struct current_user current_user;
3528 memcpy(&user, ¤t_user, sizeof(user));
3532 case JOB_CONTROL_CANCEL:
3533 case JOB_CONTROL_DELETE:
3534 if (print_job_delete(&user, jobid)) return 0x0;
3536 case JOB_CONTROL_PAUSE:
3537 if (print_job_pause(&user, jobid)) return 0x0;
3539 case JOB_CONTROL_RESUME:
3540 if (print_job_resume(&user, jobid)) return 0x0;
3543 return ERROR_INVALID_LEVEL;
3546 return ERROR_INVALID_HANDLE;
3549 /****************************************************************************
3550 Enumerates all printer drivers at level 1.
3551 ****************************************************************************/
3552 static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3557 fstring *list = NULL;
3559 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3560 DRIVER_INFO_1 *driver_info_1=NULL;
3564 #define MAX_VERSION 4
3566 for (version=0; version<MAX_VERSION; version++) {
3568 ndrivers=get_ntdrivers(&list, architecture, version);
3569 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3572 return ERROR_NOT_ENOUGH_MEMORY;
3575 if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
3577 return ERROR_NOT_ENOUGH_MEMORY;
3581 for (i=0; i<ndrivers; i++) {
3582 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3583 ZERO_STRUCT(driver);
3584 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3585 fill_printer_driver_info_1(&(driver_info_1[*returned+i]), driver, servername, architecture );
3588 *returned+=ndrivers;
3592 /* check the required size. */
3593 for (i=0; i<*returned; i++) {
3594 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3595 *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
3598 if (!alloc_buffer_size(buffer, *needed)) {
3599 safe_free(driver_info_1);
3600 return ERROR_INSUFFICIENT_BUFFER;
3603 /* fill the buffer with the form structures */
3604 for (i=0; i<*returned; i++) {
3605 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3606 new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
3609 safe_free(driver_info_1);
3611 if (*needed > offered) {
3613 return ERROR_INSUFFICIENT_BUFFER;
3616 return NT_STATUS_NO_PROBLEMO;
3619 /****************************************************************************
3620 Enumerates all printer drivers at level 2.
3621 ****************************************************************************/
3622 static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3627 fstring *list = NULL;
3629 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3630 DRIVER_INFO_2 *driver_info_2=NULL;
3634 #define MAX_VERSION 4
3636 for (version=0; version<MAX_VERSION; version++) {
3638 ndrivers=get_ntdrivers(&list, architecture, version);
3639 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3642 return ERROR_NOT_ENOUGH_MEMORY;
3645 if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
3647 return ERROR_NOT_ENOUGH_MEMORY;
3651 for (i=0; i<ndrivers; i++) {
3652 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3653 ZERO_STRUCT(driver);
3654 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3655 fill_printer_driver_info_2(&(driver_info_2[*returned+i]), driver, servername);
3658 *returned+=ndrivers;
3662 /* check the required size. */
3663 for (i=0; i<*returned; i++) {
3664 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3665 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3668 if (!alloc_buffer_size(buffer, *needed)) {
3669 safe_free(driver_info_2);
3670 return ERROR_INSUFFICIENT_BUFFER;
3673 /* fill the buffer with the form structures */
3674 for (i=0; i<*returned; i++) {
3675 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3676 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3679 safe_free(driver_info_2);
3681 if (*needed > offered) {
3683 return ERROR_INSUFFICIENT_BUFFER;
3686 return NT_STATUS_NO_PROBLEMO;
3689 /****************************************************************************
3690 Enumerates all printer drivers at level 3.
3691 ****************************************************************************/
3692 static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3697 fstring *list = NULL;
3699 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3700 DRIVER_INFO_3 *driver_info_3=NULL;
3704 #define MAX_VERSION 4
3706 for (version=0; version<MAX_VERSION; version++) {
3708 ndrivers=get_ntdrivers(&list, architecture, version);
3709 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3712 return ERROR_NOT_ENOUGH_MEMORY;
3715 if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
3717 return ERROR_NOT_ENOUGH_MEMORY;
3721 for (i=0; i<ndrivers; i++) {
3722 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3723 ZERO_STRUCT(driver);
3724 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3725 fill_printer_driver_info_3(&(driver_info_3[*returned+i]), driver, servername);
3728 *returned+=ndrivers;
3732 /* check the required size. */
3733 for (i=0; i<*returned; i++) {
3734 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3735 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3738 if (!alloc_buffer_size(buffer, *needed)) {
3739 safe_free(driver_info_3);
3740 return ERROR_INSUFFICIENT_BUFFER;
3743 /* fill the buffer with the driver structures */
3744 for (i=0; i<*returned; i++) {
3745 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3746 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
3749 for (i=0; i<*returned; i++)
3750 safe_free(driver_info_3[i].dependentfiles);
3752 safe_free(driver_info_3);
3754 if (*needed > offered) {
3756 return ERROR_INSUFFICIENT_BUFFER;
3759 return NT_STATUS_NO_PROBLEMO;
3762 /****************************************************************************
3763 Enumerates all printer drivers.
3764 ****************************************************************************/
3765 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
3766 NEW_BUFFER *buffer, uint32 offered,
3767 uint32 *needed, uint32 *returned)
3769 fstring *list = NULL;
3771 fstring architecture;
3773 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
3774 fstrcpy(servername, global_myname);
3778 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
3782 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
3785 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
3788 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
3793 return ERROR_INVALID_LEVEL;
3798 /****************************************************************************
3799 ****************************************************************************/
3800 static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
3802 form->flag=list->flag;
3803 init_unistr(&form->name, list->name);
3804 form->width=list->width;
3805 form->length=list->length;
3806 form->left=list->left;
3807 form->top=list->top;
3808 form->right=list->right;
3809 form->bottom=list->bottom;
3812 /****************************************************************************
3813 ****************************************************************************/
3814 uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
3815 NEW_BUFFER *buffer, uint32 offered,
3816 uint32 *needed, uint32 *numofforms)
3818 nt_forms_struct *list=NULL;
3823 DEBUG(4,("_new_spoolss_enumforms\n"));
3824 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3825 DEBUGADD(5,("Info level [%d]\n", level));
3827 *numofforms = get_ntforms(&list);
3828 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
3830 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
3834 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
3836 return ERROR_NOT_ENOUGH_MEMORY;
3839 /* construct the list of form structures */
3840 for (i=0; i<*numofforms; i++) {
3841 DEBUGADD(6,("Filling form number [%d]\n",i));
3842 fill_form_1(&forms_1[i], &list[i], i);
3847 /* check the required size. */
3848 for (i=0; i<*numofforms; i++) {
3849 DEBUGADD(6,("adding form [%d]'s size\n",i));
3850 buffer_size += spoolss_size_form_1(&forms_1[i]);
3853 *needed=buffer_size;
3855 if (!alloc_buffer_size(buffer, buffer_size)){
3857 return ERROR_INSUFFICIENT_BUFFER;
3860 /* fill the buffer with the form structures */
3861 for (i=0; i<*numofforms; i++) {
3862 DEBUGADD(6,("adding form [%d] to buffer\n",i));
3863 new_smb_io_form_1("", buffer, &forms_1[i], 0);
3868 if (*needed > offered) {
3870 return ERROR_INSUFFICIENT_BUFFER;
3873 return NT_STATUS_NO_PROBLEMO;
3877 return ERROR_INVALID_LEVEL;
3882 /****************************************************************************
3883 ****************************************************************************/
3884 static void fill_port_1(PORT_INFO_1 *port, char *name)
3886 init_unistr(&port->port_name, name);
3889 /****************************************************************************
3890 ****************************************************************************/
3891 static void fill_port_2(PORT_INFO_2 *port, char *name)
3893 init_unistr(&port->port_name, name);
3894 init_unistr(&port->monitor_name, "Local Monitor");
3895 init_unistr(&port->description, "Local Port");
3896 #define PORT_TYPE_WRITE 1
3897 port->port_type=PORT_TYPE_WRITE;
3901 /****************************************************************************
3903 ****************************************************************************/
3904 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3906 int n_services=lp_numservices();
3910 PORT_INFO_1 *ports=NULL;
3912 for (snum=0; snum<n_services; snum++)
3913 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3916 if((ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) )) == NULL)
3917 return ERROR_NOT_ENOUGH_MEMORY;
3919 for (snum=0; snum<n_services; snum++) {
3920 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3922 * Ensure this port name is unique.
3926 DEBUG(10,("enumports_level_1: port name %s\n", PRINTERNAME(snum)));
3928 for(j = 0; j < i; j++) {
3930 unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
3932 if (strequal(port_name, PRINTERNAME(snum)))
3939 DEBUGADD(6,("Filling port number [%d]\n", i));
3940 fill_port_1(&ports[i], PRINTERNAME(snum));
3947 /* check the required size. */
3948 for (i=0; i<*returned; i++) {
3949 DEBUGADD(6,("adding port [%d]'s size\n", i));
3950 *needed += spoolss_size_port_info_1(&ports[i]);
3953 if (!alloc_buffer_size(buffer, *needed)) {
3955 return ERROR_INSUFFICIENT_BUFFER;
3958 /* fill the buffer with the ports structures */
3959 for (i=0; i<*returned; i++) {
3960 DEBUGADD(6,("adding port [%d] to buffer\n", i));
3961 new_smb_io_port_1("", buffer, &ports[i], 0);
3966 if (*needed > offered) {
3968 return ERROR_INSUFFICIENT_BUFFER;
3971 return NT_STATUS_NO_PROBLEMO;
3974 /****************************************************************************
3976 ****************************************************************************/
3978 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3980 int n_services=lp_numservices();
3984 PORT_INFO_2 *ports=NULL;
3986 for (snum=0; snum<n_services; snum++)
3987 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3990 if((ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) )) == NULL)
3991 return ERROR_NOT_ENOUGH_MEMORY;
3993 for (snum=0; snum<n_services; snum++) {
3994 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3996 * Ensure this port name is unique.
4000 DEBUG(10,("enumports_level_2: port name %s\n", PRINTERNAME(snum)));
4002 for(j = 0; j < i; j++) {
4004 unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
4006 if (strequal(port_name, PRINTERNAME(snum)))
4013 DEBUGADD(6,("Filling port number [%d]\n", i));
4014 fill_port_2(&ports[i], PRINTERNAME(snum));
4021 /* check the required size. */
4022 for (i=0; i<*returned; i++) {
4023 DEBUGADD(6,("adding port [%d]'s size\n", i));
4024 *needed += spoolss_size_port_info_2(&ports[i]);
4027 if (!alloc_buffer_size(buffer, *needed)) {
4029 return ERROR_INSUFFICIENT_BUFFER;
4032 /* fill the buffer with the ports structures */
4033 for (i=0; i<*returned; i++) {
4034 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4035 new_smb_io_port_2("", buffer, &ports[i], 0);
4040 if (*needed > offered) {
4042 return ERROR_INSUFFICIENT_BUFFER;
4045 return NT_STATUS_NO_PROBLEMO;
4048 /****************************************************************************
4050 ****************************************************************************/
4051 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
4052 NEW_BUFFER *buffer, uint32 offered,
4053 uint32 *needed, uint32 *returned)
4055 DEBUG(4,("_spoolss_enumports\n"));
4062 return enumports_level_1(buffer, offered, needed, returned);
4065 return enumports_level_2(buffer, offered, needed, returned);
4068 return ERROR_INVALID_LEVEL;
4073 /****************************************************************************
4074 ****************************************************************************/
4075 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
4076 const SPOOL_PRINTER_INFO_LEVEL *info,
4077 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4078 uint32 user_switch, const SPOOL_USER_CTR *user,
4081 NT_PRINTER_INFO_LEVEL *printer = NULL;
4086 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
4087 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
4088 return ERROR_NOT_ENOUGH_MEMORY;
4091 ZERO_STRUCTP(printer);
4093 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
4094 convert_printer_info(info, printer, 2);
4096 unistr2_to_ascii(share_name, &info->info_2->sharename, sizeof(share_name)-1);
4098 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
4100 if ((snum = print_queue_snum(share_name)) == -1) {
4101 free_a_printer(&printer,2);
4102 return ERROR_ACCESS_DENIED;
4106 * Do sanity check on the requested changes for Samba.
4109 if (!check_printer_ok(printer->info_2, snum)) {
4110 free_a_printer(&printer,2);
4111 return ERROR_ACCESS_DENIED;
4114 /* write the ASCII on disk */
4115 if (add_a_printer(*printer, 2) != 0) {
4116 free_a_printer(&printer,2);
4117 return ERROR_ACCESS_DENIED;
4120 if (!open_printer_hnd(handle, name)) {
4121 /* Handle open failed - remove addition. */
4122 del_a_printer(share_name);
4123 free_a_printer(&printer,2);
4124 return ERROR_ACCESS_DENIED;
4127 free_a_printer(&printer,2);
4128 return NT_STATUS_NO_PROBLEMO;
4131 /****************************************************************************
4132 ****************************************************************************/
4133 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4134 const SPOOL_PRINTER_INFO_LEVEL *info,
4135 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4136 uint32 user_switch, const SPOOL_USER_CTR *user,
4141 /* we don't handle yet */
4142 /* but I know what to do ... */
4143 return ERROR_INVALID_LEVEL;
4146 return spoolss_addprinterex_level_2(uni_srv_name, info,
4147 unk0, unk1, unk2, unk3,
4148 user_switch, user, handle);
4151 return ERROR_INVALID_LEVEL;
4156 /****************************************************************************
4157 ****************************************************************************/
4158 uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
4159 uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4161 uint32 err = NT_STATUS_NO_PROBLEMO;
4162 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4163 struct current_user user;
4165 ZERO_STRUCT(driver);
4167 if (p->ntlmssp_auth_validated) {
4168 memcpy(&user, &p->pipe_user, sizeof(user));
4170 extern struct current_user current_user;
4171 memcpy(&user, ¤t_user, sizeof(user));
4174 convert_printer_driver_info(info, &driver, level);
4176 DEBUG(5,("Cleaning driver's information\n"));
4177 clean_up_driver_struct(driver, level);
4179 DEBUG(5,("Moving driver to final destination\n"));
4180 if(!move_driver_to_download_area(driver, level, &user)) {
4181 err = ERROR_ACCESS_DENIED;
4185 if (add_a_printer_driver(driver, level)!=0) {
4186 err = ERROR_ACCESS_DENIED;
4191 free_a_printer_driver(driver, level);
4195 /****************************************************************************
4196 ****************************************************************************/
4197 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4199 init_unistr(&info->name, name);
4202 /****************************************************************************
4203 ****************************************************************************/
4204 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4208 pstring short_archi;
4209 DRIVER_DIRECTORY_1 *info=NULL;
4211 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4213 if (get_short_archi(short_archi, long_archi)==FALSE)
4214 return ERROR_INVALID_ENVIRONMENT;
4216 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4217 return ERROR_NOT_ENOUGH_MEMORY;
4219 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
4221 DEBUG(4,("printer driver directory: [%s]\n", path));
4223 fill_driverdir_1(info, path);
4225 *needed += spoolss_size_driverdir_info_1(info);
4227 if (!alloc_buffer_size(buffer, *needed)) {
4229 return ERROR_INSUFFICIENT_BUFFER;
4232 new_smb_io_driverdir_1("", buffer, info, 0);
4236 if (*needed > offered)
4237 return ERROR_INSUFFICIENT_BUFFER;
4239 return NT_STATUS_NO_PROBLEMO;
4242 /****************************************************************************
4243 ****************************************************************************/
4244 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4245 NEW_BUFFER *buffer, uint32 offered,
4248 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4254 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4257 return ERROR_INVALID_LEVEL;
4262 /****************************************************************************
4263 ****************************************************************************/
4264 uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
4265 uint32 in_value_len, uint32 in_data_len,
4266 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4268 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4270 NT_PRINTER_INFO_LEVEL *printer = NULL;
4275 uint32 biggest_valuesize;
4276 uint32 biggest_datasize;
4278 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4283 ZERO_STRUCT(printer);
4285 *out_max_value_len=0;
4291 *out_max_data_len=0;
4295 DEBUG(5,("spoolss_enumprinterdata\n"));
4297 if (!OPEN_HANDLE(Printer)) {
4298 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4299 return ERROR_INVALID_HANDLE;
4302 if (!get_printer_snum(handle, &snum))
4303 return ERROR_INVALID_HANDLE;
4305 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4306 return ERROR_INVALID_HANDLE;
4309 * The NT machine wants to know the biggest size of value and data
4311 * cf: MSDN EnumPrinterData remark section
4313 if ( (in_value_len==0) && (in_data_len==0) ) {
4314 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4317 biggest_valuesize=0;
4320 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4321 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4322 if (data_len > biggest_datasize) biggest_datasize=data_len;
4324 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4330 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4331 *out_value_len=2*(1+biggest_valuesize);
4332 *out_data_len=biggest_datasize;
4334 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4336 free_a_printer(&printer, 2);
4337 return NT_STATUS_NO_PROBLEMO;
4341 * the value len is wrong in NT sp3
4342 * that's the number of bytes not the number of unicode chars
4345 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4347 free_a_printer(&printer, 2);
4348 return ERROR_NO_MORE_ITEMS;
4351 free_a_printer(&printer, 2);
4355 * - counted in bytes in the request
4356 * - counted in UNICODE chars in the max reply
4357 * - counted in bytes in the real size
4359 * take a pause *before* coding not *during* coding
4362 *out_max_value_len=(in_value_len/sizeof(uint16));
4363 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4365 return ERROR_NOT_ENOUGH_MEMORY;
4368 ZERO_STRUCTP(*out_value);
4369 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4373 /* the data is counted in bytes */
4374 *out_max_data_len=in_data_len;
4375 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4377 return ERROR_NOT_ENOUGH_MEMORY;
4380 ZERO_STRUCTP(*data_out);
4381 memcpy(*data_out, data, (size_t)data_len);
4382 *out_data_len=data_len;
4386 return NT_STATUS_NO_PROBLEMO;
4389 /****************************************************************************
4390 ****************************************************************************/
4391 uint32 _spoolss_setprinterdata( POLICY_HND *handle,
4392 const UNISTR2 *value,
4397 uint32 numeric_data)
4399 NT_PRINTER_INFO_LEVEL *printer = NULL;
4400 NT_PRINTER_PARAM *param = NULL;
4403 uint32 status = 0x0;
4404 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4406 DEBUG(5,("spoolss_setprinterdata\n"));
4409 if (!OPEN_HANDLE(Printer)) {
4410 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4411 return ERROR_INVALID_HANDLE;
4414 if (!get_printer_snum(handle, &snum))
4415 return ERROR_INVALID_HANDLE;
4417 status = get_a_printer(&printer, 2, lp_servicename(snum));
4419 return ERROR_INVALID_NAME;
4421 convert_specific_param(¶m, value , type, data, real_len);
4422 unlink_specific_param_if_exist(printer->info_2, param);
4424 if (!add_a_specific_param(printer->info_2, param))
4425 status = ERROR_INVALID_PARAMETER;
4427 status = add_a_printer(*printer, 2);
4429 free_a_printer(&printer, 2);
4433 /****************************************************************************
4434 ****************************************************************************/
4435 uint32 _spoolss_addform( POLICY_HND *handle,
4440 nt_forms_struct *list=NULL;
4441 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4443 DEBUG(5,("spoolss_addform\n"));
4445 if (!OPEN_HANDLE(Printer)) {
4446 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4447 return ERROR_INVALID_HANDLE;
4450 count=get_ntforms(&list);
4451 if(!add_a_form(&list, form, &count))
4452 return ERROR_NOT_ENOUGH_MEMORY;
4453 write_ntforms(&list, count);
4460 /****************************************************************************
4461 ****************************************************************************/
4462 uint32 _spoolss_setform( POLICY_HND *handle,
4463 const UNISTR2 *uni_name,
4468 nt_forms_struct *list=NULL;
4469 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4471 DEBUG(5,("spoolss_setform\n"));
4473 if (!OPEN_HANDLE(Printer)) {
4474 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4475 return ERROR_INVALID_HANDLE;
4477 count=get_ntforms(&list);
4478 update_a_form(&list, form, count);
4479 write_ntforms(&list, count);
4486 /****************************************************************************
4487 enumprintprocessors level 1.
4488 ****************************************************************************/
4489 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4491 PRINTPROCESSOR_1 *info_1=NULL;
4493 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4494 return ERROR_NOT_ENOUGH_MEMORY;
4498 init_unistr(&(info_1->name), "winprint");
4500 *needed += spoolss_size_printprocessor_info_1(info_1);
4502 if (!alloc_buffer_size(buffer, *needed))
4503 return ERROR_INSUFFICIENT_BUFFER;
4505 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4509 if (*needed > offered) {
4511 return ERROR_INSUFFICIENT_BUFFER;
4514 return NT_STATUS_NO_PROBLEMO;
4517 /****************************************************************************
4518 ****************************************************************************/
4519 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
4520 NEW_BUFFER *buffer, uint32 offered,
4521 uint32 *needed, uint32 *returned)
4523 DEBUG(5,("spoolss_enumprintprocessors\n"));
4526 * Enumerate the print processors ...
4528 * Just reply with "winprint", to keep NT happy
4529 * and I can use my nice printer checker.
4537 return enumprintprocessors_level_1(buffer, offered, needed, returned);
4540 return ERROR_INVALID_LEVEL;
4545 /****************************************************************************
4546 enumprintprocdatatypes level 1.
4547 ****************************************************************************/
4548 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4550 PRINTPROCDATATYPE_1 *info_1=NULL;
4552 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
4553 return ERROR_NOT_ENOUGH_MEMORY;
4557 init_unistr(&(info_1->name), "RAW");
4559 *needed += spoolss_size_printprocdatatype_info_1(info_1);
4561 if (!alloc_buffer_size(buffer, *needed))
4562 return ERROR_INSUFFICIENT_BUFFER;
4564 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
4568 if (*needed > offered) {
4570 return ERROR_INSUFFICIENT_BUFFER;
4573 return NT_STATUS_NO_PROBLEMO;
4576 /****************************************************************************
4577 ****************************************************************************/
4578 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
4579 NEW_BUFFER *buffer, uint32 offered,
4580 uint32 *needed, uint32 *returned)
4582 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
4589 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
4592 return ERROR_INVALID_LEVEL;
4597 /****************************************************************************
4598 enumprintmonitors level 1.
4599 ****************************************************************************/
4600 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4602 PRINTMONITOR_1 *info_1=NULL;
4604 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
4605 return ERROR_NOT_ENOUGH_MEMORY;
4609 init_unistr(&(info_1->name), "Local Port");
4611 *needed += spoolss_size_printmonitor_info_1(info_1);
4613 if (!alloc_buffer_size(buffer, *needed))
4614 return ERROR_INSUFFICIENT_BUFFER;
4616 smb_io_printmonitor_info_1("", buffer, info_1, 0);
4620 if (*needed > offered) {
4622 return ERROR_INSUFFICIENT_BUFFER;
4625 return NT_STATUS_NO_PROBLEMO;
4628 /****************************************************************************
4629 enumprintmonitors level 2.
4630 ****************************************************************************/
4631 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4633 PRINTMONITOR_2 *info_2=NULL;
4635 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
4636 return ERROR_NOT_ENOUGH_MEMORY;
4640 init_unistr(&(info_2->name), "Local Port");
4641 init_unistr(&(info_2->environment), "Windows NT X86");
4642 init_unistr(&(info_2->dll_name), "localmon.dll");
4644 *needed += spoolss_size_printmonitor_info_2(info_2);
4646 if (!alloc_buffer_size(buffer, *needed))
4647 return ERROR_INSUFFICIENT_BUFFER;
4649 smb_io_printmonitor_info_2("", buffer, info_2, 0);
4653 if (*needed > offered) {
4655 return ERROR_INSUFFICIENT_BUFFER;
4658 return NT_STATUS_NO_PROBLEMO;
4661 /****************************************************************************
4662 ****************************************************************************/
4663 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
4664 NEW_BUFFER *buffer, uint32 offered,
4665 uint32 *needed, uint32 *returned)
4667 DEBUG(5,("spoolss_enumprintmonitors\n"));
4670 * Enumerate the print monitors ...
4672 * Just reply with "Local Port", to keep NT happy
4673 * and I can use my nice printer checker.
4681 return enumprintmonitors_level_1(buffer, offered, needed, returned);
4684 return enumprintmonitors_level_2(buffer, offered, needed, returned);
4687 return ERROR_INVALID_LEVEL;
4692 /****************************************************************************
4693 ****************************************************************************/
4694 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4698 JOB_INFO_1 *info_1=NULL;
4700 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
4702 if (info_1 == NULL) {
4704 return ERROR_NOT_ENOUGH_MEMORY;
4707 for (i=0; i<count && found==False; i++) {
4708 if (queue[i].job==(int)jobid)
4715 /* I shoud reply something else ... I can't find the good one */
4716 return NT_STATUS_NO_PROBLEMO;
4719 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
4723 *needed += spoolss_size_job_info_1(info_1);
4725 if (!alloc_buffer_size(buffer, *needed)) {
4727 return ERROR_INSUFFICIENT_BUFFER;
4730 new_smb_io_job_info_1("", buffer, info_1, 0);
4734 if (*needed > offered)
4735 return ERROR_INSUFFICIENT_BUFFER;
4737 return NT_STATUS_NO_PROBLEMO;
4741 /****************************************************************************
4742 ****************************************************************************/
4743 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4748 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
4750 ZERO_STRUCTP(info_2);
4752 if (info_2 == NULL) {
4754 return ERROR_NOT_ENOUGH_MEMORY;
4757 for (i=0; i<count && found==False; i++) {
4758 if (queue[i].job==(int)jobid)
4765 /* I shoud reply something else ... I can't find the good one */
4766 return NT_STATUS_NO_PROBLEMO;
4769 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
4773 *needed += spoolss_size_job_info_2(info_2);
4775 if (!alloc_buffer_size(buffer, *needed)) {
4777 return ERROR_INSUFFICIENT_BUFFER;
4780 new_smb_io_job_info_2("", buffer, info_2, 0);
4782 free_dev_mode(info_2->devmode);
4785 if (*needed > offered)
4786 return ERROR_INSUFFICIENT_BUFFER;
4788 return NT_STATUS_NO_PROBLEMO;
4791 /****************************************************************************
4792 ****************************************************************************/
4793 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
4794 NEW_BUFFER *buffer, uint32 offered,
4799 print_queue_struct *queue=NULL;
4800 print_status_struct prt_status;
4802 DEBUG(5,("spoolss_getjob\n"));
4804 memset(&prt_status, 0, sizeof(prt_status));
4808 if (!get_printer_snum(handle, &snum))
4809 return ERROR_INVALID_HANDLE;
4811 count = print_queue_status(snum, &queue, &prt_status);
4813 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
4814 count, prt_status.status, prt_status.message));
4818 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
4821 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
4825 return ERROR_INVALID_LEVEL;