3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-2000,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
8 * Copyright (C) Jean François Micouleau 1998-2000.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL;
28 extern pstring global_myname;
30 #ifndef MAX_OPEN_PRINTER_EXS
31 #define MAX_OPEN_PRINTER_EXS 50
34 #define PRINTER_HANDLE_IS_PRINTER 0
35 #define PRINTER_HANDLE_IS_PRINTSERVER 1
37 /* structure to store the printer handles */
38 /* and a reference to what it's pointing to */
39 /* and the notify info asked about */
40 /* that's the central struct */
41 typedef struct _Printer{
46 BOOL document_started;
48 int jobid; /* jobid in printing backend */
49 POLICY_HND printer_hnd;
53 fstring printerservername;
62 SPOOL_NOTIFY_OPTION *option;
70 typedef struct _counter_printer_0 {
78 static ubi_dlList Printer_list;
79 static ubi_dlList counter_list;
82 #define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False) && (IVAL(pnum->printer_hnd.data,16)==(uint32)sys_getpid()))
83 #define OUR_HANDLE(pnum) ((pnum==NULL)?"NULL":(IVAL(pnum->data,16)==sys_getpid()?"OURS":"OTHER"))
85 /* translate between internal status numbers and NT status numbers */
86 static int nt_printj_status(int v)
90 return PRINTER_STATUS_PAUSED;
99 static int nt_printq_status(int v)
103 return PRINTER_STATUS_ERROR;
112 /****************************************************************************
113 initialise printer handle states...
114 ****************************************************************************/
115 void init_printer_hnd(void)
117 ubi_dlInitList(&Printer_list);
118 ubi_dlInitList(&counter_list);
121 /****************************************************************************
122 create a unique printer handle
123 ****************************************************************************/
124 static void create_printer_hnd(POLICY_HND *hnd)
126 static uint32 prt_hnd_low = 0;
127 static uint32 prt_hnd_high = 0;
129 if (hnd == NULL) return;
131 /* i severely doubt that prt_hnd_high will ever be non-zero... */
133 if (prt_hnd_low == 0) prt_hnd_high++;
135 SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
136 SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
137 SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
138 SIVAL(hnd->data, 12, time(NULL)); /* something random */
139 SIVAL(hnd->data, 16, sys_getpid()); /* something more random */
142 /****************************************************************************
143 find printer index by handle
144 ****************************************************************************/
145 static Printer_entry *find_printer_index_by_hnd(const POLICY_HND *hnd)
147 Printer_entry *find_printer;
149 find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
151 for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) {
153 if (memcmp(&(find_printer->printer_hnd), hnd, sizeof(*hnd)) == 0) {
154 DEBUG(4,("Found printer handle \n"));
155 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
160 DEBUG(3,("Whoops, Printer handle not found: "));
161 /*dump_data(4, hnd->data, sizeof(hnd->data));*/
165 /****************************************************************************
167 ****************************************************************************/
168 static void clear_handle(POLICY_HND *hnd)
173 /****************************************************************************
174 close printer index by handle
175 ****************************************************************************/
176 static BOOL close_printer_handle(POLICY_HND *hnd)
178 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
180 if (!OPEN_HANDLE(Printer)) {
181 DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
186 Printer->notify.flags=0;
187 Printer->notify.options=0;
188 Printer->notify.localmachine[0]='\0';
189 Printer->notify.printerlocal=0;
190 safe_free(Printer->notify.option);
191 Printer->notify.option=NULL;
195 ubi_dlRemThis(&Printer_list, Printer);
202 /****************************************************************************
203 delete a printer given a handle
204 ****************************************************************************/
205 static BOOL delete_printer_handle(POLICY_HND *hnd)
207 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
209 if (!OPEN_HANDLE(Printer)) {
210 DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
214 if (del_a_printer(Printer->dev.handlename) != 0) {
215 DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
219 if (*lp_deleteprinter_cmd()) {
221 pid_t local_pid = sys_getpid();
222 char *cmd = lp_deleteprinter_cmd();
229 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
230 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
234 /* Printer->dev.handlename equals portname equals sharename */
235 slprintf(command, sizeof(command), "%s \"%s\"", cmd,
236 Printer->dev.handlename);
237 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
240 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
241 ret = smbrun(command, tmp_file, False);
246 DEBUGADD(10,("returned [%d]\n", ret));
247 DEBUGADD(10,("Unlinking output file [%s]\n", tmp_file));
250 if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
251 lp_remove_service( i );
261 /****************************************************************************
262 return the snum of a printer corresponding to an handle
263 ****************************************************************************/
264 static BOOL get_printer_snum(POLICY_HND *hnd, int *number)
266 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
268 if (!OPEN_HANDLE(Printer)) {
269 DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
273 switch (Printer->printer_type) {
274 case PRINTER_HANDLE_IS_PRINTER:
275 DEBUG(4,("short name:%s\n", Printer->dev.handlename));
276 *number = print_queue_snum(Printer->dev.handlename);
277 return (*number != -1);
278 case PRINTER_HANDLE_IS_PRINTSERVER:
287 /****************************************************************************
288 set printer handle type.
289 ****************************************************************************/
290 static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required)
292 Printer_entry *Printer = find_printer_index_by_hnd(hnd);
294 if (!OPEN_HANDLE(Printer)) {
295 DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd)));
299 DEBUG(4,("Setting printer access=%x\n", access_required));
300 Printer->access = access_required;
304 /****************************************************************************
305 Set printer handle type.
306 Check if it's \\server or \\server\printer
307 ****************************************************************************/
309 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
311 DEBUG(3,("Setting printer type=%s\n", handlename));
313 if ( strlen(handlename) < 3 ) {
314 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
318 /* it's a print server */
319 if (!strchr(handlename+2, '\\')) {
320 DEBUGADD(4,("Printer is a print server\n"));
321 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
326 DEBUGADD(4,("Printer is a printer\n"));
327 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
334 /****************************************************************************
335 Set printer handle name.
336 ****************************************************************************/
338 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
340 NT_PRINTER_INFO_LEVEL *printer = NULL;
342 int n_services=lp_numservices();
346 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
348 if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
349 ZERO_STRUCT(Printer->dev.printerservername);
350 strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
354 if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
357 aprinter=strchr(handlename+2, '\\');
360 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
363 * store the Samba share name in it
364 * in back we have the long printer name
365 * need to iterate all the snum and do a
366 * get_a_printer each time to find the printer
367 * faster to do it here than later.
370 for (snum=0;snum<n_services && found==False;snum++) {
372 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
375 DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
377 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
380 DEBUG(10,("set_printer_hnd_name: name [%s], aprinter [%s]\n",
381 printer->info_2->printername, aprinter ));
383 if ( strlen(printer->info_2->printername) != strlen(aprinter) ) {
384 free_a_printer(&printer, 2);
388 if ( strncasecmp(printer->info_2->printername, aprinter, strlen(aprinter))) {
389 free_a_printer(&printer, 2);
397 * if we haven't found a printer with the given handlename
398 * then it can be a share name as you can open both \\server\printer and
403 * we still check if the printer description file exists as NT won't be happy
404 * if we reply OK in the openprinter call and can't reply in the subsequent RPC calls
408 DEBUGADD(5,("Printer not found, checking for share now\n"));
410 for (snum=0;snum<n_services && found==False;snum++) {
412 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
415 DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum)));
417 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
420 DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
421 printer->info_2->printername, aprinter ));
423 if ( strlen(lp_servicename(snum)) != strlen(aprinter) ) {
424 free_a_printer(&printer, 2);
428 if ( strncasecmp(lp_servicename(snum), aprinter, strlen(aprinter))) {
429 free_a_printer(&printer, 2);
438 DEBUGADD(4,("Printer not found\n"));
443 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s[%x]\n",
444 printer->info_2->printername, lp_servicename(snum),snum));
446 ZERO_STRUCT(Printer->dev.handlename);
447 strncpy(Printer->dev.handlename, lp_servicename(snum), strlen(lp_servicename(snum)));
449 free_a_printer(&printer, 2);
454 /****************************************************************************
455 find first available printer slot. creates a printer handle for you.
456 ****************************************************************************/
458 static BOOL open_printer_hnd(POLICY_HND *hnd, char *name)
460 Printer_entry *new_printer;
463 create_printer_hnd(hnd);
465 if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
468 ZERO_STRUCTP(new_printer);
470 new_printer->open = True;
471 new_printer->notify.option=NULL;
473 memcpy(&new_printer->printer_hnd, hnd, sizeof(*hnd));
475 ubi_dlAddHead( &Printer_list, (ubi_dlNode *)new_printer);
477 if (!set_printer_hnd_printertype(new_printer, name)) {
478 close_printer_handle(hnd);
482 if (!set_printer_hnd_name(new_printer, name)) {
483 close_printer_handle(hnd);
490 /********************************************************************
491 Return True is the handle is a print server.
492 ********************************************************************/
493 static BOOL handle_is_printserver(const POLICY_HND *handle)
495 Printer_entry *Printer=find_printer_index_by_hnd(handle);
497 if (!OPEN_HANDLE(Printer))
500 if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
506 /****************************************************************************
507 allocate more memory for a BUFFER.
508 ****************************************************************************/
509 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
517 /* damn, I'm doing the reverse operation of prs_grow() :) */
518 if (buffer_size < prs_data_size(ps))
521 extra_space = buffer_size - prs_data_size(ps);
524 * save the offset and move to the end of the buffer
525 * prs_grow() checks the extra_space against the offset
527 old_offset=prs_offset(ps);
528 prs_set_offset(ps, prs_data_size(ps));
530 if (!prs_grow(ps, extra_space))
533 prs_set_offset(ps, old_offset);
536 buffer->string_at_end = buffer_size;
538 buffer->string_at_end=prs_data_size(ps);
544 /********************************************************************
545 * spoolss_open_printer
547 * called from the spoolss dispatcher
548 ********************************************************************/
549 uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
550 const PRINTER_DEFAULT *printer_default,
551 uint32 user_switch, SPOOL_USER_CTR user_ctr,
556 if (printername == NULL)
557 return ERROR_INVALID_PRINTER_NAME;
559 /* some sanity check because you can open a printer or a print server */
560 /* aka: \\server\printer or \\server */
561 unistr2_to_ascii(name, printername, sizeof(name)-1);
563 DEBUGADD(3,("checking name: %s\n",name));
565 if (!open_printer_hnd(handle, name))
566 return ERROR_INVALID_PRINTER_NAME;
569 if (printer_default->datatype_ptr != NULL)
571 unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
572 set_printer_hnd_datatype(handle, datatype);
575 set_printer_hnd_datatype(handle, "");
578 if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
579 close_printer_handle(handle);
580 return ERROR_ACCESS_DENIED;
583 return NT_STATUS_NO_PROBLEMO;
586 /****************************************************************************
587 ****************************************************************************/
588 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
589 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
593 uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
602 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
603 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
607 printer->info_3=NULL;
608 uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3);
611 printer->info_6=NULL;
612 uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6);
621 static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devmode)
623 unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
624 unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
626 nt_devmode->specversion=devmode->specversion;
627 nt_devmode->driverversion=devmode->driverversion;
628 nt_devmode->size=devmode->size;
629 nt_devmode->driverextra=devmode->driverextra;
630 nt_devmode->fields=devmode->fields;
631 nt_devmode->orientation=devmode->orientation;
632 nt_devmode->papersize=devmode->papersize;
633 nt_devmode->paperlength=devmode->paperlength;
634 nt_devmode->paperwidth=devmode->paperwidth;
635 nt_devmode->scale=devmode->scale;
636 nt_devmode->copies=devmode->copies;
637 nt_devmode->defaultsource=devmode->defaultsource;
638 nt_devmode->printquality=devmode->printquality;
639 nt_devmode->color=devmode->color;
640 nt_devmode->duplex=devmode->duplex;
641 nt_devmode->yresolution=devmode->yresolution;
642 nt_devmode->ttoption=devmode->ttoption;
643 nt_devmode->collate=devmode->collate;
645 nt_devmode->logpixels=devmode->logpixels;
646 nt_devmode->bitsperpel=devmode->bitsperpel;
647 nt_devmode->pelswidth=devmode->pelswidth;
648 nt_devmode->pelsheight=devmode->pelsheight;
649 nt_devmode->displayflags=devmode->displayflags;
650 nt_devmode->displayfrequency=devmode->displayfrequency;
651 nt_devmode->icmmethod=devmode->icmmethod;
652 nt_devmode->icmintent=devmode->icmintent;
653 nt_devmode->mediatype=devmode->mediatype;
654 nt_devmode->dithertype=devmode->dithertype;
655 nt_devmode->reserved1=devmode->reserved1;
656 nt_devmode->reserved2=devmode->reserved2;
657 nt_devmode->panningwidth=devmode->panningwidth;
658 nt_devmode->panningheight=devmode->panningheight;
660 if (nt_devmode->driverextra != 0) {
661 /* if we had a previous private delete it and make a new one */
662 safe_free(nt_devmode->private);
663 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
665 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
671 /********************************************************************
672 * api_spoolss_closeprinter
673 ********************************************************************/
674 uint32 _spoolss_closeprinter(POLICY_HND *handle)
676 if (!close_printer_handle(handle))
677 return ERROR_INVALID_HANDLE;
679 return NT_STATUS_NO_PROBLEMO;
682 /********************************************************************
683 * api_spoolss_deleteprinter
684 ********************************************************************/
685 uint32 _spoolss_deleteprinter(POLICY_HND *handle)
687 if (!delete_printer_handle(handle))
688 return ERROR_INVALID_HANDLE;
690 return NT_STATUS_NO_PROBLEMO;
693 /********************************************************************
694 GetPrinterData on a printer server Handle.
695 ********************************************************************/
696 static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
700 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
702 if (!strcmp(value, "BeepEnabled")) {
704 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
706 SIVAL(*data, 0, 0x01);
711 if (!strcmp(value, "EventLog")) {
713 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
715 SIVAL(*data, 0, 0x1B);
720 if (!strcmp(value, "NetPopup")) {
722 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
724 SIVAL(*data, 0, 0x01);
729 if (!strcmp(value, "MajorVersion")) {
731 if((*data = (uint8 *)malloc( 4*sizeof(uint8) )) == NULL)
733 SIVAL(*data, 0, 0x02);
738 if (!strcmp(value, "DefaultSpoolDirectory")) {
739 pstring string="You are using a Samba server";
741 *needed = 2*(strlen(string)+1);
742 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
744 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
746 /* it's done by hand ready to go on the wire */
747 for (i=0; i<strlen(string); i++) {
748 (*data)[2*i]=string[i];
754 if (!strcmp(value, "Architecture")) {
755 pstring string="Windows NT x86";
757 *needed = 2*(strlen(string)+1);
758 if((*data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
760 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
761 for (i=0; i<strlen(string); i++) {
762 (*data)[2*i]=string[i];
771 /********************************************************************
772 GetPrinterData on a printer Handle.
773 ********************************************************************/
774 static BOOL getprinterdata_printer(POLICY_HND *handle,
775 fstring value, uint32 *type,
776 uint8 **data, uint32 *needed, uint32 in_size )
778 NT_PRINTER_INFO_LEVEL *printer = NULL;
782 Printer_entry *Printer = find_printer_index_by_hnd(handle);
784 DEBUG(5,("getprinterdata_printer\n"));
786 if (!OPEN_HANDLE(Printer)) {
787 DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
791 if(!get_printer_snum(handle, &snum))
794 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
797 if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
798 free_a_printer(&printer, 2);
802 free_a_printer(&printer, 2);
804 DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
807 if((*data = (uint8 *)malloc( in_size *sizeof(uint8) )) == NULL) {
811 memset(*data, 0, in_size *sizeof(uint8));
812 /* copy the min(in_size, len) */
813 memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
820 DEBUG(5,("getprinterdata_printer:copy done\n"));
827 /********************************************************************
828 * spoolss_getprinterdata
829 ********************************************************************/
830 uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
839 Printer_entry *Printer = find_printer_index_by_hnd(handle);
842 * Reminder: when it's a string, the length is in BYTES
843 * even if UNICODE is negociated.
850 /* in case of problem, return some default values */
854 DEBUG(4,("_spoolss_getprinterdata\n"));
856 if (!OPEN_HANDLE(Printer)) {
857 if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
858 return ERROR_NOT_ENOUGH_MEMORY;
859 DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
860 return ERROR_INVALID_HANDLE;
863 unistr2_to_ascii(value, valuename, sizeof(value)-1);
865 if (handle_is_printserver(handle))
866 found=getprinterdata_printer_server(value, type, data, needed, *out_size);
868 found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
871 DEBUG(5, ("value not found, allocating %d\n", *out_size));
872 /* reply this param doesn't exist */
874 if((*data=(uint8 *)malloc(*out_size*sizeof(uint8))) == NULL)
875 return ERROR_NOT_ENOUGH_MEMORY;
876 memset(*data, '\0', *out_size*sizeof(uint8));
881 return ERROR_INVALID_PARAMETER;
884 if (*needed > *out_size)
885 return ERROR_INSUFFICIENT_BUFFER;
887 return NT_STATUS_NO_PROBLEMO;
890 /********************************************************************
892 * ReplyFindFirstPrinterChangeNotifyEx
894 * jfmxxxx: before replying OK: status=0
895 * should do a rpc call to the workstation asking ReplyOpenPrinter
896 * have to code it, later.
898 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
899 * called from api_spoolss_rffpcnex
900 ********************************************************************/
901 uint32 _spoolss_rffpcnex(POLICY_HND *handle, uint32 flags, uint32 options,
902 const UNISTR2 *localmachine, uint32 printerlocal,
903 SPOOL_NOTIFY_OPTION *option)
905 /* store the notify value in the printer struct */
907 Printer_entry *Printer=find_printer_index_by_hnd(handle);
909 if (!OPEN_HANDLE(Printer)) {
910 DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
911 return ERROR_INVALID_HANDLE;
914 Printer->notify.flags=flags;
915 Printer->notify.options=options;
916 Printer->notify.printerlocal=printerlocal;
917 Printer->notify.option=option;
918 unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
920 return NT_STATUS_NO_PROBLEMO;
923 /*******************************************************************
924 * fill a notify_info_data with the servername
925 ********************************************************************/
926 static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
927 NT_PRINTER_INFO_LEVEL *printer)
931 snprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
933 data->notify_data.data.length= (uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
934 temp_name, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
937 /*******************************************************************
938 * fill a notify_info_data with the servicename
939 * jfmxxxx: it's incorrect should be long_printername
940 ********************************************************************/
941 static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue,
942 NT_PRINTER_INFO_LEVEL *printer)
945 data->notify_data.data.length=strlen(lp_servicename(snum));
946 dos_PutUniCode(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string), True);
948 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
949 printer->info_2->printername, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
952 /*******************************************************************
953 * fill a notify_info_data with the servicename
954 ********************************************************************/
955 static void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
957 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
958 lp_servicename(snum), sizeof(data->notify_data.data.string),True) - sizeof(uint16))/sizeof(uint16));
961 /*******************************************************************
962 * fill a notify_info_data with the port name
963 ********************************************************************/
964 static void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
966 /* even if it's strange, that's consistant in all the code */
968 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
969 lp_servicename(snum), sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16));
972 /*******************************************************************
973 * fill a notify_info_data with the printername
974 * jfmxxxx: it's incorrect, should be lp_printerdrivername()
975 * but it doesn't exist, have to see what to do
976 ********************************************************************/
977 static void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
979 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
980 printer->info_2->drivername, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
983 /*******************************************************************
984 * fill a notify_info_data with the comment
985 ********************************************************************/
986 static void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
988 if (*printer->info_2->comment == '\0')
989 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
990 lp_comment(snum), sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
992 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
993 printer->info_2->comment, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
996 /*******************************************************************
997 * fill a notify_info_data with the comment
998 * jfm:xxxx incorrect, have to create a new smb.conf option
999 * location = "Room 1, floor 2, building 3"
1000 ********************************************************************/
1001 static void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1003 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1004 printer->info_2->location, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1007 /*******************************************************************
1008 * fill a notify_info_data with the device mode
1009 * jfm:xxxx don't to it for know but that's a real problem !!!
1010 ********************************************************************/
1011 static void spoolss_notify_devmode(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1015 /*******************************************************************
1016 * fill a notify_info_data with the separator file name
1017 * jfm:xxxx just return no file could add an option to smb.conf
1018 * separator file = "separator.txt"
1019 ********************************************************************/
1020 static void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1022 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1023 printer->info_2->sepfile, sizeof(data->notify_data.data.string)-1,True) - sizeof(uint16))/sizeof(uint16));
1026 /*******************************************************************
1027 * fill a notify_info_data with the print processor
1028 * jfm:xxxx return always winprint to indicate we don't do anything to it
1029 ********************************************************************/
1030 static void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1032 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1033 printer->info_2->printprocessor, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1036 /*******************************************************************
1037 * fill a notify_info_data with the print processor options
1038 * jfm:xxxx send an empty string
1039 ********************************************************************/
1040 static void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1042 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1043 printer->info_2->parameters, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1046 /*******************************************************************
1047 * fill a notify_info_data with the data type
1048 * jfm:xxxx always send RAW as data type
1049 ********************************************************************/
1050 static void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1052 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1053 printer->info_2->datatype, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1056 /*******************************************************************
1057 * fill a notify_info_data with the security descriptor
1058 * jfm:xxxx send an null pointer to say no security desc
1059 * have to implement security before !
1060 ********************************************************************/
1061 static void spoolss_notify_security_desc(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1063 data->notify_data.data.length=0;
1064 data->notify_data.data.string[0]=0x00;
1067 /*******************************************************************
1068 * fill a notify_info_data with the attributes
1069 * jfm:xxxx a samba printer is always shared
1070 ********************************************************************/
1071 static void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1073 data->notify_data.value[0] = PRINTER_ATTRIBUTE_SHARED \
1074 | PRINTER_ATTRIBUTE_LOCAL \
1075 | PRINTER_ATTRIBUTE_RAW_ONLY ;
1078 /*******************************************************************
1079 * fill a notify_info_data with the priority
1080 ********************************************************************/
1081 static void spoolss_notify_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1083 data->notify_data.value[0] = printer->info_2->priority;
1086 /*******************************************************************
1087 * fill a notify_info_data with the default priority
1088 ********************************************************************/
1089 static void spoolss_notify_default_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1091 data->notify_data.value[0] = printer->info_2->default_priority;
1094 /*******************************************************************
1095 * fill a notify_info_data with the start time
1096 ********************************************************************/
1097 static void spoolss_notify_start_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1099 data->notify_data.value[0] = printer->info_2->starttime;
1102 /*******************************************************************
1103 * fill a notify_info_data with the until time
1104 ********************************************************************/
1105 static void spoolss_notify_until_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1107 data->notify_data.value[0] = printer->info_2->untiltime;
1110 /*******************************************************************
1111 * fill a notify_info_data with the status
1112 ********************************************************************/
1113 static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1116 print_queue_struct *q=NULL;
1117 print_status_struct status;
1119 memset(&status, 0, sizeof(status));
1120 count = print_queue_status(snum, &q, &status);
1121 data->notify_data.value[0]=(uint32) status.status;
1125 /*******************************************************************
1126 * fill a notify_info_data with the number of jobs queued
1127 ********************************************************************/
1128 static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1130 print_queue_struct *q=NULL;
1131 print_status_struct status;
1133 memset(&status, 0, sizeof(status));
1134 data->notify_data.value[0] = print_queue_status(snum, &q, &status);
1138 /*******************************************************************
1139 * fill a notify_info_data with the average ppm
1140 ********************************************************************/
1141 static void spoolss_notify_average_ppm(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1143 /* always respond 8 pages per minutes */
1144 /* a little hard ! */
1145 data->notify_data.value[0] = printer->info_2->averageppm;
1148 /*******************************************************************
1149 * fill a notify_info_data with
1150 ********************************************************************/
1151 static void spoolss_notify_username(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1153 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1154 queue->user, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1157 /*******************************************************************
1158 * fill a notify_info_data with
1159 ********************************************************************/
1160 static void spoolss_notify_job_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1162 data->notify_data.value[0]=nt_printj_status(queue->status);
1165 /*******************************************************************
1166 * fill a notify_info_data with
1167 ********************************************************************/
1168 static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1170 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1171 queue->file, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1174 /*******************************************************************
1175 * fill a notify_info_data with
1176 ********************************************************************/
1177 static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1179 char *p = "unknown";
1180 switch (queue->status) {
1194 data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string,
1195 p, sizeof(data->notify_data.data.string)-1, True) - sizeof(uint16))/sizeof(uint16));
1198 /*******************************************************************
1199 * fill a notify_info_data with
1200 ********************************************************************/
1201 static void spoolss_notify_job_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1203 data->notify_data.value[0]=0x0;
1206 /*******************************************************************
1207 * fill a notify_info_data with
1208 ********************************************************************/
1209 static void spoolss_notify_job_size(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1211 data->notify_data.value[0]=queue->size;
1214 /*******************************************************************
1215 * fill a notify_info_data with
1216 ********************************************************************/
1217 static void spoolss_notify_job_position(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1219 data->notify_data.value[0]=queue->job;
1224 struct s_notify_info_data_table
1230 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
1231 print_queue_struct *queue,
1232 NT_PRINTER_INFO_LEVEL *printer);
1235 struct s_notify_info_data_table notify_info_data_table[] =
1237 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
1238 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1239 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
1240 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1241 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1242 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
1243 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
1244 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1245 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
1246 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1247 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1248 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1249 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
1250 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
1251 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1252 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
1253 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1254 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1255 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
1256 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
1257 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
1258 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
1259 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
1260 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
1261 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
1262 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
1263 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
1264 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
1265 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
1266 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
1267 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
1268 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
1269 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
1270 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
1271 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
1272 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
1273 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
1274 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
1275 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
1276 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
1277 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
1278 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
1279 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, NULL },
1280 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
1281 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
1282 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
1283 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL },
1284 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL },
1285 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
1286 { JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
1287 { END, END, "", END, NULL }
1290 /*******************************************************************
1291 return the size of info_data structure
1292 ********************************************************************/
1293 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
1297 while (notify_info_data_table[i].type != END)
1299 if ( (notify_info_data_table[i].type == type ) &&
1300 (notify_info_data_table[i].field == field ) )
1302 return (notify_info_data_table[i].size);
1310 /*******************************************************************
1311 return the type of notify_info_data
1312 ********************************************************************/
1313 static BOOL type_of_notify_info_data(uint16 type, uint16 field)
1317 while (notify_info_data_table[i].type != END)
1319 if ( (notify_info_data_table[i].type == type ) &&
1320 (notify_info_data_table[i].field == field ) )
1322 if (notify_info_data_table[i].size == POINTER)
1337 /****************************************************************************
1338 ****************************************************************************/
1339 static int search_notify(uint16 type, uint16 field, int *value)
1344 for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1346 if ( (notify_info_data_table[j].type == type ) &&
1347 (notify_info_data_table[j].field == field ) )
1352 if ( found && (notify_info_data_table[j].fn != NULL) )
1358 /****************************************************************************
1359 ****************************************************************************/
1360 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1362 info_data->type = type;
1363 info_data->field = field;
1364 info_data->reserved = 0;
1366 info_data->size = size_of_notify_info_data(type, field);
1367 info_data->enc_type = type_of_notify_info_data(type, field);
1371 /*******************************************************************
1373 * fill a notify_info struct with info asked
1375 ********************************************************************/
1376 static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1382 SPOOL_NOTIFY_INFO_DATA *current_data;
1383 NT_PRINTER_INFO_LEVEL *printer = NULL;
1384 print_queue_struct *queue=NULL;
1386 DEBUG(4,("construct_notify_printer_info\n"));
1388 type=option_type->type;
1390 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
1391 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1392 option_type->count, lp_servicename(snum)));
1394 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1397 for(field_num=0; field_num<option_type->count; field_num++) {
1398 field = option_type->fields[field_num];
1399 DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field));
1401 if (!search_notify(type, field, &j) )
1404 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1407 current_data=&info->data[info->count];
1409 construct_info_data(current_data, type, field, id);
1410 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1415 free_a_printer(&printer, 2);
1419 /*******************************************************************
1421 * fill a notify_info struct with info asked
1423 ********************************************************************/
1424 static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
1430 SPOOL_NOTIFY_INFO_DATA *current_data;
1431 NT_PRINTER_INFO_LEVEL *printer = NULL;
1433 DEBUG(4,("construct_notify_jobs_info\n"));
1435 type = option_type->type;
1437 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
1438 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
1439 option_type->count));
1441 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1444 for(field_num=0; field_num<option_type->count; field_num++) {
1445 field = option_type->fields[field_num];
1447 if (!search_notify(type, field, &j) )
1450 if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
1454 current_data=&(info->data[info->count]);
1456 construct_info_data(current_data, type, field, id);
1457 notify_info_data_table[j].fn(snum, current_data, queue, printer);
1461 free_a_printer(&printer, 2);
1466 * JFM: The enumeration is not that simple, it's even non obvious.
1468 * let's take an example: I want to monitor the PRINTER SERVER for
1469 * the printer's name and the number of jobs currently queued.
1470 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
1471 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
1473 * I have 3 printers on the back of my server.
1475 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
1478 * 1 printer 1 name 1
1479 * 2 printer 1 cjob 1
1480 * 3 printer 2 name 2
1481 * 4 printer 2 cjob 2
1482 * 5 printer 3 name 3
1483 * 6 printer 3 name 3
1485 * that's the print server case, the printer case is even worse.
1490 /*******************************************************************
1492 * enumerate all printers on the printserver
1493 * fill a notify_info struct with info asked
1495 ********************************************************************/
1496 static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1499 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1500 int n_services=lp_numservices();
1503 SPOOL_NOTIFY_OPTION *option;
1504 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1506 DEBUG(4,("printserver_notify_info\n"));
1508 option=Printer->notify.option;
1514 for (i=0; i<option->count; i++) {
1515 option_type=&(option->ctr.type[i]);
1517 if (option_type->type!=PRINTER_NOTIFY_TYPE)
1520 for (snum=0; snum<n_services; snum++)
1521 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1522 if (construct_notify_printer_info(info, snum, option_type, id))
1527 * Debugging information, don't delete.
1530 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1531 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1532 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1534 for (i=0; i<info->count; i++) {
1535 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1536 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1537 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1541 return NT_STATUS_NO_PROBLEMO;
1544 /*******************************************************************
1546 * fill a notify_info struct with info asked
1548 ********************************************************************/
1549 static uint32 printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
1552 Printer_entry *Printer=find_printer_index_by_hnd(hnd);
1555 SPOOL_NOTIFY_OPTION *option;
1556 SPOOL_NOTIFY_OPTION_TYPE *option_type;
1558 print_queue_struct *queue=NULL;
1559 print_status_struct status;
1561 DEBUG(4,("printer_notify_info\n"));
1563 option=Printer->notify.option;
1569 get_printer_snum(hnd, &snum);
1571 for (i=0; i<option->count; i++) {
1572 option_type=&option->ctr.type[i];
1574 switch ( option_type->type ) {
1575 case PRINTER_NOTIFY_TYPE:
1576 if(construct_notify_printer_info(info, snum, option_type, id))
1580 case JOB_NOTIFY_TYPE:
1581 memset(&status, 0, sizeof(status));
1582 count = print_queue_status(snum, &queue, &status);
1583 for (j=0; j<count; j++)
1584 construct_notify_jobs_info(&queue[j], info, snum, option_type, queue[j].job);
1591 * Debugging information, don't delete.
1594 DEBUG(1,("dumping the NOTIFY_INFO\n"));
1595 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
1596 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
1598 for (i=0; i<info->count; i++) {
1599 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
1600 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
1601 info->data[i].id, info->data[i].size, info->data[i].enc_type));
1604 return NT_STATUS_NO_PROBLEMO;
1607 /********************************************************************
1609 ********************************************************************/
1610 uint32 _spoolss_rfnpcnex( POLICY_HND *handle, uint32 change,
1611 SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info)
1613 Printer_entry *Printer=find_printer_index_by_hnd(handle);
1615 if (!OPEN_HANDLE(Printer)) {
1616 DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",OUR_HANDLE(handle)));
1617 return ERROR_INVALID_HANDLE;
1620 DEBUG(4,("Printer type %x\n",Printer->printer_type));
1622 /* jfm: the change value isn't used right now.
1623 * we will honour it when
1624 * a) we'll be able to send notification to the client
1625 * b) we'll have a way to communicate between the spoolss process.
1627 * same thing for option->flags
1628 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
1629 * I don't have a global notification system, I'm sending back all the
1630 * informations even when _NOTHING_ has changed.
1633 /* just discard the SPOOL_NOTIFY_OPTION */
1635 safe_free(option->ctr.type);
1637 switch (Printer->printer_type) {
1638 case PRINTER_HANDLE_IS_PRINTSERVER:
1639 return printserver_notify_info(handle, info);
1641 case PRINTER_HANDLE_IS_PRINTER:
1642 return printer_notify_info(handle, info);
1646 return ERROR_INVALID_HANDLE;
1649 /********************************************************************
1650 * construct_printer_info_0
1651 * fill a printer_info_1 struct
1652 ********************************************************************/
1653 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring servername)
1657 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1658 counter_printer_0 *session_counter;
1659 uint32 global_counter;
1661 time_t setup_time = time(NULL);
1663 print_queue_struct *queue=NULL;
1664 print_status_struct status;
1666 memset(&status, 0, sizeof(status));
1668 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1671 count = print_queue_status(snum, &queue, &status);
1673 /* check if we already have a counter for this printer */
1674 session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
1676 for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
1677 if (session_counter->snum == snum)
1681 /* it's the first time, add it to the list */
1682 if (session_counter==NULL) {
1683 if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
1684 free_a_printer(&ntprinter, 2);
1687 ZERO_STRUCTP(session_counter);
1688 session_counter->snum=snum;
1689 session_counter->counter=0;
1690 ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
1694 session_counter->counter++;
1697 * the global_counter should be stored in a TDB as it's common to all the clients
1698 * and should be zeroed on samba startup
1700 global_counter=session_counter->counter;
1702 /* the description and the name are of the form \\server\share */
1703 slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter->info_2->printername);
1705 init_unistr(&printer->printername, chaine);
1707 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1708 init_unistr(&printer->servername, chaine);
1710 printer->cjobs = count;
1711 printer->total_jobs = 0;
1712 printer->total_bytes = 0;
1714 t=gmtime(&setup_time);
1715 ntprinter->info_2->setuptime = (uint32)setup_time; /* FIXME !! */
1717 printer->year = t->tm_year+1900;
1718 printer->month = t->tm_mon+1;
1719 printer->dayofweek = t->tm_wday;
1720 printer->day = t->tm_mday;
1721 printer->hour = t->tm_hour;
1722 printer->minute = t->tm_min;
1723 printer->second = t->tm_sec;
1724 printer->milliseconds = 0;
1726 printer->global_counter = global_counter;
1727 printer->total_pages = 0;
1728 printer->major_version = 0x0004; /* NT 4 */
1729 printer->build_version = 0x0565; /* build 1381 */
1730 printer->unknown7 = 0x1;
1731 printer->unknown8 = 0x0;
1732 printer->unknown9 = 0x0;
1733 printer->session_counter = session_counter->counter;
1734 printer->unknown11 = 0x0;
1735 printer->printer_errors = 0x0; /* number of print failure */
1736 printer->unknown13 = 0x0;
1737 printer->unknown14 = 0x1;
1738 printer->unknown15 = 0x024a; /* 586 Pentium ? */
1739 printer->unknown16 = 0x0;
1740 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
1741 printer->unknown18 = 0x0;
1742 printer->status = nt_printq_status(status.status);
1743 printer->unknown20 = 0x0;
1744 printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
1745 printer->unknown22 = 0x0;
1746 printer->unknown23 = 0x6; /* 6 ???*/
1747 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
1748 printer->unknown25 = 0;
1749 printer->unknown26 = 0;
1750 printer->unknown27 = 0;
1751 printer->unknown28 = 0;
1752 printer->unknown29 = 0;
1755 free_a_printer(&ntprinter,2);
1759 /********************************************************************
1760 * construct_printer_info_1
1761 * fill a printer_info_1 struct
1762 ********************************************************************/
1763 static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum)
1767 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1769 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1772 printer->flags=flags;
1774 if (*ntprinter->info_2->comment == '\0') {
1775 init_unistr(&printer->comment, lp_comment(snum));
1776 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1777 ntprinter->info_2->drivername, lp_comment(snum));
1780 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1781 snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername,
1782 ntprinter->info_2->drivername, ntprinter->info_2->comment);
1785 snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter->info_2->printername);
1787 init_unistr(&printer->description, chaine);
1788 init_unistr(&printer->name, chaine2);
1790 free_a_printer(&ntprinter,2);
1795 /****************************************************************************
1796 Free a DEVMODE struct.
1797 ****************************************************************************/
1799 static void free_dev_mode(DEVICEMODE *dev)
1805 safe_free(dev->private);
1810 /****************************************************************************
1811 Create a DEVMODE struct. Returns malloced memory.
1812 ****************************************************************************/
1814 static DEVICEMODE *construct_dev_mode(int snum, char *servername)
1818 NT_PRINTER_INFO_LEVEL *printer = NULL;
1819 NT_DEVICEMODE *ntdevmode = NULL;
1820 DEVICEMODE *devmode = NULL;
1822 DEBUG(7,("construct_dev_mode\n"));
1824 DEBUGADD(8,("getting printer characteristics\n"));
1826 if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
1827 DEBUG(0,("construct_dev_mode: malloc fail.\n"));
1831 ZERO_STRUCTP(devmode);
1833 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
1836 if (printer->info_2->devmode)
1837 ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
1840 ntdevmode = construct_nt_devicemode(printer->info_2->printername);
1842 if (ntdevmode == NULL)
1845 DEBUGADD(8,("loading DEVICEMODE\n"));
1847 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, printer->info_2->printername);
1848 init_unistr(&devmode->devicename, adevice);
1850 snprintf(aform, sizeof(aform), ntdevmode->formname);
1851 init_unistr(&devmode->formname, aform);
1853 devmode->specversion = ntdevmode->specversion;
1854 devmode->driverversion = ntdevmode->driverversion;
1855 devmode->size = ntdevmode->size;
1856 devmode->driverextra = ntdevmode->driverextra;
1857 devmode->fields = ntdevmode->fields;
1859 devmode->orientation = ntdevmode->orientation;
1860 devmode->papersize = ntdevmode->papersize;
1861 devmode->paperlength = ntdevmode->paperlength;
1862 devmode->paperwidth = ntdevmode->paperwidth;
1863 devmode->scale = ntdevmode->scale;
1864 devmode->copies = ntdevmode->copies;
1865 devmode->defaultsource = ntdevmode->defaultsource;
1866 devmode->printquality = ntdevmode->printquality;
1867 devmode->color = ntdevmode->color;
1868 devmode->duplex = ntdevmode->duplex;
1869 devmode->yresolution = ntdevmode->yresolution;
1870 devmode->ttoption = ntdevmode->ttoption;
1871 devmode->collate = ntdevmode->collate;
1872 devmode->icmmethod = ntdevmode->icmmethod;
1873 devmode->icmintent = ntdevmode->icmintent;
1874 devmode->mediatype = ntdevmode->mediatype;
1875 devmode->dithertype = ntdevmode->dithertype;
1877 if (ntdevmode->private != NULL) {
1878 if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
1882 free_nt_devicemode(&ntdevmode);
1883 free_a_printer(&printer,2);
1890 free_nt_devicemode(&ntdevmode);
1892 free_a_printer(&printer,2);
1893 free_dev_mode(devmode);
1898 /********************************************************************
1899 * construct_printer_info_2
1900 * fill a printer_info_2 struct
1901 ********************************************************************/
1903 static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer, int snum)
1909 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1911 print_queue_struct *queue=NULL;
1912 print_status_struct status;
1913 memset(&status, 0, sizeof(status));
1915 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1918 memset(&status, 0, sizeof(status));
1919 count = print_queue_status(snum, &queue, &status);
1921 snprintf(chaine, sizeof(chaine)-1, "%s", servername);
1923 if (strlen(servername)!=0)
1928 snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter->info_2->printername);
1930 init_unistr(&printer->servername, chaine); /* servername*/
1931 init_unistr(&printer->printername, chaine2); /* printername*/
1932 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
1933 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
1934 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
1936 if (*ntprinter->info_2->comment == '\0')
1937 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
1939 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
1941 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
1942 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
1943 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
1944 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
1945 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
1947 printer->attributes = ntprinter->info_2->attributes;
1949 printer->priority = ntprinter->info_2->priority; /* priority */
1950 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
1951 printer->starttime = ntprinter->info_2->starttime; /* starttime */
1952 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
1953 printer->status = nt_printq_status(status.status); /* status */
1954 printer->cjobs = count; /* jobs */
1955 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
1957 if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) {
1958 DEBUG(8, ("Returning NULL Devicemode!\n"));
1961 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
1962 /* steal the printer info sec_desc structure. [badly done]. */
1963 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
1964 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
1965 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
1966 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
1969 printer->secdesc = NULL;
1972 free_a_printer(&ntprinter, 2);
1977 /********************************************************************
1978 * construct_printer_info_3
1979 * fill a printer_info_3 struct
1980 ********************************************************************/
1981 static BOOL construct_printer_info_3(fstring servername,
1982 PRINTER_INFO_3 **pp_printer, int snum)
1984 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
1985 PRINTER_INFO_3 *printer = NULL;
1987 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1991 if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
1992 DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
1996 ZERO_STRUCTP(printer);
1998 printer->flags = 4; /* This is the offset to the SEC_DESC. */
1999 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
2000 /* steal the printer info sec_desc structure. [badly done]. */
2001 printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
2002 ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
2003 ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
2004 ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
2007 free_a_printer(&ntprinter, 2);
2009 *pp_printer = printer;
2013 /********************************************************************
2014 Spoolss_enumprinters.
2015 ********************************************************************/
2016 static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2020 int n_services=lp_numservices();
2021 PRINTER_INFO_1 *printers=NULL;
2022 PRINTER_INFO_1 current_prt;
2024 DEBUG(4,("enum_all_printers_info_1\n"));
2026 for (snum=0; snum<n_services; snum++) {
2027 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2028 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2030 if (construct_printer_info_1(server, flags, ¤t_prt, snum)) {
2031 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
2033 return ERROR_NOT_ENOUGH_MEMORY;
2035 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
2036 memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1));
2042 /* check the required size. */
2043 for (i=0; i<*returned; i++)
2044 (*needed) += spoolss_size_printer_info_1(&(printers[i]));
2046 if (!alloc_buffer_size(buffer, *needed))
2047 return ERROR_INSUFFICIENT_BUFFER;
2049 /* fill the buffer with the structures */
2050 for (i=0; i<*returned; i++)
2051 new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);
2054 safe_free(printers);
2056 if (*needed > offered) {
2058 return ERROR_INSUFFICIENT_BUFFER;
2061 return NT_STATUS_NO_PROBLEMO;
2064 /********************************************************************
2065 enum_all_printers_info_1_local.
2066 *********************************************************************/
2067 static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2070 DEBUG(4,("enum_all_printers_info_1_local\n"));
2072 fstrcpy(temp, "\\\\");
2073 fstrcat(temp, global_myname);
2075 if (!strcmp(name, temp)) {
2076 fstrcat(temp, "\\");
2077 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2080 return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2083 /********************************************************************
2084 enum_all_printers_info_1_name.
2085 *********************************************************************/
2086 static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2089 DEBUG(4,("enum_all_printers_info_1_name\n"));
2091 fstrcpy(temp, "\\\\");
2092 fstrcat(temp, global_myname);
2094 if (!strcmp(name, temp)) {
2095 fstrcat(temp, "\\");
2096 return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
2099 return ERROR_INVALID_NAME;
2102 /********************************************************************
2103 enum_all_printers_info_1_remote.
2104 *********************************************************************/
2105 static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2107 PRINTER_INFO_1 *printer;
2108 fstring printername;
2111 DEBUG(4,("enum_all_printers_info_1_remote\n"));
2113 /* JFM: currently it's more a place holder than anything else.
2114 * In the spooler world there is a notion of server registration.
2115 * the print servers are registring (sp ?) on the PDC (in the same domain)
2117 * We should have a TDB here. The registration is done thru an undocumented RPC call.
2120 if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2121 return ERROR_NOT_ENOUGH_MEMORY;
2125 snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
2126 snprintf(desc, sizeof(desc)-1,"%s", global_myname);
2127 snprintf(comment, sizeof(comment)-1, "Logged on Domain");
2129 init_unistr(&printer->description, desc);
2130 init_unistr(&printer->name, printername);
2131 init_unistr(&printer->comment, comment);
2132 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
2134 /* check the required size. */
2135 *needed += spoolss_size_printer_info_1(printer);
2137 if (!alloc_buffer_size(buffer, *needed)) {
2139 return ERROR_INSUFFICIENT_BUFFER;
2142 /* fill the buffer with the structures */
2143 new_smb_io_printer_info_1("", buffer, printer, 0);
2148 if (*needed > offered) {
2150 return ERROR_INSUFFICIENT_BUFFER;
2153 return NT_STATUS_NO_PROBLEMO;
2156 /********************************************************************
2157 enum_all_printers_info_1_network.
2158 *********************************************************************/
2159 static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2162 DEBUG(4,("enum_all_printers_info_1_network\n"));
2164 fstrcpy(temp, "\\\\");
2165 fstrcat(temp, global_myname);
2166 fstrcat(temp, "\\");
2167 return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
2170 /********************************************************************
2171 * api_spoolss_enumprinters
2173 * called from api_spoolss_enumprinters (see this to understand)
2174 ********************************************************************/
2175 static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
2179 int n_services=lp_numservices();
2180 PRINTER_INFO_2 *printers=NULL;
2181 PRINTER_INFO_2 current_prt;
2183 for (snum=0; snum<n_services; snum++) {
2184 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
2185 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
2187 if (construct_printer_info_2(servername, ¤t_prt, snum)) {
2188 if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL)
2189 return ERROR_NOT_ENOUGH_MEMORY;
2190 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
2191 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
2197 /* check the required size. */
2198 for (i=0; i<*returned; i++)
2199 (*needed) += spoolss_size_printer_info_2(&printers[i]);
2201 if (!alloc_buffer_size(buffer, *needed)) {
2202 for (i=0; i<*returned; i++) {
2203 free_devmode(printers[i].devmode);
2204 free_sec_desc(&printers[i].secdesc);
2206 safe_free(printers);
2207 return ERROR_INSUFFICIENT_BUFFER;
2210 /* fill the buffer with the structures */
2211 for (i=0; i<*returned; i++)
2212 new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);
2215 for (i=0; i<*returned; i++) {
2216 free_devmode(printers[i].devmode);
2217 free_sec_desc(&printers[i].secdesc);
2219 safe_free(printers);
2221 if (*needed > offered) {
2223 return ERROR_INSUFFICIENT_BUFFER;
2226 return NT_STATUS_NO_PROBLEMO;
2229 /********************************************************************
2230 * handle enumeration of printers at level 1
2231 ********************************************************************/
2232 static uint32 enumprinters_level1( uint32 flags, fstring name,
2233 NEW_BUFFER *buffer, uint32 offered,
2234 uint32 *needed, uint32 *returned)
2236 /* Not all the flags are equals */
2238 if (flags & PRINTER_ENUM_LOCAL)
2239 return enum_all_printers_info_1_local(name, buffer, offered, needed, returned);
2241 if (flags & PRINTER_ENUM_NAME)
2242 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
2244 if (flags & PRINTER_ENUM_REMOTE)
2245 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
2247 if (flags & PRINTER_ENUM_NETWORK)
2248 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
2250 return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
2253 /********************************************************************
2254 * handle enumeration of printers at level 2
2255 ********************************************************************/
2256 static uint32 enumprinters_level2( uint32 flags, fstring servername,
2257 NEW_BUFFER *buffer, uint32 offered,
2258 uint32 *needed, uint32 *returned)
2262 fstrcpy(temp, "\\\\");
2263 fstrcat(temp, global_myname);
2265 if (flags & PRINTER_ENUM_LOCAL) {
2266 if (!strcmp(servername, temp))
2267 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2269 return enum_all_printers_info_2("", buffer, offered, needed, returned);
2272 if (flags & PRINTER_ENUM_NAME) {
2273 if (!strcmp(servername, temp))
2274 return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
2276 return ERROR_INVALID_NAME;
2279 if (flags & PRINTER_ENUM_REMOTE)
2280 return ERROR_INVALID_LEVEL;
2282 return NT_STATUS_NO_PROBLEMO;
2285 /********************************************************************
2286 * handle enumeration of printers at level 5
2287 ********************************************************************/
2288 static uint32 enumprinters_level5( uint32 flags, fstring servername,
2289 NEW_BUFFER *buffer, uint32 offered,
2290 uint32 *needed, uint32 *returned)
2292 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
2293 return NT_STATUS_NO_PROBLEMO;
2296 /********************************************************************
2297 * api_spoolss_enumprinters
2299 * called from api_spoolss_enumprinters (see this to understand)
2300 ********************************************************************/
2301 uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
2302 NEW_BUFFER *buffer, uint32 offered,
2303 uint32 *needed, uint32 *returned)
2307 DEBUG(4,("_spoolss_enumprinters\n"));
2314 * flags==PRINTER_ENUM_NAME
2315 * if name=="" then enumerates all printers
2316 * if name!="" then enumerate the printer
2317 * flags==PRINTER_ENUM_REMOTE
2318 * name is NULL, enumerate printers
2319 * Level 2: name!="" enumerates printers, name can't be NULL
2320 * Level 3: doesn't exist
2321 * Level 4: does a local registry lookup
2322 * Level 5: same as Level 2
2325 unistr2_to_ascii(name, servername, sizeof(name)-1);
2330 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
2333 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
2336 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
2341 return ERROR_INVALID_LEVEL;
2346 /****************************************************************************
2347 ****************************************************************************/
2348 static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2350 PRINTER_INFO_0 *printer=NULL;
2352 if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
2353 return ERROR_NOT_ENOUGH_MEMORY;
2355 construct_printer_info_0(printer, snum, servername);
2357 /* check the required size. */
2358 *needed += spoolss_size_printer_info_0(printer);
2360 if (!alloc_buffer_size(buffer, *needed)) {
2362 return ERROR_INSUFFICIENT_BUFFER;
2365 /* fill the buffer with the structures */
2366 new_smb_io_printer_info_0("", buffer, printer, 0);
2371 if (*needed > offered) {
2372 return ERROR_INSUFFICIENT_BUFFER;
2375 return NT_STATUS_NO_PROBLEMO;
2378 /****************************************************************************
2379 ****************************************************************************/
2380 static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2382 PRINTER_INFO_1 *printer=NULL;
2384 if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
2385 return ERROR_NOT_ENOUGH_MEMORY;
2387 construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum);
2389 /* check the required size. */
2390 *needed += spoolss_size_printer_info_1(printer);
2392 if (!alloc_buffer_size(buffer, *needed)) {
2394 return ERROR_INSUFFICIENT_BUFFER;
2397 /* fill the buffer with the structures */
2398 new_smb_io_printer_info_1("", buffer, printer, 0);
2403 if (*needed > offered) {
2404 return ERROR_INSUFFICIENT_BUFFER;
2407 return NT_STATUS_NO_PROBLEMO;
2410 /****************************************************************************
2411 ****************************************************************************/
2412 static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2414 PRINTER_INFO_2 *printer=NULL;
2417 if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
2418 return ERROR_NOT_ENOUGH_MEMORY;
2420 fstrcpy(temp, "\\\\");
2421 fstrcat(temp, servername);
2422 construct_printer_info_2(temp, printer, snum);
2424 /* check the required size. */
2425 *needed += spoolss_size_printer_info_2(printer);
2427 if (!alloc_buffer_size(buffer, *needed)) {
2428 free_printer_info_2(printer);
2429 return ERROR_INSUFFICIENT_BUFFER;
2432 /* fill the buffer with the structures */
2433 if (!new_smb_io_printer_info_2("", buffer, printer, 0)) {
2434 free_printer_info_2(printer);
2435 return ERROR_NOT_ENOUGH_MEMORY;
2439 free_printer_info_2(printer);
2441 if (*needed > offered) {
2442 return ERROR_INSUFFICIENT_BUFFER;
2445 return NT_STATUS_NO_PROBLEMO;
2448 /****************************************************************************
2449 ****************************************************************************/
2450 static uint32 getprinter_level_3(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2452 PRINTER_INFO_3 *printer=NULL;
2455 fstrcpy(temp, "\\\\");
2456 fstrcat(temp, servername);
2457 if (!construct_printer_info_3(temp, &printer, snum))
2458 return ERROR_NOT_ENOUGH_MEMORY;
2460 /* check the required size. */
2461 *needed += spoolss_size_printer_info_3(printer);
2463 if (!alloc_buffer_size(buffer, *needed)) {
2464 free_printer_info_3(printer);
2465 return ERROR_INSUFFICIENT_BUFFER;
2468 /* fill the buffer with the structures */
2469 new_smb_io_printer_info_3("", buffer, printer, 0);
2472 free_printer_info_3(printer);
2474 if (*needed > offered) {
2475 return ERROR_INSUFFICIENT_BUFFER;
2478 return NT_STATUS_NO_PROBLEMO;
2481 /****************************************************************************
2482 ****************************************************************************/
2483 uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
2484 NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2491 pstrcpy(servername, global_myname);
2493 if (!get_printer_snum(handle, &snum))
2494 return ERROR_INVALID_HANDLE;
2498 return getprinter_level_0(servername, snum, buffer, offered, needed);
2500 return getprinter_level_1(servername,snum, buffer, offered, needed);
2502 return getprinter_level_2(servername,snum, buffer, offered, needed);
2504 return getprinter_level_3(servername,snum, buffer, offered, needed);
2506 return ERROR_INVALID_LEVEL;
2511 /********************************************************************
2512 * fill a DRIVER_INFO_1 struct
2513 ********************************************************************/
2514 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
2516 init_unistr( &info->name, driver.info_3->name);
2519 /********************************************************************
2520 * construct_printer_driver_info_1
2521 ********************************************************************/
2522 static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
2524 NT_PRINTER_INFO_LEVEL *printer = NULL;
2525 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2527 ZERO_STRUCT(driver);
2529 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2530 return ERROR_INVALID_PRINTER_NAME;
2532 if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2533 return ERROR_UNKNOWN_PRINTER_DRIVER;
2535 fill_printer_driver_info_1(info, driver, servername, architecture);
2537 free_a_printer(&printer,2);
2539 return NT_STATUS_NO_PROBLEMO;
2542 /********************************************************************
2543 * construct_printer_driver_info_2
2544 * fill a printer_info_2 struct
2545 ********************************************************************/
2546 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2548 pstring temp_driverpath;
2549 pstring temp_datafile;
2550 pstring temp_configfile;
2552 info->version=driver.info_3->cversion;
2554 init_unistr( &info->name, driver.info_3->name );
2555 init_unistr( &info->architecture, driver.info_3->environment );
2557 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2558 init_unistr( &info->driverpath, temp_driverpath );
2560 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2561 init_unistr( &info->datafile, temp_datafile );
2563 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2564 init_unistr( &info->configfile, temp_configfile );
2567 /********************************************************************
2568 * construct_printer_driver_info_2
2569 * fill a printer_info_2 struct
2570 ********************************************************************/
2571 static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
2573 NT_PRINTER_INFO_LEVEL *printer = NULL;
2574 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2576 ZERO_STRUCT(printer);
2577 ZERO_STRUCT(driver);
2579 if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
2580 return ERROR_INVALID_PRINTER_NAME;
2582 if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
2583 return ERROR_UNKNOWN_PRINTER_DRIVER;
2585 fill_printer_driver_info_2(info, driver, servername);
2587 free_a_printer(&printer,2);
2589 return NT_STATUS_NO_PROBLEMO;
2592 /********************************************************************
2593 * copy a strings array and convert to UNICODE
2595 * convert an array of ascii string to a UNICODE string
2596 ********************************************************************/
2597 static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
2604 DEBUG(6,("init_unistr_array\n"));
2608 if (char_array == NULL)
2612 if (!v) v = ""; /* hack to handle null lists */
2614 if (strlen(v) == 0) break;
2615 snprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
2616 DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
2617 if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
2618 DEBUG(0,("init_unistr_array: Realloc error\n" ));
2621 j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
2626 (*uni_array)[j]=0x0000;
2629 DEBUGADD(6,("last one:done\n"));
2632 /********************************************************************
2633 * construct_printer_info_3
2634 * fill a printer_info_3 struct
2635 ********************************************************************/
2636 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
2638 pstring temp_driverpath;
2639 pstring temp_datafile;
2640 pstring temp_configfile;
2641 pstring temp_helpfile;
2643 info->version=driver.info_3->cversion;
2645 init_unistr( &info->name, driver.info_3->name );
2646 init_unistr( &info->architecture, driver.info_3->environment );
2648 snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
2649 init_unistr( &info->driverpath, temp_driverpath );
2651 snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
2652 init_unistr( &info->datafile, temp_datafile );
2654 snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
2655 init_unistr( &info->configfile, temp_configfile );
2657 snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
2658 init_unistr( &info->helpfile, temp_helpfile );
2660 init_unistr( &info->monitorname, driver.info_3->monitorname );
2661 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
2663 info->dependentfiles=NULL;
2664 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
2667 /********************************************************************
2668 * construct_printer_info_3
2669 * fill a printer_info_3 struct
2670 ********************************************************************/
2671 static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
2673 NT_PRINTER_INFO_LEVEL *printer = NULL;
2674 NT_PRINTER_DRIVER_INFO_LEVEL driver;
2676 ZERO_STRUCT(driver);
2678 status=get_a_printer(&printer, 2, lp_servicename(snum) );
2679 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2681 return ERROR_INVALID_PRINTER_NAME;
2683 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
2684 DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
2686 free_a_printer(&printer,2);
2687 return ERROR_UNKNOWN_PRINTER_DRIVER;
2690 fill_printer_driver_info_3(info, driver, servername);
2692 free_a_printer(&printer,2);
2694 return NT_STATUS_NO_PROBLEMO;
2697 /****************************************************************************
2698 ****************************************************************************/
2700 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
2702 safe_free(info->dependentfiles);
2705 /****************************************************************************
2706 ****************************************************************************/
2707 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2709 DRIVER_INFO_1 *info=NULL;
2712 if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
2713 return ERROR_NOT_ENOUGH_MEMORY;
2715 status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
2716 if (status != NT_STATUS_NO_PROBLEMO) {
2721 /* check the required size. */
2722 *needed += spoolss_size_printer_driver_info_1(info);
2724 if (!alloc_buffer_size(buffer, *needed)) {
2726 return ERROR_INSUFFICIENT_BUFFER;
2729 /* fill the buffer with the structures */
2730 new_smb_io_printer_driver_info_1("", buffer, info, 0);
2735 if (*needed > offered)
2736 return ERROR_INSUFFICIENT_BUFFER;
2738 return NT_STATUS_NO_PROBLEMO;
2741 /****************************************************************************
2742 ****************************************************************************/
2743 static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2745 DRIVER_INFO_2 *info=NULL;
2748 if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
2749 return ERROR_NOT_ENOUGH_MEMORY;
2751 status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
2752 if (status != NT_STATUS_NO_PROBLEMO) {
2757 /* check the required size. */
2758 *needed += spoolss_size_printer_driver_info_2(info);
2760 if (!alloc_buffer_size(buffer, *needed)) {
2762 return ERROR_INSUFFICIENT_BUFFER;
2765 /* fill the buffer with the structures */
2766 new_smb_io_printer_driver_info_2("", buffer, info, 0);
2771 if (*needed > offered)
2772 return ERROR_INSUFFICIENT_BUFFER;
2774 return NT_STATUS_NO_PROBLEMO;
2777 /****************************************************************************
2778 ****************************************************************************/
2779 static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
2786 status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
2787 if (status != NT_STATUS_NO_PROBLEMO) {
2791 /* check the required size. */
2792 *needed += spoolss_size_printer_driver_info_3(&info);
2794 if (!alloc_buffer_size(buffer, *needed)) {
2795 free_printer_driver_info_3(&info);
2796 return ERROR_INSUFFICIENT_BUFFER;
2799 /* fill the buffer with the structures */
2800 new_smb_io_printer_driver_info_3("", buffer, &info, 0);
2802 free_printer_driver_info_3(&info);
2804 if (*needed > offered)
2805 return ERROR_INSUFFICIENT_BUFFER;
2807 return NT_STATUS_NO_PROBLEMO;
2810 /****************************************************************************
2811 ****************************************************************************/
2812 uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level,
2813 uint32 clientmajorversion, uint32 clientminorversion,
2814 NEW_BUFFER *buffer, uint32 offered,
2815 uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
2818 fstring architecture;
2821 DEBUG(4,("_spoolss_getprinterdriver2\n"));
2824 *servermajorversion=0;
2825 *serverminorversion=0;
2827 pstrcpy(servername, global_myname);
2828 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
2830 if (!get_printer_snum(handle, &snum))
2831 return ERROR_INVALID_HANDLE;
2835 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2838 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2841 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
2844 return ERROR_INVALID_LEVEL;
2849 /****************************************************************************
2850 ****************************************************************************/
2851 uint32 _spoolss_startpageprinter(POLICY_HND *handle)
2853 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2855 if (OPEN_HANDLE(Printer)) {
2856 Printer->page_started=True;
2860 DEBUG(3,("Error in startpageprinter printer handle\n"));
2861 return ERROR_INVALID_HANDLE;
2864 /****************************************************************************
2865 ****************************************************************************/
2866 uint32 _spoolss_endpageprinter(POLICY_HND *handle)
2868 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2870 if (!OPEN_HANDLE(Printer)) {
2871 DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
2872 return ERROR_INVALID_HANDLE;
2875 Printer->page_started=False;
2877 return NT_STATUS_NO_PROBLEMO;
2881 /********************************************************************
2882 * api_spoolss_getprinter
2883 * called from the spoolss dispatcher
2885 ********************************************************************/
2886 uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
2887 pipes_struct *p, DOC_INFO *docinfo,
2890 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
2894 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2895 struct current_user user;
2897 if (!OPEN_HANDLE(Printer)) {
2898 DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2899 return ERROR_INVALID_HANDLE;
2902 if (p->ntlmssp_auth_validated) {
2903 memcpy(&user, &p->pipe_user, sizeof(user));
2905 extern struct current_user current_user;
2906 memcpy(&user, ¤t_user, sizeof(user));
2910 * a nice thing with NT is it doesn't listen to what you tell it.
2911 * when asked to send _only_ RAW datas, it tries to send datas
2914 * So I add checks like in NT Server ...
2916 * lkclXXXX jean-francois, i love this kind of thing. oh, well,
2917 * there's a bug in NT client-side code, so we'll fix it in the
2918 * server-side code. *nnnnnggggh!*
2921 if (info_1->p_datatype != 0) {
2922 unistr2_to_ascii(datatype, &info_1->docname, sizeof(datatype));
2923 if (strcmp(datatype, "RAW") != 0) {
2925 return ERROR_INVALID_DATATYPE;
2929 /* get the share number of the printer */
2930 if (!get_printer_snum(handle, &snum)) {
2931 return ERROR_INVALID_HANDLE;
2934 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
2936 Printer->jobid = print_job_start(&user, snum, jobname);
2938 /* An error occured in print_job_start() so return an appropriate
2941 if (Printer->jobid == -1) {
2942 return map_nt_error_from_unix(errno);
2945 Printer->document_started=True;
2946 (*jobid) = Printer->jobid;
2951 /********************************************************************
2952 * api_spoolss_getprinter
2953 * called from the spoolss dispatcher
2955 ********************************************************************/
2956 uint32 _spoolss_enddocprinter(POLICY_HND *handle)
2958 Printer_entry *Printer=find_printer_index_by_hnd(handle);
2960 if (!OPEN_HANDLE(Printer)) {
2961 DEBUG(0,("_spoolss_enddocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
2962 return ERROR_INVALID_HANDLE;
2965 Printer->document_started=False;
2966 print_job_end(Printer->jobid);
2967 /* error codes unhandled so far ... */
2972 /****************************************************************************
2973 ****************************************************************************/
2974 uint32 _spoolss_writeprinter( POLICY_HND *handle,
2977 uint32 *buffer_written)
2979 Printer_entry *Printer = find_printer_index_by_hnd(handle);
2981 if (!OPEN_HANDLE(Printer)) {
2982 DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
2983 return ERROR_INVALID_HANDLE;
2986 (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer,
2992 /********************************************************************
2993 * api_spoolss_getprinter
2994 * called from the spoolss dispatcher
2996 ********************************************************************/
2997 static uint32 control_printer(POLICY_HND *handle, uint32 command,
3000 struct current_user user;
3003 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3005 if (p->ntlmssp_auth_validated) {
3006 memcpy(&user, &p->pipe_user, sizeof(user));
3008 extern struct current_user current_user;
3009 memcpy(&user, ¤t_user, sizeof(user));
3012 if (!OPEN_HANDLE(Printer)) {
3013 DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3014 return ERROR_INVALID_HANDLE;
3017 if (!get_printer_snum(handle, &snum) )
3018 return ERROR_INVALID_HANDLE;
3021 case PRINTER_CONTROL_PAUSE:
3022 if (print_queue_pause(&user, snum, &errcode)) {
3026 case PRINTER_CONTROL_RESUME:
3027 case PRINTER_CONTROL_UNPAUSE:
3028 if (print_queue_resume(&user, snum, &errcode)) {
3032 case PRINTER_CONTROL_PURGE:
3033 if (print_queue_purge(&user, snum, &errcode)) {
3040 return (uint32)errcode;
3042 return ERROR_INVALID_FUNCTION;
3045 /********************************************************************
3046 * api_spoolss_abortprinter
3047 ********************************************************************/
3049 uint32 _spoolss_abortprinter(POLICY_HND *handle, pipes_struct *p)
3051 return control_printer(handle, PRINTER_CONTROL_PURGE, p);
3054 /********************************************************************
3055 * called by spoolss_api_setprinter
3056 * when updating a printer description
3057 ********************************************************************/
3058 static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
3059 const SPOOL_PRINTER_INFO_LEVEL *info,
3060 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
3062 struct current_user user;
3066 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3068 if (!OPEN_HANDLE(Printer) || !get_printer_snum(handle, &snum)) {
3069 DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3070 return ERROR_INVALID_HANDLE;
3073 /* Work out which user is performing the operation */
3074 if (p->ntlmssp_auth_validated) {
3075 memcpy(&user, &p->pipe_user, sizeof(user));
3077 extern struct current_user current_user;
3078 memcpy(&user, ¤t_user, sizeof(user));
3081 /* Check the user has permissions to change the security
3082 descriptor. By experimentation with two NT machines, the user
3083 requires Full Access to the printer to change security
3085 if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
3086 result = ERROR_ACCESS_DENIED;
3090 result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
3096 /********************************************************************
3097 Do Samba sanity checks on a printer info struct.
3098 ********************************************************************/
3100 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
3103 * Ensure that this printer is shared under the correct name
3104 * as this is what Samba insists upon.
3107 if (!(info->attributes & PRINTER_ATTRIBUTE_SHARED)) {
3108 DEBUG(10,("check_printer_ok: SHARED check failed (%x).\n", (unsigned int)info->attributes ));
3112 if (!(info->attributes & PRINTER_ATTRIBUTE_RAW_ONLY)) {
3113 /* NT forgets to set the raw attribute but sends the correct type. */
3114 if (strequal(info->datatype, "RAW"))
3115 info->attributes |= PRINTER_ATTRIBUTE_RAW_ONLY;
3117 DEBUG(10,("check_printer_ok: RAW check failed (%x).\n", (unsigned int)info->attributes ));
3122 if (!strequal(info->sharename, lp_servicename(snum))) {
3123 DEBUG(10,("check_printer_ok: NAME check failed (%s) (%s).\n", info->sharename, lp_servicename(snum)));
3130 /****************************************************************************
3131 ****************************************************************************/
3132 static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
3134 pid_t local_pid = sys_getpid();
3135 char *cmd = lp_addprinter_cmd();
3140 pstring driverlocation;
3144 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
3145 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
3149 /* build driver path... only 9X architecture is needed for legacy reasons */
3150 slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
3152 /* change \ to \\ for the shell */
3153 all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
3155 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
3156 slprintf(command, sizeof(command), "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
3157 cmd, printer->info_2->printername, printer->info_2->sharename,
3158 printer->info_2->portname, printer->info_2->drivername,
3159 printer->info_2->location, driverlocation);
3162 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
3163 ret = smbrun(command, tmp_file, False);
3164 DEBUGADD(10,("returned [%d]\n", ret));
3172 qlines = file_lines_load(tmp_file, &numlines);
3173 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
3174 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
3178 // Set the portname to what the script says the portname should be
3179 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
3180 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
3182 // Send SIGHUP to process group... is there a better way?
3187 file_lines_free(qlines);
3191 /********************************************************************
3192 * called by spoolss_api_setprinter
3193 * when updating a printer description
3194 ********************************************************************/
3196 static uint32 update_printer(POLICY_HND *handle, uint32 level,
3197 const SPOOL_PRINTER_INFO_LEVEL *info,
3198 DEVICEMODE *devmode)
3201 NT_PRINTER_INFO_LEVEL *printer = NULL;
3202 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3205 DEBUG(8,("update_printer\n"));
3207 result = NT_STATUS_NO_PROBLEMO;
3209 /* Check calling user has permission to update printer description */
3212 DEBUG(0,("Send a mail to samba@samba.org\n"));
3213 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3214 result = ERROR_INVALID_LEVEL;
3218 if (!OPEN_HANDLE(Printer)) {
3219 result = ERROR_INVALID_HANDLE;
3223 if (!get_printer_snum(handle, &snum)) {
3224 result = ERROR_INVALID_HANDLE;
3228 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
3229 DEBUG(3, ("printer property change denied by security "
3231 result = ERROR_ACCESS_DENIED;
3235 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3236 result = ERROR_INVALID_HANDLE;
3240 DEBUGADD(8,("Converting info_2 struct\n"));
3243 * convert_printer_info converts the incoming
3244 * info from the client and overwrites the info
3245 * just read from the tdb in the pointer 'printer'.
3248 convert_printer_info(info, printer, level);
3250 if (info->info_2->devmode_ptr != 0) {
3251 /* we have a valid devmode
3252 convert it and link it*/
3255 * Ensure printer->info_2->devmode is a valid pointer
3256 * as we will be overwriting it in convert_devicemode().
3259 if (printer->info_2->devmode == NULL)
3260 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3262 DEBUGADD(8,("Converting the devicemode struct\n"));
3263 convert_devicemode(devmode, printer->info_2->devmode);
3266 if (printer->info_2->devmode != NULL)
3267 free_nt_devicemode(&printer->info_2->devmode);
3268 printer->info_2->devmode=NULL;
3272 * Do sanity check on the requested changes for Samba.
3275 if (!check_printer_ok(printer->info_2, snum)) {
3276 result = ERROR_INVALID_PARAMETER;
3280 if (*lp_addprinter_cmd() )
3281 if ( !add_printer_hook(printer) ) {
3282 result = ERROR_ACCESS_DENIED;
3286 if (add_a_printer(*printer, 2)!=0) {
3287 /* I don't really know what to return here !!! */
3288 result = ERROR_ACCESS_DENIED;
3293 free_a_printer(&printer, 2);
3298 /****************************************************************************
3299 ****************************************************************************/
3300 uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
3301 const SPOOL_PRINTER_INFO_LEVEL *info,
3302 DEVMODE_CTR devmode_ctr,
3303 SEC_DESC_BUF *secdesc_ctr,
3304 uint32 command, pipes_struct *p)
3306 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3308 if (!OPEN_HANDLE(Printer)) {
3309 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3310 return ERROR_INVALID_HANDLE;
3313 /* check the level */
3316 return control_printer(handle, command, p);
3319 return update_printer(handle, level, info, devmode_ctr.devmode);
3322 return update_printer_sec(handle, level, info, p,
3326 return ERROR_INVALID_LEVEL;
3331 /****************************************************************************
3332 ****************************************************************************/
3333 uint32 _spoolss_fcpn(POLICY_HND *handle)
3335 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3337 if (!OPEN_HANDLE(Printer)) {
3338 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3339 return ERROR_INVALID_HANDLE;
3342 Printer->notify.flags=0;
3343 Printer->notify.options=0;
3344 Printer->notify.localmachine[0]='\0';
3345 Printer->notify.printerlocal=0;
3346 if (Printer->notify.option)
3347 safe_free(Printer->notify.option->ctr.type);
3348 safe_free(Printer->notify.option);
3349 Printer->notify.option=NULL;
3351 return NT_STATUS_NO_PROBLEMO;
3354 /****************************************************************************
3355 ****************************************************************************/
3356 uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
3357 NEW_BUFFER *buffer, uint32 offered,
3361 return ERROR_INVALID_PARAMETER; /* this is what a NT server
3362 returns for AddJob. AddJob
3363 must fail on non-local
3367 /****************************************************************************
3368 ****************************************************************************/
3369 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3370 int position, int snum)
3375 time_t unixdate = time(NULL);
3377 t=gmtime(&unixdate);
3378 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3380 job_info->jobid=queue->job;
3381 init_unistr(&job_info->printername, lp_servicename(snum));
3382 init_unistr(&job_info->machinename, temp_name);
3383 init_unistr(&job_info->username, queue->user);
3384 init_unistr(&job_info->document, queue->file);
3385 init_unistr(&job_info->datatype, "RAW");
3386 init_unistr(&job_info->text_status, "");
3387 job_info->status=nt_printj_status(queue->status);
3388 job_info->priority=queue->priority;
3389 job_info->position=position;
3390 job_info->totalpages=0;
3391 job_info->pagesprinted=0;
3393 make_systemtime(&job_info->submitted, t);
3396 /****************************************************************************
3397 ****************************************************************************/
3398 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3399 int position, int snum)
3402 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3406 time_t unixdate = time(NULL);
3408 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3411 t=gmtime(&unixdate);
3412 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3414 job_info->jobid=queue->job;
3416 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3418 init_unistr(&job_info->printername, chaine);
3420 init_unistr(&job_info->machinename, temp_name);
3421 init_unistr(&job_info->username, queue->user);
3422 init_unistr(&job_info->document, queue->file);
3423 init_unistr(&job_info->notifyname, queue->user);
3424 init_unistr(&job_info->datatype, "RAW");
3425 init_unistr(&job_info->printprocessor, "winprint");
3426 init_unistr(&job_info->parameters, "");
3427 init_unistr(&job_info->text_status, "");
3429 /* and here the security descriptor */
3431 job_info->status=nt_printj_status(queue->status);
3432 job_info->priority=queue->priority;
3433 job_info->position=position;
3434 job_info->starttime=0;
3435 job_info->untiltime=0;
3436 job_info->totalpages=0;
3437 job_info->size=queue->size;
3438 make_systemtime(&(job_info->submitted), t);
3439 job_info->timeelapsed=0;
3440 job_info->pagesprinted=0;
3442 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3443 free_a_printer(&ntprinter, 2);
3447 free_a_printer(&ntprinter, 2);
3451 /****************************************************************************
3452 Enumjobs at level 1.
3453 ****************************************************************************/
3454 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3455 NEW_BUFFER *buffer, uint32 offered,
3456 uint32 *needed, uint32 *returned)
3461 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3465 return ERROR_NOT_ENOUGH_MEMORY;
3468 for (i=0; i<*returned; i++)
3469 fill_job_info_1(&info[i], &queue[i], i, snum);
3473 /* check the required size. */
3474 for (i=0; i<*returned; i++)
3475 (*needed) += spoolss_size_job_info_1(&info[i]);
3477 if (!alloc_buffer_size(buffer, *needed)) {
3479 return ERROR_INSUFFICIENT_BUFFER;
3482 /* fill the buffer with the structures */
3483 for (i=0; i<*returned; i++)
3484 new_smb_io_job_info_1("", buffer, &info[i], 0);
3489 if (*needed > offered) {
3491 return ERROR_INSUFFICIENT_BUFFER;
3494 return NT_STATUS_NO_PROBLEMO;
3497 /****************************************************************************
3498 Enumjobs at level 2.
3499 ****************************************************************************/
3500 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3501 NEW_BUFFER *buffer, uint32 offered,
3502 uint32 *needed, uint32 *returned)
3507 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3511 return ERROR_NOT_ENOUGH_MEMORY;
3514 for (i=0; i<*returned; i++)
3515 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3519 /* check the required size. */
3520 for (i=0; i<*returned; i++)
3521 (*needed) += spoolss_size_job_info_2(&info[i]);
3523 if (!alloc_buffer_size(buffer, *needed)) {
3525 return ERROR_INSUFFICIENT_BUFFER;
3528 /* fill the buffer with the structures */
3529 for (i=0; i<*returned; i++)
3530 new_smb_io_job_info_2("", buffer, &info[i], 0);
3535 if (*needed > offered) {
3537 return ERROR_INSUFFICIENT_BUFFER;
3540 return NT_STATUS_NO_PROBLEMO;
3543 /****************************************************************************
3545 ****************************************************************************/
3546 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3547 NEW_BUFFER *buffer, uint32 offered,
3548 uint32 *needed, uint32 *returned)
3551 print_queue_struct *queue=NULL;
3552 print_status_struct prt_status;
3554 DEBUG(4,("_spoolss_enumjobs\n"));
3556 ZERO_STRUCT(prt_status);
3561 if (!get_printer_snum(handle, &snum))
3562 return ERROR_INVALID_HANDLE;
3564 *returned = print_queue_status(snum, &queue, &prt_status);
3565 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3569 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3572 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3577 return ERROR_INVALID_LEVEL;
3583 /****************************************************************************
3584 ****************************************************************************/
3585 uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid)
3590 /****************************************************************************
3591 ****************************************************************************/
3592 uint32 _spoolss_setjob( POLICY_HND *handle,
3600 struct current_user user;
3602 print_status_struct prt_status;
3604 memset(&prt_status, 0, sizeof(prt_status));
3606 if (!get_printer_snum(handle, &snum)) {
3607 return ERROR_INVALID_HANDLE;
3610 if (!print_job_exists(jobid)) {
3611 return ERROR_INVALID_PRINTER_NAME;
3614 if (p->ntlmssp_auth_validated) {
3615 memcpy(&user, &p->pipe_user, sizeof(user));
3617 extern struct current_user current_user;
3618 memcpy(&user, ¤t_user, sizeof(user));
3622 case JOB_CONTROL_CANCEL:
3623 case JOB_CONTROL_DELETE:
3624 if (print_job_delete(&user, jobid)) return 0x0;
3626 case JOB_CONTROL_PAUSE:
3627 if (print_job_pause(&user, jobid)) return 0x0;
3629 case JOB_CONTROL_RESUME:
3630 if (print_job_resume(&user, jobid)) return 0x0;
3633 return ERROR_INVALID_LEVEL;
3636 return ERROR_INVALID_HANDLE;
3639 /****************************************************************************
3640 Enumerates all printer drivers at level 1.
3641 ****************************************************************************/
3642 static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3647 fstring *list = NULL;
3649 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3650 DRIVER_INFO_1 *driver_info_1=NULL;
3654 #define MAX_VERSION 4
3656 for (version=0; version<MAX_VERSION; version++) {
3658 ndrivers=get_ntdrivers(&list, architecture, version);
3659 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3662 return ERROR_NOT_ENOUGH_MEMORY;
3665 if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
3667 return ERROR_NOT_ENOUGH_MEMORY;
3671 for (i=0; i<ndrivers; i++) {
3672 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3673 ZERO_STRUCT(driver);
3674 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3675 fill_printer_driver_info_1(&(driver_info_1[*returned+i]), driver, servername, architecture );
3678 *returned+=ndrivers;
3682 /* check the required size. */
3683 for (i=0; i<*returned; i++) {
3684 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3685 *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
3688 if (!alloc_buffer_size(buffer, *needed)) {
3689 safe_free(driver_info_1);
3690 return ERROR_INSUFFICIENT_BUFFER;
3693 /* fill the buffer with the form structures */
3694 for (i=0; i<*returned; i++) {
3695 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3696 new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
3699 safe_free(driver_info_1);
3701 if (*needed > offered) {
3703 return ERROR_INSUFFICIENT_BUFFER;
3706 return NT_STATUS_NO_PROBLEMO;
3709 /****************************************************************************
3710 Enumerates all printer drivers at level 2.
3711 ****************************************************************************/
3712 static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3717 fstring *list = NULL;
3719 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3720 DRIVER_INFO_2 *driver_info_2=NULL;
3724 #define MAX_VERSION 4
3726 for (version=0; version<MAX_VERSION; version++) {
3728 ndrivers=get_ntdrivers(&list, architecture, version);
3729 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3732 return ERROR_NOT_ENOUGH_MEMORY;
3735 if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
3737 return ERROR_NOT_ENOUGH_MEMORY;
3741 for (i=0; i<ndrivers; i++) {
3742 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3743 ZERO_STRUCT(driver);
3744 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3745 fill_printer_driver_info_2(&(driver_info_2[*returned+i]), driver, servername);
3748 *returned+=ndrivers;
3752 /* check the required size. */
3753 for (i=0; i<*returned; i++) {
3754 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3755 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3758 if (!alloc_buffer_size(buffer, *needed)) {
3759 safe_free(driver_info_2);
3760 return ERROR_INSUFFICIENT_BUFFER;
3763 /* fill the buffer with the form structures */
3764 for (i=0; i<*returned; i++) {
3765 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3766 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3769 safe_free(driver_info_2);
3771 if (*needed > offered) {
3773 return ERROR_INSUFFICIENT_BUFFER;
3776 return NT_STATUS_NO_PROBLEMO;
3779 /****************************************************************************
3780 Enumerates all printer drivers at level 3.
3781 ****************************************************************************/
3782 static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3787 fstring *list = NULL;
3789 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3790 DRIVER_INFO_3 *driver_info_3=NULL;
3794 #define MAX_VERSION 4
3796 for (version=0; version<MAX_VERSION; version++) {
3798 ndrivers=get_ntdrivers(&list, architecture, version);
3799 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3802 return ERROR_NOT_ENOUGH_MEMORY;
3805 if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
3807 return ERROR_NOT_ENOUGH_MEMORY;
3811 for (i=0; i<ndrivers; i++) {
3812 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3813 ZERO_STRUCT(driver);
3814 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3815 fill_printer_driver_info_3(&(driver_info_3[*returned+i]), driver, servername);
3818 *returned+=ndrivers;
3822 /* check the required size. */
3823 for (i=0; i<*returned; i++) {
3824 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3825 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3828 if (!alloc_buffer_size(buffer, *needed)) {
3829 safe_free(driver_info_3);
3830 return ERROR_INSUFFICIENT_BUFFER;
3833 /* fill the buffer with the driver structures */
3834 for (i=0; i<*returned; i++) {
3835 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3836 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
3839 for (i=0; i<*returned; i++)
3840 safe_free(driver_info_3[i].dependentfiles);
3842 safe_free(driver_info_3);
3844 if (*needed > offered) {
3846 return ERROR_INSUFFICIENT_BUFFER;
3849 return NT_STATUS_NO_PROBLEMO;
3852 /****************************************************************************
3853 Enumerates all printer drivers.
3854 ****************************************************************************/
3855 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
3856 NEW_BUFFER *buffer, uint32 offered,
3857 uint32 *needed, uint32 *returned)
3859 fstring *list = NULL;
3861 fstring architecture;
3863 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
3864 fstrcpy(servername, global_myname);
3868 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
3872 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
3875 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
3878 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
3883 return ERROR_INVALID_LEVEL;
3888 /****************************************************************************
3889 ****************************************************************************/
3890 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
3892 form->flag=list->flag;
3893 init_unistr(&form->name, list->name);
3894 form->width=list->width;
3895 form->length=list->length;
3896 form->left=list->left;
3897 form->top=list->top;
3898 form->right=list->right;
3899 form->bottom=list->bottom;
3902 /****************************************************************************
3903 ****************************************************************************/
3904 uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
3905 NEW_BUFFER *buffer, uint32 offered,
3906 uint32 *needed, uint32 *numofforms)
3908 nt_forms_struct *list=NULL;
3913 DEBUG(4,("_new_spoolss_enumforms\n"));
3914 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3915 DEBUGADD(5,("Info level [%d]\n", level));
3917 *numofforms = get_ntforms(&list);
3918 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
3920 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
3924 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
3926 return ERROR_NOT_ENOUGH_MEMORY;
3929 /* construct the list of form structures */
3930 for (i=0; i<*numofforms; i++) {
3931 DEBUGADD(6,("Filling form number [%d]\n",i));
3932 fill_form_1(&forms_1[i], &list[i]);
3937 /* check the required size. */
3938 for (i=0; i<*numofforms; i++) {
3939 DEBUGADD(6,("adding form [%d]'s size\n",i));
3940 buffer_size += spoolss_size_form_1(&forms_1[i]);
3943 *needed=buffer_size;
3945 if (!alloc_buffer_size(buffer, buffer_size)){
3947 return ERROR_INSUFFICIENT_BUFFER;
3950 /* fill the buffer with the form structures */
3951 for (i=0; i<*numofforms; i++) {
3952 DEBUGADD(6,("adding form [%d] to buffer\n",i));
3953 new_smb_io_form_1("", buffer, &forms_1[i], 0);
3958 if (*needed > offered) {
3960 return ERROR_INSUFFICIENT_BUFFER;
3963 return NT_STATUS_NO_PROBLEMO;
3967 return ERROR_INVALID_LEVEL;
3972 /****************************************************************************
3973 ****************************************************************************/
3974 uint32 _spoolss_getform( POLICY_HND *handle, uint32 level, UNISTR2 *uni_formname, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
3976 nt_forms_struct *list=NULL;
3982 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
3984 DEBUG(4,("_spoolss_getform\n"));
3985 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3986 DEBUGADD(5,("Info level [%d]\n", level));
3988 numofforms = get_ntforms(&list);
3989 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
3991 if (numofforms == 0)
3992 return ERROR_NO_MORE_ITEMS;
3997 /* Check if the requested name is in the list of form structures */
3998 for (i=0; i<numofforms; i++) {
4000 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
4002 if (strequal(form_name, list[i].name)) {
4003 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
4004 fill_form_1(&form_1, &list[i]);
4011 /* check the required size. */
4013 *needed=spoolss_size_form_1(&form_1);
4015 if (!alloc_buffer_size(buffer, buffer_size)){
4016 return ERROR_INSUFFICIENT_BUFFER;
4019 if (*needed > offered) {
4020 return ERROR_INSUFFICIENT_BUFFER;
4023 /* fill the buffer with the form structures */
4024 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
4025 new_smb_io_form_1("", buffer, &form_1, 0);
4027 return NT_STATUS_NO_PROBLEMO;
4031 return ERROR_INVALID_LEVEL;
4035 /****************************************************************************
4036 ****************************************************************************/
4037 static void fill_port_1(PORT_INFO_1 *port, char *name)
4039 init_unistr(&port->port_name, name);
4042 /****************************************************************************
4043 ****************************************************************************/
4044 static void fill_port_2(PORT_INFO_2 *port, char *name)
4046 init_unistr(&port->port_name, name);
4047 init_unistr(&port->monitor_name, "Local Monitor");
4048 init_unistr(&port->description, "Local Port");
4049 #define PORT_TYPE_WRITE 1
4050 port->port_type=PORT_TYPE_WRITE;
4054 /****************************************************************************
4056 ****************************************************************************/
4057 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4059 PORT_INFO_1 *ports=NULL;
4062 if (*lp_enumports_cmd()) {
4063 pid_t local_pid = sys_getpid();
4064 char *cmd = lp_enumports_cmd();
4072 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4073 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4077 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4078 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 1);
4081 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4082 ret = smbrun(command, tmp_file, False);
4083 DEBUG(10,("Returned [%d]\n", ret));
4086 // Is this the best error to return here?
4087 return ERROR_ACCESS_DENIED;
4091 qlines = file_lines_load(tmp_file, &numlines);
4092 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4093 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4097 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
4098 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4099 file_lines_free(qlines);
4100 return ERROR_NOT_ENOUGH_MEMORY;
4103 for (i=0; i<numlines; i++) {
4104 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4105 fill_port_1(&ports[i], qlines[i]);
4108 file_lines_free(qlines);
4111 *returned = numlines;
4114 *returned = 1; /* Sole Samba port returned. */
4116 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
4117 return ERROR_NOT_ENOUGH_MEMORY;
4119 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4121 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
4124 /* check the required size. */
4125 for (i=0; i<*returned; i++) {
4126 DEBUGADD(6,("adding port [%d]'s size\n", i));
4127 *needed += spoolss_size_port_info_1(&ports[i]);
4130 if (!alloc_buffer_size(buffer, *needed)) {
4132 return ERROR_INSUFFICIENT_BUFFER;
4135 /* fill the buffer with the ports structures */
4136 for (i=0; i<*returned; i++) {
4137 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4138 new_smb_io_port_1("", buffer, &ports[i], 0);
4143 if (*needed > offered) {
4145 return ERROR_INSUFFICIENT_BUFFER;
4148 return NT_STATUS_NO_PROBLEMO;
4151 /****************************************************************************
4153 ****************************************************************************/
4155 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4157 PORT_INFO_2 *ports=NULL;
4160 if (*lp_enumports_cmd()) {
4161 pid_t local_pid = sys_getpid();
4162 char *cmd = lp_enumports_cmd();
4170 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4171 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4175 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4176 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 2);
4179 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4180 ret = smbrun(command, tmp_file, False);
4181 DEBUGADD(10,("returned [%d]\n", ret));
4184 // Is this the best error to return here?
4185 return ERROR_ACCESS_DENIED;
4189 qlines = file_lines_load(tmp_file, &numlines);
4190 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4191 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4195 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
4196 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4197 file_lines_free(qlines);
4198 return ERROR_NOT_ENOUGH_MEMORY;
4201 for (i=0; i<numlines; i++) {
4202 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4203 fill_port_2(&(ports[i]), qlines[i]);
4206 file_lines_free(qlines);
4209 *returned = numlines;
4215 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
4216 return ERROR_NOT_ENOUGH_MEMORY;
4218 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4220 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
4223 /* check the required size. */
4224 for (i=0; i<*returned; i++) {
4225 DEBUGADD(6,("adding port [%d]'s size\n", i));
4226 *needed += spoolss_size_port_info_2(&ports[i]);
4229 if (!alloc_buffer_size(buffer, *needed)) {
4231 return ERROR_INSUFFICIENT_BUFFER;
4234 /* fill the buffer with the ports structures */
4235 for (i=0; i<*returned; i++) {
4236 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4237 new_smb_io_port_2("", buffer, &ports[i], 0);
4242 if (*needed > offered) {
4244 return ERROR_INSUFFICIENT_BUFFER;
4247 return NT_STATUS_NO_PROBLEMO;
4250 /****************************************************************************
4252 ****************************************************************************/
4253 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
4254 NEW_BUFFER *buffer, uint32 offered,
4255 uint32 *needed, uint32 *returned)
4257 DEBUG(4,("_spoolss_enumports\n"));
4264 return enumports_level_1(buffer, offered, needed, returned);
4267 return enumports_level_2(buffer, offered, needed, returned);
4270 return ERROR_INVALID_LEVEL;
4275 /****************************************************************************
4276 ****************************************************************************/
4277 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
4278 const SPOOL_PRINTER_INFO_LEVEL *info,
4279 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4280 uint32 user_switch, const SPOOL_USER_CTR *user,
4283 NT_PRINTER_INFO_LEVEL *printer = NULL;
4287 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
4288 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
4289 return ERROR_NOT_ENOUGH_MEMORY;
4292 ZERO_STRUCTP(printer);
4294 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
4295 convert_printer_info(info, printer, 2);
4297 if (*lp_addprinter_cmd() )
4298 if ( !add_printer_hook(printer) ) {
4299 free_a_printer(&printer,2);
4300 return ERROR_ACCESS_DENIED;
4303 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
4304 printer->info_2->sharename);
4306 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
4307 free_a_printer(&printer,2);
4308 return ERROR_ACCESS_DENIED;
4311 /* you must be a printer admin to add a new printer */
4312 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4313 free_a_printer(&printer,2);
4314 return ERROR_ACCESS_DENIED;
4318 * Do sanity check on the requested changes for Samba.
4321 if (!check_printer_ok(printer->info_2, snum)) {
4322 free_a_printer(&printer,2);
4323 return ERROR_INVALID_PARAMETER;
4326 /* write the ASCII on disk */
4327 if (add_a_printer(*printer, 2) != 0) {
4328 free_a_printer(&printer,2);
4329 return ERROR_ACCESS_DENIED;
4332 if (!open_printer_hnd(handle, name)) {
4333 /* Handle open failed - remove addition. */
4334 del_a_printer(printer->info_2->sharename);
4335 free_a_printer(&printer,2);
4336 return ERROR_ACCESS_DENIED;
4339 free_a_printer(&printer,2);
4340 return NT_STATUS_NO_PROBLEMO;
4343 /****************************************************************************
4344 ****************************************************************************/
4345 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4346 const SPOOL_PRINTER_INFO_LEVEL *info,
4347 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4348 uint32 user_switch, const SPOOL_USER_CTR *user,
4353 /* we don't handle yet */
4354 /* but I know what to do ... */
4355 return ERROR_INVALID_LEVEL;
4358 return spoolss_addprinterex_level_2(uni_srv_name, info,
4359 unk0, unk1, unk2, unk3,
4360 user_switch, user, handle);
4363 return ERROR_INVALID_LEVEL;
4368 /****************************************************************************
4369 ****************************************************************************/
4370 uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
4371 uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4373 uint32 err = NT_STATUS_NO_PROBLEMO;
4374 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4375 struct current_user user;
4377 ZERO_STRUCT(driver);
4379 if (p->ntlmssp_auth_validated) {
4380 memcpy(&user, &p->pipe_user, sizeof(user));
4382 extern struct current_user current_user;
4383 memcpy(&user, ¤t_user, sizeof(user));
4386 convert_printer_driver_info(info, &driver, level);
4388 DEBUG(5,("Cleaning driver's information\n"));
4389 clean_up_driver_struct(driver, level);
4391 DEBUG(5,("Moving driver to final destination\n"));
4392 if(!move_driver_to_download_area(driver, level, &user, &err)) {
4394 err = ERROR_ACCESS_DENIED;
4398 if (add_a_printer_driver(driver, level)!=0) {
4399 err = ERROR_ACCESS_DENIED;
4404 free_a_printer_driver(driver, level);
4408 /****************************************************************************
4409 ****************************************************************************/
4410 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4412 init_unistr(&info->name, name);
4415 /****************************************************************************
4416 ****************************************************************************/
4417 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4421 pstring short_archi;
4422 DRIVER_DIRECTORY_1 *info=NULL;
4424 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4426 if (get_short_archi(short_archi, long_archi)==FALSE)
4427 return ERROR_INVALID_ENVIRONMENT;
4429 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4430 return ERROR_NOT_ENOUGH_MEMORY;
4432 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
4434 DEBUG(4,("printer driver directory: [%s]\n", path));
4436 fill_driverdir_1(info, path);
4438 *needed += spoolss_size_driverdir_info_1(info);
4440 if (!alloc_buffer_size(buffer, *needed)) {
4442 return ERROR_INSUFFICIENT_BUFFER;
4445 new_smb_io_driverdir_1("", buffer, info, 0);
4449 if (*needed > offered)
4450 return ERROR_INSUFFICIENT_BUFFER;
4452 return NT_STATUS_NO_PROBLEMO;
4455 /****************************************************************************
4456 ****************************************************************************/
4457 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4458 NEW_BUFFER *buffer, uint32 offered,
4461 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4467 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4470 return ERROR_INVALID_LEVEL;
4475 /****************************************************************************
4476 ****************************************************************************/
4477 uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
4478 uint32 in_value_len, uint32 in_data_len,
4479 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4481 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4483 NT_PRINTER_INFO_LEVEL *printer = NULL;
4488 uint32 biggest_valuesize;
4489 uint32 biggest_datasize;
4491 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4496 ZERO_STRUCT(printer);
4498 *out_max_value_len=0;
4504 *out_max_data_len=0;
4508 DEBUG(5,("spoolss_enumprinterdata\n"));
4510 if (!OPEN_HANDLE(Printer)) {
4511 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4512 return ERROR_INVALID_HANDLE;
4515 if (!get_printer_snum(handle, &snum))
4516 return ERROR_INVALID_HANDLE;
4518 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4519 return ERROR_INVALID_HANDLE;
4522 * The NT machine wants to know the biggest size of value and data
4524 * cf: MSDN EnumPrinterData remark section
4526 if ( (in_value_len==0) && (in_data_len==0) ) {
4527 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4530 * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
4531 * if this parameter size doesn't exist.
4532 * Ok - my opinion here is that the client is not asking for the greatest
4533 * possible size of all the parameters, but is asking specifically for the size needed
4534 * for this specific parameter. In that case we can remove the loop below and
4535 * simplify this lookup code considerably. JF - comments welcome. JRA.
4538 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4540 free_a_printer(&printer, 2);
4541 return ERROR_NO_MORE_ITEMS;
4548 biggest_valuesize=0;
4551 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4552 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4553 if (data_len > biggest_datasize) biggest_datasize=data_len;
4555 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4563 * I think this is correct, it doesn't break APW and
4564 * allows Gerald's Win32 test programs to work correctly,
4565 * but may need altering.... JRA.
4568 if (param_index == 0) {
4569 /* No parameters found. */
4570 free_a_printer(&printer, 2);
4571 return ERROR_NO_MORE_ITEMS;
4574 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4575 *out_value_len=2*(1+biggest_valuesize);
4576 *out_data_len=biggest_datasize;
4578 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4580 free_a_printer(&printer, 2);
4581 return NT_STATUS_NO_PROBLEMO;
4585 * the value len is wrong in NT sp3
4586 * that's the number of bytes not the number of unicode chars
4589 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4591 free_a_printer(&printer, 2);
4592 return ERROR_NO_MORE_ITEMS;
4595 free_a_printer(&printer, 2);
4599 * - counted in bytes in the request
4600 * - counted in UNICODE chars in the max reply
4601 * - counted in bytes in the real size
4603 * take a pause *before* coding not *during* coding
4606 *out_max_value_len=(in_value_len/sizeof(uint16));
4607 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4609 return ERROR_NOT_ENOUGH_MEMORY;
4612 ZERO_STRUCTP(*out_value);
4613 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4617 /* the data is counted in bytes */
4618 *out_max_data_len=in_data_len;
4619 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4621 return ERROR_NOT_ENOUGH_MEMORY;
4624 ZERO_STRUCTP(*data_out);
4625 memcpy(*data_out, data, (size_t)data_len);
4626 *out_data_len=data_len;
4630 return NT_STATUS_NO_PROBLEMO;
4633 /****************************************************************************
4634 ****************************************************************************/
4635 uint32 _spoolss_setprinterdata( POLICY_HND *handle,
4636 const UNISTR2 *value,
4641 uint32 numeric_data)
4643 NT_PRINTER_INFO_LEVEL *printer = NULL;
4644 NT_PRINTER_PARAM *param = NULL;
4646 uint32 status = 0x0;
4647 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4649 DEBUG(5,("spoolss_setprinterdata\n"));
4652 if (!OPEN_HANDLE(Printer)) {
4653 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4654 return ERROR_INVALID_HANDLE;
4657 if (!get_printer_snum(handle, &snum))
4658 return ERROR_INVALID_HANDLE;
4660 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4661 DEBUG(3, ("security descriptor change denied by existing "
4662 "security descriptor\n"));
4663 return ERROR_ACCESS_DENIED;
4666 status = get_a_printer(&printer, 2, lp_servicename(snum));
4668 return ERROR_INVALID_NAME;
4670 convert_specific_param(¶m, value , type, data, real_len);
4671 unlink_specific_param_if_exist(printer->info_2, param);
4673 if (!add_a_specific_param(printer->info_2, param))
4674 status = ERROR_INVALID_PARAMETER;
4676 status = add_a_printer(*printer, 2);
4678 free_a_printer(&printer, 2);
4682 /****************************************************************************
4683 ****************************************************************************/
4684 uint32 _spoolss_addform( POLICY_HND *handle,
4689 nt_forms_struct *list=NULL;
4690 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4692 DEBUG(5,("spoolss_addform\n"));
4694 if (!OPEN_HANDLE(Printer)) {
4695 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4696 return ERROR_INVALID_HANDLE;
4699 count=get_ntforms(&list);
4700 if(!add_a_form(&list, form, &count))
4701 return ERROR_NOT_ENOUGH_MEMORY;
4702 write_ntforms(&list, count);
4709 /****************************************************************************
4710 ****************************************************************************/
4711 uint32 _spoolss_deleteform( POLICY_HND *handle, UNISTR2 *form_name)
4715 nt_forms_struct *list=NULL;
4716 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4718 DEBUG(5,("spoolss_deleteform\n"));
4720 if (!OPEN_HANDLE(Printer)) {
4721 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4722 return ERROR_INVALID_HANDLE;
4725 count = get_ntforms(&list);
4726 if(!delete_a_form(&list, form_name, &count, &ret))
4727 return ERROR_INVALID_PARAMETER;
4734 /****************************************************************************
4735 ****************************************************************************/
4736 uint32 _spoolss_setform( POLICY_HND *handle,
4737 const UNISTR2 *uni_name,
4742 nt_forms_struct *list=NULL;
4743 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4745 DEBUG(5,("spoolss_setform\n"));
4747 if (!OPEN_HANDLE(Printer)) {
4748 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4749 return ERROR_INVALID_HANDLE;
4751 count=get_ntforms(&list);
4752 update_a_form(&list, form, count);
4753 write_ntforms(&list, count);
4760 /****************************************************************************
4761 enumprintprocessors level 1.
4762 ****************************************************************************/
4763 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4765 PRINTPROCESSOR_1 *info_1=NULL;
4767 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4768 return ERROR_NOT_ENOUGH_MEMORY;
4772 init_unistr(&info_1->name, "winprint");
4774 *needed += spoolss_size_printprocessor_info_1(info_1);
4776 if (!alloc_buffer_size(buffer, *needed))
4777 return ERROR_INSUFFICIENT_BUFFER;
4779 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4783 if (*needed > offered) {
4785 return ERROR_INSUFFICIENT_BUFFER;
4788 return NT_STATUS_NO_PROBLEMO;
4791 /****************************************************************************
4792 ****************************************************************************/
4793 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
4794 NEW_BUFFER *buffer, uint32 offered,
4795 uint32 *needed, uint32 *returned)
4797 DEBUG(5,("spoolss_enumprintprocessors\n"));
4800 * Enumerate the print processors ...
4802 * Just reply with "winprint", to keep NT happy
4803 * and I can use my nice printer checker.
4811 return enumprintprocessors_level_1(buffer, offered, needed, returned);
4814 return ERROR_INVALID_LEVEL;
4819 /****************************************************************************
4820 enumprintprocdatatypes level 1.
4821 ****************************************************************************/
4822 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4824 PRINTPROCDATATYPE_1 *info_1=NULL;
4826 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
4827 return ERROR_NOT_ENOUGH_MEMORY;
4831 init_unistr(&info_1->name, "RAW");
4833 *needed += spoolss_size_printprocdatatype_info_1(info_1);
4835 if (!alloc_buffer_size(buffer, *needed))
4836 return ERROR_INSUFFICIENT_BUFFER;
4838 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
4842 if (*needed > offered) {
4844 return ERROR_INSUFFICIENT_BUFFER;
4847 return NT_STATUS_NO_PROBLEMO;
4850 /****************************************************************************
4851 ****************************************************************************/
4852 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
4853 NEW_BUFFER *buffer, uint32 offered,
4854 uint32 *needed, uint32 *returned)
4856 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
4863 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
4866 return ERROR_INVALID_LEVEL;
4871 /****************************************************************************
4872 enumprintmonitors level 1.
4873 ****************************************************************************/
4874 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4876 PRINTMONITOR_1 *info_1=NULL;
4878 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
4879 return ERROR_NOT_ENOUGH_MEMORY;
4883 init_unistr(&info_1->name, "Local Port");
4885 *needed += spoolss_size_printmonitor_info_1(info_1);
4887 if (!alloc_buffer_size(buffer, *needed))
4888 return ERROR_INSUFFICIENT_BUFFER;
4890 smb_io_printmonitor_info_1("", buffer, info_1, 0);
4894 if (*needed > offered) {
4896 return ERROR_INSUFFICIENT_BUFFER;
4899 return NT_STATUS_NO_PROBLEMO;
4902 /****************************************************************************
4903 enumprintmonitors level 2.
4904 ****************************************************************************/
4905 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4907 PRINTMONITOR_2 *info_2=NULL;
4909 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
4910 return ERROR_NOT_ENOUGH_MEMORY;
4914 init_unistr(&info_2->name, "Local Port");
4915 init_unistr(&info_2->environment, "Windows NT X86");
4916 init_unistr(&info_2->dll_name, "localmon.dll");
4918 *needed += spoolss_size_printmonitor_info_2(info_2);
4920 if (!alloc_buffer_size(buffer, *needed))
4921 return ERROR_INSUFFICIENT_BUFFER;
4923 smb_io_printmonitor_info_2("", buffer, info_2, 0);
4927 if (*needed > offered) {
4929 return ERROR_INSUFFICIENT_BUFFER;
4932 return NT_STATUS_NO_PROBLEMO;
4935 /****************************************************************************
4936 ****************************************************************************/
4937 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
4938 NEW_BUFFER *buffer, uint32 offered,
4939 uint32 *needed, uint32 *returned)
4941 DEBUG(5,("spoolss_enumprintmonitors\n"));
4944 * Enumerate the print monitors ...
4946 * Just reply with "Local Port", to keep NT happy
4947 * and I can use my nice printer checker.
4955 return enumprintmonitors_level_1(buffer, offered, needed, returned);
4958 return enumprintmonitors_level_2(buffer, offered, needed, returned);
4961 return ERROR_INVALID_LEVEL;
4966 /****************************************************************************
4967 ****************************************************************************/
4968 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4972 JOB_INFO_1 *info_1=NULL;
4974 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
4976 if (info_1 == NULL) {
4978 return ERROR_NOT_ENOUGH_MEMORY;
4981 for (i=0; i<count && found==False; i++) {
4982 if (queue[i].job==(int)jobid)
4989 /* I shoud reply something else ... I can't find the good one */
4990 return NT_STATUS_NO_PROBLEMO;
4993 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
4997 *needed += spoolss_size_job_info_1(info_1);
4999 if (!alloc_buffer_size(buffer, *needed)) {
5001 return ERROR_INSUFFICIENT_BUFFER;
5004 new_smb_io_job_info_1("", buffer, info_1, 0);
5008 if (*needed > offered)
5009 return ERROR_INSUFFICIENT_BUFFER;
5011 return NT_STATUS_NO_PROBLEMO;
5015 /****************************************************************************
5016 ****************************************************************************/
5017 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
5022 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
5024 ZERO_STRUCTP(info_2);
5026 if (info_2 == NULL) {
5028 return ERROR_NOT_ENOUGH_MEMORY;
5031 for (i=0; i<count && found==False; i++) {
5032 if (queue[i].job==(int)jobid)
5039 /* I shoud reply something else ... I can't find the good one */
5040 return NT_STATUS_NO_PROBLEMO;
5043 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
5047 *needed += spoolss_size_job_info_2(info_2);
5049 if (!alloc_buffer_size(buffer, *needed)) {
5051 return ERROR_INSUFFICIENT_BUFFER;
5054 new_smb_io_job_info_2("", buffer, info_2, 0);
5056 free_dev_mode(info_2->devmode);
5059 if (*needed > offered)
5060 return ERROR_INSUFFICIENT_BUFFER;
5062 return NT_STATUS_NO_PROBLEMO;
5065 /****************************************************************************
5066 ****************************************************************************/
5067 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
5068 NEW_BUFFER *buffer, uint32 offered,
5073 print_queue_struct *queue=NULL;
5074 print_status_struct prt_status;
5076 DEBUG(5,("spoolss_getjob\n"));
5078 memset(&prt_status, 0, sizeof(prt_status));
5082 if (!get_printer_snum(handle, &snum))
5083 return ERROR_INVALID_HANDLE;
5085 count = print_queue_status(snum, &queue, &prt_status);
5087 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
5088 count, prt_status.status, prt_status.message));
5092 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
5095 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
5099 return ERROR_INVALID_LEVEL;