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));
3168 free_a_printer(&printer,2);
3173 qlines = file_lines_load(tmp_file, &numlines);
3174 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
3175 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
3179 // Set the portname to what the script says the portname should be
3180 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
3181 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
3183 // Send SIGHUP to process group... is there a better way?
3188 file_lines_free(qlines);
3192 /********************************************************************
3193 * called by spoolss_api_setprinter
3194 * when updating a printer description
3195 ********************************************************************/
3197 static uint32 update_printer(POLICY_HND *handle, uint32 level,
3198 const SPOOL_PRINTER_INFO_LEVEL *info,
3199 DEVICEMODE *devmode)
3202 NT_PRINTER_INFO_LEVEL *printer = NULL;
3203 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3206 DEBUG(8,("update_printer\n"));
3208 result = NT_STATUS_NO_PROBLEMO;
3210 /* Check calling user has permission to update printer description */
3213 DEBUG(0,("Send a mail to samba@samba.org\n"));
3214 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
3215 result = ERROR_INVALID_LEVEL;
3219 if (!OPEN_HANDLE(Printer)) {
3220 result = ERROR_INVALID_HANDLE;
3224 if (!get_printer_snum(handle, &snum)) {
3225 result = ERROR_INVALID_HANDLE;
3229 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
3230 DEBUG(3, ("printer property change denied by security "
3232 result = ERROR_ACCESS_DENIED;
3236 if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
3237 result = ERROR_INVALID_HANDLE;
3241 DEBUGADD(8,("Converting info_2 struct\n"));
3244 * convert_printer_info converts the incoming
3245 * info from the client and overwrites the info
3246 * just read from the tdb in the pointer 'printer'.
3249 convert_printer_info(info, printer, level);
3251 if (info->info_2->devmode_ptr != 0) {
3252 /* we have a valid devmode
3253 convert it and link it*/
3256 * Ensure printer->info_2->devmode is a valid pointer
3257 * as we will be overwriting it in convert_devicemode().
3260 if (printer->info_2->devmode == NULL)
3261 printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
3263 DEBUGADD(8,("Converting the devicemode struct\n"));
3264 convert_devicemode(devmode, printer->info_2->devmode);
3267 if (printer->info_2->devmode != NULL)
3268 free_nt_devicemode(&printer->info_2->devmode);
3269 printer->info_2->devmode=NULL;
3273 * Do sanity check on the requested changes for Samba.
3276 if (!check_printer_ok(printer->info_2, snum)) {
3277 result = ERROR_INVALID_PARAMETER;
3281 if (*lp_addprinter_cmd() )
3282 if ( !add_printer_hook(printer) ) {
3283 result = ERROR_ACCESS_DENIED;
3287 if (add_a_printer(*printer, 2)!=0) {
3288 /* I don't really know what to return here !!! */
3289 result = ERROR_ACCESS_DENIED;
3294 free_a_printer(&printer, 2);
3299 /****************************************************************************
3300 ****************************************************************************/
3301 uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
3302 const SPOOL_PRINTER_INFO_LEVEL *info,
3303 DEVMODE_CTR devmode_ctr,
3304 SEC_DESC_BUF *secdesc_ctr,
3305 uint32 command, pipes_struct *p)
3307 Printer_entry *Printer = find_printer_index_by_hnd(handle);
3309 if (!OPEN_HANDLE(Printer)) {
3310 DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3311 return ERROR_INVALID_HANDLE;
3314 /* check the level */
3317 return control_printer(handle, command, p);
3320 return update_printer(handle, level, info, devmode_ctr.devmode);
3323 return update_printer_sec(handle, level, info, p,
3327 return ERROR_INVALID_LEVEL;
3332 /****************************************************************************
3333 ****************************************************************************/
3334 uint32 _spoolss_fcpn(POLICY_HND *handle)
3336 Printer_entry *Printer= find_printer_index_by_hnd(handle);
3338 if (!OPEN_HANDLE(Printer)) {
3339 DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
3340 return ERROR_INVALID_HANDLE;
3343 Printer->notify.flags=0;
3344 Printer->notify.options=0;
3345 Printer->notify.localmachine[0]='\0';
3346 Printer->notify.printerlocal=0;
3347 if (Printer->notify.option)
3348 safe_free(Printer->notify.option->ctr.type);
3349 safe_free(Printer->notify.option);
3350 Printer->notify.option=NULL;
3352 return NT_STATUS_NO_PROBLEMO;
3355 /****************************************************************************
3356 ****************************************************************************/
3357 uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
3358 NEW_BUFFER *buffer, uint32 offered,
3362 return ERROR_INVALID_PARAMETER; /* this is what a NT server
3363 returns for AddJob. AddJob
3364 must fail on non-local
3368 /****************************************************************************
3369 ****************************************************************************/
3370 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
3371 int position, int snum)
3376 time_t unixdate = time(NULL);
3378 t=gmtime(&unixdate);
3379 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3381 job_info->jobid=queue->job;
3382 init_unistr(&job_info->printername, lp_servicename(snum));
3383 init_unistr(&job_info->machinename, temp_name);
3384 init_unistr(&job_info->username, queue->user);
3385 init_unistr(&job_info->document, queue->file);
3386 init_unistr(&job_info->datatype, "RAW");
3387 init_unistr(&job_info->text_status, "");
3388 job_info->status=nt_printj_status(queue->status);
3389 job_info->priority=queue->priority;
3390 job_info->position=position;
3391 job_info->totalpages=0;
3392 job_info->pagesprinted=0;
3394 make_systemtime(&job_info->submitted, t);
3397 /****************************************************************************
3398 ****************************************************************************/
3399 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
3400 int position, int snum)
3403 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3407 time_t unixdate = time(NULL);
3409 if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
3412 t=gmtime(&unixdate);
3413 snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
3415 job_info->jobid=queue->job;
3417 snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
3419 init_unistr(&job_info->printername, chaine);
3421 init_unistr(&job_info->machinename, temp_name);
3422 init_unistr(&job_info->username, queue->user);
3423 init_unistr(&job_info->document, queue->file);
3424 init_unistr(&job_info->notifyname, queue->user);
3425 init_unistr(&job_info->datatype, "RAW");
3426 init_unistr(&job_info->printprocessor, "winprint");
3427 init_unistr(&job_info->parameters, "");
3428 init_unistr(&job_info->text_status, "");
3430 /* and here the security descriptor */
3432 job_info->status=nt_printj_status(queue->status);
3433 job_info->priority=queue->priority;
3434 job_info->position=position;
3435 job_info->starttime=0;
3436 job_info->untiltime=0;
3437 job_info->totalpages=0;
3438 job_info->size=queue->size;
3439 make_systemtime(&(job_info->submitted), t);
3440 job_info->timeelapsed=0;
3441 job_info->pagesprinted=0;
3443 if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) {
3444 free_a_printer(&ntprinter, 2);
3448 free_a_printer(&ntprinter, 2);
3452 /****************************************************************************
3453 Enumjobs at level 1.
3454 ****************************************************************************/
3455 static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
3456 NEW_BUFFER *buffer, uint32 offered,
3457 uint32 *needed, uint32 *returned)
3462 info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
3466 return ERROR_NOT_ENOUGH_MEMORY;
3469 for (i=0; i<*returned; i++)
3470 fill_job_info_1(&info[i], &queue[i], i, snum);
3474 /* check the required size. */
3475 for (i=0; i<*returned; i++)
3476 (*needed) += spoolss_size_job_info_1(&info[i]);
3478 if (!alloc_buffer_size(buffer, *needed)) {
3480 return ERROR_INSUFFICIENT_BUFFER;
3483 /* fill the buffer with the structures */
3484 for (i=0; i<*returned; i++)
3485 new_smb_io_job_info_1("", buffer, &info[i], 0);
3490 if (*needed > offered) {
3492 return ERROR_INSUFFICIENT_BUFFER;
3495 return NT_STATUS_NO_PROBLEMO;
3498 /****************************************************************************
3499 Enumjobs at level 2.
3500 ****************************************************************************/
3501 static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
3502 NEW_BUFFER *buffer, uint32 offered,
3503 uint32 *needed, uint32 *returned)
3508 info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
3512 return ERROR_NOT_ENOUGH_MEMORY;
3515 for (i=0; i<*returned; i++)
3516 fill_job_info_2(&(info[i]), &queue[i], i, snum);
3520 /* check the required size. */
3521 for (i=0; i<*returned; i++)
3522 (*needed) += spoolss_size_job_info_2(&info[i]);
3524 if (!alloc_buffer_size(buffer, *needed)) {
3526 return ERROR_INSUFFICIENT_BUFFER;
3529 /* fill the buffer with the structures */
3530 for (i=0; i<*returned; i++)
3531 new_smb_io_job_info_2("", buffer, &info[i], 0);
3536 if (*needed > offered) {
3538 return ERROR_INSUFFICIENT_BUFFER;
3541 return NT_STATUS_NO_PROBLEMO;
3544 /****************************************************************************
3546 ****************************************************************************/
3547 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
3548 NEW_BUFFER *buffer, uint32 offered,
3549 uint32 *needed, uint32 *returned)
3552 print_queue_struct *queue=NULL;
3553 print_status_struct prt_status;
3555 DEBUG(4,("_spoolss_enumjobs\n"));
3557 ZERO_STRUCT(prt_status);
3562 if (!get_printer_snum(handle, &snum))
3563 return ERROR_INVALID_HANDLE;
3565 *returned = print_queue_status(snum, &queue, &prt_status);
3566 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
3570 return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
3573 return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
3578 return ERROR_INVALID_LEVEL;
3584 /****************************************************************************
3585 ****************************************************************************/
3586 uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid)
3591 /****************************************************************************
3592 ****************************************************************************/
3593 uint32 _spoolss_setjob( POLICY_HND *handle,
3601 struct current_user user;
3603 print_status_struct prt_status;
3605 memset(&prt_status, 0, sizeof(prt_status));
3607 if (!get_printer_snum(handle, &snum)) {
3608 return ERROR_INVALID_HANDLE;
3611 if (!print_job_exists(jobid)) {
3612 return ERROR_INVALID_PRINTER_NAME;
3615 if (p->ntlmssp_auth_validated) {
3616 memcpy(&user, &p->pipe_user, sizeof(user));
3618 extern struct current_user current_user;
3619 memcpy(&user, ¤t_user, sizeof(user));
3623 case JOB_CONTROL_CANCEL:
3624 case JOB_CONTROL_DELETE:
3625 if (print_job_delete(&user, jobid)) return 0x0;
3627 case JOB_CONTROL_PAUSE:
3628 if (print_job_pause(&user, jobid)) return 0x0;
3630 case JOB_CONTROL_RESUME:
3631 if (print_job_resume(&user, jobid)) return 0x0;
3634 return ERROR_INVALID_LEVEL;
3637 return ERROR_INVALID_HANDLE;
3640 /****************************************************************************
3641 Enumerates all printer drivers at level 1.
3642 ****************************************************************************/
3643 static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3648 fstring *list = NULL;
3650 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3651 DRIVER_INFO_1 *driver_info_1=NULL;
3655 #define MAX_VERSION 4
3657 for (version=0; version<MAX_VERSION; version++) {
3659 ndrivers=get_ntdrivers(&list, architecture, version);
3660 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3663 return ERROR_NOT_ENOUGH_MEMORY;
3666 if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
3668 return ERROR_NOT_ENOUGH_MEMORY;
3672 for (i=0; i<ndrivers; i++) {
3673 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3674 ZERO_STRUCT(driver);
3675 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3676 fill_printer_driver_info_1(&(driver_info_1[*returned+i]), driver, servername, architecture );
3679 *returned+=ndrivers;
3683 /* check the required size. */
3684 for (i=0; i<*returned; i++) {
3685 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3686 *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
3689 if (!alloc_buffer_size(buffer, *needed)) {
3690 safe_free(driver_info_1);
3691 return ERROR_INSUFFICIENT_BUFFER;
3694 /* fill the buffer with the form structures */
3695 for (i=0; i<*returned; i++) {
3696 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3697 new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
3700 safe_free(driver_info_1);
3702 if (*needed > offered) {
3704 return ERROR_INSUFFICIENT_BUFFER;
3707 return NT_STATUS_NO_PROBLEMO;
3710 /****************************************************************************
3711 Enumerates all printer drivers at level 2.
3712 ****************************************************************************/
3713 static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3718 fstring *list = NULL;
3720 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3721 DRIVER_INFO_2 *driver_info_2=NULL;
3725 #define MAX_VERSION 4
3727 for (version=0; version<MAX_VERSION; version++) {
3729 ndrivers=get_ntdrivers(&list, architecture, version);
3730 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3733 return ERROR_NOT_ENOUGH_MEMORY;
3736 if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
3738 return ERROR_NOT_ENOUGH_MEMORY;
3742 for (i=0; i<ndrivers; i++) {
3743 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3744 ZERO_STRUCT(driver);
3745 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3746 fill_printer_driver_info_2(&(driver_info_2[*returned+i]), driver, servername);
3749 *returned+=ndrivers;
3753 /* check the required size. */
3754 for (i=0; i<*returned; i++) {
3755 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3756 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
3759 if (!alloc_buffer_size(buffer, *needed)) {
3760 safe_free(driver_info_2);
3761 return ERROR_INSUFFICIENT_BUFFER;
3764 /* fill the buffer with the form structures */
3765 for (i=0; i<*returned; i++) {
3766 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3767 new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
3770 safe_free(driver_info_2);
3772 if (*needed > offered) {
3774 return ERROR_INSUFFICIENT_BUFFER;
3777 return NT_STATUS_NO_PROBLEMO;
3780 /****************************************************************************
3781 Enumerates all printer drivers at level 3.
3782 ****************************************************************************/
3783 static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3788 fstring *list = NULL;
3790 NT_PRINTER_DRIVER_INFO_LEVEL driver;
3791 DRIVER_INFO_3 *driver_info_3=NULL;
3795 #define MAX_VERSION 4
3797 for (version=0; version<MAX_VERSION; version++) {
3799 ndrivers=get_ntdrivers(&list, architecture, version);
3800 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
3803 return ERROR_NOT_ENOUGH_MEMORY;
3806 if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
3808 return ERROR_NOT_ENOUGH_MEMORY;
3812 for (i=0; i<ndrivers; i++) {
3813 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
3814 ZERO_STRUCT(driver);
3815 get_a_printer_driver(&driver, 3, list[i], architecture, version);
3816 fill_printer_driver_info_3(&(driver_info_3[*returned+i]), driver, servername);
3819 *returned+=ndrivers;
3823 /* check the required size. */
3824 for (i=0; i<*returned; i++) {
3825 DEBUGADD(6,("adding driver [%d]'s size\n",i));
3826 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
3829 if (!alloc_buffer_size(buffer, *needed)) {
3830 safe_free(driver_info_3);
3831 return ERROR_INSUFFICIENT_BUFFER;
3834 /* fill the buffer with the driver structures */
3835 for (i=0; i<*returned; i++) {
3836 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
3837 new_smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
3840 for (i=0; i<*returned; i++)
3841 safe_free(driver_info_3[i].dependentfiles);
3843 safe_free(driver_info_3);
3845 if (*needed > offered) {
3847 return ERROR_INSUFFICIENT_BUFFER;
3850 return NT_STATUS_NO_PROBLEMO;
3853 /****************************************************************************
3854 Enumerates all printer drivers.
3855 ****************************************************************************/
3856 uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
3857 NEW_BUFFER *buffer, uint32 offered,
3858 uint32 *needed, uint32 *returned)
3860 fstring *list = NULL;
3862 fstring architecture;
3864 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
3865 fstrcpy(servername, global_myname);
3869 unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
3873 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
3876 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
3879 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
3884 return ERROR_INVALID_LEVEL;
3889 /****************************************************************************
3890 ****************************************************************************/
3891 static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
3893 form->flag=list->flag;
3894 init_unistr(&form->name, list->name);
3895 form->width=list->width;
3896 form->length=list->length;
3897 form->left=list->left;
3898 form->top=list->top;
3899 form->right=list->right;
3900 form->bottom=list->bottom;
3903 /****************************************************************************
3904 ****************************************************************************/
3905 uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
3906 NEW_BUFFER *buffer, uint32 offered,
3907 uint32 *needed, uint32 *numofforms)
3909 nt_forms_struct *list=NULL;
3914 DEBUG(4,("_new_spoolss_enumforms\n"));
3915 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
3916 DEBUGADD(5,("Info level [%d]\n", level));
3918 *numofforms = get_ntforms(&list);
3919 DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
3921 if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
3925 if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
3927 return ERROR_NOT_ENOUGH_MEMORY;
3930 /* construct the list of form structures */
3931 for (i=0; i<*numofforms; i++) {
3932 DEBUGADD(6,("Filling form number [%d]\n",i));
3933 fill_form_1(&forms_1[i], &list[i], i);
3938 /* check the required size. */
3939 for (i=0; i<*numofforms; i++) {
3940 DEBUGADD(6,("adding form [%d]'s size\n",i));
3941 buffer_size += spoolss_size_form_1(&forms_1[i]);
3944 *needed=buffer_size;
3946 if (!alloc_buffer_size(buffer, buffer_size)){
3948 return ERROR_INSUFFICIENT_BUFFER;
3951 /* fill the buffer with the form structures */
3952 for (i=0; i<*numofforms; i++) {
3953 DEBUGADD(6,("adding form [%d] to buffer\n",i));
3954 new_smb_io_form_1("", buffer, &forms_1[i], 0);
3959 if (*needed > offered) {
3961 return ERROR_INSUFFICIENT_BUFFER;
3964 return NT_STATUS_NO_PROBLEMO;
3968 return ERROR_INVALID_LEVEL;
3973 /****************************************************************************
3974 ****************************************************************************/
3975 static void fill_port_1(PORT_INFO_1 *port, char *name)
3977 init_unistr(&port->port_name, name);
3980 /****************************************************************************
3981 ****************************************************************************/
3982 static void fill_port_2(PORT_INFO_2 *port, char *name)
3984 init_unistr(&port->port_name, name);
3985 init_unistr(&port->monitor_name, "Local Monitor");
3986 init_unistr(&port->description, "Local Port");
3987 #define PORT_TYPE_WRITE 1
3988 port->port_type=PORT_TYPE_WRITE;
3992 /****************************************************************************
3994 ****************************************************************************/
3995 static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
3997 PORT_INFO_1 *ports=NULL;
4000 if (*lp_enumports_cmd()) {
4001 pid_t local_pid = sys_getpid();
4002 char *cmd = lp_enumports_cmd();
4010 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4011 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4015 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4016 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 1);
4019 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4020 ret = smbrun(command, tmp_file, False);
4021 DEBUG(10,("Returned [%d]\n", ret));
4024 // Is this the best error to return here?
4025 return ERROR_ACCESS_DENIED;
4029 qlines = file_lines_load(tmp_file, &numlines);
4030 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4031 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4035 if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
4036 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4037 file_lines_free(qlines);
4038 return ERROR_NOT_ENOUGH_MEMORY;
4041 for (i=0; i<numlines; i++) {
4042 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4043 fill_port_1(&ports[i], qlines[i]);
4046 file_lines_free(qlines);
4049 *returned = numlines;
4052 *returned = 1; /* Sole Samba port returned. */
4054 if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
4055 return ERROR_NOT_ENOUGH_MEMORY;
4057 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4059 fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
4062 /* check the required size. */
4063 for (i=0; i<*returned; i++) {
4064 DEBUGADD(6,("adding port [%d]'s size\n", i));
4065 *needed += spoolss_size_port_info_1(&ports[i]);
4068 if (!alloc_buffer_size(buffer, *needed)) {
4070 return ERROR_INSUFFICIENT_BUFFER;
4073 /* fill the buffer with the ports structures */
4074 for (i=0; i<*returned; i++) {
4075 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4076 new_smb_io_port_1("", buffer, &ports[i], 0);
4081 if (*needed > offered) {
4083 return ERROR_INSUFFICIENT_BUFFER;
4086 return NT_STATUS_NO_PROBLEMO;
4089 /****************************************************************************
4091 ****************************************************************************/
4093 static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4095 PORT_INFO_2 *ports=NULL;
4098 if (*lp_enumports_cmd()) {
4099 pid_t local_pid = sys_getpid();
4100 char *cmd = lp_enumports_cmd();
4108 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
4109 path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
4113 slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
4114 slprintf(command, sizeof(command), "%s \"%d\"", cmd, 2);
4117 DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
4118 ret = smbrun(command, tmp_file, False);
4119 DEBUGADD(10,("returned [%d]\n", ret));
4122 // Is this the best error to return here?
4123 return ERROR_ACCESS_DENIED;
4127 qlines = file_lines_load(tmp_file, &numlines);
4128 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
4129 DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
4133 if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
4134 DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
4135 file_lines_free(qlines);
4136 return ERROR_NOT_ENOUGH_MEMORY;
4139 for (i=0; i<numlines; i++) {
4140 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
4141 fill_port_2(&(ports[i]), qlines[i]);
4144 file_lines_free(qlines);
4147 *returned = numlines;
4153 if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
4154 return ERROR_NOT_ENOUGH_MEMORY;
4156 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
4158 fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
4161 /* check the required size. */
4162 for (i=0; i<*returned; i++) {
4163 DEBUGADD(6,("adding port [%d]'s size\n", i));
4164 *needed += spoolss_size_port_info_2(&ports[i]);
4167 if (!alloc_buffer_size(buffer, *needed)) {
4169 return ERROR_INSUFFICIENT_BUFFER;
4172 /* fill the buffer with the ports structures */
4173 for (i=0; i<*returned; i++) {
4174 DEBUGADD(6,("adding port [%d] to buffer\n", i));
4175 new_smb_io_port_2("", buffer, &ports[i], 0);
4180 if (*needed > offered) {
4182 return ERROR_INSUFFICIENT_BUFFER;
4185 return NT_STATUS_NO_PROBLEMO;
4188 /****************************************************************************
4190 ****************************************************************************/
4191 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
4192 NEW_BUFFER *buffer, uint32 offered,
4193 uint32 *needed, uint32 *returned)
4195 DEBUG(4,("_spoolss_enumports\n"));
4202 return enumports_level_1(buffer, offered, needed, returned);
4205 return enumports_level_2(buffer, offered, needed, returned);
4208 return ERROR_INVALID_LEVEL;
4213 /****************************************************************************
4214 ****************************************************************************/
4215 static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
4216 const SPOOL_PRINTER_INFO_LEVEL *info,
4217 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4218 uint32 user_switch, const SPOOL_USER_CTR *user,
4221 NT_PRINTER_INFO_LEVEL *printer = NULL;
4225 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
4226 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
4227 return ERROR_NOT_ENOUGH_MEMORY;
4230 ZERO_STRUCTP(printer);
4232 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
4233 convert_printer_info(info, printer, 2);
4235 if (*lp_addprinter_cmd() )
4236 if ( !add_printer_hook(printer) )
4237 return ERROR_ACCESS_DENIED;
4239 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
4240 printer->info_2->sharename);
4242 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
4243 free_a_printer(&printer,2);
4244 return ERROR_ACCESS_DENIED;
4247 /* you must be a printer admin to add a new printer */
4248 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4249 free_a_printer(&printer,2);
4250 return ERROR_ACCESS_DENIED;
4254 * Do sanity check on the requested changes for Samba.
4257 if (!check_printer_ok(printer->info_2, snum)) {
4258 free_a_printer(&printer,2);
4259 return ERROR_INVALID_PARAMETER;
4262 /* write the ASCII on disk */
4263 if (add_a_printer(*printer, 2) != 0) {
4264 free_a_printer(&printer,2);
4265 return ERROR_ACCESS_DENIED;
4268 if (!open_printer_hnd(handle, name)) {
4269 /* Handle open failed - remove addition. */
4270 del_a_printer(printer->info_2->sharename);
4271 free_a_printer(&printer,2);
4272 return ERROR_ACCESS_DENIED;
4275 free_a_printer(&printer,2);
4276 return NT_STATUS_NO_PROBLEMO;
4279 /****************************************************************************
4280 ****************************************************************************/
4281 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
4282 const SPOOL_PRINTER_INFO_LEVEL *info,
4283 uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
4284 uint32 user_switch, const SPOOL_USER_CTR *user,
4289 /* we don't handle yet */
4290 /* but I know what to do ... */
4291 return ERROR_INVALID_LEVEL;
4294 return spoolss_addprinterex_level_2(uni_srv_name, info,
4295 unk0, unk1, unk2, unk3,
4296 user_switch, user, handle);
4299 return ERROR_INVALID_LEVEL;
4304 /****************************************************************************
4305 ****************************************************************************/
4306 uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
4307 uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
4309 uint32 err = NT_STATUS_NO_PROBLEMO;
4310 NT_PRINTER_DRIVER_INFO_LEVEL driver;
4311 struct current_user user;
4313 ZERO_STRUCT(driver);
4315 if (p->ntlmssp_auth_validated) {
4316 memcpy(&user, &p->pipe_user, sizeof(user));
4318 extern struct current_user current_user;
4319 memcpy(&user, ¤t_user, sizeof(user));
4322 convert_printer_driver_info(info, &driver, level);
4324 DEBUG(5,("Cleaning driver's information\n"));
4325 clean_up_driver_struct(driver, level);
4327 DEBUG(5,("Moving driver to final destination\n"));
4328 if(!move_driver_to_download_area(driver, level, &user, &err)) {
4330 err = ERROR_ACCESS_DENIED;
4334 if (add_a_printer_driver(driver, level)!=0) {
4335 err = ERROR_ACCESS_DENIED;
4340 free_a_printer_driver(driver, level);
4344 /****************************************************************************
4345 ****************************************************************************/
4346 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
4348 init_unistr(&info->name, name);
4351 /****************************************************************************
4352 ****************************************************************************/
4353 static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4357 pstring short_archi;
4358 DRIVER_DIRECTORY_1 *info=NULL;
4360 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
4362 if (get_short_archi(short_archi, long_archi)==FALSE)
4363 return ERROR_INVALID_ENVIRONMENT;
4365 if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
4366 return ERROR_NOT_ENOUGH_MEMORY;
4368 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
4370 DEBUG(4,("printer driver directory: [%s]\n", path));
4372 fill_driverdir_1(info, path);
4374 *needed += spoolss_size_driverdir_info_1(info);
4376 if (!alloc_buffer_size(buffer, *needed)) {
4378 return ERROR_INSUFFICIENT_BUFFER;
4381 new_smb_io_driverdir_1("", buffer, info, 0);
4385 if (*needed > offered)
4386 return ERROR_INSUFFICIENT_BUFFER;
4388 return NT_STATUS_NO_PROBLEMO;
4391 /****************************************************************************
4392 ****************************************************************************/
4393 uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
4394 NEW_BUFFER *buffer, uint32 offered,
4397 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
4403 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
4406 return ERROR_INVALID_LEVEL;
4411 /****************************************************************************
4412 ****************************************************************************/
4413 uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
4414 uint32 in_value_len, uint32 in_data_len,
4415 uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
4417 uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len)
4419 NT_PRINTER_INFO_LEVEL *printer = NULL;
4424 uint32 biggest_valuesize;
4425 uint32 biggest_datasize;
4427 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4432 ZERO_STRUCT(printer);
4434 *out_max_value_len=0;
4440 *out_max_data_len=0;
4444 DEBUG(5,("spoolss_enumprinterdata\n"));
4446 if (!OPEN_HANDLE(Printer)) {
4447 DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4448 return ERROR_INVALID_HANDLE;
4451 if (!get_printer_snum(handle, &snum))
4452 return ERROR_INVALID_HANDLE;
4454 if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
4455 return ERROR_INVALID_HANDLE;
4458 * The NT machine wants to know the biggest size of value and data
4460 * cf: MSDN EnumPrinterData remark section
4462 if ( (in_value_len==0) && (in_data_len==0) ) {
4463 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
4466 biggest_valuesize=0;
4469 while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
4470 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
4471 if (data_len > biggest_datasize) biggest_datasize=data_len;
4473 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
4479 /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
4480 *out_value_len=2*(1+biggest_valuesize);
4481 *out_data_len=biggest_datasize;
4483 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
4485 free_a_printer(&printer, 2);
4486 return NT_STATUS_NO_PROBLEMO;
4490 * the value len is wrong in NT sp3
4491 * that's the number of bytes not the number of unicode chars
4494 if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
4496 free_a_printer(&printer, 2);
4497 return ERROR_NO_MORE_ITEMS;
4500 free_a_printer(&printer, 2);
4504 * - counted in bytes in the request
4505 * - counted in UNICODE chars in the max reply
4506 * - counted in bytes in the real size
4508 * take a pause *before* coding not *during* coding
4511 *out_max_value_len=(in_value_len/sizeof(uint16));
4512 if((*out_value=(uint16 *)malloc(in_value_len*sizeof(uint8))) == NULL) {
4514 return ERROR_NOT_ENOUGH_MEMORY;
4517 ZERO_STRUCTP(*out_value);
4518 *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
4522 /* the data is counted in bytes */
4523 *out_max_data_len=in_data_len;
4524 if((*data_out=(uint8 *)malloc(in_data_len*sizeof(uint8))) == NULL) {
4526 return ERROR_NOT_ENOUGH_MEMORY;
4529 ZERO_STRUCTP(*data_out);
4530 memcpy(*data_out, data, (size_t)data_len);
4531 *out_data_len=data_len;
4535 return NT_STATUS_NO_PROBLEMO;
4538 /****************************************************************************
4539 ****************************************************************************/
4540 uint32 _spoolss_setprinterdata( POLICY_HND *handle,
4541 const UNISTR2 *value,
4546 uint32 numeric_data)
4548 NT_PRINTER_INFO_LEVEL *printer = NULL;
4549 NT_PRINTER_PARAM *param = NULL;
4551 uint32 status = 0x0;
4552 Printer_entry *Printer=find_printer_index_by_hnd(handle);
4554 DEBUG(5,("spoolss_setprinterdata\n"));
4557 if (!OPEN_HANDLE(Printer)) {
4558 DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4559 return ERROR_INVALID_HANDLE;
4562 if (!get_printer_snum(handle, &snum))
4563 return ERROR_INVALID_HANDLE;
4565 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4566 DEBUG(3, ("security descriptor change denied by existing "
4567 "security descriptor\n"));
4568 return ERROR_ACCESS_DENIED;
4571 status = get_a_printer(&printer, 2, lp_servicename(snum));
4573 return ERROR_INVALID_NAME;
4575 convert_specific_param(¶m, value , type, data, real_len);
4576 unlink_specific_param_if_exist(printer->info_2, param);
4578 if (!add_a_specific_param(printer->info_2, param))
4579 status = ERROR_INVALID_PARAMETER;
4581 status = add_a_printer(*printer, 2);
4583 free_a_printer(&printer, 2);
4587 /****************************************************************************
4588 ****************************************************************************/
4589 uint32 _spoolss_addform( POLICY_HND *handle,
4594 nt_forms_struct *list=NULL;
4595 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4597 DEBUG(5,("spoolss_addform\n"));
4599 if (!OPEN_HANDLE(Printer)) {
4600 DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4601 return ERROR_INVALID_HANDLE;
4604 count=get_ntforms(&list);
4605 if(!add_a_form(&list, form, &count))
4606 return ERROR_NOT_ENOUGH_MEMORY;
4607 write_ntforms(&list, count);
4614 /****************************************************************************
4615 ****************************************************************************/
4616 uint32 _spoolss_deleteform( POLICY_HND *handle, UNISTR2 *form_name)
4620 nt_forms_struct *list=NULL;
4621 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4623 DEBUG(5,("spoolss_deleteform\n"));
4625 if (!OPEN_HANDLE(Printer)) {
4626 DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4627 return ERROR_INVALID_HANDLE;
4630 count = get_ntforms(&list);
4631 if(!delete_a_form(&list, form_name, &count, &ret))
4632 return ERROR_INVALID_PARAMETER;
4639 /****************************************************************************
4640 ****************************************************************************/
4641 uint32 _spoolss_setform( POLICY_HND *handle,
4642 const UNISTR2 *uni_name,
4647 nt_forms_struct *list=NULL;
4648 Printer_entry *Printer = find_printer_index_by_hnd(handle);
4650 DEBUG(5,("spoolss_setform\n"));
4652 if (!OPEN_HANDLE(Printer)) {
4653 DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
4654 return ERROR_INVALID_HANDLE;
4656 count=get_ntforms(&list);
4657 update_a_form(&list, form, count);
4658 write_ntforms(&list, count);
4665 /****************************************************************************
4666 enumprintprocessors level 1.
4667 ****************************************************************************/
4668 static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4670 PRINTPROCESSOR_1 *info_1=NULL;
4672 if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
4673 return ERROR_NOT_ENOUGH_MEMORY;
4677 init_unistr(&info_1->name, "winprint");
4679 *needed += spoolss_size_printprocessor_info_1(info_1);
4681 if (!alloc_buffer_size(buffer, *needed))
4682 return ERROR_INSUFFICIENT_BUFFER;
4684 smb_io_printprocessor_info_1("", buffer, info_1, 0);
4688 if (*needed > offered) {
4690 return ERROR_INSUFFICIENT_BUFFER;
4693 return NT_STATUS_NO_PROBLEMO;
4696 /****************************************************************************
4697 ****************************************************************************/
4698 uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
4699 NEW_BUFFER *buffer, uint32 offered,
4700 uint32 *needed, uint32 *returned)
4702 DEBUG(5,("spoolss_enumprintprocessors\n"));
4705 * Enumerate the print processors ...
4707 * Just reply with "winprint", to keep NT happy
4708 * and I can use my nice printer checker.
4716 return enumprintprocessors_level_1(buffer, offered, needed, returned);
4719 return ERROR_INVALID_LEVEL;
4724 /****************************************************************************
4725 enumprintprocdatatypes level 1.
4726 ****************************************************************************/
4727 static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4729 PRINTPROCDATATYPE_1 *info_1=NULL;
4731 if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
4732 return ERROR_NOT_ENOUGH_MEMORY;
4736 init_unistr(&info_1->name, "RAW");
4738 *needed += spoolss_size_printprocdatatype_info_1(info_1);
4740 if (!alloc_buffer_size(buffer, *needed))
4741 return ERROR_INSUFFICIENT_BUFFER;
4743 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
4747 if (*needed > offered) {
4749 return ERROR_INSUFFICIENT_BUFFER;
4752 return NT_STATUS_NO_PROBLEMO;
4755 /****************************************************************************
4756 ****************************************************************************/
4757 uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
4758 NEW_BUFFER *buffer, uint32 offered,
4759 uint32 *needed, uint32 *returned)
4761 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
4768 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
4771 return ERROR_INVALID_LEVEL;
4776 /****************************************************************************
4777 enumprintmonitors level 1.
4778 ****************************************************************************/
4779 static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4781 PRINTMONITOR_1 *info_1=NULL;
4783 if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
4784 return ERROR_NOT_ENOUGH_MEMORY;
4788 init_unistr(&info_1->name, "Local Port");
4790 *needed += spoolss_size_printmonitor_info_1(info_1);
4792 if (!alloc_buffer_size(buffer, *needed))
4793 return ERROR_INSUFFICIENT_BUFFER;
4795 smb_io_printmonitor_info_1("", buffer, info_1, 0);
4799 if (*needed > offered) {
4801 return ERROR_INSUFFICIENT_BUFFER;
4804 return NT_STATUS_NO_PROBLEMO;
4807 /****************************************************************************
4808 enumprintmonitors level 2.
4809 ****************************************************************************/
4810 static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4812 PRINTMONITOR_2 *info_2=NULL;
4814 if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
4815 return ERROR_NOT_ENOUGH_MEMORY;
4819 init_unistr(&info_2->name, "Local Port");
4820 init_unistr(&info_2->environment, "Windows NT X86");
4821 init_unistr(&info_2->dll_name, "localmon.dll");
4823 *needed += spoolss_size_printmonitor_info_2(info_2);
4825 if (!alloc_buffer_size(buffer, *needed))
4826 return ERROR_INSUFFICIENT_BUFFER;
4828 smb_io_printmonitor_info_2("", buffer, info_2, 0);
4832 if (*needed > offered) {
4834 return ERROR_INSUFFICIENT_BUFFER;
4837 return NT_STATUS_NO_PROBLEMO;
4840 /****************************************************************************
4841 ****************************************************************************/
4842 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
4843 NEW_BUFFER *buffer, uint32 offered,
4844 uint32 *needed, uint32 *returned)
4846 DEBUG(5,("spoolss_enumprintmonitors\n"));
4849 * Enumerate the print monitors ...
4851 * Just reply with "Local Port", to keep NT happy
4852 * and I can use my nice printer checker.
4860 return enumprintmonitors_level_1(buffer, offered, needed, returned);
4863 return enumprintmonitors_level_2(buffer, offered, needed, returned);
4866 return ERROR_INVALID_LEVEL;
4871 /****************************************************************************
4872 ****************************************************************************/
4873 static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4877 JOB_INFO_1 *info_1=NULL;
4879 info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
4881 if (info_1 == NULL) {
4883 return ERROR_NOT_ENOUGH_MEMORY;
4886 for (i=0; i<count && found==False; i++) {
4887 if (queue[i].job==(int)jobid)
4894 /* I shoud reply something else ... I can't find the good one */
4895 return NT_STATUS_NO_PROBLEMO;
4898 fill_job_info_1(info_1, &(queue[i-1]), i, snum);
4902 *needed += spoolss_size_job_info_1(info_1);
4904 if (!alloc_buffer_size(buffer, *needed)) {
4906 return ERROR_INSUFFICIENT_BUFFER;
4909 new_smb_io_job_info_1("", buffer, info_1, 0);
4913 if (*needed > offered)
4914 return ERROR_INSUFFICIENT_BUFFER;
4916 return NT_STATUS_NO_PROBLEMO;
4920 /****************************************************************************
4921 ****************************************************************************/
4922 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
4927 info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
4929 ZERO_STRUCTP(info_2);
4931 if (info_2 == NULL) {
4933 return ERROR_NOT_ENOUGH_MEMORY;
4936 for (i=0; i<count && found==False; i++) {
4937 if (queue[i].job==(int)jobid)
4944 /* I shoud reply something else ... I can't find the good one */
4945 return NT_STATUS_NO_PROBLEMO;
4948 fill_job_info_2(info_2, &(queue[i-1]), i, snum);
4952 *needed += spoolss_size_job_info_2(info_2);
4954 if (!alloc_buffer_size(buffer, *needed)) {
4956 return ERROR_INSUFFICIENT_BUFFER;
4959 new_smb_io_job_info_2("", buffer, info_2, 0);
4961 free_dev_mode(info_2->devmode);
4964 if (*needed > offered)
4965 return ERROR_INSUFFICIENT_BUFFER;
4967 return NT_STATUS_NO_PROBLEMO;
4970 /****************************************************************************
4971 ****************************************************************************/
4972 uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
4973 NEW_BUFFER *buffer, uint32 offered,
4978 print_queue_struct *queue=NULL;
4979 print_status_struct prt_status;
4981 DEBUG(5,("spoolss_getjob\n"));
4983 memset(&prt_status, 0, sizeof(prt_status));
4987 if (!get_printer_snum(handle, &snum))
4988 return ERROR_INVALID_HANDLE;
4990 count = print_queue_status(snum, &queue, &prt_status);
4992 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
4993 count, prt_status.status, prt_status.message));
4997 return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
5000 return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
5004 return ERROR_INVALID_LEVEL;