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 #ifndef MANGLE_DRIVER_PATH
29 #define MANGLE_DRIVER_PATH 0
32 extern int DEBUGLEVEL;
33 extern pstring global_myname;
35 #ifndef MAX_OPEN_PRINTER_EXS
36 #define MAX_OPEN_PRINTER_EXS 50
39 #define PRINTER_HANDLE_IS_PRINTER 0
40 #define PRINTER_HANDLE_IS_PRINTSERVER 1
42 /* structure to store the printer handles */
43 /* and a reference to what it's pointing to */
44 /* and the notify info asked about */
45 /* that's the central struct */
46 typedef struct _Printer{
51 BOOL document_started;
53 int jobid; /* jobid in printing backend */
54 POLICY_HND printer_hnd;
58 fstring printerservername;
67 SPOOL_NOTIFY_OPTION *option;
75 typedef struct _counter_printer_0 {
83 static ubi_dlList Printer_list;
84 static ubi_dlList counter_list;
87 #define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False) && (IVAL(pnum->printer_hnd.data,16)==(uint32)sys_getpid()))
88 #define OUR_HANDLE(pnum) ((pnum==NULL)?"NULL":(IVAL(pnum->data,16)==sys_getpid()?"OURS":"OTHER"))
90 /* translate between internal status numbers and NT status numbers */
91 static int nt_printj_status(int v)
95 return PRINTER_STATUS_PAUSED;
104 static int nt_printq_status(int v)
108 return PRINTER_STATUS_ERROR;
117 /****************************************************************************
118 initialise printer handle states...
119 ****************************************************************************/
120 void init_printer_hnd(void)
122 ubi_dlInitList(&Printer_list);
123 ubi_dlInitList(&counter_list);
126 /****************************************************************************
127 create a unique printer handle
128 ****************************************************************************/
129 static void create_printer_hnd(POLICY_HND *hnd)
131 static uint32 prt_hnd_low = 0;
132 static uint32 prt_hnd_high = 0;
134 if (hnd == NULL) return;
136 /* i severely doubt that prt_hnd_high will ever be non-zero... */
138 if (prt_hnd_low == 0) prt_hnd_high++;
140 SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
141 SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
142 SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
143 SIVAL(hnd->data, 12, time(NULL)); /* something random */
144 SIVAL(hnd->data, 16, sys_getpid()); /* something more random */
147 /****************************************************************************
148 find printer index by handle
149 ****************************************************************************/
150 static Printer_entry *find_printer_index_by_hnd(const POLICY_HND *hnd)
152 Printer_entry *find_printer;
154 find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
156 for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) {
158 if (memcmp(&(find_printer->printer_hnd), hnd, sizeof(*hnd)) == 0) {
159 DEBUG(4,("Found printer handle \n"));
160 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
165 DEBUG(3,("Whoops, Printer handle not found: "));
166 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
170 /****************************************************************************
172 ****************************************************************************/
173 static void clear_handle(POLICY_HND *hnd)
178 /****************************************************************************
179 close printer index by handle
180 ****************************************************************************/
181 static BOOL close_printer_handle(POLICY_HND *hnd)
183 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
185 if (!OPEN_HANDLE(Printer)) {
186 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
191 Printer->notify.flags=0;
192 Printer->notify.options=0;
193 Printer->notify.localmachine[0]='\0';
194 Printer->notify.printerlocal=0;
195 safe_free(Printer->notify.option);
196 Printer->notify.option=NULL;
200 ubi_dlRemThis(&Printer_list, Printer);
207 /****************************************************************************
208 delete a printer given a handle
209 ****************************************************************************/
210 static BOOL delete_printer_handle(POLICY_HND *hnd)
212 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
214 if (!OPEN_HANDLE(Printer)) {
215 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
219 if (del_a_printer(Printer->dev.printername) != 0) {
220 DEBUG(3,("Error deleting printer %s\n", Printer->dev.printername));
227 /****************************************************************************
228 return the snum of a printer corresponding to an handle
229 ****************************************************************************/
230 static BOOL get_printer_snum(const POLICY_HND *hnd, int *number)
232 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
234 if (!OPEN_HANDLE(Printer)) {
235 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
239 switch (Printer->printer_type) {
240 case PRINTER_HANDLE_IS_PRINTER:
241 DEBUG(4,("short name:%s\n", Printer->dev.printername));
242 *number = print_queue_snum(Printer->dev.printername);
243 return (*number != -1);
244 case PRINTER_HANDLE_IS_PRINTSERVER:
253 /****************************************************************************
254 find first available printer slot. creates a printer handle for you.
255 ****************************************************************************/
256 static BOOL open_printer_hnd(POLICY_HND *hnd)
258 Printer_entry *new_printer;
260 if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
263 ZERO_STRUCTP(new_printer);
265 new_printer->open = True;
266 new_printer->notify.option=NULL;
268 memcpy(&new_printer->printer_hnd, hnd, sizeof(*hnd));
270 ubi_dlAddHead( &Printer_list, (ubi_dlNode *)new_printer);
275 /****************************************************************************
276 set printer handle type.
277 ****************************************************************************/
278 static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required)
280 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
282 if (!OPEN_HANDLE(Printer)) {
283 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd)));
287 DEBUG(4,("Setting printer access=%x\n", access_required));
288 Printer->access = access_required;
292 /****************************************************************************
293 set printer handle type.
294 check if it's \\server or \\server\printer
295 ****************************************************************************/
296 static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername)
298 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
300 if (!OPEN_HANDLE(Printer)) {
301 DEBUG(0,("set_printer_hnd_printertype: Invalid handle (%s)", OUR_HANDLE(hnd)));
305 DEBUG(3,("Setting printer type=%s\n", printername));
307 if ( strlen(printername) < 3 ) {
308 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername));
312 /* it's a print server */
313 if (!strchr(printername+2, '\\')) {
314 DEBUGADD(4,("Printer is a print server\n"));
315 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
320 DEBUGADD(4,("Printer is a printer\n"));
321 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
328 /****************************************************************************
329 set printer handle printername.
330 ****************************************************************************/
331 static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername)
333 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
334 NT_PRINTER_INFO_LEVEL *printer = NULL;
336 int n_services=lp_numservices();
340 if (!OPEN_HANDLE(Printer)) {
341 DEBUG(0,("set_printer_hnd_printername: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
345 DEBUG(4,("Setting printer name=%s (len=%d)\n", printername, strlen(printername)));
347 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
348 ZERO_STRUCT(Printer->dev.printerservername);
349 strncpy(Printer->dev.printerservername, printername, strlen(printername));
353 if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
356 aprinter=strchr(printername+2, '\\');
359 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
362 * store the Samba share name in it
363 * in back we have the long printer name
364 * need to iterate all the snum and do a
365 * get_a_printer each time to find the printer
366 * faster to do it here than later.
369 for (snum=0;snum<n_services && found==False;snum++) {
371 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
374 DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
376 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
379 DEBUG(10,("set_printer_hnd_printername: printername [%s], aprinter [%s]\n",
380 printer->info_2->printername, aprinter ));
382 if ( strlen(printer->info_2->printername) != strlen(aprinter) ) {
383 free_a_printer(&printer, 2);
387 if ( strncasecmp(printer->info_2->printername, aprinter, strlen(aprinter))) {
388 free_a_printer(&printer, 2);
396 * if we haven't found a printer with the given printername
397 * then it can be a share name as you can open both \\server\printer and
402 * we still check if the printer description file exists as NT won't be happy
403 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
407 DEBUGADD(5,("Printer not found, checking for share now\n"));
409 for (snum=0;snum<n_services && found==False;snum++) {
411 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
414 DEBUGADD(5,("set_printer_hnd_printername: share:%s\n",lp_servicename(snum)));
416 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
419 DEBUG(10,("set_printer_hnd_printername: printername [%s], aprinter [%s]\n",
420 printer->info_2->printername, aprinter ));
422 if ( strlen(lp_servicename(snum)) != strlen(aprinter) ) {
423 free_a_printer(&printer, 2);
427 if ( strncasecmp(lp_servicename(snum), aprinter, strlen(aprinter))) {
428 free_a_printer(&printer, 2);
437 DEBUGADD(4,("Printer not found\n"));
442 DEBUGADD(4,("set_printer_hnd_printername: Printer found: %s -> %s[%x]\n",
443 printer->info_2->printername, lp_servicename(snum),snum));
445 ZERO_STRUCT(Printer->dev.printername);
446 strncpy(Printer->dev.printername, lp_servicename(snum), strlen(lp_servicename(snum)));
448 free_a_printer(&printer, 2);
453 /********************************************************************
454 Return True is the handle is a print server.
455 ********************************************************************/
456 static BOOL handle_is_printserver(const POLICY_HND *handle)
458 Printer_entry *Printer=find_printer_index_by_hnd(handle);
460 if (!OPEN_HANDLE(Printer))
463 if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
469 /****************************************************************************
470 allocate more memory for a BUFFER.
471 ****************************************************************************/
472 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
480 /* damn, I'm doing the reverse operation of prs_grow() :) */
481 if (buffer_size < prs_data_size(ps))
484 extra_space = buffer_size - prs_data_size(ps);
487 * save the offset and move to the end of the buffer
488 * prs_grow() checks the extra_space against the offset
490 old_offset=prs_offset(ps);
491 prs_set_offset(ps, prs_data_size(ps));
493 if (!prs_grow(ps, extra_space))
496 prs_set_offset(ps, old_offset);
499 buffer->string_at_end = buffer_size;
501 buffer->string_at_end=prs_data_size(ps);
507 /********************************************************************
508 * spoolss_open_printer
510 * called from the spoolss dispatcher
511 ********************************************************************/
512 uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
513 const PRINTER_DEFAULT *printer_default,
514 uint32 user_switch, SPOOL_USER_CTR user_ctr,
519 clear_handle(handle);
521 if (printername == NULL)
522 return ERROR_INVALID_PRINTER_NAME;
524 /* some sanity check because you can open a printer or a print server */
525 /* aka: \\server\printer or \\server */
526 unistr2_to_ascii(name, printername, sizeof(name)-1);
528 DEBUGADD(3,("checking name: %s\n",name));
530 create_printer_hnd(handle);
532 open_printer_hnd(handle);
534 if (!set_printer_hnd_printertype(handle, name)) {
535 close_printer_handle(handle);
536 return ERROR_INVALID_PRINTER_NAME;
539 if (!set_printer_hnd_printername(handle, name)) {
540 close_printer_handle(handle);
541 return ERROR_INVALID_PRINTER_NAME;
545 if (printer_default->datatype_ptr != NULL)
547 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
548 set_printer_hnd_datatype(handle, datatype);
551 set_printer_hnd_datatype(handle, "");
554 if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
555 close_printer_handle(handle);
556 return ERROR_ACCESS_DENIED;
559 return NT_STATUS_NO_PROBLEMO;
562 /****************************************************************************
563 ****************************************************************************/
564 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
565 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
569 uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
578 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
579 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
583 printer->info_3=NULL;
584 uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3);
587 printer->info_6=NULL;
588 uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6);
597 static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devmode)
599 unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
600 unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
602 nt_devmode->specversion=devmode->specversion;
603 nt_devmode->driverversion=devmode->driverversion;
604 nt_devmode->size=devmode->size;
605 nt_devmode->driverextra=devmode->driverextra;
606 nt_devmode->fields=devmode->fields;
607 nt_devmode->orientation=devmode->orientation;
608 nt_devmode->papersize=devmode->papersize;
609 nt_devmode->paperlength=devmode->paperlength;
610 nt_devmode->paperwidth=devmode->paperwidth;
611 nt_devmode->scale=devmode->scale;
612 nt_devmode->copies=devmode->copies;
613 nt_devmode->defaultsource=devmode->defaultsource;
614 nt_devmode->printquality=devmode->printquality;
615 nt_devmode->color=devmode->color;
616 nt_devmode->duplex=devmode->duplex;
617 nt_devmode->yresolution=devmode->yresolution;
618 nt_devmode->ttoption=devmode->ttoption;
619 nt_devmode->collate=devmode->collate;
621 nt_devmode->logpixels=devmode->logpixels;
622 nt_devmode->bitsperpel=devmode->bitsperpel;
623 nt_devmode->pelswidth=devmode->pelswidth;
624 nt_devmode->pelsheight=devmode->pelsheight;
625 nt_devmode->displayflags=devmode->displayflags;
626 nt_devmode->displayfrequency=devmode->displayfrequency;
627 nt_devmode->icmmethod=devmode->icmmethod;
628 nt_devmode->icmintent=devmode->icmintent;
629 nt_devmode->mediatype=devmode->mediatype;
630 nt_devmode->dithertype=devmode->dithertype;
631 nt_devmode->reserved1=devmode->reserved1;
632 nt_devmode->reserved2=devmode->reserved2;
633 nt_devmode->panningwidth=devmode->panningwidth;
634 nt_devmode->panningheight=devmode->panningheight;
636 if (nt_devmode->driverextra != 0) {
637 /* if we had a previous private delete it and make a new one */
638 safe_free(nt_devmode->private);
639 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
641 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
647 /********************************************************************
648 * api_spoolss_closeprinter
649 ********************************************************************/
650 uint32 _spoolss_closeprinter(POLICY_HND *handle)
652 if (!close_printer_handle(handle))
653 return ERROR_INVALID_HANDLE;
655 return NT_STATUS_NO_PROBLEMO;
658 /********************************************************************
659 * api_spoolss_deleteprinter
660 ********************************************************************/
661 uint32 _spoolss_deleteprinter(POLICY_HND *handle)
663 if (!delete_printer_handle(handle))
664 return ERROR_INVALID_HANDLE;
666 return NT_STATUS_NO_PROBLEMO;
669 /********************************************************************
670 GetPrinterData on a printer server Handle.
671 ********************************************************************/
672 static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
676 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
678 if (!strcmp(value, "BeepEnabled")) {
680 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
682 SIVAL(*data, 0, 0x01);
687 if (!strcmp(value, "EventLog")) {
689 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
691 SIVAL(*data, 0, 0x1B);
696 if (!strcmp(value, "NetPopup")) {
698 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
700 SIVAL(*data, 0, 0x01);
705 if (!strcmp(value, "MajorVersion")) {
707 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
709 SIVAL(*data, 0, 0x02);
714 if (!strcmp(value, "DefaultSpoolDirectory")) {
715 pstring string="You are using a Samba server";
717 *needed = 2*(strlen(string)+1);
718 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
720 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
722 /* it's done by hand ready to go on the wire */
723 for (i=0; i<strlen(string); i++) {
724 (*data)[2*i]=string[i];
730 if (!strcmp(value, "Architecture")) {
731 pstring string="Windows NT x86";
733 *needed = 2*(strlen(string)+1);
734 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
736 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
737 for (i=0; i<strlen(string); i++) {
738 (*data)[2*i]=string[i];
747 /********************************************************************
748 GetPrinterData on a printer Handle.
749 ********************************************************************/
750 static BOOL getprinterdata_printer(const POLICY_HND *handle,
751 fstring value, uint32 *type,
752 uint8 **data, uint32 *needed, uint32 in_size )
754 NT_PRINTER_INFO_LEVEL *printer = NULL;
758 Printer_entry *Printer = find_printer_index_by_hnd(handle);
760 DEBUG(5,("getprinterdata_printer\n"));
762 if (!OPEN_HANDLE(Printer)) {
763 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
767 if(!get_printer_snum(handle, &snum))
770 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
773 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
774 free_a_printer(&printer, 2);
778 free_a_printer(&printer, 2);
780 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
783 if((*data = (uint8 *)malloc( in_size *sizeof(uint8) )) == NULL) {
787 memset(*data, 0, in_size *sizeof(uint8));
788 /* copy the min(in_size, len) */
789 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
796 DEBUG(5,("getprinterdata_printer:copy done\n"));
803 /********************************************************************
804 * spoolss_getprinterdata
805 ********************************************************************/
806 uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename,
815 Printer_entry *Printer = find_printer_index_by_hnd(handle);
818 * Reminder: when it's a string, the length is in BYTES
819 * even if UNICODE is negociated.
826 /* in case of problem, return some default values */
830 DEBUG(4,("_spoolss_getprinterdata\n"));
832 if (!OPEN_HANDLE(Printer)) {
833 if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
834 return ERROR_NOT_ENOUGH_MEMORY;
835 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
836 return ERROR_INVALID_HANDLE;
839 unistr2_to_ascii(value, valuename, sizeof(value)-1);
841 if (handle_is_printserver(handle))
842 found=getprinterdata_printer_server(value, type, data, needed, *out_size);
844 found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
847 DEBUG(5, ("value not found, allocating %d\n", *out_size));
848 /* reply this param doesn't exist */
850 if((*data=(uint8 *)malloc(*out_size*sizeof(uint8))) == NULL)
851 return ERROR_NOT_ENOUGH_MEMORY;
852 memset(*data, '\0', *out_size*sizeof(uint8));
857 return ERROR_INVALID_PARAMETER;
860 if (*needed > *out_size)
861 return ERROR_INSUFFICIENT_BUFFER;
863 return NT_STATUS_NO_PROBLEMO;
866 /********************************************************************
868 * ReplyFindFirstPrinterChangeNotifyEx
870 * jfmxxxx: before replying OK: status=0
871 * should do a rpc call to the workstation asking ReplyOpenPrinter
872 * have to code it, later.
874 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
875 * called from api_spoolss_rffpcnex
876 ********************************************************************/
877 uint32 _spoolss_rffpcnex(const POLICY_HND *handle, uint32 flags, uint32 options,
878 const UNISTR2 *localmachine, uint32 printerlocal,
879 SPOOL_NOTIFY_OPTION *option)
881 /* store the notify value in the printer struct */
883 Printer_entry *Printer=find_printer_index_by_hnd(handle);
885 if (!OPEN_HANDLE(Printer)) {
886 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
887 return ERROR_INVALID_HANDLE;
890 Printer->notify.flags=flags;
891 Printer->notify.options=options;
892 Printer->notify.printerlocal=printerlocal;
893 Printer->notify.option=option;
894 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
896 return NT_STATUS_NO_PROBLEMO;
899 /*******************************************************************
900 * fill a notify_info_data with the servername
901 ********************************************************************/
902 static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
903 NT_PRINTER_INFO_LEVEL *printer)
907 snprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
909 data->notify_data.data.length= (uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
910 temp_name, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
913 /*******************************************************************
914 * fill a notify_info_data with the servicename
915 * jfmxxxx: it's incorrect should be long_printername
916 ********************************************************************/
917 static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
918 NT_PRINTER_INFO_LEVEL *printer)
921 data->notify_data.data.length=strlen(lp_servicename(snum));
922 dos_PutUniCode(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string), True);
924 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
925 printer->info_2->printername, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
928 /*******************************************************************
929 * fill a notify_info_data with the servicename
930 ********************************************************************/
931 static void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
933 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
934 lp_servicename(snum), sizeof(data->notify_data.data.string),True) - sizeof(uint16))/sizeof(uint16));
937 /*******************************************************************
938 * fill a notify_info_data with the port name
939 ********************************************************************/
940 static void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
942 /* even if it's strange, that's consistant in all the code */
944 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
945 lp_servicename(snum), sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
948 /*******************************************************************
949 * fill a notify_info_data with the printername
950 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
951 * but it doesn't exist, have to see what to do
952 ********************************************************************/
953 static void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
955 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
956 printer->info_2->drivername, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
959 /*******************************************************************
960 * fill a notify_info_data with the comment
961 ********************************************************************/
962 static void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
964 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
965 lp_comment(snum), sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
968 /*******************************************************************
969 * fill a notify_info_data with the comment
970 * jfm:xxxx incorrect, have to create a new smb.conf option
971 * location = "Room 1, floor 2, building 3"
972 ********************************************************************/
973 static void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
975 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
976 printer->info_2->location, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
979 /*******************************************************************
980 * fill a notify_info_data with the device mode
981 * jfm:xxxx don't to it for know but that's a real problem !!!
982 ********************************************************************/
983 static void spoolss_notify_devmode(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
987 /*******************************************************************
988 * fill a notify_info_data with the separator file name
989 * jfm:xxxx just return no file could add an option to smb.conf
990 * separator file = "separator.txt"
991 ********************************************************************/
992 static void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
994 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
995 printer->info_2->sepfile, sizeof(data->notify_data.data.string)-1,True) - sizeof(uint16))/sizeof(uint16));
998 /*******************************************************************
999 * fill a notify_info_data with the print processor
1000 * jfm:xxxx return always winprint to indicate we don't do anything to it
1001 ********************************************************************/
1002 static void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1004 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1005 printer->info_2->printprocessor, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1008 /*******************************************************************
1009 * fill a notify_info_data with the print processor options
1010 * jfm:xxxx send an empty string
1011 ********************************************************************/
1012 static void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1014 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1015 printer->info_2->parameters, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1018 /*******************************************************************
1019 * fill a notify_info_data with the data type
1020 * jfm:xxxx always send RAW as data type
1021 ********************************************************************/
1022 static void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1024 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1025 printer->info_2->datatype, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1028 /*******************************************************************
1029 * fill a notify_info_data with the security descriptor
1030 * jfm:xxxx send an null pointer to say no security desc
1031 * have to implement security before !
1032 ********************************************************************/
1033 static void spoolss_notify_security_desc(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1035 data->notify_data.data.length=0;
1036 data->notify_data.data.string[0]=0x00;
1039 /*******************************************************************
1040 * fill a notify_info_data with the attributes
1041 * jfm:xxxx a samba printer is always shared
1042 ********************************************************************/
1043 static void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1045 data->notify_data.value[0] = PRINTER_ATTRIBUTE_SHARED \
1046 | PRINTER_ATTRIBUTE_LOCAL \
1047 | PRINTER_ATTRIBUTE_RAW_ONLY ;
1050 /*******************************************************************
1051 * fill a notify_info_data with the priority
1052 ********************************************************************/
1053 static void spoolss_notify_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1055 data->notify_data.value[0] = printer->info_2->priority;
1058 /*******************************************************************
1059 * fill a notify_info_data with the default priority
1060 ********************************************************************/
1061 static void spoolss_notify_default_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1063 data->notify_data.value[0] = printer->info_2->default_priority;
1066 /*******************************************************************
1067 * fill a notify_info_data with the start time
1068 ********************************************************************/
1069 static void spoolss_notify_start_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1071 data->notify_data.value[0] = printer->info_2->starttime;
1074 /*******************************************************************
1075 * fill a notify_info_data with the until time
1076 ********************************************************************/
1077 static void spoolss_notify_until_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1079 data->notify_data.value[0] = printer->info_2->untiltime;
1082 /*******************************************************************
1083 * fill a notify_info_data with the status
1084 ********************************************************************/
1085 static void spoolss_notify_status(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 count = print_queue_status(snum, &q, &status);
1093 data->notify_data.value[0]=(uint32) status.status;
1097 /*******************************************************************
1098 * fill a notify_info_data with the number of jobs queued
1099 ********************************************************************/
1100 static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1102 print_queue_struct *q=NULL;
1103 print_status_struct status;
1105 memset(&status, 0, sizeof(status));
1106 data->notify_data.value[0] = print_queue_status(snum, &q, &status);
1110 /*******************************************************************
1111 * fill a notify_info_data with the average ppm
1112 ********************************************************************/
1113 static void spoolss_notify_average_ppm(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1115 /* always respond 8 pages per minutes */
1116 /* a little hard ! */
1117 data->notify_data.value[0] = printer->info_2->averageppm;
1120 /*******************************************************************
1121 * fill a notify_info_data with
1122 ********************************************************************/
1123 static void spoolss_notify_username(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1125 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1126 queue->user, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1129 /*******************************************************************
1130 * fill a notify_info_data with
1131 ********************************************************************/
1132 static void spoolss_notify_job_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1134 data->notify_data.value[0]=nt_printj_status(queue->status);
1137 /*******************************************************************
1138 * fill a notify_info_data with
1139 ********************************************************************/
1140 static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1142 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1143 queue->file, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1146 /*******************************************************************
1147 * fill a notify_info_data with
1148 ********************************************************************/
1149 static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1151 char *p = "unknown";
1152 switch (queue->status) {
1166 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1167 p, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1170 /*******************************************************************
1171 * fill a notify_info_data with
1172 ********************************************************************/
1173 static void spoolss_notify_job_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1175 data->notify_data.value[0]=0x0;
1178 /*******************************************************************
1179 * fill a notify_info_data with
1180 ********************************************************************/
1181 static void spoolss_notify_job_size(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1183 data->notify_data.value[0]=queue->size;
1186 /*******************************************************************
1187 * fill a notify_info_data with
1188 ********************************************************************/
1189 static void spoolss_notify_job_position(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1191 data->notify_data.value[0]=queue->job;
1196 struct s_notify_info_data_table
1202 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
1203 print_queue_struct *queue,
1204 NT_PRINTER_INFO_LEVEL *printer);
1207 struct s_notify_info_data_table notify_info_data_table[] =
1209 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
1210 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1211 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
1212 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1213 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1214 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
1215 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
1216 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1217 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
1218 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1219 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1220 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1221 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
1222 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
1223 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1224 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
1225 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1226 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1227 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
1228 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
1229 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
1230 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
1231 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
1232 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
1233 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
1234 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
1235 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1236 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
1237 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1238 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
1239 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
1240 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1241 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1242 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1243 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1244 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1245 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
1246 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
1247 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
1248 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
1249 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1250 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
1251 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, NULL },
1252 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1253 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1254 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
1255 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
1256 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
1257 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
1258 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
1259 { END, END, "", END, NULL }
1262 /*******************************************************************
1263 return the size of info_data structure
1264 ********************************************************************/
1265 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
1269 while (notify_info_data_table[i].type != END)
1271 if ( (notify_info_data_table[i].type == type ) &&
1272 (notify_info_data_table[i].field == field ) )
1274 return (notify_info_data_table[i].size);
1282 /*******************************************************************
1283 return the type of notify_info_data
1284 ********************************************************************/
1285 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
1289 while (notify_info_data_table[i].type != END)
1291 if ( (notify_info_data_table[i].type == type ) &&
1292 (notify_info_data_table[i].field == field ) )
1294 if (notify_info_data_table[i].size == POINTER)
1309 /****************************************************************************
1310 ****************************************************************************/
1311 static int search_notify(uint16 type, uint16 field, int *value)
1316 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1318 if ( (notify_info_data_table[j].type == type ) &&
1319 (notify_info_data_table[j].field == field ) )
1324 if ( found && (notify_info_data_table[j].fn != NULL) )
1330 /****************************************************************************
1331 ****************************************************************************/
1332 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1334 info_data->type = type;
1335 info_data->field = field;
1336 info_data->reserved = 0;
1338 info_data->size = size_of_notify_info_data(type, field);
1339 info_data->enc_type = type_of_notify_info_data(type, field);
1343 /*******************************************************************
1345 * fill a notify_info struct with info asked
1347 ********************************************************************/
1348 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1354 SPOOL_NOTIFY_INFO_DATA *current_data;
1355 NT_PRINTER_INFO_LEVEL *printer = NULL;
1356 print_queue_struct *queue=NULL;
1358 DEBUG(4,("construct_notify_printer_info\n"));
1360 type=option_type->type;
1362 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
1363 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1364 option_type->count, lp_servicename(snum)));
1366 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1369 for(field_num=0; field_num<option_type->count; field_num++) {
1370 field = option_type->fields[field_num];
1371 DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field));
1373 if (!search_notify(type, field, &j) )
1376 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1379 current_data=&info->data[info->count];
1381 construct_info_data(current_data, type, field, id);
1382 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1387 free_a_printer(&printer, 2);
1391 /*******************************************************************
1393 * fill a notify_info struct with info asked
1395 ********************************************************************/
1396 static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1402 SPOOL_NOTIFY_INFO_DATA *current_data;
1403 NT_PRINTER_INFO_LEVEL *printer = NULL;
1405 DEBUG(4,("construct_notify_jobs_info\n"));
1407 type = option_type->type;
1409 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
1410 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1411 option_type->count));
1413 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1416 for(field_num=0; field_num<option_type->count; field_num++) {
1417 field = option_type->fields[field_num];
1419 if (!search_notify(type, field, &j) )
1422 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1426 current_data=&(info->data[info->count]);
1428 construct_info_data(current_data, type, field, id);
1429 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1433 free_a_printer(&printer, 2);
1438 * JFM: The enumeration is not that simple, it's even non obvious.
1440 * let's take an example: I want to monitor the PRINTER SERVER for
1441 * the printer's name and the number of jobs currently queued.
1442 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
1443 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
1445 * I have 3 printers on the back of my server.
1447 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
1450 * 1 printer 1 name 1
1451 * 2 printer 1 cjob 1
1452 * 3 printer 2 name 2
1453 * 4 printer 2 cjob 2
1454 * 5 printer 3 name 3
1455 * 6 printer 3 name 3
1457 * that's the print server case, the printer case is even worse.
1462 /*******************************************************************
1464 * enumerate all printers on the printserver
1465 * fill a notify_info struct with info asked
1467 ********************************************************************/
1468 static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1471 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1472 int n_services=lp_numservices();
1475 SPOOL_NOTIFY_OPTION *option;
1476 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1478 DEBUG(4,("printserver_notify_info\n"));
1480 option=Printer->notify.option;
1486 for (i=0; i<option->count; i++) {
1487 option_type=&(option->ctr.type[i]);
1489 if (option_type->type!=PRINTER_NOTIFY_TYPE)
1492 for (snum=0; snum<n_services; snum++)
1493 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1494 if (construct_notify_printer_info(info, snum, option_type, id))
1499 * Debugging information, don't delete.
1502 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1503 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1504 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1506 for (i=0; i<info->count; i++) {
1507 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1508 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1509 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1513 return NT_STATUS_NO_PROBLEMO;
1516 /*******************************************************************
1518 * fill a notify_info struct with info asked
1520 ********************************************************************/
1521 static uint32 printer_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1524 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1527 SPOOL_NOTIFY_OPTION *option;
1528 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1530 print_queue_struct *queue=NULL;
1531 print_status_struct status;
1533 DEBUG(4,("printer_notify_info\n"));
1535 option=Printer->notify.option;
1541 get_printer_snum(hnd, &snum);
1543 for (i=0; i<option->count; i++) {
1544 option_type=&option->ctr.type[i];
1546 switch ( option_type->type ) {
1547 case PRINTER_NOTIFY_TYPE:
1548 if(construct_notify_printer_info(info, snum, option_type, id))
1552 case JOB_NOTIFY_TYPE:
1553 memset(&status, 0, sizeof(status));
1554 count = print_queue_status(snum, &queue, &status);
1555 for (j=0; j<count; j++)
1556 construct_notify_jobs_info(&queue[j], info, snum, option_type, queue[j].job);
1563 * Debugging information, don't delete.
1566 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1567 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1568 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1570 for (i=0; i<info->count; i++) {
1571 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1572 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1573 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1576 return NT_STATUS_NO_PROBLEMO;
1579 /********************************************************************
1581 ********************************************************************/
1582 uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change,
1583 SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info)
1585 Printer_entry *Printer=find_printer_index_by_hnd(handle);
1587 if (!OPEN_HANDLE(Printer)) {
1588 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",OUR_HANDLE(handle)));
1589 return ERROR_INVALID_HANDLE;
1592 DEBUG(4,("Printer type %x\n",Printer->printer_type));
1594 /* jfm: the change value isn't used right now.
1595 * we will honour it when
1596 * a) we'll be able to send notification to the client
1597 * b) we'll have a way to communicate between the spoolss process.
1599 * same thing for option->flags
1600 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
1601 * I don't have a global notification system, I'm sending back all the
1602 * informations even when _NOTHING_ has changed.
1605 /* just discard the SPOOL_NOTIFY_OPTION */
1607 safe_free(option->ctr.type);
1609 switch (Printer->printer_type) {
1610 case PRINTER_HANDLE_IS_PRINTSERVER:
1611 return printserver_notify_info(handle, info);
1613 case PRINTER_HANDLE_IS_PRINTER:
1614 return printer_notify_info(handle, info);
1618 return ERROR_INVALID_HANDLE;
1621 /********************************************************************
1622 * construct_printer_info_0
1623 * fill a printer_info_1 struct
1624 ********************************************************************/
1625 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring servername)
1629 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1630 counter_printer_0 *session_counter;
1631 uint32 global_counter;
1633 time_t setup_time = time(NULL);
1635 print_queue_struct *queue=NULL;
1636 print_status_struct status;
1638 memset(&status, 0, sizeof(status));
1640 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1643 count = print_queue_status(snum, &queue, &status);
1645 /* check if we already have a counter for this printer */
1646 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
1648 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
1649 if (session_counter->snum == snum)
1653 /* it's the first time, add it to the list */
1654 if (session_counter==NULL) {
1655 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
1656 free_a_printer(&ntprinter, 2);
1659 ZERO_STRUCTP(session_counter);
1660 session_counter->snum=snum;
1661 session_counter->counter=0;
1662 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
1666 session_counter->counter++;
1669 * the global_counter should be stored in a TDB as it's common to all the clients
1670 * and should be zeroed on samba startup
1672 global_counter=session_counter->counter;
1674 /* the description and the name are of the form \\server\share */
1675 slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter->info_2->printername);
1677 init_unistr(&printer->printername, chaine);
1679 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1680 init_unistr(&printer->servername, chaine);
1682 printer->cjobs = count;
1683 printer->total_jobs = 0;
1684 printer->total_bytes = 0;
1686 t=gmtime(&setup_time);
1687 ntprinter->info_2->setuptime = (uint32)setup_time; /* FIXME !! */
1689 printer->year = t->tm_year+1900;
1690 printer->month = t->tm_mon+1;
1691 printer->dayofweek = t->tm_wday;
1692 printer->day = t->tm_mday;
1693 printer->hour = t->tm_hour;
1694 printer->minute = t->tm_min;
1695 printer->second = t->tm_sec;
1696 printer->milliseconds = 0;
1698 printer->global_counter = global_counter;
1699 printer->total_pages = 0;
1700 printer->major_version = 0x0004; /* NT 4 */
1701 printer->build_version = 0x0565; /* build 1381 */
1702 printer->unknown7 = 0x1;
1703 printer->unknown8 = 0x0;
1704 printer->unknown9 = 0x0;
1705 printer->session_counter = session_counter->counter;
1706 printer->unknown11 = 0x0;
1707 printer->printer_errors = 0x0; /* number of print failure */
1708 printer->unknown13 = 0x0;
1709 printer->unknown14 = 0x1;
1710 printer->unknown15 = 0x024a; /* 586 Pentium ? */
1711 printer->unknown16 = 0x0;
1712 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
1713 printer->unknown18 = 0x0;
1714 printer->status = nt_printq_status(status.status);
1715 printer->unknown20 = 0x0;
1716 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
1717 printer->unknown22 = 0x0;
1718 printer->unknown23 = 0x6; /* 6 ???*/
1719 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
1720 printer->unknown25 = 0;
1721 printer->unknown26 = 0;
1722 printer->unknown27 = 0;
1723 printer->unknown28 = 0;
1724 printer->unknown29 = 0;
1727 free_a_printer(&ntprinter,2);
1731 /********************************************************************
1732 * construct_printer_info_1
1733 * fill a printer_info_1 struct
1734 ********************************************************************/
1735 static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum)
1739 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1741 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1744 printer->flags=flags;
1746 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1747 ntprinter->info_2->drivername, lp_comment(snum));
1749 snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter->info_2->printername);
1751 init_unistr(&printer->description, chaine);
1752 init_unistr(&printer->name, chaine2);
1753 init_unistr(&printer->comment, lp_comment(snum));
1755 free_a_printer(&ntprinter,2);
1760 /****************************************************************************
1761 Free a DEVMODE struct.
1762 ****************************************************************************/
1764 static void free_dev_mode(DEVICEMODE *dev)
1770 safe_free(dev->private);
1775 /****************************************************************************
1776 Create a DEVMODE struct. Returns malloced memory.
1777 ****************************************************************************/
1779 static DEVICEMODE *construct_dev_mode(int snum, char *servername)
1783 NT_PRINTER_INFO_LEVEL *printer = NULL;
1784 NT_DEVICEMODE *ntdevmode = NULL;
1785 DEVICEMODE *devmode = NULL;
1787 DEBUG(7,("construct_dev_mode\n"));
1789 DEBUGADD(8,("getting printer characteristics\n"));
1791 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
1792 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
1796 ZERO_STRUCTP(devmode);
1798 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
1801 if (printer->info_2->devmode)
1802 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
1805 ntdevmode = construct_nt_devicemode(printer->info_2->printername);
1807 if (ntdevmode == NULL)
1810 DEBUGADD(8,("loading DEVICEMODE\n"));
1812 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, printer->info_2->printername);
1813 init_unistr(&devmode->devicename, adevice);
1815 snprintf(aform, sizeof(aform), ntdevmode->formname);
1816 init_unistr(&devmode->formname, aform);
1818 devmode->specversion = ntdevmode->specversion;
1819 devmode->driverversion = ntdevmode->driverversion;
1820 devmode->size = ntdevmode->size;
1821 devmode->driverextra = ntdevmode->driverextra;
1822 devmode->fields = ntdevmode->fields;
1824 devmode->orientation = ntdevmode->orientation;
1825 devmode->papersize = ntdevmode->papersize;
1826 devmode->paperlength = ntdevmode->paperlength;
1827 devmode->paperwidth = ntdevmode->paperwidth;
1828 devmode->scale = ntdevmode->scale;
1829 devmode->copies = ntdevmode->copies;
1830 devmode->defaultsource = ntdevmode->defaultsource;
1831 devmode->printquality = ntdevmode->printquality;
1832 devmode->color = ntdevmode->color;
1833 devmode->duplex = ntdevmode->duplex;
1834 devmode->yresolution = ntdevmode->yresolution;
1835 devmode->ttoption = ntdevmode->ttoption;
1836 devmode->collate = ntdevmode->collate;
1837 devmode->icmmethod = ntdevmode->icmmethod;
1838 devmode->icmintent = ntdevmode->icmintent;
1839 devmode->mediatype = ntdevmode->mediatype;
1840 devmode->dithertype = ntdevmode->dithertype;
1842 if (ntdevmode->private != NULL) {
1843 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
1847 free_nt_devicemode(&ntdevmode);
1848 free_a_printer(&printer,2);
1855 free_nt_devicemode(&ntdevmode);
1857 free_a_printer(&printer,2);
1858 free_dev_mode(devmode);
1863 /********************************************************************
1864 * construct_printer_info_2
1865 * fill a printer_info_2 struct
1866 ********************************************************************/
1868 static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer, int snum)
1874 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1876 print_queue_struct *queue=NULL;
1877 print_status_struct status;
1878 memset(&status, 0, sizeof(status));
1880 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1883 memset(&status, 0, sizeof(status));
1884 count = print_queue_status(snum, &queue, &status);
1886 snprintf(chaine, sizeof(chaine)-1, "%s", servername);
1888 if (strlen(servername)!=0)
1893 snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter->info_2->printername);
1895 init_unistr(&printer->servername, chaine); /* servername*/
1896 init_unistr(&printer->printername, chaine2); /* printername*/
1897 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
1899 /* We need to determine the correct model for this..... */
1900 init_unistr(&printer->portname, lp_printername(snum)); /* port */
1902 init_unistr(&printer->portname, lp_servicename(snum)); /* port */
1904 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
1905 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
1906 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
1907 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
1908 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
1909 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
1910 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
1912 printer->attributes = ntprinter->info_2->attributes;
1914 printer->priority = ntprinter->info_2->priority; /* priority */
1915 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
1916 printer->starttime = ntprinter->info_2->starttime; /* starttime */
1917 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
1918 printer->status = nt_printq_status(status.status); /* status */
1919 printer->cjobs = count; /* jobs */
1920 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
1922 if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) {
1923 DEBUG(8, ("Returning NULL Devicemode!\n"));
1929 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1930 /* steal the printer info sec_desc structure. [badly done]. */
1931 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1932 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
1933 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
1934 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
1937 printer->secdesc = NULL;
1940 free_a_printer(&ntprinter, 2);
1947 free_a_printer(&ntprinter, 2);
1952 /********************************************************************
1953 * construct_printer_info_3
1954 * fill a printer_info_3 struct
1955 ********************************************************************/
1956 static BOOL construct_printer_info_3(fstring servername,
1957 PRINTER_INFO_3 **pp_printer, int snum)
1959 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1960 PRINTER_INFO_3 *printer = NULL;
1962 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1966 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
1967 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
1971 ZERO_STRUCTP(printer);
1973 printer->flags = 4; /* This is the offset to the SEC_DESC. */
1974 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1975 /* steal the printer info sec_desc structure. [badly done]. */
1976 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1977 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
1978 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
1979 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
1982 free_a_printer(&ntprinter, 2);
1984 *pp_printer = printer;
1988 /********************************************************************
1989 Spoolss_enumprinters.
1990 ********************************************************************/
1991 static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
1995 int n_services=lp_numservices();
1996 PRINTER_INFO_1 *printers=NULL;
1997 PRINTER_INFO_1 current_prt;
1999 DEBUG(4,("enum_all_printers_info_1\n"));
2001 for (snum=0; snum<n_services; snum++) {
2002 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2003 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2005 if (construct_printer_info_1(server, flags, ¤t_prt, snum)) {
2006 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
2008 return ERROR_NOT_ENOUGH_MEMORY;
2010 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2011 memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1));
2017 /* check the required size. */
2018 for (i=0; i<*returned; i++)
2019 (*needed) += spoolss_size_printer_info_1(&(printers[i]));
2021 if (!alloc_buffer_size(buffer, *needed))
2022 return ERROR_INSUFFICIENT_BUFFER;
2024 /* fill the buffer with the structures */
2025 for (i=0; i<*returned; i++)
2026 new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);
2029 safe_free(printers);
2031 if (*needed > offered) {
2033 return ERROR_INSUFFICIENT_BUFFER;
2036 return NT_STATUS_NO_PROBLEMO;
2039 /********************************************************************
2040 enum_all_printers_info_1_local.
2041 *********************************************************************/
2042 static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2045 DEBUG(4,("enum_all_printers_info_1_local\n"));
2047 fstrcpy(temp, "\\\\");
2048 fstrcat(temp, global_myname);
2050 if (!strcmp(name, temp)) {
2051 fstrcat(temp, "\\");
2052 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2055 return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2058 /********************************************************************
2059 enum_all_printers_info_1_name.
2060 *********************************************************************/
2061 static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2064 DEBUG(4,("enum_all_printers_info_1_name\n"));
2066 fstrcpy(temp, "\\\\");
2067 fstrcat(temp, global_myname);
2069 if (!strcmp(name, temp)) {
2070 fstrcat(temp, "\\");
2071 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2074 return ERROR_INVALID_NAME;
2077 /********************************************************************
2078 enum_all_printers_info_1_remote.
2079 *********************************************************************/
2080 static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2082 PRINTER_INFO_1 *printer;
2083 fstring printername;
2086 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2088 /* JFM: currently it's more a place holder than anything else.
2089 * In the spooler world there is a notion of server registration.
2090 * the print servers are registring (sp ?) on the PDC (in the same domain)
2092 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2095 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2096 return ERROR_NOT_ENOUGH_MEMORY;
2100 snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
2101 snprintf(desc, sizeof(desc)-1,"%s", global_myname);
2102 snprintf(comment, sizeof(comment)-1, "Logged on Domain");
2104 init_unistr(&printer->description, desc);
2105 init_unistr(&printer->name, printername);
2106 init_unistr(&printer->comment, comment);
2107 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2109 /* check the required size. */
2110 *needed += spoolss_size_printer_info_1(printer);
2112 if (!alloc_buffer_size(buffer, *needed)) {
2114 return ERROR_INSUFFICIENT_BUFFER;
2117 /* fill the buffer with the structures */
2118 new_smb_io_printer_info_1("", buffer, printer, 0);
2123 if (*needed > offered) {
2125 return ERROR_INSUFFICIENT_BUFFER;
2128 return NT_STATUS_NO_PROBLEMO;
2131 /********************************************************************
2132 enum_all_printers_info_1_network.
2133 *********************************************************************/
2134 static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2137 DEBUG(4,("enum_all_printers_info_1_network\n"));
2139 fstrcpy(temp, "\\\\");
2140 fstrcat(temp, global_myname);
2141 fstrcat(temp, "\\");
2142 return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
2145 /********************************************************************
2146 * api_spoolss_enumprinters
2148 * called from api_spoolss_enumprinters (see this to understand)
2149 ********************************************************************/
2150 static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2154 int n_services=lp_numservices();
2155 PRINTER_INFO_2 *printers=NULL;
2156 PRINTER_INFO_2 current_prt;
2158 for (snum=0; snum<n_services; snum++) {
2159 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2160 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2162 if (construct_printer_info_2(servername, ¤t_prt, snum)) {
2163 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL)
2164 return ERROR_NOT_ENOUGH_MEMORY;
2165 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
2166 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
2172 /* check the required size. */
2173 for (i=0; i<*returned; i++)
2174 (*needed) += spoolss_size_printer_info_2(&printers[i]);
2176 if (!alloc_buffer_size(buffer, *needed)) {
2177 for (i=0; i<*returned; i++) {
2178 free_devmode(printers[i].devmode);
2179 free_sec_desc(&printers[i].secdesc);
2181 safe_free(printers);
2182 return ERROR_INSUFFICIENT_BUFFER;
2185 /* fill the buffer with the structures */
2186 for (i=0; i<*returned; i++)
2187 new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);
2190 for (i=0; i<*returned; i++) {
2191 free_devmode(printers[i].devmode);
2192 free_sec_desc(&printers[i].secdesc);
2194 safe_free(printers);
2196 if (*needed > offered) {
2198 return ERROR_INSUFFICIENT_BUFFER;
2201 return NT_STATUS_NO_PROBLEMO;
2204 /********************************************************************
2205 * handle enumeration of printers at level 1
2206 ********************************************************************/
2207 static uint32 enumprinters_level1( uint32 flags, fstring name,
2208 NEW_BUFFER *buffer, uint32 offered,
2209 uint32 *needed, uint32 *returned)
2211 /* Not all the flags are equals */
2213 if (flags & PRINTER_ENUM_LOCAL)
2214 return enum_all_printers_info_1_local(name, buffer, offered, needed, returned);
2216 if (flags & PRINTER_ENUM_NAME)
2217 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
2219 if (flags & PRINTER_ENUM_REMOTE)
2220 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
2222 if (flags & PRINTER_ENUM_NETWORK)
2223 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
2225 return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
2228 /********************************************************************
2229 * handle enumeration of printers at level 2
2230 ********************************************************************/
2231 static uint32 enumprinters_level2( uint32 flags, fstring servername,
2232 NEW_BUFFER *buffer, uint32 offered,
2233 uint32 *needed, uint32 *returned)
2237 fstrcpy(temp, "\\\\");
2238 fstrcat(temp, global_myname);
2240 if (flags & PRINTER_ENUM_LOCAL) {
2241 if (!strcmp(servername, temp))
2242 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2244 return enum_all_printers_info_2("", buffer, offered, needed, returned);
2247 if (flags & PRINTER_ENUM_NAME) {
2248 if (!strcmp(servername, temp))
2249 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2251 return ERROR_INVALID_NAME;
2254 if (flags & PRINTER_ENUM_REMOTE)
2255 return ERROR_INVALID_LEVEL;
2257 return NT_STATUS_NO_PROBLEMO;
2260 /********************************************************************
2261 * handle enumeration of printers at level 5
2262 ********************************************************************/
2263 static uint32 enumprinters_level5( uint32 flags, fstring servername,
2264 NEW_BUFFER *buffer, uint32 offered,
2265 uint32 *needed, uint32 *returned)
2267 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
2268 return NT_STATUS_NO_PROBLEMO;
2271 /********************************************************************
2272 * api_spoolss_enumprinters
2274 * called from api_spoolss_enumprinters (see this to understand)
2275 ********************************************************************/
2276 uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
2277 NEW_BUFFER *buffer, uint32 offered,
2278 uint32 *needed, uint32 *returned)
2282 DEBUG(4,("_spoolss_enumprinters\n"));
2289 * flags==PRINTER_ENUM_NAME
2290 * if name=="" then enumerates all printers
2291 * if name!="" then enumerate the printer
2292 * flags==PRINTER_ENUM_REMOTE
2293 * name is NULL, enumerate printers
2294 * Level 2: name!="" enumerates printers, name can't be NULL
2295 * Level 3: doesn't exist
2296 * Level 4: does a local registry lookup
2297 * Level 5: same as Level 2
2300 unistr2_to_ascii(name, servername, sizeof(name)-1);
2305 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
2308 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
2311 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
2316 return ERROR_INVALID_LEVEL;
2321 /****************************************************************************
2322 ****************************************************************************/
2323 static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2325 PRINTER_INFO_0 *printer=NULL;
2327 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
2328 return ERROR_NOT_ENOUGH_MEMORY;
2330 construct_printer_info_0(printer, snum, servername);
2332 /* check the required size. */
2333 *needed += spoolss_size_printer_info_0(printer);
2335 if (!alloc_buffer_size(buffer, *needed)) {
2337 return ERROR_INSUFFICIENT_BUFFER;
2340 /* fill the buffer with the structures */
2341 new_smb_io_printer_info_0("", buffer, printer, 0);
2346 if (*needed > offered) {
2347 return ERROR_INSUFFICIENT_BUFFER;
2350 return NT_STATUS_NO_PROBLEMO;
2353 /****************************************************************************
2354 ****************************************************************************/
2355 static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2357 PRINTER_INFO_1 *printer=NULL;
2359 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2360 return ERROR_NOT_ENOUGH_MEMORY;
2362 construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum);
2364 /* check the required size. */
2365 *needed += spoolss_size_printer_info_1(printer);
2367 if (!alloc_buffer_size(buffer, *needed)) {
2369 return ERROR_INSUFFICIENT_BUFFER;
2372 /* fill the buffer with the structures */
2373 new_smb_io_printer_info_1("", buffer, printer, 0);
2378 if (*needed > offered) {
2379 return ERROR_INSUFFICIENT_BUFFER;
2382 return NT_STATUS_NO_PROBLEMO;
2385 /****************************************************************************
2386 ****************************************************************************/
2387 static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2389 PRINTER_INFO_2 *printer=NULL;
2392 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
2393 return ERROR_NOT_ENOUGH_MEMORY;
2395 fstrcpy(temp, "\\\\");
2396 fstrcat(temp, servername);
2397 construct_printer_info_2(temp, printer, snum);
2399 /* check the required size. */
2400 *needed += spoolss_size_printer_info_2(printer);
2402 if (!alloc_buffer_size(buffer, *needed)) {
2403 free_printer_info_2(printer);
2404 return ERROR_INSUFFICIENT_BUFFER;
2407 /* fill the buffer with the structures */
2408 if (!new_smb_io_printer_info_2("", buffer, printer, 0)) {
2409 free_printer_info_2(printer);
2410 return ERROR_NOT_ENOUGH_MEMORY;
2414 free_printer_info_2(printer);
2416 if (*needed > offered) {
2417 return ERROR_INSUFFICIENT_BUFFER;
2420 return NT_STATUS_NO_PROBLEMO;
2423 /****************************************************************************
2424 ****************************************************************************/
2425 static uint32 getprinter_level_3(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2427 PRINTER_INFO_3 *printer=NULL;
2430 fstrcpy(temp, "\\\\");
2431 fstrcat(temp, servername);
2432 if (!construct_printer_info_3(temp, &printer, snum))
2433 return ERROR_NOT_ENOUGH_MEMORY;
2435 /* check the required size. */
2436 *needed += spoolss_size_printer_info_3(printer);
2438 if (!alloc_buffer_size(buffer, *needed)) {
2439 free_printer_info_3(printer);
2440 return ERROR_INSUFFICIENT_BUFFER;
2443 /* fill the buffer with the structures */
2444 new_smb_io_printer_info_3("", buffer, printer, 0);
2447 free_printer_info_3(printer);
2449 if (*needed > offered) {
2450 return ERROR_INSUFFICIENT_BUFFER;
2453 return NT_STATUS_NO_PROBLEMO;
2456 /****************************************************************************
2457 ****************************************************************************/
2458 uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
2459 NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2466 pstrcpy(servername, global_myname);
2468 if (!get_printer_snum(handle, &snum))
2469 return ERROR_INVALID_HANDLE;
2473 return getprinter_level_0(servername, snum, buffer, offered, needed);
2475 return getprinter_level_1(servername,snum, buffer, offered, needed);
2477 return getprinter_level_2(servername,snum, buffer, offered, needed);
2479 return getprinter_level_3(servername,snum, buffer, offered, needed);
2481 return ERROR_INVALID_LEVEL;
2486 /********************************************************************
2487 * construct_printer_driver_info_1
2488 * fill a construct_printer_driver_info_1 struct
2489 ********************************************************************/
2490 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info,
2491 NT_PRINTER_DRIVER_INFO_LEVEL driver,
2492 fstring servername, fstring architecture)
2494 init_unistr( &(info->name), driver.info_3->name);
2497 static void construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum,
2498 fstring servername, fstring architecture)
2500 NT_PRINTER_INFO_LEVEL *printer = NULL;
2501 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2503 ZERO_STRUCT(driver);
2505 get_a_printer(&printer, 2, lp_servicename(snum) );
2506 get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture);
2508 fill_printer_driver_info_1(info, driver, servername, architecture);
2510 free_a_printer(&printer,2);
2513 /********************************************************************
2514 * construct_printer_driver_info_2
2515 * fill a printer_info_2 struct
2516 ********************************************************************/
2517 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info,
2518 NT_PRINTER_DRIVER_INFO_LEVEL driver,
2519 fstring servername, fstring architecture)
2522 pstring temp_driverpath;
2523 pstring temp_datafile;
2524 pstring temp_configfile;
2525 fstring short_archi;
2527 get_short_archi(short_archi,architecture);
2529 snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
2531 info->version=driver.info_3->cversion;
2533 init_unistr( &info->name, driver.info_3->name );
2534 init_unistr( &info->architecture, architecture );
2536 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where,
2537 driver.info_3->driverpath);
2538 init_unistr( &info->driverpath, temp_driverpath );
2540 snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where,
2541 driver.info_3->datafile);
2542 init_unistr( &info->datafile, temp_datafile );
2544 snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where,
2545 driver.info_3->configfile);
2546 init_unistr( &info->configfile, temp_configfile );
2549 /********************************************************************
2550 * construct_printer_driver_info_2
2551 * fill a printer_info_2 struct
2552 ********************************************************************/
2553 static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture)
2555 NT_PRINTER_INFO_LEVEL *printer = NULL;
2556 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2558 ZERO_STRUCT(printer);
2559 ZERO_STRUCT(driver);
2561 get_a_printer(&printer, 2, lp_servicename(snum) );
2562 get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture);
2564 fill_printer_driver_info_2(info, driver, servername, architecture);
2566 free_a_printer(&printer,2);
2569 /********************************************************************
2570 * copy a strings array and convert to UNICODE
2572 * convert an array of ascii string to a UNICODE string
2573 ********************************************************************/
2574 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *where)
2581 DEBUG(6,("init_unistr_array\n"));
2585 if (char_array == NULL)
2589 if (!v) v = ""; /* hack to handle null lists */
2591 if (strlen(v) == 0) break;
2592 snprintf(line, sizeof(line)-1, "%s%s", where, v);
2593 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
2594 if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
2595 DEBUG(0,("init_unistr_array: Realloc error\n" ));
2598 j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
2603 (*uni_array)[j]=0x0000;
2606 DEBUGADD(6,("last one:done\n"));
2609 /********************************************************************
2610 * construct_printer_info_3
2611 * fill a printer_info_3 struct
2612 ********************************************************************/
2613 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info,
2614 NT_PRINTER_DRIVER_INFO_LEVEL driver,
2615 fstring servername, fstring architecture)
2618 pstring temp_driverpath;
2619 pstring temp_datafile;
2620 pstring temp_configfile;
2621 pstring temp_helpfile;
2622 fstring short_archi;
2624 get_short_archi(short_archi, architecture);
2626 #if MANGLE_DRIVER_PATH
2627 snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\%s\\", servername, short_archi, driver.info_3->name);
2629 snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
2632 info->version=driver.info_3->cversion;
2634 init_unistr( &info->name, driver.info_3->name );
2635 init_unistr( &info->architecture, architecture );
2637 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, driver.info_3->driverpath);
2638 init_unistr( &info->driverpath, temp_driverpath );
2640 snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where, driver.info_3->datafile);
2641 init_unistr( &info->datafile, temp_datafile );
2643 snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, driver.info_3->configfile);
2644 init_unistr( &info->configfile, temp_configfile );
2646 snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "%s%s", where, driver.info_3->helpfile);
2647 init_unistr( &info->helpfile, temp_helpfile );
2649 init_unistr( &info->monitorname, driver.info_3->monitorname );
2650 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
2652 info->dependentfiles=NULL;
2653 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, where);
2656 /********************************************************************
2657 * construct_printer_info_3
2658 * fill a printer_info_3 struct
2659 ********************************************************************/
2660 static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum,
2661 fstring servername, fstring architecture)
2663 NT_PRINTER_INFO_LEVEL *printer = NULL;
2664 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2666 ZERO_STRUCT(driver);
2668 get_a_printer(&printer, 2, lp_servicename(snum) );
2669 get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture);
2671 fill_printer_driver_info_3(info, driver, servername, architecture);
2673 free_a_printer(&printer,2);
2676 /****************************************************************************
2677 ****************************************************************************/
2679 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
2681 safe_free(info->dependentfiles);
2684 /****************************************************************************
2685 ****************************************************************************/
2686 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2688 DRIVER_INFO_1 *info=NULL;
2690 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
2691 return ERROR_NOT_ENOUGH_MEMORY;
2693 construct_printer_driver_info_1(info, snum, servername, architecture);
2695 /* check the required size. */
2696 *needed += spoolss_size_printer_driver_info_1(info);
2698 if (!alloc_buffer_size(buffer, *needed)) {
2700 return ERROR_INSUFFICIENT_BUFFER;
2703 /* fill the buffer with the structures */
2704 new_smb_io_printer_driver_info_1("", buffer, info, 0);
2709 if (*needed > offered)
2710 return ERROR_INSUFFICIENT_BUFFER;
2712 return NT_STATUS_NO_PROBLEMO;
2715 /****************************************************************************
2716 ****************************************************************************/
2717 static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2719 DRIVER_INFO_2 *info=NULL;
2721 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
2722 return ERROR_NOT_ENOUGH_MEMORY;
2724 construct_printer_driver_info_2(info, snum, servername, architecture);
2726 /* check the required size. */
2727 *needed += spoolss_size_printer_driver_info_2(info);
2729 if (!alloc_buffer_size(buffer, *needed)) {
2731 return ERROR_INSUFFICIENT_BUFFER;
2734 /* fill the buffer with the structures */
2735 new_smb_io_printer_driver_info_2("", buffer, info, 0);
2740 if (*needed > offered)
2741 return ERROR_INSUFFICIENT_BUFFER;
2743 return NT_STATUS_NO_PROBLEMO;
2746 /****************************************************************************
2747 ****************************************************************************/
2748 static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2754 construct_printer_driver_info_3(&info, snum, servername, architecture);
2756 /* check the required size. */
2757 *needed += spoolss_size_printer_driver_info_3(&info);
2759 if (!alloc_buffer_size(buffer, *needed)) {
2760 free_printer_driver_info_3(&info);
2761 return ERROR_INSUFFICIENT_BUFFER;
2764 /* fill the buffer with the structures */
2765 new_smb_io_printer_driver_info_3("", buffer, &info, 0);
2767 free_printer_driver_info_3(&info);
2769 if (*needed > offered)
2770 return ERROR_INSUFFICIENT_BUFFER;
2772 return NT_STATUS_NO_PROBLEMO;
2775 /****************************************************************************
2776 ****************************************************************************/
2777 uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level,
2778 uint32 clientmajorversion, uint32 clientminorversion,
2779 NEW_BUFFER *buffer, uint32 offered,
2780 uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
2783 fstring architecture;
2786 DEBUG(4,("_spoolss_getprinterdriver2\n"));
2789 *servermajorversion=0;
2790 *serverminorversion=0;
2792 pstrcpy(servername, global_myname);
2793 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
2795 if (!get_printer_snum(handle, &snum))
2796 return ERROR_INVALID_HANDLE;
2800 return getprinterdriver2_level1(servername, architecture, snum, buffer, offered, needed);
2803 return getprinterdriver2_level2(servername, architecture, snum, buffer, offered, needed);
2806 return getprinterdriver2_level3(servername, architecture, snum, buffer, offered, needed);
2809 return ERROR_INVALID_LEVEL;
2814 /****************************************************************************
2815 ****************************************************************************/
2816 uint32 _spoolss_startpageprinter(const POLICY_HND *handle)
2818 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2820 if (OPEN_HANDLE(Printer)) {
2821 Printer->page_started=True;
2825 DEBUG(3,("Error in startpageprinter printer handle\n"));
2826 return ERROR_INVALID_HANDLE;
2829 /****************************************************************************
2830 ****************************************************************************/
2831 uint32 _spoolss_endpageprinter(const POLICY_HND *handle)
2833 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2835 if (!OPEN_HANDLE(Printer)) {
2836 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
2837 return ERROR_INVALID_HANDLE;
2840 Printer->page_started=False;
2842 return NT_STATUS_NO_PROBLEMO;
2846 /********************************************************************
2847 * api_spoolss_getprinter
2848 * called from the spoolss dispatcher
2850 ********************************************************************/
2851 uint32 _spoolss_startdocprinter(const POLICY_HND *handle, uint32 level,
2852 pipes_struct *p, DOC_INFO *docinfo,
2855 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
2859 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2860 struct current_user user;
2862 if (!OPEN_HANDLE(Printer)) {
2863 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2864 return ERROR_INVALID_HANDLE;
2867 if (p->ntlmssp_auth_validated) {
2868 memcpy(&user, &p->pipe_user, sizeof(user));
2870 extern struct current_user current_user;
2871 memcpy(&user, ¤t_user, sizeof(user));
2875 * a nice thing with NT is it doesn't listen to what you tell it.
2876 * when asked to send _only_ RAW datas, it tries to send datas
2879 * So I add checks like in NT Server ...
2881 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
2882 * there's a bug in NT client-side code, so we'll fix it in the
2883 * server-side code. *nnnnnggggh!*
2886 if (info_1->p_datatype != 0)
2888 unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype));
2889 if (strcmp(datatype, "RAW") != 0)
2892 return ERROR_INVALID_DATATYPE;
2896 /* get the share number of the printer */
2897 if (!get_printer_snum(handle, &snum))
2899 return ERROR_INVALID_HANDLE;
2902 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
2904 Printer->jobid = print_job_start(&user, snum, jobname);
2906 /* need to map error codes properly - for now give out of
2907 memory as I don't know the correct codes (tridge) */
2908 if (Printer->jobid == -1) {
2909 return ERROR_NOT_ENOUGH_MEMORY;
2912 Printer->document_started=True;
2913 (*jobid) = Printer->jobid;
2918 /********************************************************************
2919 * api_spoolss_getprinter
2920 * called from the spoolss dispatcher
2922 ********************************************************************/
2923 uint32 _spoolss_enddocprinter(const POLICY_HND *handle)
2925 Printer_entry *Printer=find_printer_index_by_hnd(handle);
2927 if (!OPEN_HANDLE(Printer)) {
2928 DEBUG(0,("_spoolss_enddocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2929 return ERROR_INVALID_HANDLE;
2932 Printer->document_started=False;
2933 print_job_end(Printer->jobid);
2934 /* error codes unhandled so far ... */
2939 /****************************************************************************
2940 ****************************************************************************/
2941 uint32 _spoolss_writeprinter( const POLICY_HND *handle,
2943 const uint8 *buffer,
2944 uint32 *buffer_written)
2946 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2948 if (!OPEN_HANDLE(Printer)) {
2949 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
2950 return ERROR_INVALID_HANDLE;
2953 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer,
2959 /********************************************************************
2960 * api_spoolss_getprinter
2961 * called from the spoolss dispatcher
2963 ********************************************************************/
2964 static uint32 control_printer(const POLICY_HND *handle, uint32 command,
2967 struct current_user user;
2969 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2971 if (p->ntlmssp_auth_validated) {
2972 memcpy(&user, &p->pipe_user, sizeof(user));
2974 extern struct current_user current_user;
2975 memcpy(&user, ¤t_user, sizeof(user));
2978 if (!OPEN_HANDLE(Printer)) {
2979 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2980 return ERROR_INVALID_HANDLE;
2983 if (!get_printer_snum(handle, &snum) )
2984 return ERROR_INVALID_HANDLE;
2987 case PRINTER_CONTROL_PAUSE:
2988 if (print_queue_pause(&user, snum)) {
2992 case PRINTER_CONTROL_RESUME:
2993 case PRINTER_CONTROL_UNPAUSE:
2994 if (print_queue_resume(&user, snum)) {
2998 case PRINTER_CONTROL_PURGE:
2999 if (print_queue_purge(&user, snum)) {
3005 return ERROR_INVALID_FUNCTION;
3008 /********************************************************************
3009 * called by spoolss_api_setprinter
3010 * when updating a printer description
3011 ********************************************************************/
3012 static uint32 update_printer_sec(const POLICY_HND *handle, uint32 level,
3013 const SPOOL_PRINTER_INFO_LEVEL *info,
3014 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
3016 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3017 struct current_user user;
3018 uint32 acc_granted, status, result;
3020 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3022 if (!OPEN_HANDLE(Printer)) {
3023 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3024 return ERROR_INVALID_HANDLE;
3027 /* Work out which user is performing the operation */
3029 if (p->ntlmssp_auth_validated) {
3030 memcpy(&user, &p->pipe_user, sizeof(user));
3032 extern struct current_user current_user;
3033 memcpy(&user, ¤t_user, sizeof(user));
3036 /* Get old security descriptor */
3038 if (!nt_printing_getsec(Printer->dev.printername, &old_secdesc_ctr)) {
3039 DEBUG(3, ("could not get old security descriptor for "
3040 "printer %s", Printer->dev.printername));
3041 return ERROR_INVALID_FUNCTION;
3044 /* Check the user has permissions to change the security
3045 descriptor. By experimentation with two NT machines, the user
3046 requires Full Access to the printer to change security
3049 if (!se_access_check(old_secdesc_ctr->sec, &user,
3050 PRINTER_ACE_FULL_CONTROL, &acc_granted,
3052 DEBUG(3, ("security descriptor change denied by existing "
3053 "security descriptor\n"));
3058 result = nt_printing_setsec(Printer->dev.printername, secdesc_ctr);
3061 free_sec_desc_buf(&old_secdesc_ctr);
3065 /********************************************************************
3066 * called by spoolss_api_setprinter
3067 * when updating a printer description
3068 ********************************************************************/
3070 static uint32 update_printer(const POLICY_HND *handle, uint32 level,
3071 const SPOOL_PRINTER_INFO_LEVEL *info,
3072 DEVICEMODE *devmode)
3075 NT_PRINTER_INFO_LEVEL *printer = NULL;
3076 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3077 SEC_DESC_BUF *sd = NULL;
3078 uint32 result, acc_granted;
3079 extern struct current_user current_user;
3081 DEBUG(8,("update_printer\n"));
3083 result = NT_STATUS_NO_PROBLEMO;
3085 /* Check calling user has permission to update printer description */
3088 if (!nt_printing_getsec(Printer->dev.printername, &sd)) {
3089 DEBUG(3, ("Could not get security descriptor for printer %s",
3090 Printer->dev.printername));
3091 result = ERROR_INVALID_FUNCTION;
3095 if (!se_access_check(sd->sec, ¤t_user,
3096 PRINTER_ACE_FULL_CONTROL, &acc_granted,
3098 DEBUG(3, ("printer property change denied by security "
3104 DEBUG(0,("Send a mail to samba@samba.org\n"));
3105 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3106 result = ERROR_INVALID_LEVEL;
3110 if (!OPEN_HANDLE(Printer)) {
3111 result = ERROR_INVALID_HANDLE;
3115 if (!get_printer_snum(handle, &snum)) {
3116 result = ERROR_INVALID_HANDLE;
3120 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3121 result = ERROR_INVALID_HANDLE;
3125 DEBUGADD(8,("Converting info_2 struct\n"));
3128 * convert_printer_info converts the incoming
3129 * info from the client and overwrites the info
3130 * just read from the tdb in the pointer 'printer'.
3133 convert_printer_info(info, printer, level);
3135 if (info->info_2->devmode_ptr != 0) {
3136 /* we have a valid devmode
3137 convert it and link it*/
3140 * Ensure printer->info_2->devmode is a valid pointer
3141 * as we will be overwriting it in convert_devicemode().
3144 if (printer->info_2->devmode == NULL)
3145 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3147 DEBUGADD(8,("Converting the devicemode struct\n"));
3148 convert_devicemode(devmode, printer->info_2->devmode);
3151 if (printer->info_2->devmode != NULL)
3152 free_nt_devicemode(&printer->info_2->devmode);
3153 printer->info_2->devmode=NULL;
3156 if (add_a_printer(*printer, 2)!=0) {
3157 /* I don't really know what to return here !!! */
3158 result = ERROR_ACCESS_DENIED;
3163 free_a_printer(&printer, 2);
3164 free_sec_desc_buf(&sd);
3169 /****************************************************************************
3170 ****************************************************************************/
3171 uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
3172 const SPOOL_PRINTER_INFO_LEVEL *info,
3173 DEVMODE_CTR devmode_ctr,
3174 SEC_DESC_BUF *secdesc_ctr,
3175 uint32 command, pipes_struct *p)
3177 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3179 if (!OPEN_HANDLE(Printer)) {
3180 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3181 return ERROR_INVALID_HANDLE;
3184 /* check the level */
3187 return control_printer(handle, command, p);
3190 return update_printer(handle, level, info, devmode_ctr.devmode);
3193 return update_printer_sec(handle, level, info, p,
3197 return ERROR_INVALID_LEVEL;
3202 /****************************************************************************
3203 ****************************************************************************/
3204 uint32 _spoolss_fcpn(const POLICY_HND *handle)
3206 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3208 if (!OPEN_HANDLE(Printer)) {
3209 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3210 return ERROR_INVALID_HANDLE;
3213 Printer->notify.flags=0;
3214 Printer->notify.options=0;
3215 Printer->notify.localmachine[0]='\0';
3216 Printer->notify.printerlocal=0;
3217 if (Printer->notify.option)
3218 safe_free(Printer->notify.option->ctr.type);
3219 safe_free(Printer->notify.option);
3220 Printer->notify.option=NULL;
3222 return NT_STATUS_NO_PROBLEMO;
3225 /****************************************************************************
3226 ****************************************************************************/
3227 uint32 _spoolss_addjob(const POLICY_HND *handle, uint32 level,
3228 NEW_BUFFER *buffer, uint32 offered)
3230 return NT_STATUS_NO_PROBLEMO;
3233 /****************************************************************************
3234 ****************************************************************************/
3235 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3236 int position, int snum)
3241 time_t unixdate = time(NULL);
3243 t=gmtime(&unixdate);
3244 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3246 job_info->jobid=queue->job;
3247 init_unistr(&job_info->printername, lp_servicename(snum));
3248 init_unistr(&job_info->machinename, temp_name);
3249 init_unistr(&job_info->username, queue->user);
3250 init_unistr(&job_info->document, queue->file);
3251 init_unistr(&job_info->datatype, "RAW");
3252 init_unistr(&job_info->text_status, "");
3253 job_info->status=nt_printj_status(queue->status);
3254 job_info->priority=queue->priority;
3255 job_info->position=position;
3256 job_info->totalpages=0;
3257 job_info->pagesprinted=0;
3259 make_systemtime(&(job_info->submitted), t);
3262 /****************************************************************************
3263 ****************************************************************************/
3264 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3265 int position, int snum)
3268 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3272 time_t unixdate = time(NULL);
3274 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3277 t=gmtime(&unixdate);
3278 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3280 job_info->jobid=queue->job;
3282 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3284 init_unistr(&(job_info->printername), chaine);
3286 init_unistr(&job_info->machinename, temp_name);
3287 init_unistr(&job_info->username, queue->user);
3288 init_unistr(&job_info->document, queue->file);
3289 init_unistr(&job_info->notifyname, queue->user);
3290 init_unistr(&job_info->datatype, "RAW");
3291 init_unistr(&job_info->printprocessor, "winprint");
3292 init_unistr(&job_info->parameters, "");
3293 init_unistr(&job_info->text_status, "");
3295 /* and here the security descriptor */
3297 job_info->status=nt_printj_status(queue->status);
3298 job_info->priority=queue->priority;
3299 job_info->position=position;
3300 job_info->starttime=0;
3301 job_info->untiltime=0;
3302 job_info->totalpages=0;
3303 job_info->size=queue->size;
3304 make_systemtime(&(job_info->submitted), t);
3305 job_info->timeelapsed=0;
3306 job_info->pagesprinted=0;
3308 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3309 free_a_printer(&ntprinter, 2);
3313 free_a_printer(&ntprinter, 2);
3317 /****************************************************************************
3318 Enumjobs at level 1.
3319 ****************************************************************************/
3320 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3321 NEW_BUFFER *buffer, uint32 offered,
3322 uint32 *needed, uint32 *returned)
3327 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3331 return ERROR_NOT_ENOUGH_MEMORY;
3334 for (i=0; i<*returned; i++)
3335 fill_job_info_1(&info[i], &queue[i], i, snum);
3339 /* check the required size. */
3340 for (i=0; i<*returned; i++)
3341 (*needed) += spoolss_size_job_info_1(&info[i]);
3343 if (!alloc_buffer_size(buffer, *needed)) {
3345 return ERROR_INSUFFICIENT_BUFFER;
3348 /* fill the buffer with the structures */
3349 for (i=0; i<*returned; i++)
3350 new_smb_io_job_info_1("", buffer, &info[i], 0);
3355 if (*needed > offered) {
3357 return ERROR_INSUFFICIENT_BUFFER;
3360 return NT_STATUS_NO_PROBLEMO;
3363 /****************************************************************************
3364 Enumjobs at level 2.
3365 ****************************************************************************/
3366 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3367 NEW_BUFFER *buffer, uint32 offered,
3368 uint32 *needed, uint32 *returned)
3373 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3377 return ERROR_NOT_ENOUGH_MEMORY;
3380 for (i=0; i<*returned; i++)
3381 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3385 /* check the required size. */
3386 for (i=0; i<*returned; i++)
3387 (*needed) += spoolss_size_job_info_2(&info[i]);
3389 if (!alloc_buffer_size(buffer, *needed)) {
3391 return ERROR_INSUFFICIENT_BUFFER;
3394 /* fill the buffer with the structures */
3395 for (i=0; i<*returned; i++)
3396 new_smb_io_job_info_2("", buffer, &info[i], 0);
3401 if (*needed > offered) {
3403 return ERROR_INSUFFICIENT_BUFFER;
3406 return NT_STATUS_NO_PROBLEMO;
3409 /****************************************************************************
3411 ****************************************************************************/
3412 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3413 NEW_BUFFER *buffer, uint32 offered,
3414 uint32 *needed, uint32 *returned)
3417 print_queue_struct *queue=NULL;
3418 print_status_struct prt_status;
3420 DEBUG(4,("_spoolss_enumjobs\n"));
3422 ZERO_STRUCT(prt_status);
3427 if (!get_printer_snum(handle, &snum))
3428 return ERROR_INVALID_HANDLE;
3430 *returned = print_queue_status(snum, &queue, &prt_status);
3431 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3435 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3438 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3443 return ERROR_INVALID_LEVEL;
3449 /****************************************************************************
3450 ****************************************************************************/
3451 uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid)
3456 /****************************************************************************
3457 ****************************************************************************/
3458 uint32 _spoolss_setjob( const POLICY_HND *handle,
3466 struct current_user user;
3468 print_status_struct prt_status;
3470 memset(&prt_status, 0, sizeof(prt_status));
3472 if (!get_printer_snum(handle, &snum)) {
3473 return ERROR_INVALID_HANDLE;
3476 if (!print_job_exists(jobid)) {
3477 return ERROR_INVALID_PRINTER_NAME;
3480 if (p->ntlmssp_auth_validated) {
3481 memcpy(&user, &p->pipe_user, sizeof(user));
3483 extern struct current_user current_user;
3484 memcpy(&user, ¤t_user, sizeof(user));
3488 case JOB_CONTROL_CANCEL:
3489 case JOB_CONTROL_DELETE:
3490 if (print_job_delete(&user, jobid)) return 0x0;
3492 case JOB_CONTROL_PAUSE:
3493 if (print_job_pause(&user, jobid)) return 0x0;
3495 case JOB_CONTROL_RESUME:
3496 if (print_job_resume(&user, jobid)) return 0x0;
3499 return ERROR_INVALID_LEVEL;
3502 return ERROR_INVALID_HANDLE;
3505 /****************************************************************************
3506 Enumerates all printer drivers at level 1.
3507 ****************************************************************************/
3508 static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3511 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3512 DRIVER_INFO_1 *driver_info_1=NULL;
3514 ZERO_STRUCT(driver);
3516 if((driver_info_1=(DRIVER_INFO_1 *)malloc(*returned * sizeof(DRIVER_INFO_1))) == NULL)
3517 return ERROR_NOT_ENOUGH_MEMORY;
3519 for (i=0; i<*returned; i++) {
3520 get_a_printer_driver(&driver, 3, list[i], architecture);
3521 fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture );
3526 /* check the required size. */
3527 for (i=0; i<*returned; i++) {
3528 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3529 *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
3532 if (!alloc_buffer_size(buffer, *needed)) {
3533 safe_free(driver_info_1);
3534 return ERROR_INSUFFICIENT_BUFFER;
3537 /* fill the buffer with the form structures */
3538 for (i=0; i<*returned; i++) {
3539 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3540 new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
3543 safe_free(driver_info_1);
3545 if (*needed > offered) {
3547 return ERROR_INSUFFICIENT_BUFFER;
3550 return NT_STATUS_NO_PROBLEMO;
3553 /****************************************************************************
3554 Enumerates all printer drivers at level 2.
3555 ****************************************************************************/
3556 static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3559 DRIVER_INFO_2 *driver_info_2=NULL;
3561 if (*returned > 0 &&
3562 !(driver_info_2=(DRIVER_INFO_2 *)malloc(*returned * sizeof(DRIVER_INFO_2))))
3563 return ERROR_NOT_ENOUGH_MEMORY;
3565 for (i=0; i<*returned; i++) {
3566 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3567 ZERO_STRUCT(driver);
3568 if (get_a_printer_driver(&driver, 3, list[i], architecture)
3573 fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture );
3578 /* check the required size. */
3579 for (i=0; i<*returned; i++) {
3580 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3581 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3584 if (!alloc_buffer_size(buffer, *needed)) {
3585 safe_free(driver_info_2);
3586 return ERROR_INSUFFICIENT_BUFFER;
3589 /* fill the buffer with the form structures */
3590 for (i=0; i<*returned; i++) {
3591 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3592 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3595 safe_free(driver_info_2);
3597 if (*needed > offered) {
3599 return ERROR_INSUFFICIENT_BUFFER;
3602 return NT_STATUS_NO_PROBLEMO;
3605 /****************************************************************************
3606 Enumerates all printer drivers at level 3.
3607 ****************************************************************************/
3608 static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3611 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3612 DRIVER_INFO_3 *driver_info_3=NULL;
3614 ZERO_STRUCT(driver);
3616 if((driver_info_3=(DRIVER_INFO_3 *)malloc((*returned)*sizeof(DRIVER_INFO_3))) == NULL)
3617 return ERROR_NOT_ENOUGH_MEMORY;
3619 for (i=0; i<*returned; i++) {
3620 get_a_printer_driver(&driver, 3, list[i], architecture);
3621 fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture );
3626 /* check the required size. */
3627 for (i=0; i<*returned; i++) {
3628 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3629 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3632 if (!alloc_buffer_size(buffer, *needed)) {
3633 safe_free(driver_info_3);
3634 return ERROR_INSUFFICIENT_BUFFER;
3637 /* fill the buffer with the driver structures */
3638 for (i=0; i<*returned; i++) {
3639 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3640 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
3643 for (i=0; i<*returned; i++)
3644 safe_free(driver_info_3[i].dependentfiles);
3646 safe_free(driver_info_3);
3648 if (*needed > offered) {
3650 return ERROR_INSUFFICIENT_BUFFER;
3653 return NT_STATUS_NO_PROBLEMO;
3656 /****************************************************************************
3657 Enumerates all printer drivers.
3658 ****************************************************************************/
3659 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
3660 NEW_BUFFER *buffer, uint32 offered,
3661 uint32 *needed, uint32 *returned)
3664 fstring *list = NULL;
3666 fstring architecture;
3668 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
3669 fstrcpy(servername, global_myname);
3673 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
3674 *returned=get_ntdrivers(&list, architecture);
3676 DEBUGADD(4,("we have: [%d] drivers in environment [%s]\n", *returned, architecture));
3678 return ERROR_NOT_ENOUGH_MEMORY;
3680 for (i=0; i<*returned; i++)
3681 DEBUGADD(5,("driver: [%s]\n", list[i]));
3685 return enumprinterdrivers_level1(list, servername, architecture, buffer, offered, needed, returned);
3688 return enumprinterdrivers_level2(list, servername, architecture, buffer, offered, needed, returned);
3691 return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned);
3695 return ERROR_INVALID_LEVEL;
3700 /****************************************************************************
3701 ****************************************************************************/
3702 static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
3704 form->flag=list->flag;
3705 init_unistr(&form->name, list->name);
3706 form->width=list->width;
3707 form->length=list->length;
3708 form->left=list->left;
3709 form->top=list->top;
3710 form->right=list->right;
3711 form->bottom=list->bottom;
3714 /****************************************************************************
3715 ****************************************************************************/
3716 uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level,
3717 NEW_BUFFER *buffer, uint32 offered,
3718 uint32 *needed, uint32 *numofforms)
3720 nt_forms_struct *list=NULL;
3725 DEBUG(4,("_new_spoolss_enumforms\n"));
3726 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3727 DEBUGADD(5,("Info level [%d]\n", level));
3729 *numofforms = get_ntforms(&list);
3730 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
3732 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
3736 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
3738 return ERROR_NOT_ENOUGH_MEMORY;
3741 /* construct the list of form structures */
3742 for (i=0; i<*numofforms; i++) {
3743 DEBUGADD(6,("Filling form number [%d]\n",i));
3744 fill_form_1(&forms_1[i], &list[i], i);
3749 /* check the required size. */
3750 for (i=0; i<*numofforms; i++) {
3751 DEBUGADD(6,("adding form [%d]'s size\n",i));
3752 buffer_size += spoolss_size_form_1(&forms_1[i]);
3755 *needed=buffer_size;
3757 if (!alloc_buffer_size(buffer, buffer_size)){
3759 return ERROR_INSUFFICIENT_BUFFER;
3762 /* fill the buffer with the form structures */
3763 for (i=0; i<*numofforms; i++) {
3764 DEBUGADD(6,("adding form [%d] to buffer\n",i));
3765 new_smb_io_form_1("", buffer, &forms_1[i], 0);
3770 if (*needed > offered) {
3772 return ERROR_INSUFFICIENT_BUFFER;
3775 return NT_STATUS_NO_PROBLEMO;
3779 return ERROR_INVALID_LEVEL;
3784 /****************************************************************************
3785 ****************************************************************************/
3786 static void fill_port_1(PORT_INFO_1 *port, char *name)
3788 init_unistr(&port->port_name, name);
3791 /****************************************************************************
3792 ****************************************************************************/
3793 static void fill_port_2(PORT_INFO_2 *port, char *name)
3795 init_unistr(&port->port_name, name);
3796 init_unistr(&port->monitor_name, "Local Monitor");
3797 init_unistr(&port->description, "Local Port");
3798 #define PORT_TYPE_WRITE 1
3799 port->port_type=PORT_TYPE_WRITE;
3803 /****************************************************************************
3805 ****************************************************************************/
3806 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3808 int n_services=lp_numservices();
3812 PORT_INFO_1 *ports=NULL;
3814 for (snum=0; snum<n_services; snum++)
3815 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3818 if((ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) )) == NULL)
3819 return ERROR_NOT_ENOUGH_MEMORY;
3821 for (snum=0; snum<n_services; snum++) {
3822 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3824 * Ensure this port name is unique.
3828 DEBUG(10,("enumports_level_1: port name %s\n", PRINTERNAME(snum)));
3830 for(j = 0; j < i; j++) {
3832 unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
3834 if (strequal(port_name, PRINTERNAME(snum)))
3841 DEBUGADD(6,("Filling port number [%d]\n", i));
3842 fill_port_1(&ports[i], PRINTERNAME(snum));
3849 /* check the required size. */
3850 for (i=0; i<*returned; i++) {
3851 DEBUGADD(6,("adding port [%d]'s size\n", i));
3852 *needed += spoolss_size_port_info_1(&ports[i]);
3855 if (!alloc_buffer_size(buffer, *needed)) {
3857 return ERROR_INSUFFICIENT_BUFFER;
3860 /* fill the buffer with the ports structures */
3861 for (i=0; i<*returned; i++) {
3862 DEBUGADD(6,("adding port [%d] to buffer\n", i));
3863 new_smb_io_port_1("", buffer, &ports[i], 0);
3868 if (*needed > offered) {
3870 return ERROR_INSUFFICIENT_BUFFER;
3873 return NT_STATUS_NO_PROBLEMO;
3876 /****************************************************************************
3878 ****************************************************************************/
3880 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3882 int n_services=lp_numservices();
3886 PORT_INFO_2 *ports=NULL;
3888 for (snum=0; snum<n_services; snum++)
3889 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3892 if((ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) )) == NULL)
3893 return ERROR_NOT_ENOUGH_MEMORY;
3895 for (snum=0; snum<n_services; snum++) {
3896 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
3898 * Ensure this port name is unique.
3902 DEBUG(10,("enumports_level_2: port name %s\n", PRINTERNAME(snum)));
3904 for(j = 0; j < i; j++) {
3906 unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
3908 if (strequal(port_name, PRINTERNAME(snum)))
3915 DEBUGADD(6,("Filling port number [%d]\n", i));
3916 fill_port_2(&ports[i], PRINTERNAME(snum));
3923 /* check the required size. */
3924 for (i=0; i<*returned; i++) {
3925 DEBUGADD(6,("adding port [%d]'s size\n", i));
3926 *needed += spoolss_size_port_info_2(&ports[i]);
3929 if (!alloc_buffer_size(buffer, *needed)) {
3931 return ERROR_INSUFFICIENT_BUFFER;
3934 /* fill the buffer with the ports structures */
3935 for (i=0; i<*returned; i++) {
3936 DEBUGADD(6,("adding port [%d] to buffer\n", i));
3937 new_smb_io_port_2("", buffer, &ports[i], 0);
3942 if (*needed > offered) {
3944 return ERROR_INSUFFICIENT_BUFFER;
3947 return NT_STATUS_NO_PROBLEMO;
3950 /****************************************************************************
3952 ****************************************************************************/
3953 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
3954 NEW_BUFFER *buffer, uint32 offered,
3955 uint32 *needed, uint32 *returned)
3957 DEBUG(4,("_spoolss_enumports\n"));
3964 return enumports_level_1(buffer, offered, needed, returned);
3967 return enumports_level_2(buffer, offered, needed, returned);
3970 return ERROR_INVALID_LEVEL;
3975 /****************************************************************************
3976 ****************************************************************************/
3977 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
3978 const SPOOL_PRINTER_INFO_LEVEL *info,
3979 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
3980 uint32 user_switch, const SPOOL_USER_CTR *user,
3983 NT_PRINTER_INFO_LEVEL *printer = NULL;
3987 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3988 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
3989 return ERROR_NOT_ENOUGH_MEMORY;
3992 ZERO_STRUCTP(printer);
3994 clear_handle(handle);
3996 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
3997 convert_printer_info(info, printer, 2);
3999 unistr2_to_ascii(share_name, &info->info_2->printername, sizeof(share_name)-1);
4001 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
4003 /* write the ASCII on disk */
4004 if (add_a_printer(*printer, 2) != 0) {
4005 free_a_printer(&printer,2);
4006 return ERROR_ACCESS_DENIED;
4009 create_printer_hnd(handle);
4011 open_printer_hnd(handle);
4013 if (!set_printer_hnd_printertype(handle, name)) {
4014 free_a_printer(&printer,2);
4015 close_printer_handle(handle);
4016 return ERROR_ACCESS_DENIED;
4019 if (!set_printer_hnd_printername(handle, name)) {
4020 free_a_printer(&printer,2);
4021 close_printer_handle(handle);
4022 return ERROR_ACCESS_DENIED;
4025 free_a_printer(&printer,2);
4026 return NT_STATUS_NO_PROBLEMO;
4029 /****************************************************************************
4030 ****************************************************************************/
4031 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4032 const SPOOL_PRINTER_INFO_LEVEL *info,
4033 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4034 uint32 user_switch, const SPOOL_USER_CTR *user,
4039 /* we don't handle yet */
4040 /* but I know what to do ... */
4041 return ERROR_INVALID_LEVEL;
4044 return spoolss_addprinterex_level_2(uni_srv_name, info,
4045 unk0, unk1, unk2, unk3,
4046 user_switch, user, handle);
4049 return ERROR_INVALID_LEVEL;
4054 /****************************************************************************
4055 Modify internal driver heirarchy.
4056 ****************************************************************************/
4058 #if MANGLE_DRIVER_PATH
4059 static uint32 modify_driver_heirarchy(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level)
4063 pstring short_archi;
4066 /* find_service is an smbd-specific function call */
4067 int snum = find_service("print$");
4070 *short_archi = '\0';
4073 get_short_archi(short_archi, driver->info_3->environment);
4074 model = driver->info_3->name;
4077 get_short_archi(short_archi, driver->info_6->environment);
4078 model = driver->info_6->name;
4081 DEBUG(0,("modify_driver_heirarchy: unknown info level (%d)\n", level));
4082 return ERROR_INVALID_LEVEL;
4086 slprintf(path_old, sizeof(path_old)-1, "%s/%s/TMP_%s", lp_pathname(snum), short_archi,
4089 /* Clean up any '/' and other characters in the model name. */
4090 alpha_strcpy(model_name, model, sizeof(pstring));
4092 slprintf(path_new, sizeof(path_new)-1, "%s/%s/%s", lp_pathname(snum), short_archi, model_name);
4094 DEBUG(10,("modify_driver_heirarchy: old_path=%s, new_path=%s\n",
4095 path_old, path_new ));
4096 if (dos_rename(path_old, path_new) == -1) {
4097 DEBUG(0,("modify_driver_heirarchy: rename from %s to %s failed (%s)\n",
4098 path_old, path_new, strerror(errno) ));
4099 /* We need to clean up here.... - how ? */
4100 return ERROR_ACCESS_DENIED; /* We need a generic mapping from NT errors here... */
4103 return NT_STATUS_NO_PROBLEMO;
4107 /****************************************************************************
4108 ****************************************************************************/
4109 uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
4111 const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4113 uint32 err = NT_STATUS_NO_PROBLEMO;
4114 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4115 ZERO_STRUCT(driver);
4117 convert_printer_driver_info(info, &driver, level);
4119 if (add_a_printer_driver(driver, level)!=0)
4120 return ERROR_ACCESS_DENIED;
4122 #if MANGLE_DRIVER_PATH
4123 err = modify_driver_heirarchy(&driver, level);
4126 free_a_printer_driver(driver, level);
4131 /****************************************************************************
4132 ****************************************************************************/
4133 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4135 init_unistr(&(info->name), name);
4138 /****************************************************************************
4139 ****************************************************************************/
4140 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4144 pstring short_archi;
4145 DRIVER_DIRECTORY_1 *info=NULL;
4147 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4148 return ERROR_NOT_ENOUGH_MEMORY;
4150 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4151 get_short_archi(short_archi, long_archi);
4153 #if MANGLE_DRIVER_PATH
4154 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s\\TMP_%s", global_myname, short_archi,
4157 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s",
4158 global_myname, short_archi);
4160 DEBUG(4,("printer driver directory: [%s]\n", path));
4162 fill_driverdir_1(info, path);
4164 *needed += spoolss_size_driverdir_info_1(info);
4166 if (!alloc_buffer_size(buffer, *needed)) {
4168 return ERROR_INSUFFICIENT_BUFFER;
4171 new_smb_io_driverdir_1("", buffer, info, 0);
4175 if (*needed > offered)
4176 return ERROR_INSUFFICIENT_BUFFER;
4178 return NT_STATUS_NO_PROBLEMO;
4181 /****************************************************************************
4182 ****************************************************************************/
4183 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4184 NEW_BUFFER *buffer, uint32 offered,
4187 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4193 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4196 return ERROR_INVALID_LEVEL;
4201 /****************************************************************************
4202 ****************************************************************************/
4203 uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
4204 uint32 in_value_len, uint32 in_data_len,
4205 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4207 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4209 NT_PRINTER_INFO_LEVEL *printer = NULL;
4214 uint32 biggest_valuesize;
4215 uint32 biggest_datasize;
4217 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4222 ZERO_STRUCT(printer);
4224 *out_max_value_len=0;
4230 *out_max_data_len=0;
4234 DEBUG(5,("spoolss_enumprinterdata\n"));
4236 if (!OPEN_HANDLE(Printer)) {
4237 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4238 return ERROR_INVALID_HANDLE;
4241 if (!get_printer_snum(handle, &snum))
4242 return ERROR_INVALID_HANDLE;
4244 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4245 return ERROR_INVALID_HANDLE;
4248 * The NT machine wants to know the biggest size of value and data
4250 * cf: MSDN EnumPrinterData remark section
4252 if ( (in_value_len==0) && (in_data_len==0) ) {
4253 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4256 biggest_valuesize=0;
4259 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4260 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4261 if (data_len > biggest_datasize) biggest_datasize=data_len;
4263 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4269 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4270 *out_value_len=2*(1+biggest_valuesize);
4271 *out_data_len=biggest_datasize;
4273 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4275 free_a_printer(&printer, 2);
4276 return NT_STATUS_NO_PROBLEMO;
4280 * the value len is wrong in NT sp3
4281 * that's the number of bytes not the number of unicode chars
4284 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4286 free_a_printer(&printer, 2);
4287 return ERROR_NO_MORE_ITEMS;
4290 free_a_printer(&printer, 2);
4294 * - counted in bytes in the request
4295 * - counted in UNICODE chars in the max reply
4296 * - counted in bytes in the real size
4298 * take a pause *before* coding not *during* coding
4301 *out_max_value_len=(in_value_len/sizeof(uint16));
4302 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4304 return ERROR_NOT_ENOUGH_MEMORY;
4307 ZERO_STRUCTP(*out_value);
4308 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4312 /* the data is counted in bytes */
4313 *out_max_data_len=in_data_len;
4314 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4316 return ERROR_NOT_ENOUGH_MEMORY;
4319 ZERO_STRUCTP(*data_out);
4320 memcpy(*data_out, data, (size_t)data_len);
4321 *out_data_len=data_len;
4325 return NT_STATUS_NO_PROBLEMO;
4328 /****************************************************************************
4329 ****************************************************************************/
4330 uint32 _spoolss_setprinterdata( const POLICY_HND *handle,
4331 const UNISTR2 *value,
4336 uint32 numeric_data)
4338 NT_PRINTER_INFO_LEVEL *printer = NULL;
4339 NT_PRINTER_PARAM *param = NULL;
4342 uint32 status = 0x0;
4343 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4345 DEBUG(5,("spoolss_setprinterdata\n"));
4348 if (!OPEN_HANDLE(Printer)) {
4349 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4350 return ERROR_INVALID_HANDLE;
4353 if (!get_printer_snum(handle, &snum))
4354 return ERROR_INVALID_HANDLE;
4356 status = get_a_printer(&printer, 2, lp_servicename(snum));
4358 return ERROR_INVALID_NAME;
4360 convert_specific_param(¶m, value , type, data, real_len);
4361 unlink_specific_param_if_exist(printer->info_2, param);
4363 if (!add_a_specific_param(printer->info_2, param))
4364 status = ERROR_INVALID_PARAMETER;
4366 status = add_a_printer(*printer, 2);
4368 free_a_printer(&printer, 2);
4372 /****************************************************************************
4373 ****************************************************************************/
4374 uint32 _spoolss_addform( const POLICY_HND *handle,
4379 nt_forms_struct *list=NULL;
4380 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4382 DEBUG(5,("spoolss_addform\n"));
4384 if (!OPEN_HANDLE(Printer)) {
4385 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4386 return ERROR_INVALID_HANDLE;
4389 count=get_ntforms(&list);
4390 if(!add_a_form(&list, form, &count))
4391 return ERROR_NOT_ENOUGH_MEMORY;
4392 write_ntforms(&list, count);
4399 /****************************************************************************
4400 ****************************************************************************/
4401 uint32 _spoolss_setform( const POLICY_HND *handle,
4402 const UNISTR2 *uni_name,
4407 nt_forms_struct *list=NULL;
4408 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4410 DEBUG(5,("spoolss_setform\n"));
4412 if (!OPEN_HANDLE(Printer)) {
4413 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4414 return ERROR_INVALID_HANDLE;
4416 count=get_ntforms(&list);
4417 update_a_form(&list, form, count);
4418 write_ntforms(&list, count);
4425 /****************************************************************************
4426 enumprintprocessors level 1.
4427 ****************************************************************************/
4428 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4430 PRINTPROCESSOR_1 *info_1=NULL;
4432 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4433 return ERROR_NOT_ENOUGH_MEMORY;
4437 init_unistr(&(info_1->name), "winprint");
4439 *needed += spoolss_size_printprocessor_info_1(info_1);
4441 if (!alloc_buffer_size(buffer, *needed))
4442 return ERROR_INSUFFICIENT_BUFFER;
4444 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4448 if (*needed > offered) {
4450 return ERROR_INSUFFICIENT_BUFFER;
4453 return NT_STATUS_NO_PROBLEMO;
4456 /****************************************************************************
4457 ****************************************************************************/
4458 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
4459 NEW_BUFFER *buffer, uint32 offered,
4460 uint32 *needed, uint32 *returned)
4462 DEBUG(5,("spoolss_enumprintprocessors\n"));
4465 * Enumerate the print processors ...
4467 * Just reply with "winprint", to keep NT happy
4468 * and I can use my nice printer checker.
4476 return enumprintprocessors_level_1(buffer, offered, needed, returned);
4479 return ERROR_INVALID_LEVEL;
4484 /****************************************************************************
4485 enumprintprocdatatypes level 1.
4486 ****************************************************************************/
4487 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4489 PRINTPROCDATATYPE_1 *info_1=NULL;
4491 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
4492 return ERROR_NOT_ENOUGH_MEMORY;
4496 init_unistr(&(info_1->name), "RAW");
4498 *needed += spoolss_size_printprocdatatype_info_1(info_1);
4500 if (!alloc_buffer_size(buffer, *needed))
4501 return ERROR_INSUFFICIENT_BUFFER;
4503 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
4507 if (*needed > offered) {
4509 return ERROR_INSUFFICIENT_BUFFER;
4512 return NT_STATUS_NO_PROBLEMO;
4515 /****************************************************************************
4516 ****************************************************************************/
4517 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
4518 NEW_BUFFER *buffer, uint32 offered,
4519 uint32 *needed, uint32 *returned)
4521 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
4528 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
4531 return ERROR_INVALID_LEVEL;
4536 /****************************************************************************
4537 enumprintmonitors level 1.
4538 ****************************************************************************/
4539 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4541 PRINTMONITOR_1 *info_1=NULL;
4543 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
4544 return ERROR_NOT_ENOUGH_MEMORY;
4548 init_unistr(&(info_1->name), "Local Port");
4550 *needed += spoolss_size_printmonitor_info_1(info_1);
4552 if (!alloc_buffer_size(buffer, *needed))
4553 return ERROR_INSUFFICIENT_BUFFER;
4555 smb_io_printmonitor_info_1("", buffer, info_1, 0);
4559 if (*needed > offered) {
4561 return ERROR_INSUFFICIENT_BUFFER;
4564 return NT_STATUS_NO_PROBLEMO;
4567 /****************************************************************************
4568 enumprintmonitors level 2.
4569 ****************************************************************************/
4570 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4572 PRINTMONITOR_2 *info_2=NULL;
4574 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
4575 return ERROR_NOT_ENOUGH_MEMORY;
4579 init_unistr(&(info_2->name), "Local Port");
4580 init_unistr(&(info_2->environment), "Windows NT X86");
4581 init_unistr(&(info_2->dll_name), "localmon.dll");
4583 *needed += spoolss_size_printmonitor_info_2(info_2);
4585 if (!alloc_buffer_size(buffer, *needed))
4586 return ERROR_INSUFFICIENT_BUFFER;
4588 smb_io_printmonitor_info_2("", buffer, info_2, 0);
4592 if (*needed > offered) {
4594 return ERROR_INSUFFICIENT_BUFFER;
4597 return NT_STATUS_NO_PROBLEMO;
4600 /****************************************************************************
4601 ****************************************************************************/
4602 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
4603 NEW_BUFFER *buffer, uint32 offered,
4604 uint32 *needed, uint32 *returned)
4606 DEBUG(5,("spoolss_enumprintmonitors\n"));
4609 * Enumerate the print monitors ...
4611 * Just reply with "Local Port", to keep NT happy
4612 * and I can use my nice printer checker.
4620 return enumprintmonitors_level_1(buffer, offered, needed, returned);
4623 return enumprintmonitors_level_2(buffer, offered, needed, returned);
4626 return ERROR_INVALID_LEVEL;
4631 /****************************************************************************
4632 ****************************************************************************/
4633 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4637 JOB_INFO_1 *info_1=NULL;
4639 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
4641 if (info_1 == NULL) {
4643 return ERROR_NOT_ENOUGH_MEMORY;
4646 for (i=0; i<count && found==False; i++) {
4647 if (queue[i].job==(int)jobid)
4654 /* I shoud reply something else ... I can't find the good one */
4655 return NT_STATUS_NO_PROBLEMO;
4658 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
4662 *needed += spoolss_size_job_info_1(info_1);
4664 if (!alloc_buffer_size(buffer, *needed)) {
4666 return ERROR_INSUFFICIENT_BUFFER;
4669 new_smb_io_job_info_1("", buffer, info_1, 0);
4673 if (*needed > offered)
4674 return ERROR_INSUFFICIENT_BUFFER;
4676 return NT_STATUS_NO_PROBLEMO;
4680 /****************************************************************************
4681 ****************************************************************************/
4682 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4687 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
4689 ZERO_STRUCTP(info_2);
4691 if (info_2 == NULL) {
4693 return ERROR_NOT_ENOUGH_MEMORY;
4696 for (i=0; i<count && found==False; i++) {
4697 if (queue[i].job==(int)jobid)
4704 /* I shoud reply something else ... I can't find the good one */
4705 return NT_STATUS_NO_PROBLEMO;
4708 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
4712 *needed += spoolss_size_job_info_2(info_2);
4714 if (!alloc_buffer_size(buffer, *needed)) {
4716 return ERROR_INSUFFICIENT_BUFFER;
4719 new_smb_io_job_info_2("", buffer, info_2, 0);
4721 free_dev_mode(info_2->devmode);
4724 if (*needed > offered)
4725 return ERROR_INSUFFICIENT_BUFFER;
4727 return NT_STATUS_NO_PROBLEMO;
4730 /****************************************************************************
4731 ****************************************************************************/
4732 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
4733 NEW_BUFFER *buffer, uint32 offered,
4738 print_queue_struct *queue=NULL;
4739 print_status_struct prt_status;
4741 DEBUG(5,("spoolss_getjob\n"));
4743 memset(&prt_status, 0, sizeof(prt_status));
4747 if (!get_printer_snum(handle, &snum))
4748 return ERROR_INVALID_HANDLE;
4750 count = print_queue_status(snum, &queue, &prt_status);
4752 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
4753 count, prt_status.status, prt_status.message));
4757 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
4760 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
4764 return ERROR_INVALID_LEVEL;