a3760587cdee4ede2c05f92abfd8623015a09c15
[tprouty/samba.git] / source / rpc_server / srv_spoolss.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1998,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
7  *  Copyright (C) Jean François Micouleau      1998-1999.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24
25 #include "includes.h"
26 #include "nterr.h"
27
28 extern int DEBUGLEVEL;
29 extern pstring global_myname;
30
31 #ifndef MAX_OPEN_PRINTER_EXS
32 #define MAX_OPEN_PRINTER_EXS 50
33 #endif
34
35 #define PRINTER_HANDLE_IS_PRINTER       0
36 #define PRINTER_HANDLE_IS_PRINTSERVER   1
37
38
39 /* structure to store the printer handles */
40 /* and a reference to what it's pointing to */
41 /* and the notify info asked about */
42 /* that's the central struct */
43 static struct
44 {
45   BOOL        open;
46   BOOL        document_started;
47   BOOL        page_started;
48   uint32      current_jobid;
49   uint32      document_fd;
50   uint32      document_lastwritten;
51   pstring     document_name;
52   pstring     job_name;
53   POLICY_HND printer_hnd;
54   BOOL        printer_type;
55   union
56   {
57         fstring printername;
58         fstring printerservername;
59   } dev;
60   uint32 type;
61   uint32 access;
62   uint32 number_of_notify;
63   SPOOL_NOTIFY_OPTION_TYPE notify_info[MAX_PRINTER_NOTIFY+MAX_JOB_NOTIFY];
64 } Printer[MAX_OPEN_PRINTER_EXS];
65
66 #define VALID_HANDLE(pnum)   (((pnum) >= 0) && ((pnum) < MAX_OPEN_PRINTER_EXS))
67 #define OPEN_HANDLE(pnum)    (VALID_HANDLE(pnum) && Printer[pnum].open)
68
69 /****************************************************************************
70   initialise printer handle states...
71 ****************************************************************************/
72 void init_printer_hnd(void)
73 {
74         int i;
75         for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++)
76         {
77                 Printer[i].open = False;
78         }
79 }
80
81
82 /****************************************************************************
83   create a unique printer handle
84 ****************************************************************************/
85 static void create_printer_hnd(POLICY_HND *hnd)
86 {
87         static uint32 prt_hnd_low  = 0;
88         static uint32 prt_hnd_high = 0;
89
90         if (hnd == NULL) return;
91
92         /* i severely doubt that prt_hnd_high will ever be non-zero... */
93         prt_hnd_low++;
94         if (prt_hnd_low == 0) prt_hnd_high++;
95
96         SIVAL(hnd->data, 0 , 0x0);          /* first bit must be null */
97         SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
98         SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
99         SIVAL(hnd->data, 12, time(NULL));   /* something random */
100         SIVAL(hnd->data, 16, getpid());     /* something more random */
101 }
102
103 /****************************************************************************
104   clear an handle
105 ****************************************************************************/
106 static void clear_handle(POLICY_HND *hnd)
107 {
108         bzero(hnd->data, POLICY_HND_SIZE);
109 }
110
111 /****************************************************************************
112   find first available printer slot.  creates a printer handle for you.
113  ****************************************************************************/
114 static BOOL open_printer_hnd(POLICY_HND *hnd)
115 {
116         int i;
117
118         for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++)
119         {
120                 if (!Printer[i].open)
121                 {
122                         Printer[i].open = True;                         
123                         create_printer_hnd(hnd);
124                         memcpy(&(Printer[i].printer_hnd), hnd, sizeof(*hnd));
125
126                         DEBUG(4,("Opened printer handle[%x] ", i));
127                         dump_data(4, hnd->data, sizeof(hnd->data));
128                         return True;
129                 }
130         }
131         DEBUG(1,("ERROR - open_printer_hnd: out of Printers Handles!\n"));
132         return False;
133 }
134
135 /****************************************************************************
136   find printer index by handle
137 ****************************************************************************/
138 static int find_printer_index_by_hnd(POLICY_HND *hnd)
139 {
140         int i;
141
142         for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++)
143         {
144                 if (memcmp(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)) == 0)
145                 {
146                         DEBUG(4,("Found printer handle[%x] ", i));
147                         dump_data(4, hnd->data, sizeof(hnd->data));
148                         return i;
149                 }
150         }
151         DEBUG(3,("Whoops, Printer handle not found: "));
152         dump_data(4, hnd->data, sizeof(hnd->data));
153         return -1;
154 }
155
156 /****************************************************************************
157   set printer handle type.
158 ****************************************************************************/
159 static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required)
160 {
161         int pnum = find_printer_index_by_hnd(hnd);
162
163         if (OPEN_HANDLE(pnum))
164         {
165                 DEBUG(4,("Setting printer access=%x (pnum=%x)\n",
166                           access_required, pnum));
167
168
169
170                 Printer[pnum].access = access_required;
171                 return True;            
172         }
173         else
174         {
175                 DEBUG(4,("Error setting printer type=%x (pnum=%x)",
176                           access_required, pnum));
177                 return False;
178         }
179         return False;
180 }
181
182 /****************************************************************************
183   set printer handle type.
184 ****************************************************************************/
185 static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername)
186 {
187         int pnum = find_printer_index_by_hnd(hnd);
188                 
189         if (OPEN_HANDLE(pnum))
190         {
191                 DEBUG(3,("Setting printer type=%s (pnum=%x)\n", printername, pnum));
192
193                 if ( strlen(printername) < 3 )
194                 {
195                         DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername));
196                         return False;
197                 }
198
199                 /* check if it's \\server or \\server\printer */                
200                 /* +2 is to skip the leading \\ */
201                 if (!strchr(printername+2, '\\'))
202                 {
203                         /* it's a print server */
204                         DEBUGADD(4,("Printer is a print server\n"));
205                         Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
206                         return True;
207                 }
208                 else
209                 {
210                         /* it's a printer */
211                         DEBUGADD(4,("Printer is a printer\n"));
212                         Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTER;
213                         return True;
214                 }       
215         }
216         else
217         {
218                 DEBUGADD(4,("Error setting printer name %s (pnum=%x)",
219                           printername, pnum));
220                 return False;
221         }
222         return False;
223 }
224
225 /****************************************************************************
226   set printer handle printername.
227 ****************************************************************************/
228 static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername)
229 {
230         int pnum = find_printer_index_by_hnd(hnd);
231         char *back;
232         NT_PRINTER_INFO_LEVEL printer;
233         int snum;
234         int n_services=lp_numservices();
235         uint32 marche;
236         
237         if (OPEN_HANDLE(pnum))
238         {
239                 DEBUG(4,("Setting printer name=%s (len=%d) (pnum=%x)\n",
240                           printername,strlen(printername), pnum));
241                           
242                 switch (Printer[pnum].printer_type)
243                  {
244                    case PRINTER_HANDLE_IS_PRINTER:
245                         back=strchr(printername+2, '\\');
246                         back=back+1;
247                         DEBUGADD(5,("searching for %s (len=%d)\n", back,strlen(back)));
248                         /* 
249                          * store the Samba share name in it
250                          * in back we have the long printer name
251                          * need to iterate all the snum and do a 
252                          * get_a_printer each time to find the printer
253                          * faster to do it here than later.
254                          */
255                         for (snum=0;snum<n_services; snum++)
256                         {
257                                 if (lp_browseable(snum) && 
258                                     lp_snum_ok(snum) && 
259                                     lp_print_ok(snum) )
260                                 {
261                                         DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
262                                         
263                                         marche=get_a_printer(&printer, 2, lp_servicename(snum));
264                                         DEBUGADD(6,("marche:%d\n",marche));
265                                                                                 
266                                         if ( marche==0 && ( strlen(printer.info_2->printername) == strlen(back) ) 
267                                              && ( !strncasecmp(printer.info_2->printername, back, strlen(back))) 
268                                            )
269                                         {
270                                                 DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
271                                                 ZERO_STRUCT(Printer[pnum].dev.printername);
272                                                 strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum)));
273                                                 free_a_printer(printer, 2);
274                                                 return True;
275                                                 break;  
276                                         }
277                                         free_a_printer(printer, 2);
278                                 }
279                         }
280
281                         return False;
282                         break;          
283                    case PRINTER_HANDLE_IS_PRINTSERVER:
284                         ZERO_STRUCT(Printer[pnum].dev.printerservername);
285                         strncpy(Printer[pnum].dev.printerservername, printername, strlen(printername));
286                         return True;
287                         break;
288                    default:
289                         return False;
290                         break;
291                  }
292         }
293         else
294         {
295                 DEBUG(0,("Error setting printer name=%s (pnum=%x)\n",
296                          printername , pnum));
297                 return False;
298         }
299 }
300
301 /****************************************************************************
302   return the snum of a printer corresponding to an handle
303 ****************************************************************************/
304 static BOOL get_printer_snum(POLICY_HND *hnd, int *number)
305 {
306         int snum;
307         int pnum = find_printer_index_by_hnd(hnd);
308         int n_services=lp_numservices();
309                 
310         if (OPEN_HANDLE(pnum))
311         {
312                 switch (Printer[pnum].printer_type)
313                  {
314                    case PRINTER_HANDLE_IS_PRINTER:                 
315                         DEBUG(4,("short name:%s\n", Printer[pnum].dev.printername));                    
316                         for (snum=0;snum<n_services; snum++)
317                         {
318                                 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
319                                 {
320                                         DEBUG(4,("share:%s\n",lp_servicename(snum)));
321                                         if (   ( strlen(lp_servicename(snum)) == strlen( Printer[pnum].dev.printername ) ) 
322                                             && ( !strncasecmp(lp_servicename(snum), 
323                                                               Printer[pnum].dev.printername,
324                                                               strlen( lp_servicename(snum) ))) 
325                                            )
326                                         {
327                                                 DEBUG(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
328                                                 *number=snum;
329                                                 return True;
330                                                 break;  
331                                         }
332                                 }
333                         }
334                         return False;
335                         break;          
336                    case PRINTER_HANDLE_IS_PRINTSERVER:
337                         return False;
338                         break;
339                    default:
340                         return False;
341                         break;
342                  }
343         }
344         else
345         {
346                 DEBUG(3,("Error getting printer - take a nap quickly !\n"));
347                 return False;
348         }
349 }
350
351 /********************************************************************
352  ********************************************************************/
353 static BOOL handle_is_printserver(POLICY_HND *handle)
354 {
355         int pnum=find_printer_index_by_hnd(handle);
356
357         if (OPEN_HANDLE(pnum))
358         {
359                 switch (Printer[pnum].printer_type)
360                 {
361                 case PRINTER_HANDLE_IS_PRINTSERVER:
362                         return True;
363                         break;
364                 case PRINTER_HANDLE_IS_PRINTER:
365                         return False;
366                         break;
367                 }               
368         }
369         return False;
370 }
371
372 /********************************************************************
373  ********************************************************************/
374 /*
375 static BOOL handle_is_printer(POLICY_HND *handle)
376 {
377         return (!handle_is_printserver(handle));
378 }
379 */
380
381 /********************************************************************
382  * api_spoolss_open_printer
383  *
384  * called from the spoolss dispatcher
385  ********************************************************************/
386 static void spoolss_reply_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *rdata)                                
387 {
388         SPOOL_R_OPEN_PRINTER_EX r_u;
389         BOOL printer_open = False;
390         fstring name;
391         
392         /* some sanity check because you can open a printer or a print server */
393         /* aka: \\server\printer or \\server */
394         unistr2_to_ascii(name, &(q_u->printername), sizeof(name)-1);
395
396         DEBUGADD(3,("checking name: %s\n",name));
397
398         /* now the response */
399         r_u.status=0x00000000;
400         
401         printer_open = open_printer_hnd(&(r_u.handle));
402         set_printer_hnd_printertype(&(r_u.handle), name);
403         
404         if ( !set_printer_hnd_printername(&(r_u.handle), name) )
405         {
406                 r_u.status=0xC0000000|NT_STATUS_ACCESS_DENIED;
407         }
408         
409         set_printer_hnd_accesstype(&(r_u.handle), q_u->access_required);
410
411
412         /* if there is a error free the printer entry */
413         
414         if (r_u.status != 0x00000000)
415         {
416                 int pnum;
417
418                 pnum = find_printer_index_by_hnd(&(r_u.handle));
419                 Printer[pnum].open=False;
420                 clear_handle(&(r_u.handle));
421         }       
422
423         spoolss_io_r_open_printer_ex("",&r_u,rdata,0);
424 }
425
426 /********************************************************************
427  * api_spoolss_open_printer
428  *
429  * called from the spoolss dispatcher
430  ********************************************************************/
431 static void api_spoolss_open_printer_ex(pipes_struct *p, prs_struct *data, prs_struct *rdata)
432 {
433         SPOOL_Q_OPEN_PRINTER_EX q_u;
434
435         /* grab the spoolss open policy */
436         spoolss_io_q_open_printer_ex("", &q_u, data, 0);
437
438         /* construct reply.  always indicate success */
439         spoolss_reply_open_printer_ex(&q_u, rdata);
440 }
441
442 /********************************************************************
443  ********************************************************************/
444 static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *type, 
445                                           uint32 *numeric_data, uint8 **data, uint32 *needed)
446 {               
447         int i;
448                 
449         if (!strcmp(value, "BeepEnabled"))
450         {
451                 *type          = 0x4;
452                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
453                 ZERO_STRUCTP(*data);
454                 (*data)[0]=0x01;
455                 (*data)[1]=0x00;
456                 (*data)[2]=0x00;
457                 (*data)[3]=0x00;
458                 *numeric_data  = 0x1; /* beep enabled */        
459                 *needed        = 0x4;                   
460                 return True;
461         }
462
463         if (!strcmp(value, "EventLog"))
464         {
465                 *type          = 0x4;
466                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
467                 ZERO_STRUCTP(*data);
468                 (*data)[0]=0x1B;
469                 (*data)[1]=0x00;
470                 (*data)[2]=0x00;
471                 (*data)[3]=0x00;
472                 *numeric_data  = 0x1B; /* Don't know ??? */     
473                 *needed        = 0x4;                   
474                 return True;
475         }
476
477         if (!strcmp(value, "NetPopup"))
478         {
479                 *type          = 0x4;
480                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
481                 ZERO_STRUCTP(*data);
482                 (*data)[0]=0x01;
483                 (*data)[1]=0x00;
484                 (*data)[2]=0x00;
485                 (*data)[3]=0x00;
486                 *numeric_data  = 0x1; /* popup enabled */       
487                 *needed        = 0x4;
488                 return True;
489         }
490
491         if (!strcmp(value, "MajorVersion"))
492         {
493                 *type          = 0x4;
494                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
495                 (*data)[0]=0x02;
496                 (*data)[1]=0x00;
497                 (*data)[2]=0x00;
498                 (*data)[3]=0x00;
499                 *numeric_data  = 0x2; /* it's 2, period. */     
500                 *needed        = 0x4;
501                 return True;
502         }
503
504         if (!strcmp(value, "DefaultSpoolDirectory"))
505         {
506                 pstring directory="You are using a Samba server";
507                 *type = 0x1;                    
508                 *data  = (uint8 *)malloc( size*sizeof(uint8) );
509                 ZERO_STRUCTP(*data);
510                 
511                 /* it's done by hand ready to go on the wire */
512                 for (i=0; i<strlen(directory); i++)
513                 {
514                         (*data)[2*i]=directory[i];
515                         (*data)[2*i+1]='\0';
516                 }                       
517                 *needed = 2*(strlen(directory)+1);
518                 return True;
519         }
520
521         if (!strcmp(value, "Architecture"))
522         {                       
523                 pstring directory="Windows NT x86";
524                 *type = 0x1;                    
525                 *data  = (uint8 *)malloc( size*sizeof(uint8) );
526                 ZERO_STRUCTP(*data);
527                 for (i=0; i<strlen(directory); i++)
528                 {
529                         (*data)[2*i]=directory[i];
530                         (*data)[2*i+1]='\0';
531                 }                       
532                 *needed = 2*(strlen(directory)+1);      
533                 return True;
534         }
535         
536         return False;
537 }
538
539 /********************************************************************
540  ********************************************************************/
541 static BOOL getprinterdata_printer(POLICY_HND *handle, fstring value, uint32 size, uint32 *type, 
542                                           uint32 *numeric_data, uint8 **data, uint32 *needed )
543 {
544         NT_PRINTER_INFO_LEVEL printer;
545         int pnum=0;
546         int snum=0;
547         uint8 *idata=NULL;
548         uint32 len;
549         
550         DEBUG(5,("getprinterdata_printer\n"));
551
552         pnum = find_printer_index_by_hnd(handle);
553         if (OPEN_HANDLE(pnum))
554         {
555                 get_printer_snum(handle, &snum);                
556                 get_a_printer(&printer, 2, lp_servicename(snum));
557                 
558                 if (get_specific_param(printer, 2, value, &idata, type, &len)) 
559                 {
560                         /*switch (*type)
561                         {
562                                 case 1:
563                                 case 3:
564                                 case 4:*/
565                                         *data  = (uint8 *)malloc( size*sizeof(uint8) );
566                                         bzero(*data, sizeof(uint8)*size);
567                                         memcpy(*data, idata, len>size?size:len);
568                                         *needed = len;
569                                         if (idata) free(idata);
570                                         /*break;*/
571                                 /*case 4:
572                                         *numeric_data=atoi(idata);
573                                         break;*/
574                         /*}*/
575                         return (True);
576                 }
577                 free_a_printer(printer, 2);
578         }
579
580         return (False);
581 }       
582
583 /********************************************************************
584  * api_spoolss_reply_getprinterdata
585  *
586  * called from api_spoolss_getprinterdata
587  ********************************************************************/
588 static void spoolss_reply_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *rdata)                                
589 {
590         SPOOL_R_GETPRINTERDATA r_u;
591         fstring value;
592         BOOL found;
593         int pnum = find_printer_index_by_hnd(&(q_u->handle));
594         
595         /* 
596          * Reminder: when it's a string, the length is in BYTES
597          * even if UNICODE is negociated.
598          *
599          * r_u.type is the kind of data
600          * 1 is a string
601          * 4 is a uint32
602          *
603          * I think it's documented in MSDN somewhere in
604          * the registry data type (yep it's linked ...)
605          * 
606          * JFM, 4/19/1999
607          */
608
609         if (OPEN_HANDLE(pnum))
610         {
611                 r_u.size  = q_u->size;
612                 r_u.status = 0x0;
613                 r_u.type   = 0x4;
614                 r_u.needed = 0x0;
615                 r_u.data   = NULL;
616                 r_u.numeric_data=0x0;
617                 
618                 unistr2_to_ascii(value, &(q_u->valuename), sizeof(value)-1);
619                 
620                 if (handle_is_printserver(&(q_u->handle)))
621                 {               
622                         found=getprinterdata_printer_server(value, r_u.size, 
623                                                             &(r_u.type), &(r_u.numeric_data),
624                                                             &(r_u.data), &(r_u.needed));
625                 }
626                 else
627                 {
628                         found=getprinterdata_printer(&(q_u->handle), value, r_u.size, 
629                                                      &(r_u.type), &(r_u.numeric_data),
630                                                      &(r_u.data), &(r_u.needed));
631                 }
632
633                 if (found==False)
634                 {
635                         /* reply this param doesn't exist */
636                         r_u.type   = 0x4;
637                         r_u.size   = 0x0;
638                         r_u.data   = NULL;
639                         r_u.numeric_data=0x0;
640                         r_u.needed = 0x0;
641                         r_u.status = ERROR_INVALID_PARAMETER;
642                 }
643                         
644                 spoolss_io_r_getprinterdata("", &r_u, rdata, 0);
645                 DEBUG(3,("freeing memory\n"));
646                 if (r_u.data) free(r_u.data);
647                 DEBUG(3,("freeing memory:ok\n"));
648         }       
649 }
650
651 /********************************************************************
652  * api_spoolss_getprinterdata
653  *
654  * called from the spoolss dispatcher
655  ********************************************************************/
656 static void api_spoolss_getprinterdata(pipes_struct *p, prs_struct *data, 
657                                         prs_struct *rdata)
658 {
659         SPOOL_Q_GETPRINTERDATA q_u;
660
661         /* read the stream and fill the struct */
662         spoolss_io_q_getprinterdata("", &q_u, data, 0);
663
664         spoolss_reply_getprinterdata(&q_u,rdata);
665 }
666
667 /********************************************************************
668  * api_spoolss_reply_closeprinter
669  *
670  * called from api_spoolss_closeprinter
671  ********************************************************************/
672 static void spoolss_reply_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *rdata)                                
673 {
674         SPOOL_R_CLOSEPRINTER r_u;
675         
676         int pnum = find_printer_index_by_hnd(&(q_u->handle));
677
678         clear_handle(&(r_u.handle));
679
680         if (OPEN_HANDLE(pnum))
681         {
682                 Printer[pnum].open=False;
683                 r_u.status=0x0; 
684         }
685         else
686         {
687                 r_u.status= 0xC0000000 | NT_STATUS_INVALID_HANDLE;      
688                 DEBUG(3,("Error closing printer handle (pnum=%x)\n", pnum));
689         }
690         
691         spoolss_io_r_closeprinter("",&r_u,rdata,0);
692 }
693
694 /********************************************************************
695  * api_spoolss_closeprinter
696  *
697  * called from the spoolss dispatcher
698  ********************************************************************/
699 static void api_spoolss_closeprinter(pipes_struct *p, prs_struct *data, 
700                                       prs_struct *rdata)
701 {
702         SPOOL_Q_CLOSEPRINTER q_u;
703
704         spoolss_io_q_closeprinter("", &q_u, data, 0);
705
706         spoolss_reply_closeprinter(&q_u,rdata);
707 }
708
709 /********************************************************************
710  * api_spoolss_reply_rffpcnex
711  *
712  * called from api_spoolss_rffpcnex (see this to understand)
713  ********************************************************************/
714 static void spoolss_reply_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, prs_struct *rdata)
715 {
716         SPOOL_R_RFFPCNEX r_u;
717         
718         r_u.status = 0x0000;
719
720         spoolss_io_r_rffpcnex("",&r_u,rdata,0);
721 }
722
723 /********************************************************************
724  * api_spoolss_rffpcnex
725  * ReplyFindFirstPrinterChangeNotifyEx
726  * called from the spoolss dispatcher
727  *
728  * jfmxxxx: before replying OK: status=0
729  * should do a rpc call to the workstation asking ReplyOpenPrinter
730  * have to code it, later.
731  *
732  * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
733  ********************************************************************/
734 static void api_spoolss_rffpcnex(pipes_struct *p, prs_struct *data, 
735                                   prs_struct *rdata)
736 {
737         SPOOL_Q_RFFPCNEX q_u;
738         
739         int i,j,k;
740
741         spoolss_io_q_rffpcnex("", &q_u, data, 0);
742
743         /* store the notify value in the printer struct */
744
745         i=find_printer_index_by_hnd(&(q_u.handle));
746
747         Printer[i].number_of_notify=q_u.option.count;
748
749         DEBUG(3,("Copying %x notify option info\n",Printer[i].number_of_notify));
750
751         for (j=0;j<Printer[i].number_of_notify;j++)
752         {
753                 Printer[i].notify_info[j].count=q_u.option.type[j].count;
754                 Printer[i].notify_info[j].type=q_u.option.type[j].type  ;
755                 
756                 DEBUG(4,("Copying %x info fields of type %x\n",
757                          Printer[i].notify_info[j].count,
758                          Printer[i].notify_info[j].type));
759                 for(k=0;k<Printer[i].notify_info[j].count;k++)
760                 {
761                         Printer[i].notify_info[j].fields[k]=q_u.option.type[j].fields[k];
762                 }
763         }
764         spoolss_reply_rffpcnex(&q_u,rdata);
765 }
766
767 /*******************************************************************
768  * fill a notify_info_data with the servername
769  ********************************************************************/
770 static void spoolss_notify_server_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
771 {
772         pstring temp_name;
773
774         snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
775
776         data->notify_data.data.length=strlen(temp_name);
777         ascii_to_unistr(data->notify_data.data.string, temp_name, sizeof(data->notify_data.data.string)-1);
778 }
779
780 /*******************************************************************
781  * fill a notify_info_data with the servicename
782  * jfmxxxx: it's incorrect should be long_printername
783  ********************************************************************/
784 static void spoolss_notify_printer_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
785 {
786 /*
787         data->notify_data.data.length=strlen(lp_servicename(snum));
788         ascii_to_unistr(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string)-1);
789 */
790         data->notify_data.data.length=strlen(printer->info_2->printername);
791         ascii_to_unistr(data->notify_data.data.string, 
792                         printer->info_2->printername, 
793                         sizeof(data->notify_data.data.string)-1);
794 }
795
796 /*******************************************************************
797  * fill a notify_info_data with the servicename
798  ********************************************************************/
799 static void spoolss_notify_share_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
800 {
801         data->notify_data.data.length=strlen(lp_servicename(snum));
802         ascii_to_unistr(data->notify_data.data.string,
803                         lp_servicename(snum), 
804                         sizeof(data->notify_data.data.string)-1);
805 }
806
807 /*******************************************************************
808  * fill a notify_info_data with the port name
809  ********************************************************************/
810 static void spoolss_notify_port_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
811 {
812         /* even if it's strange, that's consistant in all the code */
813
814         data->notify_data.data.length=strlen(lp_servicename(snum));
815         ascii_to_unistr(data->notify_data.data.string,
816                         lp_servicename(snum), 
817                         sizeof(data->notify_data.data.string)-1);
818 }
819
820 /*******************************************************************
821  * fill a notify_info_data with the printername
822  * jfmxxxx: it's incorrect, should be lp_printerdrivername()
823  * but it doesn't exist, have to see what to do
824  ********************************************************************/
825 static void spoolss_notify_driver_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
826 {
827         data->notify_data.data.length=strlen(printer->info_2->drivername);
828         ascii_to_unistr(data->notify_data.data.string, 
829                         printer->info_2->drivername, 
830                         sizeof(data->notify_data.data.string)-1);
831 }
832
833 /*******************************************************************
834  * fill a notify_info_data with the comment
835  ********************************************************************/
836 static void spoolss_notify_comment(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
837 {
838         data->notify_data.data.length=strlen(lp_comment(snum));
839         ascii_to_unistr(data->notify_data.data.string,
840                         lp_comment(snum),
841                         sizeof(data->notify_data.data.string)-1);
842 }
843
844 /*******************************************************************
845  * fill a notify_info_data with the comment
846  * jfm:xxxx incorrect, have to create a new smb.conf option
847  * location = "Room 1, floor 2, building 3"
848  ********************************************************************/
849 static void spoolss_notify_location(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
850 {
851         data->notify_data.data.length=strlen(printer->info_2->location);
852         ascii_to_unistr(data->notify_data.data.string, 
853                         printer->info_2->location, 
854                         sizeof(data->notify_data.data.string)-1);
855 }
856
857 /*******************************************************************
858  * fill a notify_info_data with the device mode
859  * jfm:xxxx don't to it for know but that's a real problem !!!
860  ********************************************************************/
861 static void spoolss_notify_devmode(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
862 {
863 }
864
865 /*******************************************************************
866  * fill a notify_info_data with the separator file name
867  * jfm:xxxx just return no file could add an option to smb.conf
868  * separator file = "separator.txt"
869  ********************************************************************/
870 static void spoolss_notify_sepfile(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
871 {
872         data->notify_data.data.length=strlen(printer->info_2->sepfile);
873         ascii_to_unistr(data->notify_data.data.string, 
874                         printer->info_2->sepfile, 
875                         sizeof(data->notify_data.data.string)-1);
876 }
877
878 /*******************************************************************
879  * fill a notify_info_data with the print processor
880  * jfm:xxxx return always winprint to indicate we don't do anything to it
881  ********************************************************************/
882 static void spoolss_notify_print_processor(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
883 {
884         data->notify_data.data.length=strlen(printer->info_2->printprocessor);
885         ascii_to_unistr(data->notify_data.data.string, 
886                         printer->info_2->printprocessor, 
887                         sizeof(data->notify_data.data.string)-1);
888 }
889
890 /*******************************************************************
891  * fill a notify_info_data with the print processor options
892  * jfm:xxxx send an empty string
893  ********************************************************************/
894 static void spoolss_notify_parameters(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
895 {
896         data->notify_data.data.length=strlen(printer->info_2->parameters);
897         ascii_to_unistr(data->notify_data.data.string, 
898                         printer->info_2->parameters, 
899                         sizeof(data->notify_data.data.string)-1);
900 }
901
902 /*******************************************************************
903  * fill a notify_info_data with the data type
904  * jfm:xxxx always send RAW as data type
905  ********************************************************************/
906 static void spoolss_notify_datatype(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
907 {
908         data->notify_data.data.length=strlen(printer->info_2->datatype);
909         ascii_to_unistr(data->notify_data.data.string, 
910                         printer->info_2->datatype, 
911                         sizeof(data->notify_data.data.string)-1);
912 }
913
914 /*******************************************************************
915  * fill a notify_info_data with the security descriptor
916  * jfm:xxxx send an null pointer to say no security desc
917  * have to implement security before !
918  ********************************************************************/
919 static void spoolss_notify_security_desc(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
920 {
921         data->notify_data.data.length=0;
922         data->notify_data.data.string[0]=0x00;
923 }
924
925 /*******************************************************************
926  * fill a notify_info_data with the attributes
927  * jfm:xxxx a samba printer is always shared
928  ********************************************************************/
929 static void spoolss_notify_attributes(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
930 {
931         data->notify_data.value[0] =   PRINTER_ATTRIBUTE_SHARED   \
932                                      | PRINTER_ATTRIBUTE_NETWORK  \
933                                      | PRINTER_ATTRIBUTE_RAW_ONLY ;
934 }
935
936 /*******************************************************************
937  * fill a notify_info_data with the priority
938  ********************************************************************/
939 static void spoolss_notify_priority(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
940 {
941         data->notify_data.value[0] = printer->info_2->priority;
942 }
943
944 /*******************************************************************
945  * fill a notify_info_data with the default priority
946  ********************************************************************/
947 static void spoolss_notify_default_priority(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
948 {
949         data->notify_data.value[0] = printer->info_2->default_priority;
950 }
951
952 /*******************************************************************
953  * fill a notify_info_data with the start time
954  ********************************************************************/
955 static void spoolss_notify_start_time(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
956 {
957         data->notify_data.value[0] = printer->info_2->starttime;
958 }
959
960 /*******************************************************************
961  * fill a notify_info_data with the until time
962  ********************************************************************/
963 static void spoolss_notify_until_time(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
964 {
965         data->notify_data.value[0] = printer->info_2->untiltime;
966 }
967
968 /*******************************************************************
969  * fill a notify_info_data with the status
970  ********************************************************************/
971 static void spoolss_notify_status(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
972 {
973         int count;
974         print_queue_struct *q=NULL;
975         print_status_struct status;
976
977         bzero(&status,sizeof(status));
978
979         count=get_printqueue(snum, conn, &q, &status);
980
981         data->notify_data.value[0]=(uint32) status.status;
982         if (q) free(q);
983 }
984
985 /*******************************************************************
986  * fill a notify_info_data with the number of jobs queued
987  ********************************************************************/
988 static void spoolss_notify_cjobs(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
989 {
990         print_queue_struct *q=NULL;
991         print_status_struct status;
992
993         bzero(&status,sizeof(status));
994
995         data->notify_data.value[0]=get_printqueue(snum, conn, &q, &status);
996         if (q) free(q);
997 }
998
999 /*******************************************************************
1000  * fill a notify_info_data with the average ppm
1001  ********************************************************************/
1002 static void spoolss_notify_average_ppm(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1003 {
1004         /* always respond 8 pages per minutes */
1005         /* a little hard ! */
1006         data->notify_data.value[0] = printer->info_2->averageppm;
1007 }
1008
1009 /*******************************************************************
1010  * fill a notify_info_data with 
1011  ********************************************************************/
1012 static void spoolss_notify_username(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1013 {
1014         data->notify_data.data.length=strlen(queue->user);
1015         ascii_to_unistr(data->notify_data.data.string, queue->user, sizeof(data->notify_data.data.string)-1);
1016 }
1017
1018 /*******************************************************************
1019  * fill a notify_info_data with 
1020  ********************************************************************/
1021 static void spoolss_notify_job_status(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1022 {
1023         data->notify_data.value[0]=queue->status;
1024 }
1025
1026 /*******************************************************************
1027  * fill a notify_info_data with 
1028  ********************************************************************/
1029 static void spoolss_notify_job_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1030 {
1031         data->notify_data.data.length=strlen(queue->file);
1032         ascii_to_unistr(data->notify_data.data.string, queue->file, sizeof(data->notify_data.data.string)-1);
1033 }
1034
1035 /*******************************************************************
1036  * fill a notify_info_data with 
1037  ********************************************************************/
1038 static void spoolss_notify_job_status_string(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1039 {
1040         data->notify_data.data.length=strlen("En attente");
1041         ascii_to_unistr(data->notify_data.data.string, "En attente", sizeof(data->notify_data.data.string)-1);
1042 }
1043
1044 /*******************************************************************
1045  * fill a notify_info_data with 
1046  ********************************************************************/
1047 static void spoolss_notify_job_time(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1048 {
1049         data->notify_data.value[0]=0x0;
1050 }
1051
1052 /*******************************************************************
1053  * fill a notify_info_data with 
1054  ********************************************************************/
1055 static void spoolss_notify_job_size(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1056 {
1057         data->notify_data.value[0]=queue->size;
1058 }
1059
1060 /*******************************************************************
1061  * fill a notify_info_data with 
1062  ********************************************************************/
1063 static void spoolss_notify_job_position(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1064 {
1065         data->notify_data.value[0]=queue->job;
1066 }
1067
1068 #define END 65535
1069
1070 struct s_notify_info_data_table notify_info_data_table[] =
1071 {
1072 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME,         "PRINTER_NOTIFY_SERVER_NAME",         POINTER,   spoolss_notify_server_name },
1073 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,        "PRINTER_NOTIFY_PRINTER_NAME",        POINTER,   spoolss_notify_printer_name },
1074 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,          "PRINTER_NOTIFY_SHARE_NAME",          POINTER,   spoolss_notify_share_name },
1075 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,           "PRINTER_NOTIFY_PORT_NAME",           POINTER,   spoolss_notify_port_name },
1076 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,         "PRINTER_NOTIFY_DRIVER_NAME",         POINTER,   spoolss_notify_driver_name },
1077 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,             "PRINTER_NOTIFY_COMMENT",             POINTER,   spoolss_notify_comment },
1078 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,            "PRINTER_NOTIFY_LOCATION",            POINTER,   spoolss_notify_location },
1079 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE,             "PRINTER_NOTIFY_DEVMODE",             POINTER,   spoolss_notify_devmode },
1080 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE,             "PRINTER_NOTIFY_SEPFILE",             POINTER,   spoolss_notify_sepfile },
1081 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR,     "PRINTER_NOTIFY_PRINT_PROCESSOR",     POINTER,   spoolss_notify_print_processor },
1082 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS,          "PRINTER_NOTIFY_PARAMETERS",          POINTER,   spoolss_notify_parameters },
1083 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE,            "PRINTER_NOTIFY_DATATYPE",            POINTER,   spoolss_notify_datatype },
1084 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER,   spoolss_notify_security_desc },
1085 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES,          "PRINTER_NOTIFY_ATTRIBUTES",          ONE_VALUE, spoolss_notify_attributes },
1086 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY,            "PRINTER_NOTIFY_PRIORITY",            ONE_VALUE, spoolss_notify_priority },
1087 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_DEFAULT_PRIORITY",    ONE_VALUE, spoolss_notify_default_priority },
1088 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME,          "PRINTER_NOTIFY_START_TIME",          ONE_VALUE, spoolss_notify_start_time },
1089 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME,          "PRINTER_NOTIFY_UNTIL_TIME",          ONE_VALUE, spoolss_notify_until_time },
1090 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS,              "PRINTER_NOTIFY_STATUS",              ONE_VALUE, spoolss_notify_status },
1091 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING,       "PRINTER_NOTIFY_STATUS_STRING",       POINTER,   NULL },
1092 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS,               "PRINTER_NOTIFY_CJOBS",               ONE_VALUE, spoolss_notify_cjobs },
1093 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM,         "PRINTER_NOTIFY_AVERAGE_PPM",         ONE_VALUE, spoolss_notify_average_ppm },
1094 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES,         "PRINTER_NOTIFY_TOTAL_PAGES",         POINTER,   NULL },
1095 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED,       "PRINTER_NOTIFY_PAGES_PRINTED",       POINTER,   NULL },
1096 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES,         "PRINTER_NOTIFY_TOTAL_BYTES",         POINTER,   NULL },
1097 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED,       "PRINTER_NOTIFY_BYTES_PRINTED",       POINTER,   NULL },
1098 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRINTER_NAME,            "JOB_NOTIFY_PRINTER_NAME",            POINTER,   spoolss_notify_printer_name },
1099 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_MACHINE_NAME,            "JOB_NOTIFY_MACHINE_NAME",            POINTER,   spoolss_notify_server_name },
1100 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PORT_NAME,               "JOB_NOTIFY_PORT_NAME",               POINTER,   spoolss_notify_port_name },
1101 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_USER_NAME,               "JOB_NOTIFY_USER_NAME",               POINTER,   spoolss_notify_username },
1102 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_NOTIFY_NAME,             "JOB_NOTIFY_NOTIFY_NAME",             POINTER,   spoolss_notify_username },
1103 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DATATYPE,                "JOB_NOTIFY_DATATYPE",                POINTER,   spoolss_notify_datatype },
1104 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRINT_PROCESSOR,         "JOB_NOTIFY_PRINT_PROCESSOR",         POINTER,   spoolss_notify_print_processor },
1105 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PARAMETERS,              "JOB_NOTIFY_PARAMETERS",              POINTER,   spoolss_notify_parameters },
1106 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DRIVER_NAME,             "JOB_NOTIFY_DRIVER_NAME",             POINTER,   spoolss_notify_driver_name },
1107 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DEVMODE,                 "JOB_NOTIFY_DEVMODE",                 POINTER,   spoolss_notify_devmode },
1108 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_STATUS,                  "JOB_NOTIFY_STATUS",                  ONE_VALUE, spoolss_notify_job_status },
1109 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_STATUS_STRING,           "JOB_NOTIFY_STATUS_STRING",           POINTER,   spoolss_notify_job_status_string },
1110 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_SECURITY_DESCRIPTOR",     POINTER,   NULL },
1111 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DOCUMENT,                "JOB_NOTIFY_DOCUMENT",                POINTER,   spoolss_notify_job_name },
1112 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRIORITY,                "JOB_NOTIFY_PRIORITY",                ONE_VALUE, spoolss_notify_priority },
1113 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_POSITION,                "JOB_NOTIFY_POSITION",                ONE_VALUE, spoolss_notify_job_position },
1114 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_SUBMITTED,               "JOB_NOTIFY_SUBMITTED",               POINTER,   NULL },
1115 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_START_TIME,              "JOB_NOTIFY_START_TIME",              ONE_VALUE, spoolss_notify_start_time },
1116 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_UNTIL_TIME,              "JOB_NOTIFY_UNTIL_TIME",              ONE_VALUE, spoolss_notify_until_time },
1117 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TIME,                    "JOB_NOTIFY_TIME",                    ONE_VALUE, spoolss_notify_job_time },
1118 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_PAGES,             "JOB_NOTIFY_TOTAL_PAGES",             ONE_VALUE, NULL },
1119 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PAGES_PRINTED,           "JOB_NOTIFY_PAGES_PRINTED",           ONE_VALUE, NULL },
1120 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_BYTES,             "JOB_NOTIFY_TOTAL_BYTES",             ONE_VALUE, spoolss_notify_job_size },
1121 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_BYTES_PRINTED,           "JOB_NOTIFY_BYTES_PRINTED",           ONE_VALUE, NULL },
1122 { END,                 END,                                "",                                   END,       NULL }
1123 };
1124
1125 /*******************************************************************
1126 return the size of info_data structure
1127 ********************************************************************/  
1128 uint32 size_of_notify_info_data(uint16 type, uint16 field)
1129 {
1130         int i=0;
1131
1132         while (notify_info_data_table[i].type != END)
1133         {
1134                 if ( (notify_info_data_table[i].type == type ) &&
1135                      (notify_info_data_table[i].field == field ) )
1136                 {
1137                         return (notify_info_data_table[i].size);
1138                         continue;
1139                 }
1140                 i++;
1141         }
1142         return (65535);
1143 }
1144
1145 /*******************************************************************
1146 return the type of notify_info_data
1147 ********************************************************************/  
1148 BOOL type_of_notify_info_data(uint16 type, uint16 field)
1149 {
1150         int i=0;
1151
1152         while (notify_info_data_table[i].type != END)
1153         {
1154                 if ( (notify_info_data_table[i].type == type ) &&
1155                      (notify_info_data_table[i].field == field ) )
1156                 {
1157                         if (notify_info_data_table[i].size == POINTER)
1158                         {
1159                                 return (False);
1160                         }
1161                         else
1162                         {
1163                                 return (True);
1164                         }
1165                         continue;
1166                 }
1167                 i++;
1168         }
1169         return (False);
1170 }
1171
1172 /****************************************************************************
1173 ****************************************************************************/
1174 static int search_notify(uint16 type, uint16 field, int *value)
1175 {       
1176         int j;
1177         BOOL found;
1178
1179         DEBUG(4,("\tsearch_notify: in\n"));     
1180         for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1181         {
1182                 if ( (notify_info_data_table[j].type  == type  ) &&
1183                      (notify_info_data_table[j].field == field ) )
1184                 {
1185                         found=True;
1186                 }
1187         }
1188         *value=--j;
1189
1190         if ( found && (notify_info_data_table[j].fn != NULL) )
1191         {
1192                 DEBUG(4,("\tsearch_notify: out TRUE\n"));
1193                 return (True);
1194         }
1195         else
1196         {
1197                 DEBUG(4,("\tsearch_notify: out FALSE\n"));
1198                 return (False); 
1199         }
1200 }
1201
1202 /****************************************************************************
1203 ****************************************************************************/
1204 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1205 {
1206         DEBUG(4,("\tconstruct_info_data: in\n"));
1207         info_data->type     = type;
1208         info_data->field    = field;
1209         info_data->id       = id;
1210         info_data->size     = size_of_notify_info_data(type, field);
1211         info_data->enc_type = type_of_notify_info_data(type, field);
1212         DEBUG(4,("\tconstruct_info_data: out\n"));
1213 }
1214
1215
1216 /*******************************************************************
1217  *
1218  * fill a notify_info struct with info asked
1219  * 
1220  ********************************************************************/
1221 static void construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int pnum, 
1222                                           int snum, int i, uint32 id, connection_struct *conn)
1223 {
1224
1225         int k,j;
1226         uint16 type;
1227         uint16 field;
1228
1229         SPOOL_NOTIFY_INFO_DATA *info_data;
1230         print_queue_struct *queue=NULL;
1231         NT_PRINTER_INFO_LEVEL printer;
1232         
1233         DEBUG(4,("construct_notify_printer_info\n"));
1234         
1235         info_data=&(info->data[info->count]);
1236         
1237         type = Printer[pnum].notify_info[i].type;
1238
1239         DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count));
1240         
1241         if (!get_a_printer(&printer, 2, lp_servicename(snum)))
1242         {
1243                 
1244                 for(k=0; k<Printer[pnum].notify_info[i].count; k++)
1245                 {
1246                         field = Printer[pnum].notify_info[i].fields[k];
1247                         DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", k, type, field));
1248
1249                         if (search_notify(type, field, &j) )
1250                         {
1251                                 DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name));
1252                                 construct_info_data(info_data, type, field, id);
1253                         
1254                                 DEBUGADD(4,("notify_info_data_table: in\n"));
1255                                 notify_info_data_table[j].fn(conn,snum, info_data, queue, &printer);
1256                                 DEBUGADD(4,("notify_info_data_table: out\n"));
1257                                 info->count++;
1258                                 info_data=&(info->data[info->count]);
1259                         }
1260                 }
1261         
1262                 free_a_printer(printer, 2);
1263         }
1264 }
1265
1266 /*******************************************************************
1267  *
1268  * fill a notify_info struct with info asked
1269  * 
1270  ********************************************************************/
1271 static void construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info,
1272                                        int pnum, int snum, int i, uint32 id, connection_struct *conn)
1273 {
1274
1275         int k,j;
1276         uint16 type;
1277         uint16 field;
1278
1279         SPOOL_NOTIFY_INFO_DATA *info_data;
1280         NT_PRINTER_INFO_LEVEL printer;
1281         
1282         DEBUG(4,("construct_notify_jobs_info\n"));
1283         info_data=&(info->data[info->count]);
1284         
1285         type = Printer[pnum].notify_info[i].type;
1286
1287         DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count));
1288
1289         if (!get_a_printer(&printer, 2, lp_servicename(snum)))
1290         {       
1291                 for(k=0; k<Printer[pnum].notify_info[i].count; k++)
1292                 {
1293                         field = Printer[pnum].notify_info[i].fields[k];
1294                         DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n",k, type, field));
1295
1296                         if (search_notify(type, field, &j) )
1297                         {
1298                                 DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name));
1299                                 construct_info_data(info_data, type, field, id);
1300                                 DEBUGADD(4,("notify_info_data_table: in\n"));
1301                                 notify_info_data_table[j].fn(conn, snum, info_data, queue, &printer);
1302                                 DEBUGADD(4,("notify_info_data_table: out\n"));
1303                                 info->count++;
1304                                 info_data=&(info->data[info->count]);
1305                         }
1306                 }
1307                 free_a_printer(printer, 2);
1308         }
1309 }
1310
1311
1312 /*******************************************************************
1313  *
1314  * enumerate all printers on the printserver
1315  * fill a notify_info struct with info asked
1316  * 
1317  ********************************************************************/
1318 static void printserver_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info, connection_struct *conn)
1319 {
1320         int snum;
1321         int pnum=find_printer_index_by_hnd(hnd);
1322         int n_services=lp_numservices();
1323         int i=0;
1324         uint32 id=1;
1325         info->count=0;
1326
1327         DEBUG(4,("Enumerating printers\n"));
1328
1329         for (i=0; i<Printer[pnum].number_of_notify; i++)
1330         {
1331          if ( Printer[pnum].notify_info[i].type == PRINTER_NOTIFY_TYPE )
1332          {
1333           for (snum=0; snum<n_services; snum++)
1334           {
1335            if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1336            {
1337                 construct_notify_printer_info(info, pnum, snum, i, id, conn);
1338                 id++;
1339            }
1340           }
1341          }
1342         }
1343         DEBUG(4,("All printers enumerated\n"));
1344 }
1345
1346 /*******************************************************************
1347  *
1348  * fill a notify_info struct with info asked
1349  * 
1350  ********************************************************************/
1351 static void printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info, connection_struct *conn)
1352 {
1353         int snum;
1354         int pnum=find_printer_index_by_hnd(hnd);
1355         int i=0, j;
1356         uint32 id=0xFFFF;
1357         
1358         info->count=0;
1359
1360         if (get_printer_snum(hnd, &snum) )
1361         {
1362                 for (i=0; i<Printer[pnum].number_of_notify; i++)
1363                 {
1364                  switch ( Printer[pnum].notify_info[i].type )
1365                  {
1366                   case PRINTER_NOTIFY_TYPE:
1367                    {
1368                         construct_notify_printer_info(info, pnum, snum, i, id, conn);
1369                         id--;
1370                         break;
1371                    }
1372                   case JOB_NOTIFY_TYPE:
1373                    {
1374                         int count;
1375                         print_queue_struct *queue=NULL;
1376                         print_status_struct status;
1377                         bzero(&status, sizeof(status)); 
1378                         count=get_printqueue(snum, conn, &queue, &status);
1379                         for (j=0; j<count; j++)
1380                         {
1381                                 construct_notify_jobs_info(&(queue[j]), info, pnum, snum, i, queue[j].job, conn);
1382                         }
1383                         if (queue) free(queue);
1384                         break;
1385                    }
1386                  }
1387                 }
1388         }
1389 }
1390
1391 /********************************************************************
1392  * api_spoolss_reply_rfnpcnex
1393  *
1394  * called from api_spoolss_rfnpcnex (see this to understand)
1395  ********************************************************************/
1396 static void spoolss_reply_rfnpcnex(SPOOL_Q_RFNPCNEX *q_u, prs_struct *rdata, connection_struct *conn)
1397 {
1398         SPOOL_R_RFNPCNEX r_u;
1399         int pnum=find_printer_index_by_hnd(&(q_u->handle));
1400
1401         if (OPEN_HANDLE(pnum))
1402         {
1403                 DEBUG(4,("Printer %x of type %x\n",pnum,Printer[pnum].printer_type));
1404                 switch (Printer[pnum].printer_type)
1405                 {
1406                 case PRINTER_HANDLE_IS_PRINTSERVER:
1407                         printserver_notify_info(&(q_u->handle), &(r_u.info), conn);
1408                         break;
1409                 case PRINTER_HANDLE_IS_PRINTER:
1410                         printer_notify_info(&(q_u->handle), &(r_u.info), conn);
1411                         break;
1412                 }
1413                 
1414                 spoolss_io_r_rfnpcnex("", &r_u, rdata, 0);
1415         }
1416 }
1417
1418 /********************************************************************
1419  * api_spoolss_rfnpcnex
1420  * ReplyFindNextPrinterChangeNotifyEx
1421  * called from the spoolss dispatcher
1422  *
1423  ********************************************************************/
1424 static void api_spoolss_rfnpcnex(pipes_struct *p, prs_struct *data, 
1425                                   prs_struct *rdata)
1426 {
1427         SPOOL_Q_RFNPCNEX q_u;
1428
1429         spoolss_io_q_rfnpcnex("", &q_u, data, 0);
1430
1431         spoolss_reply_rfnpcnex(&q_u, rdata, p->conn);
1432 }
1433
1434 /********************************************************************
1435  * construct_printer_info_0
1436  * fill a printer_info_1 struct
1437  ********************************************************************/
1438 static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring servername, connection_struct *conn)
1439 {
1440         pstring chaine;
1441         int count;
1442         NT_PRINTER_INFO_LEVEL ntprinter;
1443         
1444         print_queue_struct *queue=NULL;
1445         print_status_struct status;
1446         bzero(&status,sizeof(status));  
1447
1448         if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1449         {
1450                 return (False);
1451         }
1452
1453         count=get_printqueue(snum, conn ,&queue,&status);
1454         
1455         /* the description and the name are of the form \\server\share */
1456         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter.info_2->printername);
1457                                                             
1458         make_unistr(&(printer->printername), chaine);
1459         
1460         slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1461         make_unistr(&(printer->servername), chaine);
1462         
1463         printer->cjobs = count;
1464         printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
1465                               | PRINTER_ATTRIBUTE_NETWORK  \
1466                               | PRINTER_ATTRIBUTE_RAW_ONLY ;
1467         printer->unknown0     = 0x1; /* pointer */
1468         printer->unknown1     = 0x000A07CE; /* don't known */
1469         printer->unknown2     = 0x00020005;
1470         printer->unknown3     = 0x0006000D;
1471         printer->unknown4     = 0x02180026;
1472         printer->unknown5     = 0x09;
1473         printer->unknown6     = 0x36;
1474         printer->majorversion = 0x0004; /* NT 4 */
1475         printer->buildversion = 0x0565; /* build 1381 */
1476         printer->unknown7     = 0x1;
1477         printer->unknown8     = 0x0;
1478         printer->unknown9     = 0x2;
1479         printer->unknown10    = 0x3;
1480         printer->unknown11    = 0x0;
1481         printer->unknown12    = 0x0;
1482         printer->unknown13    = 0x0;
1483         printer->unknown14    = 0x1;
1484         printer->unknown15    = 0x024a; /*586 Pentium ? */
1485         printer->unknown16    = 0x0;
1486         printer->unknown17    = 0x423ed444;
1487         printer->unknown18    = 0x0;
1488         printer->status       = status.status;
1489         printer->unknown20    = 0x0;
1490         printer->unknown21    = 0x0648;
1491         printer->unknown22    = 0x0;
1492         printer->unknown23    = 0x5;
1493
1494         if (queue) free(queue);
1495
1496         free_a_printer(ntprinter, 2);
1497         return (True);  
1498 }
1499
1500 /********************************************************************
1501  * construct_printer_info_1
1502  * fill a printer_info_1 struct
1503  ********************************************************************/
1504 static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer,int snum, pstring servername, connection_struct *conn)
1505 {
1506         pstring chaine;
1507         NT_PRINTER_INFO_LEVEL ntprinter;
1508         
1509         if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1510         {
1511                 return (False);
1512         }
1513         
1514         printer->flags=PRINTER_ENUM_NAME;
1515
1516         /* the description and the name are of the form \\server\share */
1517         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername,
1518                                                             ntprinter.info_2->printername,
1519                                                             ntprinter.info_2->drivername,
1520                                                             lp_comment(snum));
1521         make_unistr(&(printer->description), chaine);
1522         
1523         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername);
1524         make_unistr(&(printer->name), chaine);
1525         
1526         make_unistr(&(printer->comment), lp_comment(snum));
1527         
1528         free_a_printer(ntprinter, 2);
1529         return (True);
1530 }
1531
1532 /****************************************************************************
1533 ****************************************************************************/
1534 static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername)
1535 {
1536         char adevice[32];
1537         char aform[32];
1538         NT_PRINTER_INFO_LEVEL printer;  
1539         NT_DEVICEMODE *ntdevmode;
1540
1541         DEBUG(7,("construct_dev_mode\n"));
1542         
1543         bzero(&(devmode->devicename), 2*sizeof(adevice));
1544         bzero(&(devmode->formname), 2*sizeof(aform));
1545
1546         DEBUGADD(8,("getting printer characteristics\n"));
1547
1548         get_a_printer(&printer, 2, lp_servicename(snum));
1549         ntdevmode=(printer.info_2)->devmode;
1550
1551         DEBUGADD(8,("loading DEVICEMODE\n"));
1552         snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, 
1553                                                          printer.info_2->printername);
1554         make_unistr(&(devmode->devicename), adevice);
1555
1556         snprintf(aform, sizeof(aform), ntdevmode->formname);
1557         make_unistr(&(devmode->formname), aform);
1558
1559         devmode->specversion      = ntdevmode->specversion;
1560         devmode->driverversion    = ntdevmode->driverversion;
1561         devmode->size             = ntdevmode->size;
1562         devmode->driverextra      = ntdevmode->driverextra;
1563         devmode->fields           = ntdevmode->fields;
1564                                     
1565         devmode->orientation      = ntdevmode->orientation;     
1566         devmode->papersize        = ntdevmode->papersize;
1567         devmode->paperlength      = ntdevmode->paperlength;
1568         devmode->paperwidth       = ntdevmode->paperwidth;
1569         devmode->scale            = ntdevmode->scale;
1570         devmode->copies           = ntdevmode->copies;
1571         devmode->defaultsource    = ntdevmode->defaultsource;
1572         devmode->printquality     = ntdevmode->printquality;
1573         devmode->color            = ntdevmode->color;
1574         devmode->duplex           = ntdevmode->duplex;
1575         devmode->yresolution      = ntdevmode->yresolution;
1576         devmode->ttoption         = ntdevmode->ttoption;
1577         devmode->collate          = ntdevmode->collate;
1578         devmode->icmmethod        = ntdevmode->icmmethod;
1579         devmode->icmintent        = ntdevmode->icmintent;
1580         devmode->mediatype        = ntdevmode->mediatype;
1581         devmode->dithertype       = ntdevmode->dithertype;
1582
1583         if (ntdevmode->private != NULL)
1584         {
1585                 devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8));
1586                 memcpy(devmode->private, ntdevmode->private, devmode->driverextra);
1587         }
1588
1589         free_a_printer(printer, 2);
1590 }
1591
1592 /********************************************************************
1593  * construct_printer_info_2
1594  * fill a printer_info_2 struct
1595  ********************************************************************/
1596 static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring servername, connection_struct *conn)
1597 {
1598         pstring chaine;
1599         int count;
1600         DEVICEMODE *devmode;
1601         NT_PRINTER_INFO_LEVEL ntprinter;
1602         
1603         print_queue_struct *queue=NULL;
1604         print_status_struct status;
1605         bzero(&status, sizeof(status)); 
1606         count=get_printqueue(snum, conn, &queue, &status);
1607
1608         if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1609         {
1610                 return (False);
1611         }       
1612
1613         snprintf(chaine, sizeof(chaine)-1, "\\\\%s", servername);
1614         make_unistr(&(printer->servername), chaine);                    /* servername*/
1615         
1616         snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", servername, ntprinter.info_2->printername);
1617         make_unistr(&(printer->printername), chaine);                   /* printername*/
1618
1619         make_unistr(&(printer->sharename),      lp_servicename(snum));  /* sharename */
1620
1621         make_unistr(&(printer->portname),       lp_servicename(snum));          /* port */      
1622         make_unistr(&(printer->drivername),     ntprinter.info_2->drivername);  /* drivername */
1623                 
1624         make_unistr(&(printer->comment),        ntprinter.info_2->comment);     /* comment */   
1625         make_unistr(&(printer->location),       ntprinter.info_2->location);    /* location */  
1626         make_unistr(&(printer->sepfile),        ntprinter.info_2->sepfile);     /* separator file */
1627         make_unistr(&(printer->printprocessor), ntprinter.info_2->printprocessor);/* print processor */
1628         make_unistr(&(printer->datatype),       ntprinter.info_2->datatype);    /* datatype */  
1629         make_unistr(&(printer->parameters),     ntprinter.info_2->parameters);  /* parameters (of print processor) */   
1630
1631         printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
1632                               | PRINTER_ATTRIBUTE_NETWORK  \
1633                               | PRINTER_ATTRIBUTE_RAW_ONLY ;            /* attributes */
1634
1635         printer->priority        = ntprinter.info_2->priority;          /* priority */  
1636         printer->defaultpriority = ntprinter.info_2->default_priority;  /* default priority */
1637         printer->starttime       = ntprinter.info_2->starttime;         /* starttime */
1638         printer->untiltime       = ntprinter.info_2->untiltime;         /* untiltime */
1639         printer->status          = status.status;                       /* status */
1640         printer->cjobs           = count;                               /* jobs */
1641         printer->averageppm      = ntprinter.info_2->averageppm;        /* average pages per minute */
1642                         
1643         devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
1644         ZERO_STRUCTP(devmode);  
1645         construct_dev_mode(devmode, snum, servername);                  
1646         printer->devmode=devmode;
1647         
1648         if (queue) free(queue);
1649         free_a_printer(ntprinter, 2);
1650         return (True);
1651 }
1652
1653 /********************************************************************
1654  * enum_printer_info_1
1655  * glue between spoolss_reply_enumprinters and construct_printer_info_1
1656  ********************************************************************/
1657 static BOOL enum_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number, connection_struct *conn)
1658 {
1659         pstring servername;
1660
1661         *printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
1662         DEBUG(4,("Allocated memory for ONE PRINTER_INFO_1 at [%p]\n", *printer));       
1663         pstrcpy(servername, global_myname);
1664         if (!construct_printer_info_1(*printer, snum, servername, conn))
1665         {
1666                 free(*printer);
1667                 return (False);
1668         }
1669         else
1670         {
1671                 return (True);
1672         }
1673 }
1674
1675 /********************************************************************
1676  * enum_printer_info_2
1677  * glue between spoolss_reply_enumprinters and construct_printer_info_2
1678  ********************************************************************/
1679 static BOOL enum_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number, connection_struct *conn)
1680 {
1681         pstring servername;
1682
1683         *printer=(PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2));
1684         DEBUG(4,("Allocated memory for ONE PRINTER_INFO_2 at [%p]\n", *printer));       
1685         pstrcpy(servername, global_myname);
1686         if (!construct_printer_info_2(*printer, snum, servername, conn))
1687         {
1688                 free(*printer);
1689                 return (False);
1690         }
1691         else
1692         {
1693                 return (True);
1694         }
1695 }
1696
1697 /********************************************************************
1698  * api_spoolss_reply_enumprinters
1699  *
1700  * called from api_spoolss_enumprinters (see this to understand)
1701  ********************************************************************/
1702 static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number, connection_struct *conn)
1703 {
1704         int snum;
1705         int n_services=lp_numservices();
1706         *printers=NULL;
1707         *number=0;
1708
1709         for (snum=0;snum<n_services; snum++)
1710         {
1711                 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1712                 {
1713                         DEBUG(4,("Found a printer: %s[%x]\n",lp_servicename(snum),snum));
1714                         *printers=Realloc(*printers, (*number+1)*sizeof(PRINTER_INFO_1 *));                     
1715                         DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1 pointers at [%p]\n", *number+1, *printers));         
1716                         if (enum_printer_info_1( &((*printers)[*number]), snum, *number, conn) )
1717                         {                       
1718                                 (*number)++;
1719                         }
1720                 }
1721         }
1722 }
1723
1724 /********************************************************************
1725  * api_spoolss_reply_enumprinters
1726  *
1727  * called from api_spoolss_enumprinters (see this to understand)
1728  ********************************************************************/
1729 static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number, connection_struct *conn)
1730 {
1731         int snum;
1732         int n_services=lp_numservices();
1733         *printers=NULL;
1734         *number=0;
1735
1736         for (snum=0;snum<n_services; snum++)
1737         {
1738                 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1739                 {
1740                         DEBUG(4,("Found a printer: %s[%x]\n",lp_servicename(snum),snum));
1741                         *printers=Realloc(*printers, (*number+1)*sizeof(PRINTER_INFO_2 *));                     
1742                         DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2 pointers at [%p]\n", *number+1, *printers));                 
1743                         if (enum_printer_info_2( &((*printers)[*number]), snum, *number, conn) )
1744                         {                       
1745                                 (*number)++;
1746                         }
1747                 }
1748         }
1749 }
1750
1751 /********************************************************************
1752  * api_spoolss_reply_enumprinters
1753  *
1754  * called from api_spoolss_enumprinters (see this to understand)
1755  ********************************************************************/
1756 static void spoolss_reply_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *rdata, connection_struct *conn)
1757 {
1758         SPOOL_R_ENUMPRINTERS r_u;
1759         
1760         DEBUG(4,("Enumerating printers\n"));
1761
1762         memcpy(r_u.servername.buffer,q_u->servername.buffer,2*q_u->servername.uni_str_len);
1763         r_u.servername.buffer[q_u->servername.uni_str_len]=0x0000;
1764         r_u.returned=0;
1765
1766         switch (q_u->level)
1767         {
1768                 case 1:
1769                         if ( (q_u->flags==PRINTER_ENUM_NAME) || (q_u->flags==PRINTER_ENUM_NETWORK) )
1770                                 /*if (is_a_printerserver(q_u->servername))*/
1771                                         enum_all_printers_info_1(&(r_u.printer.printers_1), &(r_u.returned), conn );
1772                                 /*else  
1773                                         enum_one_printer_info_1(&r_u);*/
1774                         break;
1775                 case 2:
1776                         if ( (q_u->flags==PRINTER_ENUM_NAME) || (q_u->flags==PRINTER_ENUM_NETWORK) )
1777                                 /*if (is_a_printerserver(q_u->servername))*/
1778                                         enum_all_printers_info_2(&(r_u.printer.printers_2), &(r_u.returned), conn );
1779                                 /*else  
1780                                         enum_one_printer_info_2(&r_u);*/
1781                         break;
1782                 case 3:         /* doesn't exist */
1783                         break;
1784                 case 4:         /* can't, always on local machine */
1785                         break;
1786                 case 5:
1787                         break;
1788                         
1789         }
1790         DEBUG(4,("%d printers enumerated\n", r_u.returned));
1791         r_u.offered=q_u->buffer.size;
1792         r_u.level=q_u->level;
1793         r_u.status=0x0000;
1794
1795         spoolss_io_r_enumprinters("",&r_u,rdata,0);
1796 }
1797
1798 /********************************************************************
1799  * api_spoolss_enumprinters
1800  * called from the spoolss dispatcher
1801  *
1802  ********************************************************************/
1803 static void api_spoolss_enumprinters(pipes_struct *p, prs_struct *data, 
1804                                      prs_struct *rdata)
1805 {
1806         SPOOL_Q_ENUMPRINTERS q_u;
1807
1808         spoolss_io_q_enumprinters("", &q_u, data, 0);
1809
1810         spoolss_reply_enumprinters(&q_u, rdata, p->conn);
1811         
1812         spoolss_io_free_buffer(&(q_u.buffer));
1813 }
1814
1815
1816 /****************************************************************************
1817 ****************************************************************************/
1818 static void spoolss_reply_getprinter(SPOOL_Q_GETPRINTER *q_u, prs_struct *rdata, connection_struct *conn)
1819 {
1820         SPOOL_R_GETPRINTER r_u;
1821         int snum;
1822         pstring servername;
1823         
1824         pstrcpy(servername, global_myname);
1825
1826         get_printer_snum(&(q_u->handle),&snum);
1827         
1828         switch (q_u->level)
1829         {
1830                 case 0:
1831                 { 
1832                         PRINTER_INFO_0 *printer;
1833                         
1834                         printer=(PRINTER_INFO_0 *)malloc(sizeof(PRINTER_INFO_0));
1835                         
1836                         construct_printer_info_0(printer, snum, servername, conn);
1837                         r_u.printer.info0=printer;
1838                         r_u.status=0x0000;
1839                         r_u.offered=q_u->offered;
1840                         r_u.level=q_u->level;
1841                         
1842                         spoolss_io_r_getprinter("",&r_u,rdata,0);
1843                         
1844                         free(printer);
1845                         
1846                         break;
1847                 }
1848                 case 1:
1849                 {
1850                         PRINTER_INFO_1 *printer;
1851                         
1852                         printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
1853
1854                         construct_printer_info_1(printer, snum, servername, conn);
1855
1856                         r_u.printer.info1=printer;                      
1857                         r_u.status=0x0000;
1858                         r_u.offered=q_u->offered;
1859                         r_u.level=q_u->level;
1860                         spoolss_io_r_getprinter("",&r_u,rdata,0);
1861                         
1862                         free(printer);
1863                                 
1864                         break;
1865                 }
1866                 case 2:
1867                 {
1868                         PRINTER_INFO_2 *printer;
1869                         
1870                         printer=(PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2));       
1871                         construct_printer_info_2(printer, snum, servername, conn);
1872                         
1873                         r_u.printer.info2=printer;      
1874                         r_u.status=0x0000;
1875                         r_u.offered=q_u->offered;
1876                         r_u.level=q_u->level;
1877                         spoolss_io_r_getprinter("",&r_u,rdata,0);
1878                         
1879                         free_printer_info_2(printer);
1880                                 
1881                         break;
1882                 }
1883         }
1884 }
1885
1886 /********************************************************************
1887  * api_spoolss_getprinter
1888  * called from the spoolss dispatcher
1889  *
1890  ********************************************************************/
1891 static void api_spoolss_getprinter(pipes_struct *p, prs_struct *data, 
1892                                    prs_struct *rdata)
1893 {
1894         SPOOL_Q_GETPRINTER q_u;
1895         
1896         spoolss_io_q_getprinter("", &q_u, data, 0);
1897
1898         spoolss_reply_getprinter(&q_u, rdata, p->conn);
1899 }
1900
1901 /********************************************************************
1902  * construct_printer_driver_info_1
1903  * fill a construct_printer_driver_info_1 struct
1904  ********************************************************************/
1905 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, 
1906                                        NT_PRINTER_DRIVER_INFO_LEVEL driver, 
1907                                        pstring servername, fstring architecture)
1908 {
1909         make_unistr( &(info->name), driver.info_3->name);
1910 }
1911
1912 static void construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, 
1913                                             pstring servername, fstring architecture)
1914 {       
1915         NT_PRINTER_INFO_LEVEL printer;
1916         NT_PRINTER_DRIVER_INFO_LEVEL driver;
1917
1918         get_a_printer(&printer, 2, lp_servicename(snum) );
1919         get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture);     
1920         
1921         fill_printer_driver_info_1(info, driver, servername, architecture);
1922         
1923         free_a_printer_driver(driver, 3);
1924         free_a_printer(printer, 2);
1925 }
1926
1927 /********************************************************************
1928  * construct_printer_driver_info_2
1929  * fill a printer_info_2 struct
1930  ********************************************************************/
1931 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, 
1932                                        NT_PRINTER_DRIVER_INFO_LEVEL driver, 
1933                                        pstring servername, fstring architecture)
1934 {
1935         pstring where;
1936         pstring temp_driverpath;
1937         pstring temp_datafile;
1938         pstring temp_configfile;
1939         fstring short_archi;
1940
1941         get_short_archi(short_archi,architecture);
1942         
1943         snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
1944
1945         info->version=driver.info_3->cversion;
1946
1947         make_unistr( &(info->name),         driver.info_3->name );
1948         make_unistr( &(info->architecture), architecture );
1949         
1950         snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, 
1951                  driver.info_3->driverpath);
1952         make_unistr( &(info->driverpath),   temp_driverpath );
1953
1954         snprintf(temp_datafile,   sizeof(temp_datafile)-1, "%s%s", where, 
1955                  driver.info_3->datafile);
1956         make_unistr( &(info->datafile),     temp_datafile );
1957
1958         snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, 
1959                  driver.info_3->configfile);
1960         make_unistr( &(info->configfile),   temp_configfile );  
1961 }
1962
1963 /********************************************************************
1964  * construct_printer_driver_info_2
1965  * fill a printer_info_2 struct
1966  ********************************************************************/
1967 static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, 
1968                                             pstring servername, fstring architecture)
1969 {
1970         NT_PRINTER_INFO_LEVEL printer;
1971         NT_PRINTER_DRIVER_INFO_LEVEL driver;
1972         
1973         get_a_printer(&printer, 2, lp_servicename(snum) );
1974         get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture);     
1975
1976         fill_printer_driver_info_2(info, driver, servername, architecture);
1977
1978         free_a_printer_driver(driver, 3);
1979         free_a_printer(printer, 2);
1980 }
1981
1982 /********************************************************************
1983  * copy a strings array and convert to UNICODE
1984  ********************************************************************/
1985 static void make_unistr_array(UNISTR ***uni_array, char **char_array, char *where)
1986 {
1987         int i=0;
1988         char *v;
1989         pstring line;
1990
1991         DEBUG(6,("make_unistr_array\n"));
1992
1993         for (v=char_array[i]; *v!='\0'; v=char_array[i])
1994         {
1995                 DEBUGADD(6,("i:%d:", i));
1996                 DEBUGADD(6,("%s:%d:", v, strlen(v)));
1997         
1998                 *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1));
1999                 DEBUGADD(7,("realloc:[%p],", *uni_array));
2000                         
2001                 (*uni_array)[i]=(UNISTR *)malloc( sizeof(UNISTR) );
2002                 DEBUGADD(7,("alloc:[%p],", (*uni_array)[i]));
2003
2004                 snprintf(line, sizeof(line)-1, "%s%s", where, v);
2005                 make_unistr( (*uni_array)[i], line );
2006                 DEBUGADD(7,("copy\n"));
2007                         
2008                 i++;
2009         }
2010         DEBUGADD(7,("last one\n"));
2011         
2012         *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1));
2013         (*uni_array)[i]=0x0000;
2014         DEBUGADD(6,("last one:done\n"));
2015 }
2016
2017 /********************************************************************
2018  * construct_printer_info_3
2019  * fill a printer_info_3 struct
2020  ********************************************************************/
2021 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, 
2022                                        NT_PRINTER_DRIVER_INFO_LEVEL driver, 
2023                                        pstring servername, fstring architecture)
2024 {
2025         pstring where;
2026         pstring temp_driverpath;
2027         pstring temp_datafile;
2028         pstring temp_configfile;
2029         pstring temp_helpfile;
2030         fstring short_archi;
2031         
2032         get_short_archi(short_archi, architecture);
2033         
2034         snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
2035         
2036         info->version=driver.info_3->cversion;
2037
2038         make_unistr( &(info->name),         driver.info_3->name );      
2039         make_unistr( &(info->architecture), architecture );
2040         
2041         snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, driver.info_3->driverpath);          
2042         make_unistr( &(info->driverpath), temp_driverpath );
2043         
2044         snprintf(temp_datafile,   sizeof(temp_datafile)-1,   "%s%s", where, driver.info_3->datafile); 
2045         make_unistr( &(info->datafile), temp_datafile );
2046         
2047         snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, driver.info_3->configfile);
2048         make_unistr( &(info->configfile), temp_configfile );    
2049         
2050         snprintf(temp_helpfile,   sizeof(temp_helpfile)-1,   "%s%s", where, driver.info_3->helpfile);
2051         make_unistr( &(info->helpfile), temp_helpfile );
2052
2053         make_unistr( &(info->monitorname), driver.info_3->monitorname );        
2054         make_unistr( &(info->defaultdatatype), driver.info_3->defaultdatatype );
2055
2056         info->dependentfiles=NULL;
2057         make_unistr_array(&(info->dependentfiles), driver.info_3->dependentfiles, where);
2058 }
2059
2060 /********************************************************************
2061  * construct_printer_info_3
2062  * fill a printer_info_3 struct
2063  ********************************************************************/
2064 static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, 
2065                                             pstring servername, fstring architecture)
2066 {       
2067         NT_PRINTER_INFO_LEVEL printer;
2068         NT_PRINTER_DRIVER_INFO_LEVEL driver;
2069         
2070         get_a_printer(&printer, 2, lp_servicename(snum) );      
2071         get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture);     
2072
2073         fill_printer_driver_info_3(info, driver, servername, architecture);
2074
2075         free_a_printer_driver(driver, 3);
2076         free_a_printer(printer, 2);
2077 }
2078
2079 /****************************************************************************
2080 ****************************************************************************/
2081 static void spoolss_reply_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *rdata)
2082 {
2083         SPOOL_R_GETPRINTERDRIVER2 r_u;
2084         pstring servername;
2085         fstring architecture;
2086         int snum;
2087         DRIVER_INFO_1 *info1=NULL;
2088         DRIVER_INFO_2 *info2=NULL;
2089         DRIVER_INFO_3 *info3=NULL;
2090
2091         pstrcpy(servername, global_myname);
2092         get_printer_snum(&(q_u->handle),&snum);
2093
2094         r_u.offered=q_u->buf_size;
2095         r_u.level=q_u->level;
2096         r_u.status=0x0000;      
2097         
2098         unistr2_to_ascii(architecture, &(q_u->architecture), sizeof(architecture) );
2099         
2100         DEBUG(1,("spoolss_reply_getprinterdriver2:[%d]\n", q_u->level));
2101         
2102         switch (q_u->level)
2103         {
2104                 case 1:
2105                 {                       
2106                         info1=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1));
2107                         construct_printer_driver_info_1(info1, snum, servername, architecture);
2108                         r_u.printer.info1=info1;                        
2109                         break;                  
2110                 }
2111                 case 2:
2112                 {
2113                         info2=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2));
2114                         construct_printer_driver_info_2(info2, snum, servername, architecture);
2115                         r_u.printer.info2=info2;                        
2116                         break;
2117                 }
2118                 case 3:
2119                 {
2120                         info3=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3));
2121                         construct_printer_driver_info_3(info3, snum, servername, architecture);
2122                         r_u.printer.info3=info3;
2123                         break;
2124                 }
2125         }
2126         
2127         spoolss_io_r_getprinterdriver2("",&r_u,rdata,0);
2128         
2129         if (info1!=NULL) free(info1);
2130         if (info2!=NULL) free(info2);
2131         if (info3!=NULL) 
2132         {
2133                 UNISTR **dependentfiles;
2134                 int j=0;
2135                 dependentfiles=info3->dependentfiles;
2136                 while ( dependentfiles[j] != NULL )
2137                 {
2138                         free(dependentfiles[j]);
2139                         j++;
2140                 }
2141                 free(dependentfiles);
2142         
2143                 free(info3);
2144         }
2145 }
2146
2147 /********************************************************************
2148  * api_spoolss_getprinter
2149  * called from the spoolss dispatcher
2150  *
2151  ********************************************************************/
2152 static void api_spoolss_getprinterdriver2(pipes_struct *p, prs_struct *data,
2153                                           prs_struct *rdata)
2154 {
2155         SPOOL_Q_GETPRINTERDRIVER2 q_u;
2156         
2157         spoolss_io_q_getprinterdriver2("", &q_u, data, 0);
2158         
2159         spoolss_reply_getprinterdriver2(&q_u, rdata);
2160         
2161         spoolss_io_free_buffer(&(q_u.buffer));
2162 }
2163
2164 /****************************************************************************
2165 ****************************************************************************/
2166 static void spoolss_reply_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *rdata)
2167 {
2168         SPOOL_R_STARTPAGEPRINTER r_u;
2169         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2170
2171         if (OPEN_HANDLE(pnum))
2172         {
2173                 Printer[pnum].page_started=True;
2174                 r_u.status=0x0;
2175
2176                 spoolss_io_r_startpageprinter("",&r_u,rdata,0);         
2177         }
2178         else
2179         {
2180                 DEBUG(3,("Error in startpageprinter printer handle (pnum=%x)\n",pnum));
2181         }
2182 }
2183
2184 /********************************************************************
2185  * api_spoolss_getprinter
2186  * called from the spoolss dispatcher
2187  *
2188  ********************************************************************/
2189 static void api_spoolss_startpageprinter(pipes_struct *p, prs_struct *data,
2190                                           prs_struct *rdata)
2191 {
2192         SPOOL_Q_STARTPAGEPRINTER q_u;
2193         
2194         spoolss_io_q_startpageprinter("", &q_u, data, 0);
2195         
2196         spoolss_reply_startpageprinter(&q_u, rdata);
2197 }
2198
2199 /****************************************************************************
2200 ****************************************************************************/
2201 static void spoolss_reply_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *rdata)
2202 {
2203         SPOOL_R_ENDPAGEPRINTER r_u;
2204         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2205
2206         if (OPEN_HANDLE(pnum))
2207         {
2208                 Printer[pnum].page_started=False;
2209                 r_u.status=0x0;
2210
2211                 spoolss_io_r_endpageprinter("",&r_u,rdata,0);           
2212         }
2213         else
2214         {
2215                 DEBUG(3,("Error in endpageprinter printer handle (pnum=%x)\n",pnum));
2216         }
2217 }
2218
2219 /********************************************************************
2220  * api_spoolss_getprinter
2221  * called from the spoolss dispatcher
2222  *
2223  ********************************************************************/
2224 static void api_spoolss_endpageprinter(pipes_struct *p, prs_struct *data,
2225                                           prs_struct *rdata)
2226 {
2227         SPOOL_Q_ENDPAGEPRINTER q_u;
2228         
2229         spoolss_io_q_endpageprinter("", &q_u, data, 0);
2230         
2231         spoolss_reply_endpageprinter(&q_u, rdata);
2232 }
2233
2234 /********************************************************************
2235  * api_spoolss_getprinter
2236  * called from the spoolss dispatcher
2237  *
2238  ********************************************************************/
2239 static void api_spoolss_startdocprinter(pipes_struct *p, prs_struct *data,
2240                                           prs_struct *rdata)
2241 {
2242         SPOOL_Q_STARTDOCPRINTER q_u;
2243         SPOOL_R_STARTDOCPRINTER r_u;
2244         DOC_INFO_1 *info_1;
2245         
2246         pstring fname;
2247         pstring tempname;
2248         pstring datatype;
2249         int fd = -1;
2250         int snum;
2251         int pnum;
2252
2253         /* decode the stream and fill the struct */
2254         spoolss_io_q_startdocprinter("", &q_u, data, 0);
2255         
2256         info_1=&(q_u.doc_info_container.docinfo.doc_info_1);
2257         r_u.status=0x0;
2258         pnum = find_printer_index_by_hnd(&(q_u.handle));
2259
2260         /*
2261          * a nice thing with NT is it doesn't listen to what you tell it.
2262          * when asked to send _only_ RAW datas, it tries to send datas
2263          * in EMF format.
2264          *
2265          * So I add checks like in NT Server ...
2266          */
2267         
2268         if (info_1->p_datatype != 0)
2269         {
2270                 unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype));
2271                 if (strcmp(datatype, "RAW") != 0)
2272                 {
2273                         r_u.jobid=0;
2274                         r_u.status=1804;
2275                 }               
2276         }                
2277         
2278         if (r_u.status==0 && OPEN_HANDLE(pnum))
2279         {
2280                 /* get the share number of the printer */
2281                 get_printer_snum(&(q_u.handle),&snum);
2282
2283                 /* Create a temporary file in the printer spool directory
2284                  * and open it
2285                  */
2286
2287                 slprintf(tempname,sizeof(tempname)-1, "%s/smb_print.XXXXXX",lp_pathname(snum));  
2288                 pstrcpy(fname, (char *)mktemp(tempname));
2289
2290                 fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
2291                 DEBUG(4,("Temp spool file created: [%s]\n", fname));
2292
2293                 Printer[pnum].current_jobid=fd;
2294                 pstrcpy(Printer[pnum].document_name,fname);
2295                 
2296                 unistr2_to_ascii(Printer[pnum].job_name, 
2297                                  &(q_u.doc_info_container.docinfo.doc_info_1.docname), 
2298                                  sizeof(Printer[pnum].job_name));
2299                 
2300                 Printer[pnum].document_fd=fd;
2301                 Printer[pnum].document_started=True;
2302                 r_u.jobid=Printer[pnum].current_jobid;
2303                 r_u.status=0x0;
2304
2305         }
2306                 
2307         spoolss_io_r_startdocprinter("",&r_u,rdata,0);          
2308 }
2309
2310 /****************************************************************************
2311 ****************************************************************************/
2312 static void spoolss_reply_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *rdata)
2313 {
2314         SPOOL_R_ENDDOCPRINTER r_u;
2315         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2316
2317         if (OPEN_HANDLE(pnum))
2318         {
2319                 r_u.status=0x0;
2320
2321                 spoolss_io_r_enddocprinter("",&r_u,rdata,0);            
2322         }
2323         else
2324         {
2325                 DEBUG(3,("Error in enddocprinter printer handle (pnum=%x)\n",pnum));
2326         }
2327 }
2328
2329 /********************************************************************
2330  * api_spoolss_getprinter
2331  * called from the spoolss dispatcher
2332  *
2333  ********************************************************************/
2334 static void api_spoolss_enddocprinter(pipes_struct *p, prs_struct *data,
2335                                           prs_struct *rdata)
2336 {
2337         SPOOL_Q_ENDDOCPRINTER q_u;
2338         int pnum;
2339         int snum;
2340         pstring filename;
2341         pstring filename1;
2342         pstring job_name;
2343         pstring syscmd;
2344         char *tstr;
2345         
2346         spoolss_io_q_enddocprinter("", &q_u, data, 0);
2347         
2348         *syscmd=0;
2349         
2350         pnum = find_printer_index_by_hnd(&(q_u.handle));
2351         
2352         if (OPEN_HANDLE(pnum))
2353         {
2354                 Printer[pnum].document_started=False;
2355                 close(Printer[pnum].document_fd);
2356                 DEBUG(4,("Temp spool file closed, printing now ...\n"));
2357
2358                 pstrcpy(filename1, Printer[pnum].document_name);
2359                 pstrcpy(job_name, Printer[pnum].job_name);
2360                 
2361                 get_printer_snum(&(q_u.handle),&snum);
2362                 
2363                 /* copy the command into the buffer for extensive meddling. */
2364                 StrnCpy(syscmd, lp_printcommand(snum), sizeof(pstring) - 1);
2365
2366                 /* look for "%s" in the string. If there is no %s, we cannot print. */   
2367                 if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f"))
2368                 {
2369                         DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
2370                 }
2371
2372                 if (strstr(syscmd,"%s"))
2373                 {
2374                         pstrcpy(filename,filename1);
2375                         string_sub(syscmd, "%s", filename);
2376                 }
2377
2378                 string_sub(syscmd, "%f", filename1);
2379
2380                 /* Does the service have a printername? If not, make a fake and empty    */
2381                 /* printer name. That way a %p is treated sanely if no printer */
2382                 /* name was specified to replace it. This eventuality is logged.         */
2383                 tstr = lp_printername(snum);
2384                 if (tstr == NULL || tstr[0] == '\0')
2385                 {
2386                         DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum)));
2387                         tstr = SERVICE(snum);
2388                 }
2389
2390                 string_sub(syscmd, "%p", tstr);
2391
2392                 /* If the lpr command support the 'Job' option replace here */
2393                 string_sub(syscmd, "%j", job_name);
2394
2395                 if ( *syscmd != '\0')
2396                 {
2397                   int ret = smbrun(syscmd, NULL, False);
2398                   DEBUG(3,("Running the command `%s' gave %d\n", syscmd, ret));
2399                 }
2400                 else
2401                   DEBUG(0,("Null print command?\n"));
2402
2403                 lpq_reset(snum);
2404         }
2405         
2406         spoolss_reply_enddocprinter(&q_u, rdata);
2407 }
2408
2409 /****************************************************************************
2410 ****************************************************************************/
2411 static void spoolss_reply_writeprinter(SPOOL_Q_WRITEPRINTER *q_u, prs_struct *rdata)
2412 {
2413         SPOOL_R_WRITEPRINTER r_u;
2414         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2415
2416         if (OPEN_HANDLE(pnum))
2417         {
2418                 r_u.buffer_written=Printer[pnum].document_lastwritten;
2419                 r_u.status=0x0;
2420
2421                 spoolss_io_r_writeprinter("",&r_u,rdata,0);             
2422         }
2423         else
2424         {
2425                 DEBUG(3,("Error in writeprinter printer handle (pnum=%x)\n",pnum));
2426         }
2427 }
2428
2429 /********************************************************************
2430  * api_spoolss_getprinter
2431  * called from the spoolss dispatcher
2432  *
2433  ********************************************************************/
2434 static void api_spoolss_writeprinter(pipes_struct *p, prs_struct *data,
2435                                           prs_struct *rdata)
2436 {
2437         SPOOL_Q_WRITEPRINTER q_u;
2438         int pnum;
2439         int fd;
2440         int size;
2441         spoolss_io_q_writeprinter("", &q_u, data, 0);
2442         
2443         pnum = find_printer_index_by_hnd(&(q_u.handle));
2444         
2445         if (OPEN_HANDLE(pnum))
2446         {
2447                 fd=Printer[pnum].document_fd;
2448                 size=write(fd, q_u.buffer, q_u.buffer_size);
2449                 if (q_u.buffer) free(q_u.buffer);
2450                 Printer[pnum].document_lastwritten=size;
2451         }
2452         
2453         spoolss_reply_writeprinter(&q_u, rdata);
2454 }
2455
2456 /********************************************************************
2457  * api_spoolss_getprinter
2458  * called from the spoolss dispatcher
2459  *
2460  ********************************************************************/
2461 static void control_printer(POLICY_HND handle, uint32 command, connection_struct *conn)
2462 {
2463         int pnum;
2464         int snum;
2465         pnum = find_printer_index_by_hnd(&(handle));
2466
2467         if ( get_printer_snum(&handle, &snum) )
2468         {                
2469                 switch (command)
2470                 {
2471                         case PRINTER_CONTROL_PAUSE:
2472                                 /* pause the printer here */
2473                                 status_printqueue(conn, snum, LPSTAT_STOPPED);
2474                                 break;
2475
2476                         case PRINTER_CONTROL_RESUME:
2477                         case PRINTER_CONTROL_UNPAUSE:
2478                                 /* UN-pause the printer here */
2479                                 status_printqueue(conn, snum, LPSTAT_OK);
2480                                 break;
2481                         case PRINTER_CONTROL_PURGE:
2482                                 /* Envoi des dragées FUCA dans l'imprimante */
2483                                 break;
2484                 }
2485         }
2486 }
2487
2488 /********************************************************************
2489  * called by spoolss_api_setprinter
2490  * when updating a printer description
2491  ********************************************************************/
2492 static void update_printer(POLICY_HND handle, uint32 level,
2493                            SPOOL_PRINTER_INFO_LEVEL info, DEVICEMODE *devmode)
2494 {
2495         int pnum;
2496         int snum;
2497         NT_PRINTER_INFO_LEVEL printer;
2498         NT_DEVICEMODE *nt_devmode;
2499
2500         nt_devmode=NULL;
2501         
2502         DEBUG(8,("update_printer\n"));
2503         
2504         if (level!=2)
2505         {
2506                 DEBUG(0,("Send a mail to samba-bugs@samba.org\n"));
2507                 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
2508                 return;
2509         }
2510
2511         pnum = find_printer_index_by_hnd(&handle);
2512         
2513         if ( get_printer_snum(&handle, &snum) )
2514         {
2515                 get_a_printer(&printer, level, lp_servicename(snum));
2516
2517                 DEBUGADD(8,("Converting info_2 struct\n"));
2518                 convert_printer_info(info, &printer, level);
2519                 
2520                 if ((info.info_2)->devmode_ptr != 0)
2521                 {
2522                         /* we have a valid devmode
2523                            convert it and link it*/
2524                         
2525                         /* the nt_devmode memory is already alloced
2526                          * while doing the get_a_printer call
2527                          * but the devmode private part is not
2528                          * it's done by convert_devicemode
2529                          */
2530                         DEBUGADD(8,("Converting the devicemode struct\n"));
2531                         nt_devmode=printer.info_2->devmode;
2532                         
2533                         init_devicemode(nt_devmode);
2534                                         
2535                         convert_devicemode(*devmode, nt_devmode);
2536                         
2537                         /* now clear the memory used in 
2538                          * the RPC parsing routine
2539                          */
2540                         if (devmode->private != NULL)
2541                                 free(devmode->private);
2542                         free(devmode);
2543                 }
2544                 else
2545                 {
2546                         if (printer.info_2->devmode != NULL)
2547                         {
2548                                 free(printer.info_2->devmode);
2549                         }
2550                         printer.info_2->devmode=NULL;
2551                 }
2552                                 
2553                 add_a_printer(printer, level);
2554                 free_a_printer(printer, level);
2555         }       
2556 }
2557
2558 /****************************************************************************
2559 ****************************************************************************/
2560 static void spoolss_reply_setprinter(SPOOL_Q_SETPRINTER *q_u, prs_struct *rdata)
2561 {
2562         SPOOL_R_SETPRINTER r_u;
2563
2564         /*
2565           Let's the sun shine !!!
2566           Always respond everything is alright
2567         */
2568         
2569         r_u.status=0x0;
2570
2571         spoolss_io_r_setprinter("",&r_u,rdata,0);
2572 }
2573
2574 /****************************************************************************
2575 ****************************************************************************/
2576 static void api_spoolss_setprinter(pipes_struct *p, prs_struct *data,
2577                                    prs_struct *rdata)
2578 {
2579         SPOOL_Q_SETPRINTER q_u;
2580         int pnum;
2581         spoolss_io_q_setprinter("", &q_u, data, 0);
2582         
2583         pnum = find_printer_index_by_hnd(&(q_u.handle));
2584         
2585         if (OPEN_HANDLE(pnum))
2586         {
2587                 /* check the level */   
2588                 switch (q_u.level)
2589                 {
2590                         case 0:
2591                                 control_printer(q_u.handle, q_u.command, p->conn);
2592                                 break;
2593                         case 2:
2594                                 update_printer(q_u.handle, q_u.level, q_u.info, q_u.devmode);
2595                                 break;
2596                 }
2597         }
2598         spoolss_reply_setprinter(&q_u, rdata);
2599 }
2600
2601 /****************************************************************************
2602 ****************************************************************************/
2603 static void spoolss_reply_fcpn(SPOOL_Q_FCPN *q_u, prs_struct *rdata)
2604 {
2605         SPOOL_R_FCPN r_u;
2606         
2607         r_u.status=0x0;
2608
2609         spoolss_io_r_fcpn("",&r_u,rdata,0);             
2610 }
2611
2612 /****************************************************************************
2613 ****************************************************************************/
2614 static void api_spoolss_fcpn(pipes_struct *p, prs_struct *data,
2615                                    prs_struct *rdata)
2616 {
2617         SPOOL_Q_FCPN q_u;
2618         
2619         spoolss_io_q_fcpn("", &q_u, data, 0);
2620
2621         spoolss_reply_fcpn(&q_u, rdata);
2622 }
2623
2624 /****************************************************************************
2625 ****************************************************************************/
2626 static void spoolss_reply_addjob(SPOOL_Q_ADDJOB *q_u, prs_struct *rdata)
2627 {
2628         SPOOL_R_ADDJOB r_u;
2629         
2630         r_u.status=0x0;
2631
2632         spoolss_io_r_addjob("",&r_u,rdata,0);           
2633 }
2634
2635 /****************************************************************************
2636 ****************************************************************************/
2637 static void api_spoolss_addjob(pipes_struct *p, prs_struct *data,
2638                                    prs_struct *rdata)
2639 {
2640         SPOOL_Q_ADDJOB q_u;
2641         
2642         spoolss_io_q_addjob("", &q_u, data, 0);
2643
2644         spoolss_reply_addjob(&q_u, rdata);
2645         
2646         spoolss_io_free_buffer(&(q_u.buffer));
2647 }
2648
2649 /****************************************************************************
2650 ****************************************************************************/
2651 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
2652                             int position, int snum)
2653 {
2654         pstring temp_name;
2655         
2656         struct tm *t;
2657         time_t unixdate = time(NULL);
2658         
2659         t=gmtime(&unixdate);
2660         snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
2661
2662         job_info->jobid=queue->job;     
2663         make_unistr(&(job_info->printername), lp_servicename(snum));
2664         make_unistr(&(job_info->machinename), temp_name);
2665         make_unistr(&(job_info->username), queue->user);
2666         make_unistr(&(job_info->document), queue->file);
2667         make_unistr(&(job_info->datatype), "RAW");
2668         make_unistr(&(job_info->text_status), "");
2669         job_info->status=queue->status;
2670         job_info->priority=queue->priority;
2671         job_info->position=position;
2672         job_info->totalpages=0;
2673         job_info->pagesprinted=0;
2674
2675         make_systemtime(&(job_info->submitted), t);
2676 }
2677
2678 /****************************************************************************
2679 ****************************************************************************/
2680 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
2681                             int position, int snum)
2682 {
2683         pstring temp_name;
2684         DEVICEMODE *devmode;
2685         NT_PRINTER_INFO_LEVEL ntprinter;
2686         pstring chaine;
2687
2688         struct tm *t;
2689         time_t unixdate = time(NULL);
2690
2691         if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
2692         {
2693                 return (False);
2694         }       
2695         
2696         t=gmtime(&unixdate);
2697         snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
2698
2699         job_info->jobid=queue->job;
2700         
2701         snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter.info_2->printername);
2702         make_unistr(&(job_info->printername), chaine);
2703         
2704         make_unistr(&(job_info->machinename), temp_name);
2705         make_unistr(&(job_info->username), queue->user);
2706         make_unistr(&(job_info->document), queue->file);
2707         make_unistr(&(job_info->notifyname), queue->user);
2708         make_unistr(&(job_info->datatype), "RAW");
2709         make_unistr(&(job_info->printprocessor), "winprint");
2710         make_unistr(&(job_info->parameters), "");
2711         make_unistr(&(job_info->text_status), "");
2712         
2713 /* and here the security descriptor */
2714
2715         job_info->status=queue->status;
2716         job_info->priority=queue->priority;
2717         job_info->position=position;
2718         job_info->starttime=0;
2719         job_info->untiltime=0;
2720         job_info->totalpages=0;
2721         job_info->size=queue->size;
2722         make_systemtime(&(job_info->submitted), t);
2723         job_info->timeelapsed=0;
2724         job_info->pagesprinted=0;
2725
2726         devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
2727         ZERO_STRUCTP(devmode);  
2728         construct_dev_mode(devmode, snum, global_myname);                       
2729         job_info->devmode=devmode;
2730
2731         free_a_printer(ntprinter, 2);
2732         return (True);
2733 }
2734
2735 /****************************************************************************
2736 ****************************************************************************/
2737 static void spoolss_reply_enumjobs(SPOOL_Q_ENUMJOBS *q_u, prs_struct *rdata, connection_struct *conn)
2738 {
2739         SPOOL_R_ENUMJOBS r_u;
2740         int snum;
2741         int count;
2742         int i;
2743         print_queue_struct *queue=NULL;
2744         print_status_struct status;
2745         JOB_INFO_1 *job_info_1=NULL;
2746         JOB_INFO_2 *job_info_2=NULL;
2747
2748         DEBUG(4,("spoolss_reply_enumjobs\n"));
2749         
2750         bzero(&status,sizeof(status));
2751
2752         r_u.offered=q_u->buf_size;
2753
2754
2755         if (get_printer_snum(&(q_u->handle), &snum))
2756         {
2757                 count=get_printqueue(snum, conn, &queue, &status);
2758                 r_u.numofjobs=0;
2759                 
2760                 r_u.level=q_u->level;
2761                 
2762                 DEBUG(4,("count:[%d], status:[%d], [%s]\n", count, status.status, status.message));
2763                 
2764                 switch (r_u.level)
2765                 {
2766                         case 1:
2767                         {
2768                                 for (i=0; i<count; i++)
2769                                 {
2770                                         job_info_1=(JOB_INFO_1 *)malloc(count*sizeof(JOB_INFO_1));
2771                                         add_job1_to_array(&r_u.numofjobs,
2772                                                           &r_u.job.job_info_1,
2773                                                           job_info_1);
2774
2775                                         fill_job_info_1(r_u.job.job_info_1[i], &(queue[i]), i, snum);
2776                                 }
2777                                 break;
2778                         }
2779                         case 2:
2780                         {
2781                                 for (i=0; i<count; i++)
2782                                 {
2783                                         job_info_2=(JOB_INFO_2 *)malloc(count*sizeof(JOB_INFO_2));
2784                                         add_job2_to_array(&r_u.numofjobs,
2785                                                           &r_u.job.job_info_2,
2786                                                           job_info_2);
2787
2788                                         fill_job_info_2(r_u.job.job_info_2[i], &(queue[i]), i, snum);
2789                                 }
2790                                 break;
2791                         }
2792                 }
2793         }
2794
2795         r_u.status = 0x0;
2796
2797         spoolss_io_r_enumjobs("",&r_u,rdata,0);
2798
2799         if (queue) free(queue);
2800 }
2801
2802 /****************************************************************************
2803 ****************************************************************************/
2804 static void api_spoolss_enumjobs(pipes_struct *p, prs_struct *data,
2805                                    prs_struct *rdata)
2806 {
2807         SPOOL_Q_ENUMJOBS q_u;
2808         
2809         spoolss_io_q_enumjobs("", &q_u, data, 0);
2810
2811         spoolss_reply_enumjobs(&q_u, rdata, p->conn);
2812         
2813         spoolss_io_free_buffer(&(q_u.buffer));
2814 }
2815
2816 /****************************************************************************
2817 ****************************************************************************/
2818 static void spoolss_reply_schedulejob(SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *rdata)
2819 {
2820         SPOOL_R_SCHEDULEJOB r_u;
2821         
2822         r_u.status=0x0;
2823
2824         spoolss_io_r_schedulejob("",&r_u,rdata,0);              
2825 }
2826
2827 /****************************************************************************
2828 ****************************************************************************/
2829 static void api_spoolss_schedulejob(pipes_struct *p, prs_struct *data,
2830                                    prs_struct *rdata)
2831 {
2832         SPOOL_Q_SCHEDULEJOB q_u;
2833         
2834         spoolss_io_q_schedulejob("", &q_u, data, 0);
2835
2836         spoolss_reply_schedulejob(&q_u, rdata);
2837 }
2838
2839 /****************************************************************************
2840 ****************************************************************************/
2841 static void spoolss_reply_setjob(SPOOL_Q_SETJOB *q_u, prs_struct *rdata, connection_struct *conn)
2842 {
2843         SPOOL_R_SETJOB r_u;
2844         int snum;
2845         print_queue_struct *queue=NULL;
2846         print_status_struct status;
2847         int i=0;
2848         BOOL found=False;
2849         int count;
2850                 
2851         bzero(&status,sizeof(status));
2852
2853         if (get_printer_snum(&(q_u->handle), &snum))
2854         {
2855                 count=get_printqueue(snum, conn, &queue, &status);              
2856                 while ( (i<count) && found==False )
2857                 {
2858                         if ( q_u->jobid == queue[i].job )
2859                         {
2860                                 found=True;
2861                         }
2862                         i++;
2863                 }
2864                 
2865                 if (found==True)
2866                 {
2867                         switch (q_u->command)
2868                         {
2869                                 case JOB_CONTROL_CANCEL:
2870                                 case JOB_CONTROL_DELETE:
2871                                 {
2872                                         del_printqueue(conn, snum, q_u->jobid);
2873                                         break;
2874                                 }
2875                                 case JOB_CONTROL_PAUSE:
2876                                 {
2877                                         status_printjob(conn, snum, q_u->jobid, LPQ_PAUSED);
2878                                         break;
2879                                 }
2880                                 case JOB_CONTROL_RESUME:
2881                                 {
2882                                         status_printjob(conn, snum, q_u->jobid, LPQ_QUEUED);
2883                                         break;
2884                                 }
2885                         }
2886                 }
2887         }
2888         r_u.status=0x0;
2889         spoolss_io_r_setjob("",&r_u,rdata,0);
2890         if (queue) free(queue);
2891
2892 }
2893
2894 /****************************************************************************
2895 ****************************************************************************/
2896 static void api_spoolss_setjob(pipes_struct *p, prs_struct *data,
2897                                    prs_struct *rdata)
2898 {
2899         SPOOL_Q_SETJOB q_u;
2900         
2901         spoolss_io_q_setjob("", &q_u, data, 0);
2902
2903         spoolss_reply_setjob(&q_u, rdata, p->conn);
2904 }
2905
2906 /****************************************************************************
2907 ****************************************************************************/
2908 static void spoolss_reply_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *rdata, connection_struct *conn)
2909 {
2910         SPOOL_R_ENUMPRINTERDRIVERS r_u;
2911         NT_PRINTER_DRIVER_INFO_LEVEL driver;
2912         int count;
2913         int i;
2914         fstring *list;
2915         DRIVER_INFO_1 *driver_info_1=NULL;
2916         DRIVER_INFO_2 *driver_info_2=NULL;
2917         DRIVER_INFO_3 *driver_info_3=NULL;
2918         fstring servername;
2919         fstring architecture;
2920
2921         DEBUG(4,("spoolss_reply_enumdrivers\n"));
2922         fstrcpy(servername, global_myname);
2923
2924         unistr2_to_ascii(architecture, &(q_u->environment), sizeof(architecture));
2925         count=get_ntdrivers(conn, &list, architecture);
2926
2927         DEBUGADD(4,("we have: [%d] drivers on archi [%s]\n",count, architecture));
2928         for (i=0; i<count; i++)
2929         {
2930                 DEBUGADD(5,("driver [%s]\n",list[i]));
2931         }
2932         
2933         r_u.offered=q_u->buf_size;
2934         r_u.numofdrivers=count;
2935         r_u.level=q_u->level;
2936         
2937         switch (r_u.level)
2938         {
2939                 case 1:
2940                 {
2941                         driver_info_1=(DRIVER_INFO_1 *)malloc(count*sizeof(DRIVER_INFO_1));
2942
2943                         for (i=0; i<count; i++)
2944                         {
2945                                 get_a_printer_driver(&driver, 3, list[i], architecture);
2946                                 fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture );
2947                                 free_a_printer_driver(driver, 3);
2948                         }
2949                         r_u.driver.driver_info_1=driver_info_1;
2950                         break;
2951                 }
2952                 case 2:
2953                 {
2954                         driver_info_2=(DRIVER_INFO_2 *)malloc(count*sizeof(DRIVER_INFO_2));
2955
2956                         for (i=0; i<count; i++)
2957                         {
2958                                 get_a_printer_driver(&driver, 3, list[i], architecture);
2959                                 fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture );
2960                                 free_a_printer_driver(driver, 3);
2961                         }
2962                         r_u.driver.driver_info_2=driver_info_2;
2963                         break;
2964                 }
2965                 case 3:
2966                 {
2967                         driver_info_3=(DRIVER_INFO_3 *)malloc(count*sizeof(DRIVER_INFO_3));
2968
2969                         for (i=0; i<count; i++)
2970                         {
2971                                 get_a_printer_driver(&driver, 3, list[i], architecture);
2972                                 fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture );
2973                                 free_a_printer_driver(driver, 3);
2974                         }
2975                         r_u.driver.driver_info_3=driver_info_3;
2976                         break;
2977                 }
2978         }
2979
2980         r_u.status=0x0;
2981
2982         spoolss_io_r_enumdrivers("",&r_u,rdata,0);
2983
2984         switch (r_u.level)
2985         {
2986                 case 1:
2987                 {
2988                         free(driver_info_1);
2989                         break;
2990                 }
2991                 case 2:
2992                 {
2993                         free(driver_info_2);
2994                         break;
2995                 }
2996                 case 3:
2997                 {
2998                         UNISTR **dependentfiles;
2999                         
3000                         for (i=0; i<count; i++)
3001                         {
3002                                 int j=0;
3003                                 dependentfiles=(driver_info_3[i]).dependentfiles;
3004                                 while ( dependentfiles[j] != NULL )
3005                                 {
3006                                         free(dependentfiles[j]);
3007                                         j++;
3008                                 }
3009                                 
3010                                 free(dependentfiles);           
3011                         }
3012                         free(driver_info_3);
3013                         break;
3014                 }
3015         }
3016 }
3017
3018 /****************************************************************************
3019 ****************************************************************************/
3020
3021 static void api_spoolss_enumprinterdrivers(pipes_struct *p, prs_struct *data,
3022                                    prs_struct *rdata)
3023 {
3024         SPOOL_Q_ENUMPRINTERDRIVERS q_u;
3025         
3026         spoolss_io_q_enumprinterdrivers("", &q_u, data, 0);
3027
3028         spoolss_reply_enumprinterdrivers(&q_u, rdata, p->conn);
3029         
3030         spoolss_io_free_buffer(&(q_u.buffer));
3031 }
3032
3033
3034 /****************************************************************************
3035 ****************************************************************************/
3036 static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
3037 {
3038         form->flag=list->flag;
3039         make_unistr(&(form->name), list->name);
3040         form->width=list->width;
3041         form->length=list->length;
3042         form->left=list->left;
3043         form->top=list->top;
3044         form->right=list->right;
3045         form->bottom=list->bottom;      
3046 }
3047
3048 /****************************************************************************
3049 ****************************************************************************/
3050 static void spoolss_reply_enumforms(SPOOL_Q_ENUMFORMS *q_u, prs_struct *rdata)
3051 {
3052         SPOOL_R_ENUMFORMS r_u;
3053         int count;
3054         int i;
3055         nt_forms_struct *list=NULL;
3056         FORM_1 *forms_1=NULL;
3057
3058         DEBUG(4,("spoolss_reply_enumforms\n"));
3059         
3060         count=get_ntforms(&list);
3061         r_u.offered=q_u->buf_size;
3062         r_u.numofforms=count;
3063         r_u.level=q_u->level;
3064         r_u.status=0x0;
3065
3066         DEBUGADD(5,("Offered buffer size [%d]\n", r_u.offered));
3067         DEBUGADD(5,("Number of forms [%d]\n",     r_u.numofforms));
3068         DEBUGADD(5,("Info level [%d]\n",          r_u.level));
3069                 
3070         switch (r_u.level)
3071         {
3072                 case 1:
3073                 {
3074                         forms_1=(FORM_1 *)malloc(count*sizeof(FORM_1));
3075                         for (i=0; i<count; i++)
3076                         {
3077                                 DEBUGADD(6,("Filling form number [%d]\n",i));
3078                                 fill_form_1(&(forms_1[i]), &(list[i]), i);
3079                         }
3080                         r_u.forms_1=forms_1;
3081                         break;
3082                 }
3083         }
3084         spoolss_io_r_enumforms("",&r_u,rdata,0);
3085         switch (r_u.level)
3086         {
3087                 case 1:
3088                 {
3089                         free(forms_1);
3090                         break;
3091                 }
3092         }
3093         free(list);
3094 }
3095
3096 /****************************************************************************
3097 ****************************************************************************/
3098 static void api_spoolss_enumforms(pipes_struct *p, prs_struct *data,
3099                                    prs_struct *rdata)
3100 {
3101         SPOOL_Q_ENUMFORMS q_u;
3102         
3103         spoolss_io_q_enumforms("", &q_u, data, 0);
3104
3105         spoolss_reply_enumforms(&q_u, rdata);
3106         
3107         spoolss_io_free_buffer(&(q_u.buffer));
3108 }
3109
3110 /****************************************************************************
3111 ****************************************************************************/
3112 static void fill_port_2(PORT_INFO_2 *port, char *name)
3113 {
3114         make_unistr(&(port->port_name), name);
3115         make_unistr(&(port->monitor_name), "Moniteur Local");
3116         make_unistr(&(port->description), "Local Port");
3117 #define PORT_TYPE_WRITE 1
3118         port->port_type=PORT_TYPE_WRITE;
3119         port->reserved=0x0;     
3120 }
3121
3122 /****************************************************************************
3123 ****************************************************************************/
3124 static void spoolss_reply_enumports(SPOOL_Q_ENUMPORTS *q_u, prs_struct *rdata)
3125 {
3126         SPOOL_R_ENUMPORTS r_u;
3127         int i=0;
3128         PORT_INFO_2 *ports_2=NULL;
3129         int n_services=lp_numservices();
3130         int snum;
3131
3132         DEBUG(4,("spoolss_reply_enumports\n"));
3133         
3134         r_u.offered=q_u->buf_size;
3135         r_u.level=q_u->level;
3136         r_u.status=0x0;
3137                 
3138         switch (r_u.level)
3139         {
3140                 case 2:
3141                 {
3142                         ports_2=(PORT_INFO_2 *)malloc(n_services*sizeof(PORT_INFO_2));
3143                         for (snum=0; snum<n_services; snum++)
3144                         {
3145                                 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3146                                 {
3147                                         DEBUGADD(6,("Filling port number [%d]\n",i));
3148                                         fill_port_2(&(ports_2[i]), lp_servicename(snum));
3149                                         i++;
3150                                 }
3151                         }
3152                         r_u.port.port_info_2=ports_2;
3153                         break;
3154                 }
3155         }
3156         r_u.numofports=i;
3157         spoolss_io_r_enumports("",&r_u,rdata,0);
3158         switch (r_u.level)
3159         {
3160                 case 2:
3161                 {
3162                         free(ports_2);
3163                         break;
3164                 }
3165         }
3166 }
3167
3168 /****************************************************************************
3169 ****************************************************************************/
3170 static void api_spoolss_enumports(pipes_struct *p, prs_struct *data,
3171                                    prs_struct *rdata)
3172 {
3173         SPOOL_Q_ENUMPORTS q_u;
3174         
3175         spoolss_io_q_enumports("", &q_u, data, 0);
3176
3177         spoolss_reply_enumports(&q_u, rdata);
3178         
3179         spoolss_io_free_buffer(&(q_u.buffer));
3180 }
3181
3182 /****************************************************************************
3183 ****************************************************************************/
3184 static void spoolss_reply_addprinterex(SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *rdata)
3185 {
3186         SPOOL_R_ADDPRINTEREX r_u;
3187         BOOL printer_open = False;
3188         fstring ascii_name;
3189         fstring server_name;
3190         fstring share_name;
3191         UNISTR2 *portname;
3192         SPOOL_PRINTER_INFO_LEVEL_2 *info2;
3193         SPOOL_PRINTER_INFO_LEVEL *info;
3194         
3195         info=&(q_u->info);
3196         info2=info->info_2;
3197         portname=&(info2->portname);
3198
3199         r_u.status=0x0; /* everything is always nice in this world */
3200
3201         StrnCpy(server_name, global_myname, strlen(global_myname) );
3202         unistr2_to_ascii(share_name, portname, sizeof(share_name)-1);
3203         
3204         slprintf(ascii_name, sizeof(ascii_name)-1, "\\\\%s\\%s", 
3205                  server_name, share_name);
3206                 
3207         printer_open = open_printer_hnd(&(r_u.handle));
3208         set_printer_hnd_printertype(&(r_u.handle), ascii_name);
3209         set_printer_hnd_printername(&(r_u.handle), ascii_name);
3210
3211         spoolss_io_r_addprinterex("", &r_u, rdata, 0);
3212 }
3213
3214 /****************************************************************************
3215 ****************************************************************************/
3216 static void api_spoolss_addprinterex(pipes_struct *p, prs_struct *data, prs_struct *rdata)
3217 {
3218         SPOOL_Q_ADDPRINTEREX q_u;
3219         NT_PRINTER_INFO_LEVEL printer;  
3220         
3221         /* read the stream and decode */
3222         spoolss_io_q_addprinterex("", &q_u, data, 0);
3223
3224         /* NULLify info_2 here */
3225         /* don't put it in convert_printer_info as it's used also with non-NULL values */
3226         printer.info_2=NULL;
3227
3228         /* convert from UNICODE to ASCII */
3229         convert_printer_info(q_u.info, &printer, q_u.level);
3230
3231         /* write the ASCII on disk */
3232         add_a_printer(printer, q_u.level);
3233
3234         spoolss_reply_addprinterex(&q_u, rdata);
3235         /* free mem used in q_u and r_u */
3236         
3237         /* free_add_printer(q_u, r_u); */
3238 }
3239
3240 /****************************************************************************
3241 ****************************************************************************/
3242 static void spoolss_reply_addprinterdriver(SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *rdata)
3243 {
3244         SPOOL_R_ADDPRINTERDRIVER r_u;
3245
3246         r_u.status=0x0; /* everything is always nice in this world */
3247
3248         spoolss_io_r_addprinterdriver("", &r_u, rdata, 0);
3249 }
3250
3251 /****************************************************************************
3252 ****************************************************************************/
3253 static void api_spoolss_addprinterdriver(pipes_struct *p, prs_struct *data,
3254                                          prs_struct *rdata)
3255 {
3256         SPOOL_Q_ADDPRINTERDRIVER q_u;
3257         NT_PRINTER_DRIVER_INFO_LEVEL driver;
3258         
3259         spoolss_io_q_addprinterdriver("", &q_u, data, 0);
3260
3261         convert_printer_driver_info(q_u.info, &driver, q_u.level);
3262
3263         add_a_printer_driver(driver, q_u.level);
3264
3265         spoolss_reply_addprinterdriver(&q_u, rdata);
3266         /* free mem used in q_u and r_u */
3267 }
3268
3269 /****************************************************************************
3270 ****************************************************************************/
3271 static void spoolss_reply_getprinterdriverdirectory(SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *rdata)
3272 {
3273         SPOOL_R_GETPRINTERDRIVERDIR r_u;
3274         pstring chaine;
3275         pstring long_archi;
3276         pstring archi;
3277
3278         r_u.offered=q_u->buf_size;
3279         r_u.level=q_u->level;
3280         r_u.status=0x0;
3281         
3282         unistr2_to_ascii(long_archi, &(q_u->environment), sizeof(long_archi)-1);
3283         get_short_archi(archi, long_archi);
3284                 
3285         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\print$\\%s", global_myname, archi);
3286
3287         DEBUG(4,("printer driver directory: [%s]\n", chaine));
3288                                                             
3289         make_unistr(&(r_u.driver.driver_info_1.name), chaine);
3290
3291         spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0);
3292 }
3293
3294 /****************************************************************************
3295 ****************************************************************************/
3296 static void api_spoolss_getprinterdriverdirectory(pipes_struct *p, prs_struct *data,
3297                                                   prs_struct *rdata)
3298 {
3299         SPOOL_Q_GETPRINTERDRIVERDIR q_u;
3300         
3301         spoolss_io_q_getprinterdriverdir("", &q_u, data, 0);
3302         
3303         spoolss_reply_getprinterdriverdirectory(&q_u, rdata);
3304         
3305         spoolss_io_free_buffer(&(q_u.buffer));
3306 }
3307
3308 /****************************************************************************
3309 ****************************************************************************/
3310 static void spoolss_reply_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *rdata)
3311 {
3312         SPOOL_R_ENUMPRINTERDATA r_u;
3313         NT_PRINTER_INFO_LEVEL printer;
3314         
3315         uint32 type;
3316         fstring value;
3317         uint8 *data=NULL;
3318         
3319         uint32 param_index;
3320         uint32 biggest_valuesize;
3321         uint32 biggest_datasize;
3322         uint32 data_len;
3323         
3324         int pnum = find_printer_index_by_hnd(&(q_u->handle));
3325         int snum;
3326         
3327         DEBUG(5,("spoolss_reply_enumprinterdata\n"));
3328
3329         if (OPEN_HANDLE(pnum))
3330         {
3331                 get_printer_snum(&(q_u->handle), &snum);
3332                 get_a_printer(&printer, 2, lp_servicename(snum));
3333
3334                 /* The NT machine wants to know the biggest size of value and data */   
3335                 if ( (q_u->valuesize==0) && (q_u->datasize==0) )
3336                 {
3337                         DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
3338                         
3339                         r_u.valuesize=0;
3340                         r_u.realvaluesize=0;
3341                         r_u.type=0;
3342                         r_u.datasize=0;
3343                         r_u.realdatasize=0;
3344                         r_u.status=0;
3345                         
3346                         param_index=0;
3347                         biggest_valuesize=0;
3348                         biggest_datasize=0;
3349                         
3350                         while (get_specific_param_by_index(printer, 2, param_index, value, &data, &type, &data_len))
3351                         {
3352                                 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
3353                                 if (data_len  > biggest_datasize)  biggest_datasize=data_len;
3354
3355                                 param_index++;
3356                         }
3357                         
3358                         /* I wrote it, I didn't designed the protocol */
3359                         if (biggest_valuesize!=0)
3360                         {
3361                                 SIVAL(&(r_u.value),0, 2*(biggest_valuesize+1) );
3362                         }
3363                         r_u.data=(uint8 *)malloc(4*sizeof(uint8));
3364                         SIVAL(r_u.data, 0, biggest_datasize );
3365                 }
3366                 else
3367                 {
3368                         /* 
3369                          * the value len is wrong in NT sp3
3370                          * that's the number of bytes not the number of unicode chars
3371                          */
3372                          
3373                         r_u.valuesize=q_u->valuesize;
3374                         r_u.datasize=q_u->datasize;
3375
3376                         if (get_specific_param_by_index(printer, 2, q_u->index, value, &data, &type, &data_len))
3377                         {
3378                                 make_unistr(&(r_u.value), value);
3379                                 r_u.data=data;
3380                                 
3381                                 r_u.type=type;
3382
3383                                 /* the length are in bytes including leading NULL */
3384                                 r_u.realvaluesize=2*(strlen(value)+1);
3385                                 r_u.realdatasize=data_len;
3386                                 
3387                                 r_u.status=0;
3388                         }
3389                         else
3390                         {
3391                                 r_u.valuesize=0;
3392                                 r_u.realvaluesize=0;
3393                                 r_u.datasize=0;
3394                                 r_u.realdatasize=0;
3395                                 r_u.type=0;
3396                                 r_u.status=0x0103; /* ERROR_NO_MORE_ITEMS */
3397                         }               
3398                 }
3399                 
3400                 free_a_printer(printer, 2);
3401         }
3402         spoolss_io_r_enumprinterdata("", &r_u, rdata, 0);
3403         if (r_u.data!=NULL) free(r_u.data);
3404 }
3405
3406 /****************************************************************************
3407 ****************************************************************************/
3408 static void api_spoolss_enumprinterdata(pipes_struct *p, prs_struct *data,
3409                                                   prs_struct *rdata)
3410 {
3411         SPOOL_Q_ENUMPRINTERDATA q_u;
3412         
3413         spoolss_io_q_enumprinterdata("", &q_u, data, 0);
3414         
3415         spoolss_reply_enumprinterdata(&q_u, rdata);
3416 }
3417
3418 /****************************************************************************
3419 ****************************************************************************/
3420 static void spoolss_reply_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *rdata)
3421 {
3422         SPOOL_R_SETPRINTERDATA r_u;     
3423         NT_PRINTER_INFO_LEVEL printer;
3424         NT_PRINTER_PARAM *param = NULL;
3425                 
3426         int pnum=0;
3427         int snum=0;
3428         
3429         DEBUG(5,("spoolss_reply_setprinterdata\n"));
3430
3431         pnum = find_printer_index_by_hnd(&(q_u->handle));
3432         
3433         if (OPEN_HANDLE(pnum))
3434         {
3435                 get_printer_snum(&(q_u->handle), &snum);                
3436                 get_a_printer(&printer, 2, lp_servicename(snum));
3437                 convert_specific_param(&param, q_u->value , q_u->type, q_u->data, q_u->real_len);
3438
3439                 unlink_specific_param_if_exist(printer.info_2, param);
3440                 
3441                 add_a_specific_param(printer.info_2, param);
3442                 
3443                 add_a_printer(printer, 2);
3444                 
3445                 free_a_printer(printer, 2);
3446         }       
3447         
3448         r_u.status = 0x0;
3449         spoolss_io_r_setprinterdata("", &r_u, rdata, 0);
3450 }
3451
3452 /****************************************************************************
3453 ****************************************************************************/
3454 static void api_spoolss_setprinterdata(pipes_struct *p, prs_struct *data,
3455                                        prs_struct *rdata)
3456 {
3457         SPOOL_Q_SETPRINTERDATA q_u;
3458         
3459         spoolss_io_q_setprinterdata("", &q_u, data, 0);
3460         
3461         spoolss_reply_setprinterdata(&q_u, rdata);
3462         
3463         free(q_u.data);
3464 }
3465
3466 /****************************************************************************
3467 ****************************************************************************/
3468 static void spoolss_reply_addform(SPOOL_Q_ADDFORM *q_u, prs_struct *rdata)
3469 {
3470        SPOOL_R_ADDFORM r_u;
3471        int pnum=0;
3472        int count=0;
3473        nt_forms_struct *list=NULL;
3474
3475        DEBUG(5,("spoolss_reply_addform\n"));
3476
3477        pnum = find_printer_index_by_hnd(&(q_u->handle));
3478
3479        if (OPEN_HANDLE(pnum))
3480        {
3481                count=get_ntforms(&list);
3482
3483                add_a_form(&list, q_u->form, &count);
3484
3485                write_ntforms(&list, count);
3486
3487                free(list);
3488        }
3489
3490        r_u.status = 0x0;
3491        spoolss_io_r_addform("", &r_u, rdata, 0);
3492 }
3493
3494 /****************************************************************************
3495 ****************************************************************************/
3496 static void api_spoolss_addform(pipes_struct *p, prs_struct *data,
3497                                 prs_struct *rdata)
3498 {
3499        SPOOL_Q_ADDFORM q_u;
3500
3501        spoolss_io_q_addform("", &q_u, data, 0);
3502
3503        spoolss_reply_addform(&q_u, rdata);
3504 }
3505
3506 /****************************************************************************
3507 ****************************************************************************/
3508 static void spoolss_reply_setform(SPOOL_Q_SETFORM *q_u, prs_struct *rdata)
3509 {
3510         SPOOL_R_SETFORM r_u;
3511         int pnum=0;
3512         int count=0;
3513         nt_forms_struct *list=NULL;
3514
3515         DEBUG(5,("spoolss_reply_setform\n"));
3516
3517         pnum = find_printer_index_by_hnd(&(q_u->handle));
3518
3519         if (OPEN_HANDLE(pnum))
3520         {
3521                 count=get_ntforms(&list);
3522
3523                 update_a_form(&list, q_u->form, count);
3524
3525                 write_ntforms(&list, count);
3526
3527                 free(list);
3528         }
3529         r_u.status = 0x0;
3530         spoolss_io_r_setform("", &r_u, rdata, 0);
3531 }
3532
3533 /****************************************************************************
3534 ****************************************************************************/
3535 static void api_spoolss_setform(pipes_struct *p, prs_struct *data,
3536                                 prs_struct *rdata)
3537 {
3538         SPOOL_Q_SETFORM q_u;
3539
3540         spoolss_io_q_setform("", &q_u, data, 0);
3541
3542         spoolss_reply_setform(&q_u, rdata);
3543 }
3544
3545 /****************************************************************************
3546 ****************************************************************************/
3547 static void spoolss_reply_enumprintprocessors(SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *rdata)
3548 {
3549         SPOOL_R_ENUMPRINTPROCESSORS r_u;
3550         PRINTPROCESSOR_1 *info_1;
3551         
3552         DEBUG(5,("spoolss_reply_enumprintprocessors\n"));
3553
3554         /* 
3555          * Enumerate the print processors ...
3556          *
3557          * Just reply with "winprint", to keep NT happy
3558          * and I can use my nice printer checker.
3559          */
3560         
3561         r_u.status = 0x0;
3562         r_u.offered = q_u->buf_size;
3563         r_u.level = q_u->level;
3564         
3565         r_u.numofprintprocessors = 0x1;
3566         
3567         info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1));
3568         
3569         make_unistr(&(info_1->name), "winprint");
3570         
3571         r_u.info_1=info_1;
3572         
3573         spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0);
3574         
3575         free(info_1);
3576 }
3577
3578 /****************************************************************************
3579 ****************************************************************************/
3580 static void api_spoolss_enumprintprocessors(pipes_struct *p, prs_struct *data,
3581                                             prs_struct *rdata)
3582 {
3583         SPOOL_Q_ENUMPRINTPROCESSORS q_u;
3584
3585         spoolss_io_q_enumprintprocessors("", &q_u, data, 0);
3586
3587         spoolss_reply_enumprintprocessors(&q_u, rdata);
3588
3589         spoolss_io_free_buffer(&(q_u.buffer));