* basic implementation of SPOOLSS_DELETEPRINTERDATAEX and
[Samba.git] / source / rpc_parse / parse_spoolss.c
blobb350bf6db3059128de710b25428576ee81066a85
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Gerald Carter 2000-2002,
8 * Copyright (C) Tim Potter 2001-2002.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_PARSE
30 /*******************************************************************
31 return the length of a UNISTR string.
32 ********************************************************************/
34 static uint32 str_len_uni(UNISTR *source)
36 uint32 i=0;
38 if (!source->buffer)
39 return 0;
41 while (source->buffer[i])
42 i++;
44 return i;
47 /*******************************************************************
48 This should be moved in a more generic lib.
49 ********************************************************************/
51 BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
53 if(!prs_uint16("year", ps, depth, &systime->year))
54 return False;
55 if(!prs_uint16("month", ps, depth, &systime->month))
56 return False;
57 if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
58 return False;
59 if(!prs_uint16("day", ps, depth, &systime->day))
60 return False;
61 if(!prs_uint16("hour", ps, depth, &systime->hour))
62 return False;
63 if(!prs_uint16("minute", ps, depth, &systime->minute))
64 return False;
65 if(!prs_uint16("second", ps, depth, &systime->second))
66 return False;
67 if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
68 return False;
70 return True;
73 /*******************************************************************
74 ********************************************************************/
76 BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
78 systime->year=unixtime->tm_year+1900;
79 systime->month=unixtime->tm_mon+1;
80 systime->dayofweek=unixtime->tm_wday;
81 systime->day=unixtime->tm_mday;
82 systime->hour=unixtime->tm_hour;
83 systime->minute=unixtime->tm_min;
84 systime->second=unixtime->tm_sec;
85 systime->milliseconds=0;
87 return True;
90 /*******************************************************************
91 reads or writes an DOC_INFO structure.
92 ********************************************************************/
94 static BOOL smb_io_doc_info_1(char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
96 if (info_1 == NULL) return False;
98 prs_debug(ps, depth, desc, "smb_io_doc_info_1");
99 depth++;
101 if(!prs_align(ps))
102 return False;
104 if(!prs_uint32("p_docname", ps, depth, &info_1->p_docname))
105 return False;
106 if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
107 return False;
108 if(!prs_uint32("p_datatype", ps, depth, &info_1->p_datatype))
109 return False;
111 if(!smb_io_unistr2("", &info_1->docname, info_1->p_docname, ps, depth))
112 return False;
113 if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
114 return False;
115 if(!smb_io_unistr2("", &info_1->datatype, info_1->p_datatype, ps, depth))
116 return False;
118 return True;
121 /*******************************************************************
122 reads or writes an DOC_INFO structure.
123 ********************************************************************/
125 static BOOL smb_io_doc_info(char *desc, DOC_INFO *info, prs_struct *ps, int depth)
127 uint32 useless_ptr=0;
129 if (info == NULL) return False;
131 prs_debug(ps, depth, desc, "smb_io_doc_info");
132 depth++;
134 if(!prs_align(ps))
135 return False;
137 if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
138 return False;
140 if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
141 return False;
143 switch (info->switch_value)
145 case 1:
146 if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
147 return False;
148 break;
149 case 2:
151 this is just a placeholder
153 MSDN July 1998 says doc_info_2 is only on
154 Windows 95, and as Win95 doesn't do RPC to print
155 this case is nearly impossible
157 Maybe one day with Windows for dishwasher 2037 ...
160 /* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
161 break;
162 default:
163 DEBUG(0,("Something is obviously wrong somewhere !\n"));
164 break;
167 return True;
170 /*******************************************************************
171 reads or writes an DOC_INFO_CONTAINER structure.
172 ********************************************************************/
174 static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
176 if (cont == NULL) return False;
178 prs_debug(ps, depth, desc, "smb_io_doc_info_container");
179 depth++;
181 if(!prs_align(ps))
182 return False;
184 if(!prs_uint32("level", ps, depth, &cont->level))
185 return False;
187 if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
188 return False;
190 return True;
193 /*******************************************************************
194 reads or writes an NOTIFY OPTION TYPE structure.
195 ********************************************************************/
197 /* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
198 structure. The _TYPE structure is really the deferred referrants (i.e
199 the notify fields array) of the _TYPE structure. -tpot */
201 static BOOL smb_io_notify_option_type(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
203 prs_debug(ps, depth, desc, "smb_io_notify_option_type");
204 depth++;
206 if (!prs_align(ps))
207 return False;
209 if(!prs_uint16("type", ps, depth, &type->type))
210 return False;
211 if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
212 return False;
213 if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
214 return False;
215 if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
216 return False;
217 if(!prs_uint32("count", ps, depth, &type->count))
218 return False;
219 if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
220 return False;
222 return True;
225 /*******************************************************************
226 reads or writes an NOTIFY OPTION TYPE DATA.
227 ********************************************************************/
229 static BOOL smb_io_notify_option_type_data(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
231 int i;
233 prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
234 depth++;
236 /* if there are no fields just return */
237 if (type->fields_ptr==0)
238 return True;
240 if(!prs_align(ps))
241 return False;
243 if(!prs_uint32("count2", ps, depth, &type->count2))
244 return False;
246 if (type->count2 != type->count)
247 DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
249 /* parse the option type data */
250 for(i=0;i<type->count2;i++)
251 if(!prs_uint16("fields",ps,depth,&type->fields[i]))
252 return False;
253 return True;
256 /*******************************************************************
257 reads or writes an NOTIFY OPTION structure.
258 ********************************************************************/
260 static BOOL smb_io_notify_option_type_ctr(char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
262 int i;
264 prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
265 depth++;
267 if(!prs_uint32("count", ps, depth, &ctr->count))
268 return False;
270 /* reading */
271 if (UNMARSHALLING(ps))
272 if((ctr->type=(SPOOL_NOTIFY_OPTION_TYPE *)prs_alloc_mem(ps,ctr->count*sizeof(SPOOL_NOTIFY_OPTION_TYPE))) == NULL)
273 return False;
275 /* the option type struct */
276 for(i=0;i<ctr->count;i++)
277 if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
278 return False;
280 /* the type associated with the option type struct */
281 for(i=0;i<ctr->count;i++)
282 if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
283 return False;
285 return True;
288 /*******************************************************************
289 reads or writes an NOTIFY OPTION structure.
290 ********************************************************************/
292 static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
294 prs_debug(ps, depth, desc, "smb_io_notify_option");
295 depth++;
297 if(!prs_uint32("version", ps, depth, &option->version))
298 return False;
299 if(!prs_uint32("flags", ps, depth, &option->flags))
300 return False;
301 if(!prs_uint32("count", ps, depth, &option->count))
302 return False;
303 if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
304 return False;
306 /* marshalling or unmarshalling, that would work */
307 if (option->option_type_ptr!=0) {
308 if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
309 return False;
311 else {
312 option->ctr.type=NULL;
313 option->ctr.count=0;
316 return True;
319 /*******************************************************************
320 reads or writes an NOTIFY INFO DATA structure.
321 ********************************************************************/
323 static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
325 uint32 useless_ptr=0xADDE0FF0;
327 prs_debug(ps, depth, desc, "smb_io_notify_info_data");
328 depth++;
330 if(!prs_align(ps))
331 return False;
332 if(!prs_uint16("type", ps, depth, &data->type))
333 return False;
334 if(!prs_uint16("field", ps, depth, &data->field))
335 return False;
337 if(!prs_uint32("how many words", ps, depth, &data->size))
338 return False;
339 if(!prs_uint32("id", ps, depth, &data->id))
340 return False;
341 if(!prs_uint32("how many words", ps, depth, &data->size))
342 return False;
344 switch (data->enc_type) {
346 /* One and two value data has two uint32 values */
348 case NOTIFY_ONE_VALUE:
349 case NOTIFY_TWO_VALUE:
351 if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
352 return False;
353 if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
354 return False;
355 break;
357 /* Pointers and strings have a string length and a
358 pointer. For a string the length is expressed as
359 the number of uint16 characters plus a trailing
360 \0\0. */
362 case NOTIFY_POINTER:
364 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
365 return False;
366 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
367 return False;
369 break;
371 case NOTIFY_STRING:
373 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
374 return False;
376 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
377 return False;
379 break;
381 default:
382 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
383 data->enc_type));
384 break;
387 return True;
390 /*******************************************************************
391 reads or writes an NOTIFY INFO DATA structure.
392 ********************************************************************/
394 BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
395 prs_struct *ps, int depth)
397 prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
398 depth++;
400 if(!prs_align(ps))
401 return False;
403 switch(data->enc_type) {
405 /* No data for values */
407 case NOTIFY_ONE_VALUE:
408 case NOTIFY_TWO_VALUE:
410 break;
412 /* Strings start with a length in uint16s */
414 case NOTIFY_STRING:
416 if (UNMARSHALLING(ps)) {
417 data->notify_data.data.string =
418 (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
420 if (!data->notify_data.data.string)
421 return False;
424 if (MARSHALLING(ps))
425 data->notify_data.data.length /= 2;
427 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
428 return False;
430 if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
431 data->notify_data.data.length))
432 return False;
434 if (MARSHALLING(ps))
435 data->notify_data.data.length *= 2;
437 break;
439 case NOTIFY_POINTER:
441 if (UNMARSHALLING(ps)) {
442 data->notify_data.data.string =
443 (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
445 if (!data->notify_data.data.string)
446 return False;
449 if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
450 return False;
452 break;
454 default:
455 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
456 data->enc_type));
457 break;
460 #if 0
461 if (isvalue==False) {
463 /* length of string in unicode include \0 */
464 x=data->notify_data.data.length+1;
466 if (data->field != 16)
467 if(!prs_uint32("string length", ps, depth, &x ))
468 return False;
470 if (MARSHALLING(ps)) {
471 /* These are already in little endian format. Don't byte swap. */
472 if (x == 1) {
474 /* No memory allocated for this string
475 therefore following the data.string
476 pointer is a bad idea. Use a pointer to
477 the uint32 length union member to
478 provide a source for a unicode NULL */
480 if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2))
481 return False;
482 } else {
484 if (data->field == 16)
485 x /= 2;
487 if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
488 return False;
490 } else {
492 /* Tallocate memory for string */
494 data->notify_data.data.string = (uint16 *)prs_alloc_mem(ps, x * 2);
495 if (!data->notify_data.data.string)
496 return False;
498 if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
499 return False;
503 #endif
505 #if 0 /* JERRY */
506 /* Win2k does not seem to put this parse align here */
507 if(!prs_align(ps))
508 return False;
509 #endif
511 return True;
514 /*******************************************************************
515 reads or writes an NOTIFY INFO structure.
516 ********************************************************************/
518 static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
520 int i;
522 prs_debug(ps, depth, desc, "smb_io_notify_info");
523 depth++;
525 if(!prs_align(ps))
526 return False;
528 if(!prs_uint32("count", ps, depth, &info->count))
529 return False;
530 if(!prs_uint32("version", ps, depth, &info->version))
531 return False;
532 if(!prs_uint32("flags", ps, depth, &info->flags))
533 return False;
534 if(!prs_uint32("count", ps, depth, &info->count))
535 return False;
537 for (i=0;i<info->count;i++) {
538 if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
539 return False;
542 /* now do the strings at the end of the stream */
543 for (i=0;i<info->count;i++) {
544 if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
545 return False;
548 return True;
551 /*******************************************************************
552 ********************************************************************/
554 static BOOL spool_io_user_level_1(char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth)
556 prs_debug(ps, depth, desc, "");
557 depth++;
559 /* reading */
560 if (UNMARSHALLING(ps))
561 ZERO_STRUCTP(q_u);
563 if (!prs_align(ps))
564 return False;
565 if (!prs_uint32("size", ps, depth, &q_u->size))
566 return False;
567 if (!prs_uint32("client_name_ptr", ps, depth, &q_u->client_name_ptr))
568 return False;
569 if (!prs_uint32("user_name_ptr", ps, depth, &q_u->user_name_ptr))
570 return False;
571 if (!prs_uint32("build", ps, depth, &q_u->build))
572 return False;
573 if (!prs_uint32("major", ps, depth, &q_u->major))
574 return False;
575 if (!prs_uint32("minor", ps, depth, &q_u->minor))
576 return False;
577 if (!prs_uint32("processor", ps, depth, &q_u->processor))
578 return False;
580 if (!smb_io_unistr2("", &q_u->client_name, q_u->client_name_ptr, ps, depth))
581 return False;
582 if (!prs_align(ps))
583 return False;
584 if (!smb_io_unistr2("", &q_u->user_name, q_u->user_name_ptr, ps, depth))
585 return False;
587 return True;
590 /*******************************************************************
591 ********************************************************************/
593 static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
595 if (q_u==NULL)
596 return False;
598 prs_debug(ps, depth, desc, "spool_io_user_level");
599 depth++;
601 if (!prs_align(ps))
602 return False;
603 if (!prs_uint32("level", ps, depth, &q_u->level))
604 return False;
605 if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
606 return False;
608 switch (q_u->level) {
609 case 1:
610 if (!spool_io_user_level_1("", &q_u->user1, ps, depth))
611 return False;
612 break;
613 default:
614 return False;
617 return True;
620 /*******************************************************************
621 * read or write a DEVICEMODE struct.
622 * on reading allocate memory for the private member
623 ********************************************************************/
625 #define DM_NUM_OPTIONAL_FIELDS 8
627 BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
629 uint32 available_space; /* size of the device mode left to parse */
630 /* only important on unmarshalling */
631 int i = 0;
633 struct optional_fields {
634 fstring name;
635 uint32* field;
636 } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
637 { "icmmethod", NULL },
638 { "icmintent", NULL },
639 { "mediatype", NULL },
640 { "dithertype", NULL },
641 { "reserved1", NULL },
642 { "reserved2", NULL },
643 { "panningwidth", NULL },
644 { "panningheight", NULL }
647 /* assign at run time to keep non-gcc vompilers happy */
649 opt_fields[0].field = &devmode->icmmethod;
650 opt_fields[1].field = &devmode->icmintent;
651 opt_fields[2].field = &devmode->mediatype;
652 opt_fields[3].field = &devmode->dithertype;
653 opt_fields[4].field = &devmode->reserved1;
654 opt_fields[5].field = &devmode->reserved2;
655 opt_fields[6].field = &devmode->panningwidth;
656 opt_fields[7].field = &devmode->panningheight;
659 prs_debug(ps, depth, desc, "spoolss_io_devmode");
660 depth++;
662 if (UNMARSHALLING(ps)) {
663 devmode->devicename.buffer = (uint16 *)prs_alloc_mem(ps, 32 * sizeof(uint16) );
664 if (devmode->devicename.buffer == NULL)
665 return False;
668 if (!prs_uint16uni(True,"devicename", ps, depth, devmode->devicename.buffer, 32))
669 return False;
671 if (!prs_uint16("specversion", ps, depth, &devmode->specversion))
672 return False;
674 /* Sanity Check - look for unknown specversions, but don't fail if we see one.
675 Let the size determine that */
677 switch (devmode->specversion) {
678 case 0x0320:
679 case 0x0400:
680 case 0x0401:
681 break;
683 default:
684 DEBUG(0,("spoolss_io_devmode: Unknown specversion in devicemode [0x%x]\n",
685 devmode->specversion));
686 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
687 break;
691 if (!prs_uint16("driverversion", ps, depth, &devmode->driverversion))
692 return False;
693 if (!prs_uint16("size", ps, depth, &devmode->size))
694 return False;
695 if (!prs_uint16("driverextra", ps, depth, &devmode->driverextra))
696 return False;
697 if (!prs_uint32("fields", ps, depth, &devmode->fields))
698 return False;
699 if (!prs_uint16("orientation", ps, depth, &devmode->orientation))
700 return False;
701 if (!prs_uint16("papersize", ps, depth, &devmode->papersize))
702 return False;
703 if (!prs_uint16("paperlength", ps, depth, &devmode->paperlength))
704 return False;
705 if (!prs_uint16("paperwidth", ps, depth, &devmode->paperwidth))
706 return False;
707 if (!prs_uint16("scale", ps, depth, &devmode->scale))
708 return False;
709 if (!prs_uint16("copies", ps, depth, &devmode->copies))
710 return False;
711 if (!prs_uint16("defaultsource", ps, depth, &devmode->defaultsource))
712 return False;
713 if (!prs_uint16("printquality", ps, depth, &devmode->printquality))
714 return False;
715 if (!prs_uint16("color", ps, depth, &devmode->color))
716 return False;
717 if (!prs_uint16("duplex", ps, depth, &devmode->duplex))
718 return False;
719 if (!prs_uint16("yresolution", ps, depth, &devmode->yresolution))
720 return False;
721 if (!prs_uint16("ttoption", ps, depth, &devmode->ttoption))
722 return False;
723 if (!prs_uint16("collate", ps, depth, &devmode->collate))
724 return False;
726 if (UNMARSHALLING(ps)) {
727 devmode->formname.buffer = (uint16 *)prs_alloc_mem(ps, 32 * sizeof(uint16) );
728 if (devmode->formname.buffer == NULL)
729 return False;
732 if (!prs_uint16uni(True, "formname", ps, depth, devmode->formname.buffer, 32))
733 return False;
734 if (!prs_uint16("logpixels", ps, depth, &devmode->logpixels))
735 return False;
736 if (!prs_uint32("bitsperpel", ps, depth, &devmode->bitsperpel))
737 return False;
738 if (!prs_uint32("pelswidth", ps, depth, &devmode->pelswidth))
739 return False;
740 if (!prs_uint32("pelsheight", ps, depth, &devmode->pelsheight))
741 return False;
742 if (!prs_uint32("displayflags", ps, depth, &devmode->displayflags))
743 return False;
744 if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
745 return False;
747 * every device mode I've ever seen on the wire at least has up
748 * to the displayfrequency field. --jerry (05-09-2002)
751 /* add uint32's + uint16's + two UNICODE strings */
753 available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
755 /* Sanity check - we only have uint32's left tp parse */
757 if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
758 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
759 available_space, devmode->size));
760 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
761 return False;
765 * Conditional parsing. Assume that the DeviceMode has been
766 * zero'd by the caller.
769 while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
771 DEBUG(10, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
772 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
773 return False;
774 available_space -= sizeof(uint32);
775 i++;
778 /* Sanity Check - we should no available space at this point unless
779 MS changes the device mode structure */
781 if (available_space) {
782 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
783 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
784 available_space, devmode->size));
785 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
786 return False;
790 if (devmode->driverextra!=0) {
791 if (UNMARSHALLING(ps)) {
792 devmode->private=(uint8 *)prs_alloc_mem(ps, devmode->driverextra*sizeof(uint8));
793 if(devmode->private == NULL)
794 return False;
795 DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra));
798 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra));
799 if (!prs_uint8s(False, "private", ps, depth,
800 devmode->private, devmode->driverextra))
801 return False;
804 return True;
807 /*******************************************************************
808 Read or write a DEVICEMODE container
809 ********************************************************************/
811 static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
813 if (dm_c==NULL)
814 return False;
816 prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
817 depth++;
819 if(!prs_align(ps))
820 return False;
822 if (!prs_uint32("size", ps, depth, &dm_c->size))
823 return False;
825 if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
826 return False;
828 if (dm_c->size==0 || dm_c->devmode_ptr==0) {
829 if (UNMARSHALLING(ps))
830 /* if while reading there is no DEVMODE ... */
831 dm_c->devmode=NULL;
832 return True;
835 /* so we have a DEVICEMODE to follow */
836 if (UNMARSHALLING(ps)) {
837 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
838 dm_c->devmode=(DEVICEMODE *)prs_alloc_mem(ps,sizeof(DEVICEMODE));
839 if(dm_c->devmode == NULL)
840 return False;
843 /* this is bad code, shouldn't be there */
844 if (!prs_uint32("size", ps, depth, &dm_c->size))
845 return False;
847 if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
848 return False;
850 return True;
853 /*******************************************************************
854 ********************************************************************/
856 static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
858 if (pd==NULL)
859 return False;
861 prs_debug(ps, depth, desc, "spoolss_io_printer_default");
862 depth++;
864 if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
865 return False;
867 if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
868 return False;
870 if (!prs_align(ps))
871 return False;
873 if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
874 return False;
876 if (!prs_align(ps))
877 return False;
879 if (!prs_uint32("access_required", ps, depth, &pd->access_required))
880 return False;
882 return True;
885 /*******************************************************************
886 * init a structure.
887 ********************************************************************/
889 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
890 const fstring printername,
891 const fstring datatype,
892 uint32 access_required,
893 const fstring clientname,
894 const fstring user_name)
896 DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
897 q_u->printername_ptr = (printername!=NULL)?1:0;
898 init_unistr2(&q_u->printername, printername, strlen(printername)+1);
900 q_u->printer_default.datatype_ptr = 0;
902 q_u->printer_default.datatype_ptr = (datatype!=NULL)?1:0;
903 init_unistr2(&q_u->printer_default.datatype, datatype, strlen(datatype));
905 q_u->printer_default.devmode_cont.size=0;
906 q_u->printer_default.devmode_cont.devmode_ptr=0;
907 q_u->printer_default.devmode_cont.devmode=NULL;
908 q_u->printer_default.access_required=access_required;
909 q_u->user_switch=1;
910 q_u->user_ctr.level=1;
911 q_u->user_ctr.ptr=1;
912 q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+10;
913 q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
914 q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
915 q_u->user_ctr.user1.build=1381;
916 q_u->user_ctr.user1.major=2;
917 q_u->user_ctr.user1.minor=0;
918 q_u->user_ctr.user1.processor=0;
919 init_unistr2(&q_u->user_ctr.user1.client_name, clientname, strlen(clientname)+1);
920 init_unistr2(&q_u->user_ctr.user1.user_name, user_name, strlen(user_name)+1);
922 return True;
925 /*******************************************************************
926 * init a structure.
927 ********************************************************************/
929 BOOL make_spoolss_q_addprinterex(
930 TALLOC_CTX *mem_ctx,
931 SPOOL_Q_ADDPRINTEREX *q_u,
932 const char *srv_name,
933 const char* clientname,
934 const char* user_name,
935 uint32 level,
936 PRINTER_INFO_CTR *ctr)
938 DEBUG(5,("make_spoolss_q_addprinterex\n"));
940 if (!ctr) return False;
942 ZERO_STRUCTP(q_u);
944 q_u->server_name_ptr = (srv_name!=NULL)?1:0;
945 init_unistr2(&q_u->server_name, srv_name, strlen(srv_name));
947 q_u->level = level;
949 q_u->info.level = level;
950 q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
951 switch (level) {
952 case 2:
953 /* init q_u->info.info2 from *info */
954 if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
955 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
956 return False;
958 break;
959 default :
960 break;
963 q_u->user_switch=1;
965 q_u->user_ctr.level=1;
966 q_u->user_ctr.ptr=1;
967 q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
968 q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
969 q_u->user_ctr.user1.build=1381;
970 q_u->user_ctr.user1.major=2;
971 q_u->user_ctr.user1.minor=0;
972 q_u->user_ctr.user1.processor=0;
973 init_unistr2(&q_u->user_ctr.user1.client_name, clientname, strlen(clientname)+1);
974 init_unistr2(&q_u->user_ctr.user1.user_name, user_name, strlen(user_name)+1);
975 q_u->user_ctr.user1.size=q_u->user_ctr.user1.user_name.uni_str_len +
976 q_u->user_ctr.user1.client_name.uni_str_len + 2;
978 return True;
981 /*******************************************************************
982 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
983 *******************************************************************/
985 BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
986 PRINTER_INFO_2 *info)
989 SPOOL_PRINTER_INFO_LEVEL_2 *inf;
991 /* allocate the necessary memory */
992 if (!(inf=(SPOOL_PRINTER_INFO_LEVEL_2*)talloc(mem_ctx, sizeof(SPOOL_PRINTER_INFO_LEVEL_2)))) {
993 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
994 return False;
997 inf->servername_ptr = (info->servername.buffer!=NULL)?1:0;
998 inf->printername_ptr = (info->printername.buffer!=NULL)?1:0;
999 inf->sharename_ptr = (info->sharename.buffer!=NULL)?1:0;
1000 inf->portname_ptr = (info->portname.buffer!=NULL)?1:0;
1001 inf->drivername_ptr = (info->drivername.buffer!=NULL)?1:0;
1002 inf->comment_ptr = (info->comment.buffer!=NULL)?1:0;
1003 inf->location_ptr = (info->location.buffer!=NULL)?1:0;
1004 inf->devmode_ptr = (info->devmode!=NULL)?1:0;
1005 inf->sepfile_ptr = (info->sepfile.buffer!=NULL)?1:0;
1006 inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
1007 inf->datatype_ptr = (info->datatype.buffer!=NULL)?1:0;
1008 inf->parameters_ptr = (info->parameters.buffer!=NULL)?1:0;
1009 inf->secdesc_ptr = (info->secdesc!=NULL)?1:0;
1010 inf->attributes = info->attributes;
1011 inf->priority = info->priority;
1012 inf->default_priority = info->defaultpriority;
1013 inf->starttime = info->starttime;
1014 inf->untiltime = info->untiltime;
1015 inf->cjobs = info->cjobs;
1016 inf->averageppm = info->averageppm;
1017 init_unistr2_from_unistr(&inf->servername, &info->servername);
1018 init_unistr2_from_unistr(&inf->printername, &info->printername);
1019 init_unistr2_from_unistr(&inf->sharename, &info->sharename);
1020 init_unistr2_from_unistr(&inf->portname, &info->portname);
1021 init_unistr2_from_unistr(&inf->drivername, &info->drivername);
1022 init_unistr2_from_unistr(&inf->comment, &info->comment);
1023 init_unistr2_from_unistr(&inf->location, &info->location);
1024 init_unistr2_from_unistr(&inf->sepfile, &info->sepfile);
1025 init_unistr2_from_unistr(&inf->printprocessor, &info->printprocessor);
1026 init_unistr2_from_unistr(&inf->datatype, &info->datatype);
1027 init_unistr2_from_unistr(&inf->parameters, &info->parameters);
1028 init_unistr2_from_unistr(&inf->datatype, &info->datatype);
1030 *spool_info2 = inf;
1032 return True;
1036 /*******************************************************************
1037 * read a structure.
1038 * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1039 ********************************************************************/
1041 BOOL spoolss_io_q_open_printer(char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
1043 if (q_u == NULL)
1044 return False;
1046 prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
1047 depth++;
1049 if (!prs_align(ps))
1050 return False;
1052 if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
1053 return False;
1054 if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
1055 return False;
1057 if (!prs_align(ps))
1058 return False;
1060 if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1061 return False;
1063 return True;
1066 /*******************************************************************
1067 * write a structure.
1068 * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1069 * called from spoolss_open_printer_ex (cli_spoolss.c)
1070 ********************************************************************/
1072 BOOL spoolss_io_r_open_printer(char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
1074 if (r_u == NULL) return False;
1076 prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
1077 depth++;
1079 if (!prs_align(ps))
1080 return False;
1082 if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1083 return False;
1085 if (!prs_werror("status code", ps, depth, &(r_u->status)))
1086 return False;
1088 return True;
1092 /*******************************************************************
1093 * read a structure.
1094 * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1095 ********************************************************************/
1097 BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
1099 if (q_u == NULL)
1100 return False;
1102 prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
1103 depth++;
1105 if (!prs_align(ps))
1106 return False;
1108 if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
1109 return False;
1110 if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
1111 return False;
1113 if (!prs_align(ps))
1114 return False;
1116 if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1117 return False;
1119 if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
1120 return False;
1121 if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
1122 return False;
1124 return True;
1127 /*******************************************************************
1128 * write a structure.
1129 * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1130 * called from spoolss_open_printer_ex (cli_spoolss.c)
1131 ********************************************************************/
1133 BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1135 if (r_u == NULL) return False;
1137 prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1138 depth++;
1140 if (!prs_align(ps))
1141 return False;
1143 if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1144 return False;
1146 if (!prs_werror("status code", ps, depth, &(r_u->status)))
1147 return False;
1149 return True;
1152 /*******************************************************************
1153 * init a structure.
1154 ********************************************************************/
1155 BOOL make_spoolss_q_deleteprinterdriver(
1156 TALLOC_CTX *mem_ctx,
1157 SPOOL_Q_DELETEPRINTERDRIVER *q_u,
1158 const char *server,
1159 const char* arch,
1160 const char* driver
1163 DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
1165 q_u->server_ptr = (server!=NULL)?1:0;
1167 /* these must be NULL terminated or else NT4 will
1168 complain about invalid parameters --jerry */
1169 init_unistr2(&q_u->server, server, strlen(server)+1);
1170 init_unistr2(&q_u->arch, arch, strlen(arch)+1);
1171 init_unistr2(&q_u->driver, driver, strlen(driver)+1);
1174 return True;
1178 /*******************************************************************
1179 * make a structure.
1180 ********************************************************************/
1182 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1183 const POLICY_HND *handle,
1184 char *valuename, uint32 size)
1186 if (q_u == NULL) return False;
1188 DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1190 q_u->handle = *handle;
1191 init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1);
1192 q_u->size = size;
1194 return True;
1197 /*******************************************************************
1198 * read a structure.
1199 * called from spoolss_q_getprinterdata (srv_spoolss.c)
1200 ********************************************************************/
1202 BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1204 if (q_u == NULL)
1205 return False;
1207 prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1208 depth++;
1210 if (!prs_align(ps))
1211 return False;
1212 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1213 return False;
1214 if (!prs_align(ps))
1215 return False;
1216 if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1217 return False;
1218 if (!prs_align(ps))
1219 return False;
1220 if (!prs_uint32("size", ps, depth, &q_u->size))
1221 return False;
1223 return True;
1226 /*******************************************************************
1227 * read a structure.
1228 * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
1229 ********************************************************************/
1231 BOOL spoolss_io_q_deleteprinterdata(char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
1233 if (q_u == NULL)
1234 return False;
1236 prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
1237 depth++;
1239 if (!prs_align(ps))
1240 return False;
1241 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1242 return False;
1243 if (!prs_align(ps))
1244 return False;
1245 if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1246 return False;
1248 return True;
1251 /*******************************************************************
1252 * write a structure.
1253 * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
1254 ********************************************************************/
1256 BOOL spoolss_io_r_deleteprinterdata(char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
1258 prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
1259 depth++;
1260 if(!prs_werror("status", ps, depth, &r_u->status))
1261 return False;
1263 return True;
1266 /*******************************************************************
1267 * read a structure.
1268 * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
1269 ********************************************************************/
1271 BOOL spoolss_io_q_deleteprinterdataex(char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1273 if (q_u == NULL)
1274 return False;
1276 prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
1277 depth++;
1279 if (!prs_align(ps))
1280 return False;
1281 if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1282 return False;
1284 if (!smb_io_unistr2("keyname ", &q_u->keyname, True, ps, depth))
1285 return False;
1286 if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
1287 return False;
1289 return True;
1292 /*******************************************************************
1293 * write a structure.
1294 * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
1295 ********************************************************************/
1297 BOOL spoolss_io_r_deleteprinterdataex(char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
1299 prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
1300 depth++;
1302 if(!prs_werror("status", ps, depth, &r_u->status))
1303 return False;
1305 return True;
1308 /*******************************************************************
1309 * write a structure.
1310 * called from spoolss_r_getprinterdata (srv_spoolss.c)
1311 ********************************************************************/
1313 BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1315 if (r_u == NULL)
1316 return False;
1318 prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1319 depth++;
1321 if (!prs_align(ps))
1322 return False;
1323 if (!prs_uint32("type", ps, depth, &r_u->type))
1324 return False;
1325 if (!prs_uint32("size", ps, depth, &r_u->size))
1326 return False;
1328 if (UNMARSHALLING(ps) && r_u->size) {
1329 r_u->data = prs_alloc_mem(ps, r_u->size);
1330 if(r_u->data)
1331 return False;
1334 if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
1335 return False;
1337 if (!prs_align(ps))
1338 return False;
1340 if (!prs_uint32("needed", ps, depth, &r_u->needed))
1341 return False;
1342 if (!prs_werror("status", ps, depth, &r_u->status))
1343 return False;
1345 return True;
1348 /*******************************************************************
1349 * make a structure.
1350 ********************************************************************/
1352 BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
1354 if (q_u == NULL) return False;
1356 DEBUG(5,("make_spoolss_q_closeprinter\n"));
1358 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1360 return True;
1363 /*******************************************************************
1364 * read a structure.
1365 * called from static spoolss_q_abortprinter (srv_spoolss.c)
1366 * called from spoolss_abortprinter (cli_spoolss.c)
1367 ********************************************************************/
1369 BOOL spoolss_io_q_abortprinter(char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
1371 if (q_u == NULL) return False;
1373 prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
1374 depth++;
1376 if (!prs_align(ps))
1377 return False;
1379 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1380 return False;
1382 return True;
1385 /*******************************************************************
1386 * write a structure.
1387 * called from spoolss_r_abortprinter (srv_spoolss.c)
1388 ********************************************************************/
1390 BOOL spoolss_io_r_abortprinter(char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
1392 prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
1393 depth++;
1394 if(!prs_werror("status", ps, depth, &r_u->status))
1395 return False;
1397 return True;
1400 /*******************************************************************
1401 * read a structure.
1402 * called from static spoolss_q_deleteprinter (srv_spoolss.c)
1403 * called from spoolss_deleteprinter (cli_spoolss.c)
1404 ********************************************************************/
1406 BOOL spoolss_io_q_deleteprinter(char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
1408 if (q_u == NULL) return False;
1410 prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
1411 depth++;
1413 if (!prs_align(ps))
1414 return False;
1416 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1417 return False;
1419 return True;
1422 /*******************************************************************
1423 * write a structure.
1424 * called from static spoolss_r_deleteprinter (srv_spoolss.c)
1425 * called from spoolss_deleteprinter (cli_spoolss.c)
1426 ********************************************************************/
1428 BOOL spoolss_io_r_deleteprinter(char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
1430 prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
1431 depth++;
1433 if (!prs_align(ps))
1434 return False;
1436 if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1437 return False;
1438 if (!prs_werror("status", ps, depth, &r_u->status))
1439 return False;
1441 return True;
1445 /*******************************************************************
1446 * read a structure.
1447 * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1448 * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1449 ********************************************************************/
1451 BOOL spoolss_io_q_deleteprinterdriver(char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
1453 if (q_u == NULL) return False;
1455 prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
1456 depth++;
1458 if (!prs_align(ps))
1459 return False;
1461 if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1462 return False;
1463 if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1464 return False;
1465 if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1466 return False;
1467 if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1468 return False;
1471 return True;
1475 /*******************************************************************
1476 * write a structure.
1477 ********************************************************************/
1478 BOOL spoolss_io_r_deleteprinterdriver(char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
1480 if (r_u == NULL) return False;
1482 prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
1483 depth++;
1485 if (!prs_align(ps))
1486 return False;
1488 if (!prs_werror("status", ps, depth, &r_u->status))
1489 return False;
1491 return True;
1496 /*******************************************************************
1497 * read a structure.
1498 * called from static spoolss_q_closeprinter (srv_spoolss.c)
1499 * called from spoolss_closeprinter (cli_spoolss.c)
1500 ********************************************************************/
1502 BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
1504 if (q_u == NULL) return False;
1506 prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
1507 depth++;
1509 if (!prs_align(ps))
1510 return False;
1512 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1513 return False;
1515 return True;
1518 /*******************************************************************
1519 * write a structure.
1520 * called from static spoolss_r_closeprinter (srv_spoolss.c)
1521 * called from spoolss_closeprinter (cli_spoolss.c)
1522 ********************************************************************/
1524 BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
1526 prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
1527 depth++;
1529 if (!prs_align(ps))
1530 return False;
1532 if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1533 return False;
1534 if (!prs_werror("status", ps, depth, &r_u->status))
1535 return False;
1537 return True;
1540 /*******************************************************************
1541 * read a structure.
1542 * called from spoolss_q_startdocprinter (srv_spoolss.c)
1543 ********************************************************************/
1545 BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
1547 if (q_u == NULL) return False;
1549 prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
1550 depth++;
1552 if(!prs_align(ps))
1553 return False;
1555 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1556 return False;
1558 if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
1559 return False;
1561 return True;
1564 /*******************************************************************
1565 * write a structure.
1566 * called from spoolss_r_startdocprinter (srv_spoolss.c)
1567 ********************************************************************/
1569 BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
1571 prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
1572 depth++;
1573 if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
1574 return False;
1575 if(!prs_werror("status", ps, depth, &r_u->status))
1576 return False;
1578 return True;
1581 /*******************************************************************
1582 * read a structure.
1583 * called from spoolss_q_enddocprinter (srv_spoolss.c)
1584 ********************************************************************/
1586 BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
1588 if (q_u == NULL) return False;
1590 prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1591 depth++;
1593 if(!prs_align(ps))
1594 return False;
1596 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1597 return False;
1599 return True;
1602 /*******************************************************************
1603 * write a structure.
1604 * called from spoolss_r_enddocprinter (srv_spoolss.c)
1605 ********************************************************************/
1607 BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1609 prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1610 depth++;
1611 if(!prs_werror("status", ps, depth, &r_u->status))
1612 return False;
1614 return True;
1617 /*******************************************************************
1618 * read a structure.
1619 * called from spoolss_q_startpageprinter (srv_spoolss.c)
1620 ********************************************************************/
1622 BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1624 if (q_u == NULL) return False;
1626 prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1627 depth++;
1629 if(!prs_align(ps))
1630 return False;
1632 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1633 return False;
1635 return True;
1638 /*******************************************************************
1639 * write a structure.
1640 * called from spoolss_r_startpageprinter (srv_spoolss.c)
1641 ********************************************************************/
1643 BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1645 prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1646 depth++;
1647 if(!prs_werror("status", ps, depth, &r_u->status))
1648 return False;
1650 return True;
1653 /*******************************************************************
1654 * read a structure.
1655 * called from spoolss_q_endpageprinter (srv_spoolss.c)
1656 ********************************************************************/
1658 BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1660 if (q_u == NULL) return False;
1662 prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1663 depth++;
1665 if(!prs_align(ps))
1666 return False;
1668 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1669 return False;
1671 return True;
1674 /*******************************************************************
1675 * write a structure.
1676 * called from spoolss_r_endpageprinter (srv_spoolss.c)
1677 ********************************************************************/
1679 BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1681 prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1682 depth++;
1683 if(!prs_werror("status", ps, depth, &r_u->status))
1684 return False;
1686 return True;
1689 /*******************************************************************
1690 * read a structure.
1691 * called from spoolss_q_writeprinter (srv_spoolss.c)
1692 ********************************************************************/
1694 BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1696 if (q_u == NULL) return False;
1698 prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1699 depth++;
1701 if(!prs_align(ps))
1702 return False;
1704 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1705 return False;
1706 if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
1707 return False;
1709 if (q_u->buffer_size!=0)
1711 if (UNMARSHALLING(ps))
1712 q_u->buffer=(uint8 *)prs_alloc_mem(ps,q_u->buffer_size*sizeof(uint8));
1713 if(q_u->buffer == NULL)
1714 return False;
1715 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1716 return False;
1718 if(!prs_align(ps))
1719 return False;
1720 if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
1721 return False;
1723 return True;
1726 /*******************************************************************
1727 * write a structure.
1728 * called from spoolss_r_writeprinter (srv_spoolss.c)
1729 ********************************************************************/
1731 BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1733 prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1734 depth++;
1735 if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
1736 return False;
1737 if(!prs_werror("status", ps, depth, &r_u->status))
1738 return False;
1740 return True;
1743 /*******************************************************************
1744 * read a structure.
1745 * called from spoolss_q_rffpcnex (srv_spoolss.c)
1746 ********************************************************************/
1748 BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1750 prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1751 depth++;
1753 if(!prs_align(ps))
1754 return False;
1756 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1757 return False;
1758 if(!prs_uint32("flags", ps, depth, &q_u->flags))
1759 return False;
1760 if(!prs_uint32("options", ps, depth, &q_u->options))
1761 return False;
1762 if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1763 return False;
1764 if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1765 return False;
1767 if(!prs_align(ps))
1768 return False;
1770 if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1771 return False;
1773 if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1774 return False;
1776 if (q_u->option_ptr!=0) {
1778 if (UNMARSHALLING(ps))
1779 if((q_u->option=(SPOOL_NOTIFY_OPTION *)prs_alloc_mem(ps,sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1780 return False;
1782 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1783 return False;
1786 return True;
1789 /*******************************************************************
1790 * write a structure.
1791 * called from spoolss_r_rffpcnex (srv_spoolss.c)
1792 ********************************************************************/
1794 BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1796 prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1797 depth++;
1799 if(!prs_werror("status", ps, depth, &r_u->status))
1800 return False;
1802 return True;
1805 /*******************************************************************
1806 * read a structure.
1807 * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1808 ********************************************************************/
1810 BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1812 prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1813 depth++;
1815 if(!prs_align(ps))
1816 return False;
1818 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1819 return False;
1821 if(!prs_uint32("change", ps, depth, &q_u->change))
1822 return False;
1824 if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1825 return False;
1827 if (q_u->option_ptr!=0) {
1829 if (UNMARSHALLING(ps))
1830 if((q_u->option=(SPOOL_NOTIFY_OPTION *)prs_alloc_mem(ps,sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1831 return False;
1833 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1834 return False;
1837 return True;
1840 /*******************************************************************
1841 * write a structure.
1842 * called from spoolss_r_rfnpcnex (srv_spoolss.c)
1843 ********************************************************************/
1845 BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
1847 prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
1848 depth++;
1850 if(!prs_align(ps))
1851 return False;
1853 if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
1854 return False;
1856 if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
1857 return False;
1859 if(!prs_align(ps))
1860 return False;
1861 if(!prs_werror("status", ps, depth, &r_u->status))
1862 return False;
1864 return True;
1867 /*******************************************************************
1868 * return the length of a uint16 (obvious, but the code is clean)
1869 ********************************************************************/
1871 static uint32 size_of_uint16(uint16 *value)
1873 return (sizeof(*value));
1876 /*******************************************************************
1877 * return the length of a uint32 (obvious, but the code is clean)
1878 ********************************************************************/
1880 static uint32 size_of_uint32(uint32 *value)
1882 return (sizeof(*value));
1885 /*******************************************************************
1886 * return the length of a NTTIME (obvious, but the code is clean)
1887 ********************************************************************/
1889 static uint32 size_of_nttime(NTTIME *value)
1891 return (sizeof(*value));
1894 /*******************************************************************
1895 * return the length of a UNICODE string in number of char, includes:
1896 * - the leading zero
1897 * - the relative pointer size
1898 ********************************************************************/
1900 static uint32 size_of_relative_string(UNISTR *string)
1902 uint32 size=0;
1904 size=str_len_uni(string); /* the string length */
1905 size=size+1; /* add the trailing zero */
1906 size=size*2; /* convert in char */
1907 size=size+4; /* add the size of the ptr */
1909 #if 0 /* JERRY */
1911 * Do not include alignment as Win2k does not align relative
1912 * strings within a buffer --jerry
1914 /* Ensure size is 4 byte multiple (prs_align is being called...). */
1915 /* size += ((4 - (size & 3)) & 3); */
1916 #endif
1918 return size;
1921 /*******************************************************************
1922 * return the length of a uint32 (obvious, but the code is clean)
1923 ********************************************************************/
1925 static uint32 size_of_device_mode(DEVICEMODE *devmode)
1927 if (devmode==NULL)
1928 return (4);
1929 else
1930 return (4+devmode->size+devmode->driverextra);
1933 /*******************************************************************
1934 * return the length of a uint32 (obvious, but the code is clean)
1935 ********************************************************************/
1937 static uint32 size_of_systemtime(SYSTEMTIME *systime)
1939 if (systime==NULL)
1940 return (4);
1941 else
1942 return (sizeof(SYSTEMTIME) +4);
1945 /*******************************************************************
1946 * write a UNICODE string and its relative pointer.
1947 * used by all the RPC structs passing a buffer
1949 * As I'm a nice guy, I'm forcing myself to explain this code.
1950 * MS did a good job in the overall spoolss code except in some
1951 * functions where they are passing the API buffer directly in the
1952 * RPC request/reply. That's to maintain compatiility at the API level.
1953 * They could have done it the good way the first time.
1955 * So what happen is: the strings are written at the buffer's end,
1956 * in the reverse order of the original structure. Some pointers to
1957 * the strings are also in the buffer. Those are relative to the
1958 * buffer's start.
1960 * If you don't understand or want to change that function,
1961 * first get in touch with me: jfm@samba.org
1963 ********************************************************************/
1965 static BOOL smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
1967 prs_struct *ps=&buffer->prs;
1969 if (MARSHALLING(ps)) {
1970 uint32 struct_offset = prs_offset(ps);
1971 uint32 relative_offset;
1973 buffer->string_at_end -= (size_of_relative_string(string) - 4);
1974 if(!prs_set_offset(ps, buffer->string_at_end))
1975 return False;
1976 #if 0 /* JERRY */
1978 * Win2k does not align strings in a buffer
1979 * Tested against WinNT 4.0 SP 6a & 2k SP2 --jerry
1981 if (!prs_align(ps))
1982 return False;
1983 #endif
1984 buffer->string_at_end = prs_offset(ps);
1986 /* write the string */
1987 if (!smb_io_unistr(desc, string, ps, depth))
1988 return False;
1990 if(!prs_set_offset(ps, struct_offset))
1991 return False;
1993 relative_offset=buffer->string_at_end - buffer->struct_start;
1994 /* write its offset */
1995 if (!prs_uint32("offset", ps, depth, &relative_offset))
1996 return False;
1998 else {
1999 uint32 old_offset;
2001 /* read the offset */
2002 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
2003 return False;
2005 old_offset = prs_offset(ps);
2006 if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
2007 return False;
2009 /* read the string */
2010 if (!smb_io_unistr(desc, string, ps, depth))
2011 return False;
2013 if(!prs_set_offset(ps, old_offset))
2014 return False;
2016 return True;
2019 /*******************************************************************
2020 * write a array of UNICODE strings and its relative pointer.
2021 * used by 2 RPC structs
2022 ********************************************************************/
2024 static BOOL smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
2026 UNISTR chaine;
2028 prs_struct *ps=&buffer->prs;
2030 if (MARSHALLING(ps)) {
2031 uint32 struct_offset = prs_offset(ps);
2032 uint32 relative_offset;
2033 uint16 *p;
2034 uint16 *q;
2035 uint16 zero=0;
2036 p=*string;
2037 q=*string;
2039 /* first write the last 0 */
2040 buffer->string_at_end -= 2;
2041 if(!prs_set_offset(ps, buffer->string_at_end))
2042 return False;
2044 if(!prs_uint16("leading zero", ps, depth, &zero))
2045 return False;
2047 while (p && (*p!=0)) {
2048 while (*q!=0)
2049 q++;
2051 /* Yes this should be malloc not talloc. Don't change. */
2053 chaine.buffer = malloc((q-p+1)*sizeof(uint16));
2054 if (chaine.buffer == NULL)
2055 return False;
2057 memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
2059 buffer->string_at_end -= (q-p+1)*sizeof(uint16);
2061 if(!prs_set_offset(ps, buffer->string_at_end)) {
2062 SAFE_FREE(chaine.buffer);
2063 return False;
2066 /* write the string */
2067 if (!smb_io_unistr(desc, &chaine, ps, depth)) {
2068 SAFE_FREE(chaine.buffer);
2069 return False;
2071 q++;
2072 p=q;
2074 SAFE_FREE(chaine.buffer);
2077 if(!prs_set_offset(ps, struct_offset))
2078 return False;
2080 relative_offset=buffer->string_at_end - buffer->struct_start;
2081 /* write its offset */
2082 if (!prs_uint32("offset", ps, depth, &relative_offset))
2083 return False;
2085 } else {
2087 /* UNMARSHALLING */
2089 uint32 old_offset;
2090 uint16 *chaine2=NULL;
2091 int l_chaine=0;
2092 int l_chaine2=0;
2093 size_t realloc_size = 0;
2095 *string=NULL;
2097 /* read the offset */
2098 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2099 return False;
2101 old_offset = prs_offset(ps);
2102 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2103 return False;
2105 do {
2106 if (!smb_io_unistr(desc, &chaine, ps, depth))
2107 return False;
2109 l_chaine=str_len_uni(&chaine);
2111 /* we're going to add two more bytes here in case this
2112 is the last string in the array and we need to add
2113 an extra NULL for termination */
2114 if (l_chaine > 0)
2116 uint16 *tc2;
2118 realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
2120 /* Yes this should be realloc - it's freed below. JRA */
2122 if((tc2=(uint16 *)Realloc(chaine2, realloc_size)) == NULL) {
2123 SAFE_FREE(chaine2);
2124 return False;
2126 else chaine2 = tc2;
2127 memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
2128 l_chaine2+=l_chaine+1;
2131 } while(l_chaine!=0);
2133 /* the end should be bould NULL terminated so add
2134 the second one here */
2135 if (chaine2)
2137 chaine2[l_chaine2] = '\0';
2138 *string=(uint16 *)talloc_memdup(prs_get_mem_context(ps),chaine2,realloc_size);
2139 SAFE_FREE(chaine2);
2142 if(!prs_set_offset(ps, old_offset))
2143 return False;
2145 return True;
2148 /*******************************************************************
2149 Parse a DEVMODE structure and its relative pointer.
2150 ********************************************************************/
2152 static BOOL smb_io_relsecdesc(char *desc, NEW_BUFFER *buffer, int depth, SEC_DESC **secdesc)
2154 prs_struct *ps= &buffer->prs;
2156 prs_debug(ps, depth, desc, "smb_io_relsecdesc");
2157 depth++;
2159 if (MARSHALLING(ps)) {
2160 uint32 struct_offset = prs_offset(ps);
2161 uint32 relative_offset;
2163 if (! *secdesc) {
2164 relative_offset = 0;
2165 if (!prs_uint32("offset", ps, depth, &relative_offset))
2166 return False;
2167 return True;
2170 if (*secdesc != NULL) {
2171 buffer->string_at_end -= sec_desc_size(*secdesc);
2173 if(!prs_set_offset(ps, buffer->string_at_end))
2174 return False;
2175 /* write the secdesc */
2176 if (!sec_io_desc(desc, secdesc, ps, depth))
2177 return False;
2179 if(!prs_set_offset(ps, struct_offset))
2180 return False;
2183 relative_offset=buffer->string_at_end - buffer->struct_start;
2184 /* write its offset */
2186 if (!prs_uint32("offset", ps, depth, &relative_offset))
2187 return False;
2188 } else {
2189 uint32 old_offset;
2191 /* read the offset */
2192 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2193 return False;
2195 old_offset = prs_offset(ps);
2196 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2197 return False;
2199 /* read the sd */
2200 if (!sec_io_desc(desc, secdesc, ps, depth))
2201 return False;
2203 if(!prs_set_offset(ps, old_offset))
2204 return False;
2206 return True;
2209 /*******************************************************************
2210 Parse a DEVMODE structure and its relative pointer.
2211 ********************************************************************/
2213 static BOOL smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
2215 prs_struct *ps=&buffer->prs;
2217 prs_debug(ps, depth, desc, "smb_io_reldevmode");
2218 depth++;
2220 if (MARSHALLING(ps)) {
2221 uint32 struct_offset = prs_offset(ps);
2222 uint32 relative_offset;
2224 if (*devmode == NULL) {
2225 relative_offset=0;
2226 if (!prs_uint32("offset", ps, depth, &relative_offset))
2227 return False;
2228 DEBUG(8, ("boing, the devmode was NULL\n"));
2230 return True;
2233 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
2235 if(!prs_set_offset(ps, buffer->string_at_end))
2236 return False;
2238 /* write the DEVMODE */
2239 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2240 return False;
2242 if(!prs_set_offset(ps, struct_offset))
2243 return False;
2245 relative_offset=buffer->string_at_end - buffer->struct_start;
2246 /* write its offset */
2247 if (!prs_uint32("offset", ps, depth, &relative_offset))
2248 return False;
2250 else {
2251 uint32 old_offset;
2253 /* read the offset */
2254 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2255 return False;
2256 if (buffer->string_at_end == 0) {
2257 *devmode = NULL;
2258 return True;
2261 old_offset = prs_offset(ps);
2262 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2263 return False;
2265 /* read the string */
2266 if((*devmode=(DEVICEMODE *)prs_alloc_mem(ps,sizeof(DEVICEMODE))) == NULL)
2267 return False;
2268 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2269 return False;
2271 if(!prs_set_offset(ps, old_offset))
2272 return False;
2274 return True;
2277 /*******************************************************************
2278 Parse a PRINTER_INFO_0 structure.
2279 ********************************************************************/
2281 BOOL smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2283 prs_struct *ps=&buffer->prs;
2285 prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2286 depth++;
2288 buffer->struct_start=prs_offset(ps);
2290 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2291 return False;
2292 if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2293 return False;
2295 if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2296 return False;
2297 if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2298 return False;
2299 if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2300 return False;
2302 if(!prs_uint16("year", ps, depth, &info->year))
2303 return False;
2304 if(!prs_uint16("month", ps, depth, &info->month))
2305 return False;
2306 if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2307 return False;
2308 if(!prs_uint16("day", ps, depth, &info->day))
2309 return False;
2310 if(!prs_uint16("hour", ps, depth, &info->hour))
2311 return False;
2312 if(!prs_uint16("minute", ps, depth, &info->minute))
2313 return False;
2314 if(!prs_uint16("second", ps, depth, &info->second))
2315 return False;
2316 if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2317 return False;
2319 if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2320 return False;
2321 if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2322 return False;
2324 if(!prs_uint16("major_version", ps, depth, &info->major_version))
2325 return False;
2326 if(!prs_uint16("build_version", ps, depth, &info->build_version))
2327 return False;
2328 if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2329 return False;
2330 if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2331 return False;
2332 if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2333 return False;
2334 if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2335 return False;
2336 if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2337 return False;
2338 if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2339 return False;
2340 if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2341 return False;
2342 if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2343 return False;
2344 if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2345 return False;
2346 if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2347 return False;
2348 if(!prs_uint32("change_id", ps, depth, &info->change_id))
2349 return False;
2350 if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2351 return False;
2352 if(!prs_uint32("status" , ps, depth, &info->status))
2353 return False;
2354 if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2355 return False;
2356 if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2357 return False;
2358 if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2359 return False;
2360 if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2361 return False;
2362 if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2363 return False;
2364 if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2365 return False;
2366 if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2367 return False;
2368 if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2369 return False;
2370 if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2371 return False;
2372 if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2373 return False;
2375 return True;
2378 /*******************************************************************
2379 Parse a PRINTER_INFO_1 structure.
2380 ********************************************************************/
2382 BOOL smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2384 prs_struct *ps=&buffer->prs;
2386 prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2387 depth++;
2389 buffer->struct_start=prs_offset(ps);
2391 if (!prs_uint32("flags", ps, depth, &info->flags))
2392 return False;
2393 if (!smb_io_relstr("description", buffer, depth, &info->description))
2394 return False;
2395 if (!smb_io_relstr("name", buffer, depth, &info->name))
2396 return False;
2397 if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2398 return False;
2400 return True;
2403 /*******************************************************************
2404 Parse a PRINTER_INFO_2 structure.
2405 ********************************************************************/
2407 BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2409 prs_struct *ps=&buffer->prs;
2410 uint32 dm_offset, sd_offset, current_offset;
2411 uint32 dummy_value = 0;
2413 prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2414 depth++;
2416 buffer->struct_start=prs_offset(ps);
2418 if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2419 return False;
2420 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2421 return False;
2422 if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2423 return False;
2424 if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2425 return False;
2426 if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2427 return False;
2428 if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2429 return False;
2430 if (!smb_io_relstr("location", buffer, depth, &info->location))
2431 return False;
2433 /* save current offset and wind forwared by a uint32 */
2434 dm_offset = prs_offset(ps);
2435 if (!prs_uint32("devmode", ps, depth, &dummy_value))
2436 return False;
2438 if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2439 return False;
2440 if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2441 return False;
2442 if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2443 return False;
2444 if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2445 return False;
2447 /* save current offset for the sec_desc */
2448 sd_offset = prs_offset(ps);
2449 if (!prs_uint32("sec_desc", ps, depth, &dummy_value))
2450 return False;
2453 /* save current location so we can pick back up here */
2454 current_offset = prs_offset(ps);
2456 /* parse the devmode */
2457 if (!prs_set_offset(ps, dm_offset))
2458 return False;
2459 if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2460 return False;
2462 /* parse the sec_desc */
2463 if (!prs_set_offset(ps, sd_offset))
2464 return False;
2465 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2466 return False;
2468 /* pick up where we left off */
2469 if (!prs_set_offset(ps, current_offset))
2470 return False;
2472 if (!prs_uint32("attributes", ps, depth, &info->attributes))
2473 return False;
2474 if (!prs_uint32("priority", ps, depth, &info->priority))
2475 return False;
2476 if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2477 return False;
2478 if (!prs_uint32("starttime", ps, depth, &info->starttime))
2479 return False;
2480 if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2481 return False;
2482 if (!prs_uint32("status", ps, depth, &info->status))
2483 return False;
2484 if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2485 return False;
2486 if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2487 return False;
2489 return True;
2492 /*******************************************************************
2493 Parse a PRINTER_INFO_3 structure.
2494 ********************************************************************/
2496 BOOL smb_io_printer_info_3(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2498 prs_struct *ps=&buffer->prs;
2500 prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2501 depth++;
2503 buffer->struct_start=prs_offset(ps);
2505 if (!prs_uint32("flags", ps, depth, &info->flags))
2506 return False;
2507 if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2508 return False;
2510 return True;
2513 /*******************************************************************
2514 Parse a PRINTER_INFO_4 structure.
2515 ********************************************************************/
2517 BOOL smb_io_printer_info_4(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
2519 prs_struct *ps=&buffer->prs;
2521 prs_debug(ps, depth, desc, "smb_io_printer_info_4");
2522 depth++;
2524 buffer->struct_start=prs_offset(ps);
2526 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2527 return False;
2528 if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2529 return False;
2530 if (!prs_uint32("attributes", ps, depth, &info->attributes))
2531 return False;
2532 return True;
2535 /*******************************************************************
2536 Parse a PRINTER_INFO_5 structure.
2537 ********************************************************************/
2539 BOOL smb_io_printer_info_5(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
2541 prs_struct *ps=&buffer->prs;
2543 prs_debug(ps, depth, desc, "smb_io_printer_info_5");
2544 depth++;
2546 buffer->struct_start=prs_offset(ps);
2548 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2549 return False;
2550 if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2551 return False;
2552 if (!prs_uint32("attributes", ps, depth, &info->attributes))
2553 return False;
2554 if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
2555 return False;
2556 if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
2557 return False;
2558 return True;
2561 /*******************************************************************
2562 Parse a PORT_INFO_1 structure.
2563 ********************************************************************/
2565 BOOL smb_io_port_info_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2567 prs_struct *ps=&buffer->prs;
2569 prs_debug(ps, depth, desc, "smb_io_port_info_1");
2570 depth++;
2572 buffer->struct_start=prs_offset(ps);
2574 if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2575 return False;
2577 return True;
2580 /*******************************************************************
2581 Parse a PORT_INFO_2 structure.
2582 ********************************************************************/
2584 BOOL smb_io_port_info_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2586 prs_struct *ps=&buffer->prs;
2588 prs_debug(ps, depth, desc, "smb_io_port_info_2");
2589 depth++;
2591 buffer->struct_start=prs_offset(ps);
2593 if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2594 return False;
2595 if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2596 return False;
2597 if (!smb_io_relstr("description", buffer, depth, &info->description))
2598 return False;
2599 if (!prs_uint32("port_type", ps, depth, &info->port_type))
2600 return False;
2601 if (!prs_uint32("reserved", ps, depth, &info->reserved))
2602 return False;
2604 return True;
2607 /*******************************************************************
2608 Parse a DRIVER_INFO_1 structure.
2609 ********************************************************************/
2611 BOOL smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth)
2613 prs_struct *ps=&buffer->prs;
2615 prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2616 depth++;
2618 buffer->struct_start=prs_offset(ps);
2620 if (!smb_io_relstr("name", buffer, depth, &info->name))
2621 return False;
2623 return True;
2626 /*******************************************************************
2627 Parse a DRIVER_INFO_2 structure.
2628 ********************************************************************/
2630 BOOL smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth)
2632 prs_struct *ps=&buffer->prs;
2634 prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2635 depth++;
2637 buffer->struct_start=prs_offset(ps);
2639 if (!prs_uint32("version", ps, depth, &info->version))
2640 return False;
2641 if (!smb_io_relstr("name", buffer, depth, &info->name))
2642 return False;
2643 if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2644 return False;
2645 if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2646 return False;
2647 if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2648 return False;
2649 if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2650 return False;
2652 return True;
2655 /*******************************************************************
2656 Parse a DRIVER_INFO_3 structure.
2657 ********************************************************************/
2659 BOOL smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2661 prs_struct *ps=&buffer->prs;
2663 prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2664 depth++;
2666 buffer->struct_start=prs_offset(ps);
2668 if (!prs_uint32("version", ps, depth, &info->version))
2669 return False;
2670 if (!smb_io_relstr("name", buffer, depth, &info->name))
2671 return False;
2672 if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2673 return False;
2674 if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2675 return False;
2676 if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2677 return False;
2678 if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2679 return False;
2680 if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2681 return False;
2683 if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2684 return False;
2686 if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2687 return False;
2688 if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2689 return False;
2691 return True;
2694 /*******************************************************************
2695 Parse a DRIVER_INFO_6 structure.
2696 ********************************************************************/
2698 BOOL smb_io_printer_driver_info_6(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2700 prs_struct *ps=&buffer->prs;
2702 prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2703 depth++;
2705 buffer->struct_start=prs_offset(ps);
2707 if (!prs_uint32("version", ps, depth, &info->version))
2708 return False;
2709 if (!smb_io_relstr("name", buffer, depth, &info->name))
2710 return False;
2711 if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2712 return False;
2713 if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2714 return False;
2715 if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2716 return False;
2717 if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2718 return False;
2719 if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2720 return False;
2722 if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2723 return False;
2725 if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2726 return False;
2727 if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2728 return False;
2730 if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2731 return False;
2733 if (!prs_uint32("date.low", ps, depth, &info->driver_date.low))
2734 return False;
2735 if (!prs_uint32("date.high", ps, depth, &info->driver_date.high))
2736 return False;
2738 if (!prs_uint32("padding", ps, depth, &info->padding))
2739 return False;
2741 if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2742 return False;
2744 if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2745 return False;
2747 if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2748 return False;
2749 if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2750 return False;
2751 if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2752 return False;
2753 if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2754 return False;
2756 return True;
2759 /*******************************************************************
2760 Parse a JOB_INFO_1 structure.
2761 ********************************************************************/
2763 BOOL smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2765 prs_struct *ps=&buffer->prs;
2767 prs_debug(ps, depth, desc, "smb_io_job_info_1");
2768 depth++;
2770 buffer->struct_start=prs_offset(ps);
2772 if (!prs_uint32("jobid", ps, depth, &info->jobid))
2773 return False;
2774 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2775 return False;
2776 if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2777 return False;
2778 if (!smb_io_relstr("username", buffer, depth, &info->username))
2779 return False;
2780 if (!smb_io_relstr("document", buffer, depth, &info->document))
2781 return False;
2782 if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2783 return False;
2784 if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2785 return False;
2786 if (!prs_uint32("status", ps, depth, &info->status))
2787 return False;
2788 if (!prs_uint32("priority", ps, depth, &info->priority))
2789 return False;
2790 if (!prs_uint32("position", ps, depth, &info->position))
2791 return False;
2792 if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2793 return False;
2794 if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2795 return False;
2796 if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2797 return False;
2799 return True;
2802 /*******************************************************************
2803 Parse a JOB_INFO_2 structure.
2804 ********************************************************************/
2806 BOOL smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2808 uint32 pipo=0;
2809 prs_struct *ps=&buffer->prs;
2811 prs_debug(ps, depth, desc, "smb_io_job_info_2");
2812 depth++;
2814 buffer->struct_start=prs_offset(ps);
2816 if (!prs_uint32("jobid",ps, depth, &info->jobid))
2817 return False;
2818 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2819 return False;
2820 if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2821 return False;
2822 if (!smb_io_relstr("username", buffer, depth, &info->username))
2823 return False;
2824 if (!smb_io_relstr("document", buffer, depth, &info->document))
2825 return False;
2826 if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2827 return False;
2828 if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2829 return False;
2831 if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2832 return False;
2833 if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2834 return False;
2835 if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2836 return False;
2837 if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2838 return False;
2839 if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2840 return False;
2842 /* SEC_DESC sec_desc;*/
2843 if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2844 return False;
2846 if (!prs_uint32("status",ps, depth, &info->status))
2847 return False;
2848 if (!prs_uint32("priority",ps, depth, &info->priority))
2849 return False;
2850 if (!prs_uint32("position",ps, depth, &info->position))
2851 return False;
2852 if (!prs_uint32("starttime",ps, depth, &info->starttime))
2853 return False;
2854 if (!prs_uint32("untiltime",ps, depth, &info->untiltime))
2855 return False;
2856 if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2857 return False;
2858 if (!prs_uint32("size",ps, depth, &info->size))
2859 return False;
2860 if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2861 return False;
2862 if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2863 return False;
2864 if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2865 return False;
2867 return True;
2870 /*******************************************************************
2871 ********************************************************************/
2873 BOOL smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
2875 prs_struct *ps=&buffer->prs;
2877 prs_debug(ps, depth, desc, "smb_io_form_1");
2878 depth++;
2880 buffer->struct_start=prs_offset(ps);
2882 if (!prs_uint32("flag", ps, depth, &info->flag))
2883 return False;
2885 if (!smb_io_relstr("name", buffer, depth, &info->name))
2886 return False;
2888 if (!prs_uint32("width", ps, depth, &info->width))
2889 return False;
2890 if (!prs_uint32("length", ps, depth, &info->length))
2891 return False;
2892 if (!prs_uint32("left", ps, depth, &info->left))
2893 return False;
2894 if (!prs_uint32("top", ps, depth, &info->top))
2895 return False;
2896 if (!prs_uint32("right", ps, depth, &info->right))
2897 return False;
2898 if (!prs_uint32("bottom", ps, depth, &info->bottom))
2899 return False;
2901 return True;
2904 /*******************************************************************
2905 Read/write a BUFFER struct.
2906 ********************************************************************/
2908 static BOOL spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER **pp_buffer)
2910 NEW_BUFFER *buffer = *pp_buffer;
2912 prs_debug(ps, depth, desc, "spoolss_io_buffer");
2913 depth++;
2915 if (UNMARSHALLING(ps))
2916 buffer = *pp_buffer = (NEW_BUFFER *)prs_alloc_mem(ps, sizeof(NEW_BUFFER));
2918 if (buffer == NULL)
2919 return False;
2921 if (!prs_uint32("ptr", ps, depth, &buffer->ptr))
2922 return False;
2924 /* reading */
2925 if (UNMARSHALLING(ps)) {
2926 buffer->size=0;
2927 buffer->string_at_end=0;
2929 if (buffer->ptr==0) {
2931 * JRA. I'm not sure if the data in here is in big-endian format if
2932 * the client is big-endian. Leave as default (little endian) for now.
2935 if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL))
2936 return False;
2937 return True;
2940 if (!prs_uint32("size", ps, depth, &buffer->size))
2941 return False;
2944 * JRA. I'm not sure if the data in here is in big-endian format if
2945 * the client is big-endian. Leave as default (little endian) for now.
2948 if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
2949 return False;
2951 if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
2952 return False;
2954 if (!prs_set_offset(&buffer->prs, 0))
2955 return False;
2957 if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
2958 return False;
2960 buffer->string_at_end=buffer->size;
2962 return True;
2964 else {
2965 BOOL ret = False;
2967 /* writing */
2968 if (buffer->ptr==0) {
2969 /* We have finished with the data in buffer->prs - free it. */
2970 prs_mem_free(&buffer->prs);
2971 return True;
2974 if (!prs_uint32("size", ps, depth, &buffer->size))
2975 goto out;
2977 if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
2978 goto out;
2980 ret = True;
2981 out:
2983 /* We have finished with the data in buffer->prs - free it. */
2984 prs_mem_free(&buffer->prs);
2986 return ret;
2990 /*******************************************************************
2991 move a BUFFER from the query to the reply.
2992 As the data pointers in NEW_BUFFER are malloc'ed, not talloc'ed,
2993 this is ok. This is an OPTIMIZATION and is not strictly neccessary.
2994 Clears the memory to zero also.
2995 ********************************************************************/
2997 void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
2999 prs_switch_type(&src->prs, MARSHALL);
3000 if(!prs_set_offset(&src->prs, 0))
3001 return;
3002 prs_force_dynamic(&src->prs);
3003 prs_mem_clear(&src->prs);
3004 *dest=src;
3007 /*******************************************************************
3008 Get the size of a BUFFER struct.
3009 ********************************************************************/
3011 uint32 new_get_buffer_size(NEW_BUFFER *buffer)
3013 return (buffer->size);
3016 /*******************************************************************
3017 Parse a DRIVER_DIRECTORY_1 structure.
3018 ********************************************************************/
3020 BOOL smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
3022 prs_struct *ps=&buffer->prs;
3024 prs_debug(ps, depth, desc, "smb_io_driverdir_1");
3025 depth++;
3027 buffer->struct_start=prs_offset(ps);
3029 if (!smb_io_unistr(desc, &info->name, ps, depth))
3030 return False;
3032 return True;
3035 /*******************************************************************
3036 Parse a PORT_INFO_1 structure.
3037 ********************************************************************/
3039 BOOL smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
3041 prs_struct *ps=&buffer->prs;
3043 prs_debug(ps, depth, desc, "smb_io_port_1");
3044 depth++;
3046 buffer->struct_start=prs_offset(ps);
3048 if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
3049 return False;
3051 return True;
3054 /*******************************************************************
3055 Parse a PORT_INFO_2 structure.
3056 ********************************************************************/
3058 BOOL smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
3060 prs_struct *ps=&buffer->prs;
3062 prs_debug(ps, depth, desc, "smb_io_port_2");
3063 depth++;
3065 buffer->struct_start=prs_offset(ps);
3067 if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
3068 return False;
3069 if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
3070 return False;
3071 if(!smb_io_relstr("description", buffer, depth, &info->description))
3072 return False;
3073 if(!prs_uint32("port_type", ps, depth, &info->port_type))
3074 return False;
3075 if(!prs_uint32("reserved", ps, depth, &info->reserved))
3076 return False;
3078 return True;
3081 /*******************************************************************
3082 ********************************************************************/
3084 BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
3086 prs_struct *ps=&buffer->prs;
3088 prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
3089 depth++;
3091 buffer->struct_start=prs_offset(ps);
3093 if (smb_io_relstr("name", buffer, depth, &info->name))
3094 return False;
3096 return True;
3099 /*******************************************************************
3100 ********************************************************************/
3102 BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
3104 prs_struct *ps=&buffer->prs;
3106 prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
3107 depth++;
3109 buffer->struct_start=prs_offset(ps);
3111 if (smb_io_relstr("name", buffer, depth, &info->name))
3112 return False;
3114 return True;
3117 /*******************************************************************
3118 ********************************************************************/
3120 BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
3122 prs_struct *ps=&buffer->prs;
3124 prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
3125 depth++;
3127 buffer->struct_start=prs_offset(ps);
3129 if (!smb_io_relstr("name", buffer, depth, &info->name))
3130 return False;
3132 return True;
3135 /*******************************************************************
3136 ********************************************************************/
3138 BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
3140 prs_struct *ps=&buffer->prs;
3142 prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
3143 depth++;
3145 buffer->struct_start=prs_offset(ps);
3147 if (!smb_io_relstr("name", buffer, depth, &info->name))
3148 return False;
3149 if (!smb_io_relstr("environment", buffer, depth, &info->environment))
3150 return False;
3151 if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
3152 return False;
3154 return True;
3157 /*******************************************************************
3158 return the size required by a struct in the stream
3159 ********************************************************************/
3161 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
3163 int size=0;
3165 size+=size_of_relative_string( &info->printername );
3166 size+=size_of_relative_string( &info->servername );
3168 size+=size_of_uint32( &info->cjobs);
3169 size+=size_of_uint32( &info->total_jobs);
3170 size+=size_of_uint32( &info->total_bytes);
3172 size+=size_of_uint16( &info->year);
3173 size+=size_of_uint16( &info->month);
3174 size+=size_of_uint16( &info->dayofweek);
3175 size+=size_of_uint16( &info->day);
3176 size+=size_of_uint16( &info->hour);
3177 size+=size_of_uint16( &info->minute);
3178 size+=size_of_uint16( &info->second);
3179 size+=size_of_uint16( &info->milliseconds);
3181 size+=size_of_uint32( &info->global_counter);
3182 size+=size_of_uint32( &info->total_pages);
3184 size+=size_of_uint16( &info->major_version);
3185 size+=size_of_uint16( &info->build_version);
3187 size+=size_of_uint32( &info->unknown7);
3188 size+=size_of_uint32( &info->unknown8);
3189 size+=size_of_uint32( &info->unknown9);
3190 size+=size_of_uint32( &info->session_counter);
3191 size+=size_of_uint32( &info->unknown11);
3192 size+=size_of_uint32( &info->printer_errors);
3193 size+=size_of_uint32( &info->unknown13);
3194 size+=size_of_uint32( &info->unknown14);
3195 size+=size_of_uint32( &info->unknown15);
3196 size+=size_of_uint32( &info->unknown16);
3197 size+=size_of_uint32( &info->change_id);
3198 size+=size_of_uint32( &info->unknown18);
3199 size+=size_of_uint32( &info->status);
3200 size+=size_of_uint32( &info->unknown20);
3201 size+=size_of_uint32( &info->c_setprinter);
3203 size+=size_of_uint16( &info->unknown22);
3204 size+=size_of_uint16( &info->unknown23);
3205 size+=size_of_uint16( &info->unknown24);
3206 size+=size_of_uint16( &info->unknown25);
3207 size+=size_of_uint16( &info->unknown26);
3208 size+=size_of_uint16( &info->unknown27);
3209 size+=size_of_uint16( &info->unknown28);
3210 size+=size_of_uint16( &info->unknown29);
3212 return size;
3215 /*******************************************************************
3216 return the size required by a struct in the stream
3217 ********************************************************************/
3219 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
3221 int size=0;
3223 size+=size_of_uint32( &info->flags );
3224 size+=size_of_relative_string( &info->description );
3225 size+=size_of_relative_string( &info->name );
3226 size+=size_of_relative_string( &info->comment );
3228 return size;
3231 /*******************************************************************
3232 return the size required by a struct in the stream
3233 ********************************************************************/
3235 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
3237 uint32 size=0;
3239 size += 4;
3241 size += sec_desc_size( info->secdesc );
3243 size+=size_of_device_mode( info->devmode );
3245 size+=size_of_relative_string( &info->servername );
3246 size+=size_of_relative_string( &info->printername );
3247 size+=size_of_relative_string( &info->sharename );
3248 size+=size_of_relative_string( &info->portname );
3249 size+=size_of_relative_string( &info->drivername );
3250 size+=size_of_relative_string( &info->comment );
3251 size+=size_of_relative_string( &info->location );
3253 size+=size_of_relative_string( &info->sepfile );
3254 size+=size_of_relative_string( &info->printprocessor );
3255 size+=size_of_relative_string( &info->datatype );
3256 size+=size_of_relative_string( &info->parameters );
3258 size+=size_of_uint32( &info->attributes );
3259 size+=size_of_uint32( &info->priority );
3260 size+=size_of_uint32( &info->defaultpriority );
3261 size+=size_of_uint32( &info->starttime );
3262 size+=size_of_uint32( &info->untiltime );
3263 size+=size_of_uint32( &info->status );
3264 size+=size_of_uint32( &info->cjobs );
3265 size+=size_of_uint32( &info->averageppm );
3268 * add any adjustments for alignment. This is
3269 * not optimal since we could be calling this
3270 * function from a loop (e.g. enumprinters), but
3271 * it is easier to maintain the calculation here and
3272 * not place the burden on the caller to remember. --jerry
3274 size += size % 4;
3276 return size;
3279 /*******************************************************************
3280 return the size required by a struct in the stream
3281 ********************************************************************/
3283 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
3285 uint32 size=0;
3287 size+=size_of_relative_string( &info->printername );
3288 size+=size_of_relative_string( &info->servername );
3290 size+=size_of_uint32( &info->attributes );
3291 return size;
3294 /*******************************************************************
3295 return the size required by a struct in the stream
3296 ********************************************************************/
3298 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
3300 uint32 size=0;
3302 size+=size_of_relative_string( &info->printername );
3303 size+=size_of_relative_string( &info->portname );
3305 size+=size_of_uint32( &info->attributes );
3306 size+=size_of_uint32( &info->device_not_selected_timeout );
3307 size+=size_of_uint32( &info->transmission_retry_timeout );
3308 return size;
3312 /*******************************************************************
3313 return the size required by a struct in the stream
3314 ********************************************************************/
3316 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
3318 /* The 4 is for the self relative pointer.. */
3319 /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
3320 return 4 + (uint32)sec_desc_size( info->secdesc );
3323 /*******************************************************************
3324 return the size required by a struct in the stream
3325 ********************************************************************/
3327 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
3329 int size=0;
3330 size+=size_of_relative_string( &info->name );
3332 return size;
3335 /*******************************************************************
3336 return the size required by a struct in the stream
3337 ********************************************************************/
3339 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
3341 int size=0;
3342 size+=size_of_uint32( &info->version );
3343 size+=size_of_relative_string( &info->name );
3344 size+=size_of_relative_string( &info->architecture );
3345 size+=size_of_relative_string( &info->driverpath );
3346 size+=size_of_relative_string( &info->datafile );
3347 size+=size_of_relative_string( &info->configfile );
3349 return size;
3352 /*******************************************************************
3353 return the size required by a string array.
3354 ********************************************************************/
3356 uint32 spoolss_size_string_array(uint16 *string)
3358 uint32 i = 0;
3360 if (string) {
3361 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
3363 i=i+2; /* to count all chars including the leading zero */
3364 i=2*i; /* because we need the value in bytes */
3365 i=i+4; /* the offset pointer size */
3367 return i;
3370 /*******************************************************************
3371 return the size required by a struct in the stream
3372 ********************************************************************/
3374 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3376 int size=0;
3378 size+=size_of_uint32( &info->version );
3379 size+=size_of_relative_string( &info->name );
3380 size+=size_of_relative_string( &info->architecture );
3381 size+=size_of_relative_string( &info->driverpath );
3382 size+=size_of_relative_string( &info->datafile );
3383 size+=size_of_relative_string( &info->configfile );
3384 size+=size_of_relative_string( &info->helpfile );
3385 size+=size_of_relative_string( &info->monitorname );
3386 size+=size_of_relative_string( &info->defaultdatatype );
3388 size+=spoolss_size_string_array(info->dependentfiles);
3390 return size;
3393 /*******************************************************************
3394 return the size required by a struct in the stream
3395 ********************************************************************/
3397 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3399 uint32 size=0;
3401 size+=size_of_uint32( &info->version );
3402 size+=size_of_relative_string( &info->name );
3403 size+=size_of_relative_string( &info->architecture );
3404 size+=size_of_relative_string( &info->driverpath );
3405 size+=size_of_relative_string( &info->datafile );
3406 size+=size_of_relative_string( &info->configfile );
3407 size+=size_of_relative_string( &info->helpfile );
3409 size+=spoolss_size_string_array(info->dependentfiles);
3411 size+=size_of_relative_string( &info->monitorname );
3412 size+=size_of_relative_string( &info->defaultdatatype );
3414 size+=spoolss_size_string_array(info->previousdrivernames);
3416 size+=size_of_nttime(&info->driver_date);
3417 size+=size_of_uint32( &info->padding );
3418 size+=size_of_uint32( &info->driver_version_low );
3419 size+=size_of_uint32( &info->driver_version_high );
3420 size+=size_of_relative_string( &info->mfgname );
3421 size+=size_of_relative_string( &info->oem_url );
3422 size+=size_of_relative_string( &info->hardware_id );
3423 size+=size_of_relative_string( &info->provider );
3425 return size;
3428 /*******************************************************************
3429 return the size required by a struct in the stream
3430 ********************************************************************/
3432 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3434 int size=0;
3435 size+=size_of_uint32( &info->jobid );
3436 size+=size_of_relative_string( &info->printername );
3437 size+=size_of_relative_string( &info->machinename );
3438 size+=size_of_relative_string( &info->username );
3439 size+=size_of_relative_string( &info->document );
3440 size+=size_of_relative_string( &info->datatype );
3441 size+=size_of_relative_string( &info->text_status );
3442 size+=size_of_uint32( &info->status );
3443 size+=size_of_uint32( &info->priority );
3444 size+=size_of_uint32( &info->position );
3445 size+=size_of_uint32( &info->totalpages );
3446 size+=size_of_uint32( &info->pagesprinted );
3447 size+=size_of_systemtime( &info->submitted );
3449 return size;
3452 /*******************************************************************
3453 return the size required by a struct in the stream
3454 ********************************************************************/
3456 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3458 int size=0;
3460 size+=4; /* size of sec desc ptr */
3462 size+=size_of_uint32( &info->jobid );
3463 size+=size_of_relative_string( &info->printername );
3464 size+=size_of_relative_string( &info->machinename );
3465 size+=size_of_relative_string( &info->username );
3466 size+=size_of_relative_string( &info->document );
3467 size+=size_of_relative_string( &info->notifyname );
3468 size+=size_of_relative_string( &info->datatype );
3469 size+=size_of_relative_string( &info->printprocessor );
3470 size+=size_of_relative_string( &info->parameters );
3471 size+=size_of_relative_string( &info->drivername );
3472 size+=size_of_device_mode( info->devmode );
3473 size+=size_of_relative_string( &info->text_status );
3474 /* SEC_DESC sec_desc;*/
3475 size+=size_of_uint32( &info->status );
3476 size+=size_of_uint32( &info->priority );
3477 size+=size_of_uint32( &info->position );
3478 size+=size_of_uint32( &info->starttime );
3479 size+=size_of_uint32( &info->untiltime );
3480 size+=size_of_uint32( &info->totalpages );
3481 size+=size_of_uint32( &info->size );
3482 size+=size_of_systemtime( &info->submitted );
3483 size+=size_of_uint32( &info->timeelapsed );
3484 size+=size_of_uint32( &info->pagesprinted );
3486 return size;
3489 /*******************************************************************
3490 return the size required by a struct in the stream
3491 ********************************************************************/
3493 uint32 spoolss_size_form_1(FORM_1 *info)
3495 int size=0;
3497 size+=size_of_uint32( &info->flag );
3498 size+=size_of_relative_string( &info->name );
3499 size+=size_of_uint32( &info->width );
3500 size+=size_of_uint32( &info->length );
3501 size+=size_of_uint32( &info->left );
3502 size+=size_of_uint32( &info->top );
3503 size+=size_of_uint32( &info->right );
3504 size+=size_of_uint32( &info->bottom );
3506 return size;
3509 /*******************************************************************
3510 return the size required by a struct in the stream
3511 ********************************************************************/
3513 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3515 int size=0;
3517 size+=size_of_relative_string( &info->port_name );
3519 return size;
3522 /*******************************************************************
3523 return the size required by a struct in the stream
3524 ********************************************************************/
3526 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3528 int size=0;
3530 size=str_len_uni(&info->name); /* the string length */
3531 size=size+1; /* add the leading zero */
3532 size=size*2; /* convert in char */
3534 return size;
3537 /*******************************************************************
3538 return the size required by a struct in the stream
3539 ********************************************************************/
3541 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
3543 int size=0;
3545 size=str_len_uni(&info->name); /* the string length */
3546 size=size+1; /* add the leading zero */
3547 size=size*2; /* convert in char */
3549 return size;
3552 /*******************************************************************
3553 return the size required by a struct in the stream
3554 ********************************************************************/
3556 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3558 int size=0;
3560 size+=size_of_relative_string( &info->port_name );
3561 size+=size_of_relative_string( &info->monitor_name );
3562 size+=size_of_relative_string( &info->description );
3564 size+=size_of_uint32( &info->port_type );
3565 size+=size_of_uint32( &info->reserved );
3567 return size;
3570 /*******************************************************************
3571 return the size required by a struct in the stream
3572 ********************************************************************/
3574 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
3576 int size=0;
3577 size+=size_of_relative_string( &info->name );
3579 return size;
3582 /*******************************************************************
3583 return the size required by a struct in the stream
3584 ********************************************************************/
3586 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
3588 int size=0;
3589 size+=size_of_relative_string( &info->name );
3591 return size;
3594 /*******************************************************************
3595 return the size required by a struct in the stream
3596 ********************************************************************/
3597 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
3599 uint32 size = 0;
3601 if (!p)
3602 return 0;
3604 /* uint32(offset) + uint32(length) + length) */
3605 size += (size_of_uint32(&p->value_len)*2) + p->value_len;
3606 size += (size_of_uint32(&p->data_len)*2) + p->data_len;
3608 size += size_of_uint32(&p->type);
3610 return size;
3613 /*******************************************************************
3614 return the size required by a struct in the stream
3615 ********************************************************************/
3617 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
3619 int size=0;
3620 size+=size_of_relative_string( &info->name );
3622 return size;
3625 /*******************************************************************
3626 return the size required by a struct in the stream
3627 ********************************************************************/
3629 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
3631 int size=0;
3632 size+=size_of_relative_string( &info->name);
3633 size+=size_of_relative_string( &info->environment);
3634 size+=size_of_relative_string( &info->dll_name);
3636 return size;
3639 /*******************************************************************
3640 * init a structure.
3641 ********************************************************************/
3643 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
3644 const POLICY_HND *hnd,
3645 const fstring architecture,
3646 uint32 level, uint32 clientmajor, uint32 clientminor,
3647 NEW_BUFFER *buffer, uint32 offered)
3649 if (q_u == NULL)
3650 return False;
3652 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3654 init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
3656 q_u->level=level;
3657 q_u->clientmajorversion=clientmajor;
3658 q_u->clientminorversion=clientminor;
3660 q_u->buffer=buffer;
3661 q_u->offered=offered;
3663 return True;
3666 /*******************************************************************
3667 * read a structure.
3668 * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3669 ********************************************************************/
3671 BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
3673 prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
3674 depth++;
3676 if(!prs_align(ps))
3677 return False;
3679 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3680 return False;
3681 if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
3682 return False;
3683 if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
3684 return False;
3686 if(!prs_align(ps))
3687 return False;
3688 if(!prs_uint32("level", ps, depth, &q_u->level))
3689 return False;
3691 if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3692 return False;
3694 if(!prs_align(ps))
3695 return False;
3697 if(!prs_uint32("offered", ps, depth, &q_u->offered))
3698 return False;
3700 if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
3701 return False;
3702 if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
3703 return False;
3705 return True;
3708 /*******************************************************************
3709 * read a structure.
3710 * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3711 ********************************************************************/
3713 BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
3715 prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
3716 depth++;
3718 if (!prs_align(ps))
3719 return False;
3721 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3722 return False;
3724 if (!prs_align(ps))
3725 return False;
3726 if (!prs_uint32("needed", ps, depth, &r_u->needed))
3727 return False;
3728 if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
3729 return False;
3730 if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
3731 return False;
3732 if (!prs_werror("status", ps, depth, &r_u->status))
3733 return False;
3735 return True;
3738 /*******************************************************************
3739 * init a structure.
3740 ********************************************************************/
3742 BOOL make_spoolss_q_enumprinters(
3743 SPOOL_Q_ENUMPRINTERS *q_u,
3744 uint32 flags,
3745 char *servername,
3746 uint32 level,
3747 NEW_BUFFER *buffer,
3748 uint32 offered
3751 q_u->flags=flags;
3753 q_u->servername_ptr = (servername != NULL) ? 1 : 0;
3754 init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
3756 q_u->level=level;
3757 q_u->buffer=buffer;
3758 q_u->offered=offered;
3760 return True;
3763 /*******************************************************************
3764 * init a structure.
3765 ********************************************************************/
3767 BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u,
3768 fstring servername, uint32 level,
3769 NEW_BUFFER *buffer, uint32 offered)
3771 q_u->name_ptr = (servername != NULL) ? 1 : 0;
3772 init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
3774 q_u->level=level;
3775 q_u->buffer=buffer;
3776 q_u->offered=offered;
3778 return True;
3781 /*******************************************************************
3782 * read a structure.
3783 * called from spoolss_enumprinters (srv_spoolss.c)
3784 ********************************************************************/
3786 BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
3788 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
3789 depth++;
3791 if (!prs_align(ps))
3792 return False;
3794 if (!prs_uint32("flags", ps, depth, &q_u->flags))
3795 return False;
3796 if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
3797 return False;
3799 if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
3800 return False;
3802 if (!prs_align(ps))
3803 return False;
3804 if (!prs_uint32("level", ps, depth, &q_u->level))
3805 return False;
3807 if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3808 return False;
3810 if (!prs_align(ps))
3811 return False;
3812 if (!prs_uint32("offered", ps, depth, &q_u->offered))
3813 return False;
3815 return True;
3818 /*******************************************************************
3819 Parse a SPOOL_R_ENUMPRINTERS structure.
3820 ********************************************************************/
3822 BOOL spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3824 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3825 depth++;
3827 if (!prs_align(ps))
3828 return False;
3830 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3831 return False;
3833 if (!prs_align(ps))
3834 return False;
3836 if (!prs_uint32("needed", ps, depth, &r_u->needed))
3837 return False;
3839 if (!prs_uint32("returned", ps, depth, &r_u->returned))
3840 return False;
3842 if (!prs_werror("status", ps, depth, &r_u->status))
3843 return False;
3845 return True;
3848 /*******************************************************************
3849 * write a structure.
3850 * called from spoolss_r_enum_printers (srv_spoolss.c)
3852 ********************************************************************/
3854 BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3856 prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3857 depth++;
3859 if (!prs_align(ps))
3860 return False;
3862 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3863 return False;
3865 if (!prs_align(ps))
3866 return False;
3868 if (!prs_uint32("needed", ps, depth, &r_u->needed))
3869 return False;
3871 if (!prs_werror("status", ps, depth, &r_u->status))
3872 return False;
3874 return True;
3877 /*******************************************************************
3878 * read a structure.
3879 * called from spoolss_getprinter (srv_spoolss.c)
3880 ********************************************************************/
3882 BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
3884 prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
3885 depth++;
3887 if (!prs_align(ps))
3888 return False;
3890 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3891 return False;
3892 if (!prs_uint32("level", ps, depth, &q_u->level))
3893 return False;
3895 if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3896 return False;
3898 if (!prs_align(ps))
3899 return False;
3900 if (!prs_uint32("offered", ps, depth, &q_u->offered))
3901 return False;
3903 return True;
3906 /*******************************************************************
3907 * init a structure.
3908 ********************************************************************/
3910 BOOL make_spoolss_q_getprinter(
3911 TALLOC_CTX *mem_ctx,
3912 SPOOL_Q_GETPRINTER *q_u,
3913 const POLICY_HND *hnd,
3914 uint32 level,
3915 NEW_BUFFER *buffer,
3916 uint32 offered
3919 if (q_u == NULL)
3921 return False;
3923 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3925 q_u->level=level;
3926 q_u->buffer=buffer;
3927 q_u->offered=offered;
3929 return True;
3932 /*******************************************************************
3933 * init a structure.
3934 ********************************************************************/
3935 BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
3936 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info,
3937 uint32 command)
3939 SEC_DESC *secdesc;
3940 DEVICEMODE *devmode;
3942 if (q_u == NULL)
3943 return False;
3945 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3947 q_u->level = level;
3948 q_u->info.level = level;
3949 q_u->info.info_ptr = (info != NULL) ? 1 : 0;
3950 switch (level) {
3952 /* There's no such thing as a setprinter level 1 */
3954 case 2:
3955 secdesc = info->printers_2->secdesc;
3956 devmode = info->printers_2->devmode;
3958 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
3959 #if 1 /* JERRY TEST */
3960 q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF));
3961 if (!q_u->secdesc_ctr)
3962 return False;
3963 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3964 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3965 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3966 q_u->secdesc_ctr->sec = secdesc;
3968 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3969 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
3970 q_u->devmode_ctr.devmode = devmode;
3971 #else
3972 q_u->secdesc_ctr = NULL;
3974 q_u->devmode_ctr.devmode_ptr = 0;
3975 q_u->devmode_ctr.size = 0;
3976 q_u->devmode_ctr.devmode = NULL;
3977 #endif
3978 break;
3979 default:
3980 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3981 break;
3985 q_u->command = command;
3987 return True;
3991 /*******************************************************************
3992 ********************************************************************/
3994 BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3996 prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3997 depth++;
3999 if(!prs_align(ps))
4000 return False;
4002 if(!prs_werror("status", ps, depth, &r_u->status))
4003 return False;
4005 return True;
4008 /*******************************************************************
4009 Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
4010 ********************************************************************/
4012 BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
4014 uint32 ptr_sec_desc = 0;
4016 prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
4017 depth++;
4019 if(!prs_align(ps))
4020 return False;
4022 if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
4023 return False;
4024 if(!prs_uint32("level", ps, depth, &q_u->level))
4025 return False;
4027 if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4028 return False;
4030 if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4031 return False;
4033 if(!prs_align(ps))
4034 return False;
4036 switch (q_u->level)
4038 case 2:
4040 ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4041 break;
4043 case 3:
4045 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4046 break;
4049 if (ptr_sec_desc)
4051 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4052 return False;
4053 } else {
4054 uint32 dummy = 0;
4056 /* Parse a NULL security descriptor. This should really
4057 happen inside the sec_io_desc_buf() function. */
4059 prs_debug(ps, depth, "", "sec_io_desc_buf");
4060 if (!prs_uint32("size", ps, depth + 1, &dummy))
4061 return False;
4062 if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
4063 False;
4066 if(!prs_uint32("command", ps, depth, &q_u->command))
4067 return False;
4069 return True;
4072 /*******************************************************************
4073 ********************************************************************/
4075 BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
4077 prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
4078 depth++;
4080 if(!prs_align(ps))
4081 return False;
4083 if(!prs_werror("status", ps, depth, &r_u->status))
4084 return False;
4086 return True;
4089 /*******************************************************************
4090 ********************************************************************/
4092 BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
4095 prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
4096 depth++;
4098 if(!prs_align(ps))
4099 return False;
4101 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4102 return False;
4104 return True;
4108 /*******************************************************************
4109 ********************************************************************/
4111 BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
4113 prs_debug(ps, depth, desc, "");
4114 depth++;
4116 if(!prs_align(ps))
4117 return False;
4119 if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4120 return False;
4122 if(!prs_align(ps))
4123 return False;
4125 if(!prs_uint32("needed", ps, depth, &r_u->needed))
4126 return False;
4128 if(!prs_werror("status", ps, depth, &r_u->status))
4129 return False;
4131 return True;
4134 /*******************************************************************
4135 ********************************************************************/
4137 BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
4139 prs_debug(ps, depth, desc, "");
4140 depth++;
4142 if(!prs_align(ps))
4143 return False;
4145 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4146 return False;
4147 if(!prs_uint32("level", ps, depth, &q_u->level))
4148 return False;
4150 if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4151 return False;
4153 if(!prs_align(ps))
4154 return False;
4156 if(!prs_uint32("offered", ps, depth, &q_u->offered))
4157 return False;
4159 return True;
4162 /*******************************************************************
4163 ********************************************************************/
4165 BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
4167 prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
4168 depth++;
4170 if (!prs_align(ps))
4171 return False;
4173 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4174 return False;
4176 if (!prs_align(ps))
4177 return False;
4179 if (!prs_uint32("needed", ps, depth, &r_u->needed))
4180 return False;
4182 if (!prs_uint32("returned", ps, depth, &r_u->returned))
4183 return False;
4185 if (!prs_werror("status", ps, depth, &r_u->status))
4186 return False;
4188 return True;
4191 /*******************************************************************
4192 ********************************************************************/
4194 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
4195 uint32 firstjob,
4196 uint32 numofjobs,
4197 uint32 level,
4198 NEW_BUFFER *buffer,
4199 uint32 offered)
4201 if (q_u == NULL)
4203 return False;
4205 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4206 q_u->firstjob = firstjob;
4207 q_u->numofjobs = numofjobs;
4208 q_u->level = level;
4209 q_u->buffer= buffer;
4210 q_u->offered = offered;
4211 return True;
4214 /*******************************************************************
4215 ********************************************************************/
4217 BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
4219 prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
4220 depth++;
4222 if (!prs_align(ps))
4223 return False;
4225 if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
4226 return False;
4228 if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
4229 return False;
4230 if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
4231 return False;
4232 if (!prs_uint32("level", ps, depth, &q_u->level))
4233 return False;
4235 if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4236 return False;
4238 if(!prs_align(ps))
4239 return False;
4241 if (!prs_uint32("offered", ps, depth, &q_u->offered))
4242 return False;
4244 return True;
4247 /*******************************************************************
4248 ********************************************************************/
4250 BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
4252 prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
4253 depth++;
4255 if(!prs_align(ps))
4256 return False;
4258 if(!prs_werror("status", ps, depth, &r_u->status))
4259 return False;
4261 return True;
4264 /*******************************************************************
4265 ********************************************************************/
4267 BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
4269 prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
4270 depth++;
4272 if(!prs_align(ps))
4273 return False;
4275 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4276 return False;
4277 if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4278 return False;
4280 return True;
4283 /*******************************************************************
4284 ********************************************************************/
4286 BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
4288 prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
4289 depth++;
4291 if(!prs_align(ps))
4292 return False;
4294 if(!prs_werror("status", ps, depth, &r_u->status))
4295 return False;
4297 return True;
4300 /*******************************************************************
4301 ********************************************************************/
4303 BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
4305 prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
4306 depth++;
4308 if(!prs_align(ps))
4309 return False;
4311 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4312 return False;
4313 if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4314 return False;
4316 * level is usually 0. If (level!=0) then I'm in trouble !
4317 * I will try to generate setjob command with level!=0, one day.
4319 if(!prs_uint32("level", ps, depth, &q_u->level))
4320 return False;
4321 if(!prs_uint32("command", ps, depth, &q_u->command))
4322 return False;
4324 return True;
4327 /*******************************************************************
4328 Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
4329 ********************************************************************/
4331 BOOL spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
4333 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
4334 depth++;
4336 if (!prs_align(ps))
4337 return False;
4339 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4340 return False;
4342 if (!prs_align(ps))
4343 return False;
4345 if (!prs_uint32("needed", ps, depth, &r_u->needed))
4346 return False;
4348 if (!prs_uint32("returned", ps, depth, &r_u->returned))
4349 return False;
4351 if (!prs_werror("status", ps, depth, &r_u->status))
4352 return False;
4354 return True;
4357 /*******************************************************************
4358 * init a structure.
4359 ********************************************************************/
4361 BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
4362 const char *name,
4363 const char *environment,
4364 uint32 level,
4365 NEW_BUFFER *buffer, uint32 offered)
4367 init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
4368 init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
4370 q_u->level=level;
4371 q_u->buffer=buffer;
4372 q_u->offered=offered;
4374 return True;
4377 /*******************************************************************
4378 Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
4379 ********************************************************************/
4381 BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
4384 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
4385 depth++;
4387 if (!prs_align(ps))
4388 return False;
4390 if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4391 return False;
4392 if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
4393 return False;
4395 if (!prs_align(ps))
4396 return False;
4397 if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4398 return False;
4399 if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4400 return False;
4402 if (!prs_align(ps))
4403 return False;
4404 if (!prs_uint32("level", ps, depth, &q_u->level))
4405 return False;
4407 if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4408 return False;
4410 if (!prs_align(ps))
4411 return False;
4413 if (!prs_uint32("offered", ps, depth, &q_u->offered))
4414 return False;
4416 return True;
4419 /*******************************************************************
4420 ********************************************************************/
4422 BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4425 prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4426 depth++;
4428 if (!prs_align(ps))
4429 return False;
4430 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4431 return False;
4432 if (!prs_uint32("level", ps, depth, &q_u->level))
4433 return False;
4435 if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4436 return False;
4438 if (!prs_align(ps))
4439 return False;
4440 if (!prs_uint32("offered", ps, depth, &q_u->offered))
4441 return False;
4443 return True;
4446 /*******************************************************************
4447 ********************************************************************/
4449 BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4451 prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4452 depth++;
4454 if (!prs_align(ps))
4455 return False;
4457 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4458 return False;
4460 if (!prs_align(ps))
4461 return False;
4463 if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4464 return False;
4466 if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4467 return False;
4469 if (!prs_werror("status", ps, depth, &r_u->status))
4470 return False;
4472 return True;
4475 /*******************************************************************
4476 ********************************************************************/
4478 BOOL spoolss_io_q_getform(char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4481 prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4482 depth++;
4484 if (!prs_align(ps))
4485 return False;
4486 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4487 return False;
4488 if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4489 return False;
4491 if (!prs_align(ps))
4492 return False;
4494 if (!prs_uint32("level", ps, depth, &q_u->level))
4495 return False;
4497 if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4498 return False;
4500 if (!prs_align(ps))
4501 return False;
4502 if (!prs_uint32("offered", ps, depth, &q_u->offered))
4503 return False;
4505 return True;
4508 /*******************************************************************
4509 ********************************************************************/
4511 BOOL spoolss_io_r_getform(char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4513 prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4514 depth++;
4516 if (!prs_align(ps))
4517 return False;
4519 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4520 return False;
4522 if (!prs_align(ps))
4523 return False;
4525 if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4526 return False;
4528 if (!prs_werror("status", ps, depth, &r_u->status))
4529 return False;
4531 return True;
4534 /*******************************************************************
4535 Parse a SPOOL_R_ENUMPORTS structure.
4536 ********************************************************************/
4538 BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4540 prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
4541 depth++;
4543 if (!prs_align(ps))
4544 return False;
4546 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4547 return False;
4549 if (!prs_align(ps))
4550 return False;
4552 if (!prs_uint32("needed", ps, depth, &r_u->needed))
4553 return False;
4555 if (!prs_uint32("returned", ps, depth, &r_u->returned))
4556 return False;
4558 if (!prs_werror("status", ps, depth, &r_u->status))
4559 return False;
4561 return True;
4564 /*******************************************************************
4565 ********************************************************************/
4567 BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4569 prs_debug(ps, depth, desc, "");
4570 depth++;
4572 if (!prs_align(ps))
4573 return False;
4575 if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4576 return False;
4577 if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4578 return False;
4580 if (!prs_align(ps))
4581 return False;
4582 if (!prs_uint32("level", ps, depth, &q_u->level))
4583 return False;
4585 if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4586 return False;
4588 if (!prs_align(ps))
4589 return False;
4590 if (!prs_uint32("offered", ps, depth, &q_u->offered))
4591 return False;
4593 return True;
4596 /*******************************************************************
4597 Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4598 ********************************************************************/
4600 BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4602 prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4603 depth++;
4605 if(!prs_align(ps))
4606 return False;
4608 if(!prs_uint32("flags", ps, depth, &il->flags))
4609 return False;
4610 if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4611 return False;
4612 if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4613 return False;
4614 if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4615 return False;
4617 if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4618 return False;
4619 if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4620 return False;
4621 if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4622 return False;
4624 return True;
4627 /*******************************************************************
4628 Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4629 ********************************************************************/
4631 BOOL spool_io_printer_info_level_3(char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4633 prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4634 depth++;
4636 if(!prs_align(ps))
4637 return False;
4639 if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4640 return False;
4642 return True;
4645 /*******************************************************************
4646 Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4647 ********************************************************************/
4649 BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4651 prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4652 depth++;
4654 if(!prs_align(ps))
4655 return False;
4657 if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4658 return False;
4659 if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4660 return False;
4661 if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4662 return False;
4663 if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4664 return False;
4666 if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4667 return False;
4668 if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4669 return False;
4670 if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4671 return False;
4672 if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4673 return False;
4674 if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4675 return False;
4676 if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4677 return False;
4678 if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4679 return False;
4680 if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4681 return False;
4682 if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4683 return False;
4685 if(!prs_uint32("attributes", ps, depth, &il->attributes))
4686 return False;
4687 if(!prs_uint32("priority", ps, depth, &il->priority))
4688 return False;
4689 if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4690 return False;
4691 if(!prs_uint32("starttime", ps, depth, &il->starttime))
4692 return False;
4693 if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4694 return False;
4695 if(!prs_uint32("status", ps, depth, &il->status))
4696 return False;
4697 if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4698 return False;
4699 if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4700 return False;
4702 if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4703 return False;
4704 if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4705 return False;
4706 if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4707 return False;
4708 if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4709 return False;
4710 if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4711 return False;
4712 if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4713 return False;
4714 if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4715 return False;
4716 if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4717 return False;
4718 if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4719 return False;
4720 if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4721 return False;
4722 if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4723 return False;
4725 return True;
4728 /*******************************************************************
4729 ********************************************************************/
4731 BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4733 prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4734 depth++;
4736 if(!prs_align(ps))
4737 return False;
4738 if(!prs_uint32("level", ps, depth, &il->level))
4739 return False;
4740 if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4741 return False;
4743 /* if no struct inside just return */
4744 if (il->info_ptr==0) {
4745 if (UNMARSHALLING(ps)) {
4746 il->info_1=NULL;
4747 il->info_2=NULL;
4749 return True;
4752 switch (il->level) {
4754 * level 0 is used by setprinter when managing the queue
4755 * (hold, stop, start a queue)
4757 case 0:
4758 break;
4759 /* DOCUMENT ME!!! What is level 1 used for? */
4760 case 1:
4762 if (UNMARSHALLING(ps)) {
4763 if ((il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_1))) == NULL)
4764 return False;
4766 if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4767 return False;
4768 break;
4771 * level 2 is used by addprinter
4772 * and by setprinter when updating printer's info
4774 case 2:
4775 if (UNMARSHALLING(ps)) {
4776 if ((il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_2))) == NULL)
4777 return False;
4779 if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4780 return False;
4781 break;
4782 /* DOCUMENT ME!!! What is level 3 used for? */
4783 case 3:
4785 if (UNMARSHALLING(ps)) {
4786 if ((il->info_3=(SPOOL_PRINTER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_3))) == NULL)
4787 return False;
4789 if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4790 return False;
4791 break;
4795 return True;
4798 /*******************************************************************
4799 ********************************************************************/
4801 BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4803 uint32 ptr_sec_desc = 0;
4805 prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4806 depth++;
4808 if(!prs_align(ps))
4809 return False;
4810 if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
4811 return False;
4812 if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4813 return False;
4815 if(!prs_align(ps))
4816 return False;
4818 if(!prs_uint32("info_level", ps, depth, &q_u->level))
4819 return False;
4821 if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4822 return False;
4824 if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4825 return False;
4827 if(!prs_align(ps))
4828 return False;
4830 switch (q_u->level) {
4831 case 2:
4832 ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4833 break;
4834 case 3:
4835 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4836 break;
4838 if (ptr_sec_desc) {
4839 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4840 return False;
4841 } else {
4842 uint32 dummy;
4844 /* Parse a NULL security descriptor. This should really
4845 happen inside the sec_io_desc_buf() function. */
4847 prs_debug(ps, depth, "", "sec_io_desc_buf");
4848 if (!prs_uint32("size", ps, depth + 1, &dummy))
4849 return False;
4850 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
4851 return False;
4854 if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
4855 return False;
4856 if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
4857 return False;
4859 return True;
4862 /*******************************************************************
4863 ********************************************************************/
4865 BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u,
4866 prs_struct *ps, int depth)
4868 prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
4869 depth++;
4871 if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
4872 return False;
4874 if(!prs_werror("status", ps, depth, &r_u->status))
4875 return False;
4877 return True;
4880 /*******************************************************************
4881 ********************************************************************/
4883 BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
4884 prs_struct *ps, int depth)
4886 SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
4888 prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
4889 depth++;
4891 /* reading */
4892 if (UNMARSHALLING(ps)) {
4893 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
4894 if(il == NULL)
4895 return False;
4896 *q_u=il;
4898 else {
4899 il=*q_u;
4902 if(!prs_align(ps))
4903 return False;
4905 if(!prs_uint32("cversion", ps, depth, &il->cversion))
4906 return False;
4907 if(!prs_uint32("name", ps, depth, &il->name_ptr))
4908 return False;
4909 if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
4910 return False;
4911 if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
4912 return False;
4913 if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
4914 return False;
4915 if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
4916 return False;
4917 if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
4918 return False;
4919 if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
4920 return False;
4921 if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4922 return False;
4923 if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
4924 return False;
4925 if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4926 return False;
4928 if(!prs_align(ps))
4929 return False;
4931 if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4932 return False;
4933 if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4934 return False;
4935 if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4936 return False;
4937 if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4938 return False;
4939 if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4940 return False;
4941 if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4942 return False;
4943 if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4944 return False;
4945 if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4946 return False;
4948 if(!prs_align(ps))
4949 return False;
4951 if (il->dependentfiles_ptr)
4952 smb_io_buffer5("", &il->dependentfiles, ps, depth);
4954 return True;
4957 /*******************************************************************
4958 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4959 ********************************************************************/
4961 BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u,
4962 prs_struct *ps, int depth)
4964 SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4966 prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4967 depth++;
4969 /* reading */
4970 if (UNMARSHALLING(ps)) {
4971 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6));
4972 if(il == NULL)
4973 return False;
4974 *q_u=il;
4976 else {
4977 il=*q_u;
4980 if(!prs_align(ps))
4981 return False;
4984 /* parse the main elements the packet */
4986 if(!prs_uint32("version", ps, depth, &il->version))
4987 return False;
4989 if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4990 return False;
4992 * If name_ptr is NULL then the next 4 bytes are the name_ptr. A driver
4993 * with a NULL name just isn't a driver For example: "HP LaserJet 4si"
4994 * from W2K CDROM (which uses unidriver). JohnR 010205
4996 if (!il->name_ptr) {
4997 DEBUG(5,("spool_io_printer_driver_info_level_6: name_ptr is NULL! Get next value\n"));
4998 if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4999 return False;
5002 if(!prs_uint32("environment_ptr", ps, depth, &il->environment_ptr))
5003 return False;
5004 if(!prs_uint32("driverpath_ptr", ps, depth, &il->driverpath_ptr))
5005 return False;
5006 if(!prs_uint32("datafile_ptr", ps, depth, &il->datafile_ptr))
5007 return False;
5008 if(!prs_uint32("configfile_ptr", ps, depth, &il->configfile_ptr))
5009 return False;
5010 if(!prs_uint32("helpfile_ptr", ps, depth, &il->helpfile_ptr))
5011 return False;
5012 if(!prs_uint32("monitorname_ptr", ps, depth, &il->monitorname_ptr))
5013 return False;
5014 if(!prs_uint32("defaultdatatype_ptr", ps, depth, &il->defaultdatatype_ptr))
5015 return False;
5016 if(!prs_uint32("dependentfiles_len", ps, depth, &il->dependentfiles_len))
5017 return False;
5018 if(!prs_uint32("dependentfiles_ptr", ps, depth, &il->dependentfiles_ptr))
5019 return False;
5020 if(!prs_uint32("previousnames_len", ps, depth, &il->previousnames_len))
5021 return False;
5022 if(!prs_uint32("previousnames_ptr", ps, depth, &il->previousnames_ptr))
5023 return False;
5024 if(!smb_io_time("driverdate", &il->driverdate, ps, depth))
5025 return False;
5026 if(!prs_uint32("dummy4", ps, depth, &il->dummy4))
5027 return False;
5028 if(!prs_uint64("driverversion", ps, depth, &il->driverversion))
5029 return False;
5030 if(!prs_uint32("mfgname_ptr", ps, depth, &il->mfgname_ptr))
5031 return False;
5032 if(!prs_uint32("oemurl_ptr", ps, depth, &il->oemurl_ptr))
5033 return False;
5034 if(!prs_uint32("hardwareid_ptr", ps, depth, &il->hardwareid_ptr))
5035 return False;
5036 if(!prs_uint32("provider_ptr", ps, depth, &il->provider_ptr))
5037 return False;
5039 /* parse the structures in the packet */
5041 if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
5042 return False;
5043 if(!prs_align(ps))
5044 return False;
5046 if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
5047 return False;
5048 if(!prs_align(ps))
5049 return False;
5051 if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
5052 return False;
5053 if(!prs_align(ps))
5054 return False;
5056 if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
5057 return False;
5058 if(!prs_align(ps))
5059 return False;
5061 if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
5062 return False;
5063 if(!prs_align(ps))
5064 return False;
5066 if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
5067 return False;
5068 if(!prs_align(ps))
5069 return False;
5071 if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
5072 return False;
5073 if(!prs_align(ps))
5074 return False;
5076 if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
5077 return False;
5078 if(!prs_align(ps))
5079 return False;
5080 if (il->dependentfiles_ptr) {
5081 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
5082 return False;
5083 if(!prs_align(ps))
5084 return False;
5086 if (il->previousnames_ptr) {
5087 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
5088 return False;
5089 if(!prs_align(ps))
5090 return False;
5092 if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
5093 return False;
5094 if(!prs_align(ps))
5095 return False;
5096 if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
5097 return False;
5098 if(!prs_align(ps))
5099 return False;
5100 if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
5101 return False;
5102 if(!prs_align(ps))
5103 return False;
5104 if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
5105 return False;
5107 return True;
5110 /*******************************************************************
5111 convert a buffer of UNICODE strings null terminated
5112 the buffer is terminated by a NULL
5114 convert to an dos codepage array (null terminated)
5116 dynamically allocate memory
5118 ********************************************************************/
5119 static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
5121 fstring f, *tar;
5122 int n = 0;
5123 char *src;
5125 if (buf5==NULL)
5126 return False;
5128 src = (char *)buf5->buffer;
5129 *ar = NULL;
5131 while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
5132 rpcstr_pull(f, src, sizeof(f)-1, -1, 0);
5133 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
5134 tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
5135 if (!tar)
5136 return False;
5137 else
5138 *ar = tar;
5139 fstrcpy((*ar)[n], f);
5140 n++;
5142 fstrcpy((*ar)[n], "");
5144 return True;
5150 /*******************************************************************
5151 read a UNICODE array with null terminated strings
5152 and null terminated array
5153 and size of array at beginning
5154 ********************************************************************/
5156 BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
5158 if (buffer==NULL) return False;
5160 buffer->undoc=0;
5161 buffer->uni_str_len=buffer->uni_max_len;
5163 if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
5164 return False;
5166 if(!prs_unistr2(True, "buffer ", ps, depth, buffer))
5167 return False;
5169 return True;
5172 /*******************************************************************
5173 ********************************************************************/
5175 BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
5177 prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
5178 depth++;
5180 if(!prs_align(ps))
5181 return False;
5182 if(!prs_uint32("level", ps, depth, &il->level))
5183 return False;
5184 if(!prs_uint32("ptr", ps, depth, &il->ptr))
5185 return False;
5187 if (il->ptr==0)
5188 return True;
5190 switch (il->level) {
5191 case 3:
5192 if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
5193 return False;
5194 break;
5195 case 6:
5196 if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
5197 return False;
5198 break;
5199 default:
5200 return False;
5203 return True;
5206 /*******************************************************************
5207 init a SPOOL_Q_ADDPRINTERDRIVER struct
5208 ******************************************************************/
5210 BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
5211 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name,
5212 uint32 level, PRINTER_DRIVER_CTR *info)
5214 DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
5216 q_u->server_name_ptr = (srv_name!=NULL)?1:0;
5217 init_unistr2(&q_u->server_name, srv_name, strlen(srv_name)+1);
5219 q_u->level = level;
5221 q_u->info.level = level;
5222 q_u->info.ptr = (info!=NULL)?1:0;
5223 switch (level)
5225 /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
5226 case 3 :
5227 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
5228 break;
5230 default:
5231 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
5232 break;
5235 return True;
5238 BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
5239 SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
5240 DRIVER_INFO_3 *info3)
5242 uint32 len = 0;
5243 uint16 *ptr = info3->dependentfiles;
5244 BOOL done = False;
5245 BOOL null_char = False;
5246 SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
5248 if (!(inf=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3*)talloc_zero(mem_ctx, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3))))
5249 return False;
5251 inf->cversion = info3->version;
5252 inf->name_ptr = (info3->name.buffer!=NULL)?1:0;
5253 inf->environment_ptr = (info3->architecture.buffer!=NULL)?1:0;
5254 inf->driverpath_ptr = (info3->driverpath.buffer!=NULL)?1:0;
5255 inf->datafile_ptr = (info3->datafile.buffer!=NULL)?1:0;
5256 inf->configfile_ptr = (info3->configfile.buffer!=NULL)?1:0;
5257 inf->helpfile_ptr = (info3->helpfile.buffer!=NULL)?1:0;
5258 inf->monitorname_ptr = (info3->monitorname.buffer!=NULL)?1:0;
5259 inf->defaultdatatype_ptr = (info3->defaultdatatype.buffer!=NULL)?1:0;
5261 init_unistr2_from_unistr(&inf->name, &info3->name);
5262 init_unistr2_from_unistr(&inf->environment, &info3->architecture);
5263 init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
5264 init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
5265 init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
5266 init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
5267 init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
5268 init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
5270 while (!done)
5272 switch (*ptr)
5274 case 0:
5275 /* the null_char BOOL is used to help locate
5276 two '\0's back to back */
5277 if (null_char)
5278 done = True;
5279 else
5280 null_char = True;
5281 break;
5283 default:
5284 null_char = False;
5286 break;
5288 len++;
5289 ptr++;
5291 inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
5292 inf->dependentfilessize = len;
5293 if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles))
5295 SAFE_FREE(inf);
5296 return False;
5299 *spool_drv_info = inf;
5301 return True;
5304 /*******************************************************************
5305 make a BUFFER5 struct from a uint16*
5306 ******************************************************************/
5307 BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
5310 buf5->buf_len = len;
5311 if((buf5->buffer=(uint16*)talloc_memdup(mem_ctx, src, sizeof(uint16)*len)) == NULL)
5313 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
5314 return False;
5317 return True;
5320 /*******************************************************************
5321 fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5322 ********************************************************************/
5324 BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5326 prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
5327 depth++;
5329 if(!prs_align(ps))
5330 return False;
5332 if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5333 return False;
5334 if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5335 return False;
5337 if(!prs_align(ps))
5338 return False;
5339 if(!prs_uint32("info_level", ps, depth, &q_u->level))
5340 return False;
5342 if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5343 return False;
5345 return True;
5348 /*******************************************************************
5349 ********************************************************************/
5351 BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5353 prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
5354 depth++;
5356 if(!prs_werror("status", ps, depth, &q_u->status))
5357 return False;
5359 return True;
5362 /*******************************************************************
5363 ********************************************************************/
5365 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
5366 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
5368 NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
5370 DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
5372 if (*asc==NULL)
5374 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3));
5375 if(*asc == NULL)
5376 return False;
5377 ZERO_STRUCTP(*asc);
5380 d=*asc;
5382 d->cversion=uni->cversion;
5384 unistr2_to_ascii(d->name, &uni->name, sizeof(d->name)-1);
5385 unistr2_to_ascii(d->environment, &uni->environment, sizeof(d->environment)-1);
5386 unistr2_to_ascii(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
5387 unistr2_to_ascii(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
5388 unistr2_to_ascii(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
5389 unistr2_to_ascii(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
5390 unistr2_to_ascii(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
5391 unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5393 DEBUGADD(8,( "version: %d\n", d->cversion));
5394 DEBUGADD(8,( "name: %s\n", d->name));
5395 DEBUGADD(8,( "environment: %s\n", d->environment));
5396 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
5397 DEBUGADD(8,( "datafile: %s\n", d->datafile));
5398 DEBUGADD(8,( "configfile: %s\n", d->configfile));
5399 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
5400 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
5401 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5403 if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5404 return True;
5406 SAFE_FREE(*asc);
5407 return False;
5410 /*******************************************************************
5411 ********************************************************************/
5412 BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5413 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5415 NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5417 DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5419 if (*asc==NULL)
5421 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_6 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_6));
5422 if(*asc == NULL)
5423 return False;
5424 ZERO_STRUCTP(*asc);
5427 d=*asc;
5429 d->version=uni->version;
5431 unistr2_to_ascii(d->name, &uni->name, sizeof(d->name)-1);
5432 unistr2_to_ascii(d->environment, &uni->environment, sizeof(d->environment)-1);
5433 unistr2_to_ascii(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
5434 unistr2_to_ascii(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
5435 unistr2_to_ascii(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
5436 unistr2_to_ascii(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
5437 unistr2_to_ascii(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
5438 unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5440 DEBUGADD(8,( "version: %d\n", d->version));
5441 DEBUGADD(8,( "name: %s\n", d->name));
5442 DEBUGADD(8,( "environment: %s\n", d->environment));
5443 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
5444 DEBUGADD(8,( "datafile: %s\n", d->datafile));
5445 DEBUGADD(8,( "configfile: %s\n", d->configfile));
5446 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
5447 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
5448 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5450 if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5451 goto error;
5452 if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5453 goto error;
5455 return True;
5457 error:
5458 SAFE_FREE(*asc);
5459 return False;
5462 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5463 NT_PRINTER_INFO_LEVEL_2 **asc)
5465 NT_PRINTER_INFO_LEVEL_2 *d;
5466 time_t time_unix;
5468 DEBUG(7,("Converting from UNICODE to ASCII\n"));
5469 time_unix=time(NULL);
5471 if (*asc==NULL) {
5472 DEBUGADD(8,("allocating memory\n"));
5474 *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
5475 if(*asc == NULL)
5476 return False;
5477 ZERO_STRUCTP(*asc);
5479 /* we allocate memory iff called from
5480 * addprinter(ex) so we can do one time stuff here.
5482 (*asc)->setuptime=time_unix;
5485 DEBUGADD(8,("start converting\n"));
5487 d=*asc;
5489 d->attributes=uni->attributes;
5490 d->priority=uni->priority;
5491 d->default_priority=uni->default_priority;
5492 d->starttime=uni->starttime;
5493 d->untiltime=uni->untiltime;
5494 d->status=uni->status;
5495 d->cjobs=uni->cjobs;
5497 unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5498 unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5499 unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5500 unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5501 unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5502 unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5503 unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5504 unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5505 unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5506 unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5507 unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5509 return True;
5512 /*******************************************************************
5513 * init a structure.
5514 ********************************************************************/
5516 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5517 fstring servername, fstring env_name, uint32 level,
5518 NEW_BUFFER *buffer, uint32 offered)
5520 init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5521 init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5523 q_u->level=level;
5524 q_u->buffer=buffer;
5525 q_u->offered=offered;
5527 return True;
5530 /*******************************************************************
5531 Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5532 ********************************************************************/
5534 BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5536 prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5537 depth++;
5539 if(!prs_align(ps))
5540 return False;
5541 if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5542 return False;
5543 if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5544 return False;
5546 if(!prs_align(ps))
5547 return False;
5549 if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5550 return False;
5551 if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5552 return False;
5554 if(!prs_align(ps))
5555 return False;
5557 if(!prs_uint32("level", ps, depth, &q_u->level))
5558 return False;
5560 if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5561 return False;
5563 if(!prs_align(ps))
5564 return False;
5566 if(!prs_uint32("offered", ps, depth, &q_u->offered))
5567 return False;
5569 return True;
5572 /*******************************************************************
5573 Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5574 ********************************************************************/
5576 BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5578 prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5579 depth++;
5581 if (!prs_align(ps))
5582 return False;
5584 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5585 return False;
5587 if (!prs_align(ps))
5588 return False;
5590 if (!prs_uint32("needed", ps, depth, &r_u->needed))
5591 return False;
5593 if (!prs_werror("status", ps, depth, &r_u->status))
5594 return False;
5596 return True;
5599 /*******************************************************************
5600 ********************************************************************/
5602 BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5604 prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5605 depth++;
5607 if (!prs_align(ps))
5608 return False;
5610 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5611 return False;
5613 if (!prs_align(ps))
5614 return False;
5616 if (!prs_uint32("needed", ps, depth, &r_u->needed))
5617 return False;
5619 if (!prs_uint32("returned", ps, depth, &r_u->returned))
5620 return False;
5622 if (!prs_werror("status", ps, depth, &r_u->status))
5623 return False;
5625 return True;
5628 /*******************************************************************
5629 ********************************************************************/
5631 BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5633 prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5634 depth++;
5636 if (!prs_align(ps))
5637 return False;
5639 if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5640 return False;
5641 if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5642 return False;
5644 if (!prs_align(ps))
5645 return False;
5647 if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
5648 return False;
5649 if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5650 return False;
5652 if (!prs_align(ps))
5653 return False;
5655 if (!prs_uint32("level", ps, depth, &q_u->level))
5656 return False;
5658 if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5659 return False;
5661 if (!prs_align(ps))
5662 return False;
5664 if (!prs_uint32("offered", ps, depth, &q_u->offered))
5665 return False;
5667 return True;
5670 /*******************************************************************
5671 ********************************************************************/
5673 BOOL spoolss_io_q_addprintprocessor(char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5675 prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5676 depth++;
5678 if (!prs_align(ps))
5679 return False;
5681 if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5682 return False;
5683 if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5684 return False;
5686 if (!prs_align(ps))
5687 return False;
5688 if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5689 return False;
5691 if (!prs_align(ps))
5692 return False;
5693 if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5694 return False;
5696 if (!prs_align(ps))
5697 return False;
5698 if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5699 return False;
5701 return True;
5704 /*******************************************************************
5705 ********************************************************************/
5707 BOOL spoolss_io_r_addprintprocessor(char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5709 prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
5710 depth++;
5712 if (!prs_align(ps))
5713 return False;
5715 if (!prs_werror("status", ps, depth, &r_u->status))
5716 return False;
5718 return True;
5721 /*******************************************************************
5722 ********************************************************************/
5724 BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
5726 prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
5727 depth++;
5729 if (!prs_align(ps))
5730 return False;
5732 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5733 return False;
5735 if (!prs_align(ps))
5736 return False;
5738 if (!prs_uint32("needed", ps, depth, &r_u->needed))
5739 return False;
5741 if (!prs_uint32("returned", ps, depth, &r_u->returned))
5742 return False;
5744 if (!prs_werror("status", ps, depth, &r_u->status))
5745 return False;
5747 return True;
5750 /*******************************************************************
5751 ********************************************************************/
5753 BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
5755 prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
5756 depth++;
5758 if (!prs_align(ps))
5759 return False;
5761 if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5762 return False;
5763 if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5764 return False;
5766 if (!prs_align(ps))
5767 return False;
5769 if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
5770 return False;
5771 if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
5772 return False;
5774 if (!prs_align(ps))
5775 return False;
5777 if (!prs_uint32("level", ps, depth, &q_u->level))
5778 return False;
5780 if(!spoolss_io_buffer("buffer", ps, depth, &q_u->buffer))
5781 return False;
5783 if (!prs_align(ps))
5784 return False;
5786 if (!prs_uint32("offered", ps, depth, &q_u->offered))
5787 return False;
5789 return True;
5792 /*******************************************************************
5793 Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
5794 ********************************************************************/
5796 BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
5798 prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
5799 depth++;
5801 if (!prs_align(ps))
5802 return False;
5804 if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5805 return False;
5806 if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5807 return False;
5809 if (!prs_align(ps))
5810 return False;
5812 if (!prs_uint32("level", ps, depth, &q_u->level))
5813 return False;
5815 if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5816 return False;
5818 if (!prs_align(ps))
5819 return False;
5821 if (!prs_uint32("offered", ps, depth, &q_u->offered))
5822 return False;
5824 return True;
5827 /*******************************************************************
5828 ********************************************************************/
5830 BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
5832 prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
5833 depth++;
5835 if (!prs_align(ps))
5836 return False;
5838 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5839 return False;
5841 if (!prs_align(ps))
5842 return False;
5844 if (!prs_uint32("needed", ps, depth, &r_u->needed))
5845 return False;
5847 if (!prs_uint32("returned", ps, depth, &r_u->returned))
5848 return False;
5850 if (!prs_werror("status", ps, depth, &r_u->status))
5851 return False;
5853 return True;
5856 /*******************************************************************
5857 ********************************************************************/
5859 BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
5861 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
5862 depth++;
5864 if(!prs_align(ps))
5865 return False;
5866 if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
5867 return False;
5869 if (UNMARSHALLING(ps) && r_u->valuesize) {
5870 r_u->value = (uint16 *)prs_alloc_mem(ps, r_u->valuesize * 2);
5871 if (!r_u->value) {
5872 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
5873 return False;
5877 if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
5878 return False;
5880 if(!prs_align(ps))
5881 return False;
5883 if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
5884 return False;
5886 if(!prs_uint32("type", ps, depth, &r_u->type))
5887 return False;
5889 if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
5890 return False;
5892 if (UNMARSHALLING(ps) && r_u->datasize) {
5893 r_u->data = (uint8 *)prs_alloc_mem(ps, r_u->datasize);
5894 if (!r_u->data) {
5895 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
5896 return False;
5900 if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
5901 return False;
5902 if(!prs_align(ps))
5903 return False;
5905 if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
5906 return False;
5907 if(!prs_werror("status", ps, depth, &r_u->status))
5908 return False;
5910 return True;
5913 /*******************************************************************
5914 ********************************************************************/
5916 BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
5918 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
5919 depth++;
5921 if(!prs_align(ps))
5922 return False;
5923 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5924 return False;
5925 if(!prs_uint32("index", ps, depth, &q_u->index))
5926 return False;
5927 if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
5928 return False;
5929 if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
5930 return False;
5932 return True;
5935 /*******************************************************************
5936 ********************************************************************/
5938 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
5939 const POLICY_HND *hnd,
5940 uint32 idx, uint32 valuelen, uint32 datalen)
5942 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5943 q_u->index=idx;
5944 q_u->valuesize=valuelen;
5945 q_u->datasize=datalen;
5947 return True;
5950 /*******************************************************************
5951 ********************************************************************/
5952 BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
5953 char* value, char* data, uint32 data_size)
5955 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5956 q_u->type = REG_SZ;
5957 init_unistr2(&q_u->value, value, strlen(value)+1);
5959 q_u->max_len = q_u->real_len = data_size;
5960 q_u->data = data;
5962 return True;
5964 /*******************************************************************
5965 ********************************************************************/
5967 BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
5969 prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
5970 depth++;
5972 if(!prs_align(ps))
5973 return False;
5974 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5975 return False;
5976 if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5977 return False;
5979 if(!prs_align(ps))
5980 return False;
5982 if(!prs_uint32("type", ps, depth, &q_u->type))
5983 return False;
5985 if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
5986 return False;
5988 switch (q_u->type)
5990 case REG_SZ:
5991 case REG_BINARY:
5992 case REG_DWORD:
5993 case REG_MULTI_SZ:
5994 if (q_u->max_len) {
5995 if (UNMARSHALLING(ps))
5996 q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
5997 if(q_u->data == NULL)
5998 return False;
5999 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6000 return False;
6002 if(!prs_align(ps))
6003 return False;
6004 break;
6007 if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6008 return False;
6010 return True;
6013 /*******************************************************************
6014 ********************************************************************/
6016 BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
6018 prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
6019 depth++;
6021 if(!prs_align(ps))
6022 return False;
6023 if(!prs_werror("status", ps, depth, &r_u->status))
6024 return False;
6026 return True;
6029 /*******************************************************************
6030 ********************************************************************/
6031 BOOL spoolss_io_q_resetprinter(char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
6033 prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
6034 depth++;
6036 if (!prs_align(ps))
6037 return False;
6038 if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6039 return False;
6041 if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
6042 return False;
6044 if (q_u->datatype_ptr) {
6045 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
6046 return False;
6049 if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
6050 return False;
6052 return True;
6056 /*******************************************************************
6057 ********************************************************************/
6058 BOOL spoolss_io_r_resetprinter(char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
6060 prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
6061 depth++;
6063 if(!prs_align(ps))
6064 return False;
6065 if(!prs_werror("status", ps, depth, &r_u->status))
6066 return False;
6068 return True;
6071 /*******************************************************************
6072 ********************************************************************/
6073 BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
6074 uint32 type, const uint8 *data, uint32 len)
6076 DEBUG(5,("converting a specific param struct\n"));
6078 if (*param == NULL)
6080 *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
6081 if(*param == NULL)
6082 return False;
6083 memset((char *)*param, '\0', sizeof(NT_PRINTER_PARAM));
6084 DEBUGADD(6,("Allocated a new PARAM struct\n"));
6086 unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1);
6087 (*param)->type = type;
6089 /* le champ data n'est pas NULL termine */
6090 /* on stocke donc la longueur */
6092 (*param)->data_len=len;
6094 if (len) {
6095 (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
6096 if((*param)->data == NULL)
6097 return False;
6098 memcpy((*param)->data, data, len);
6101 DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
6102 dump_data(10, (char *)(*param)->data, (*param)->data_len);
6104 return True;
6107 /*******************************************************************
6108 ********************************************************************/
6110 static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
6112 prs_debug(ps, depth, desc, "spoolss_io_addform");
6113 depth++;
6114 if(!prs_align(ps))
6115 return False;
6117 if (ptr!=0)
6119 if(!prs_uint32("flags", ps, depth, &f->flags))
6120 return False;
6121 if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
6122 return False;
6123 if(!prs_uint32("size_x", ps, depth, &f->size_x))
6124 return False;
6125 if(!prs_uint32("size_y", ps, depth, &f->size_y))
6126 return False;
6127 if(!prs_uint32("left", ps, depth, &f->left))
6128 return False;
6129 if(!prs_uint32("top", ps, depth, &f->top))
6130 return False;
6131 if(!prs_uint32("right", ps, depth, &f->right))
6132 return False;
6133 if(!prs_uint32("bottom", ps, depth, &f->bottom))
6134 return False;
6136 if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
6137 return False;
6140 return True;
6143 /*******************************************************************
6144 ********************************************************************/
6146 BOOL spoolss_io_q_deleteform(char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
6148 prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
6149 depth++;
6151 if(!prs_align(ps))
6152 return False;
6153 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6154 return False;
6155 if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
6156 return False;
6158 return True;
6161 /*******************************************************************
6162 ********************************************************************/
6164 BOOL spoolss_io_r_deleteform(char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
6166 prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
6167 depth++;
6169 if(!prs_align(ps))
6170 return False;
6171 if(!prs_werror("status", ps, depth, &r_u->status))
6172 return False;
6174 return True;
6177 /*******************************************************************
6178 ********************************************************************/
6180 BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
6182 uint32 useless_ptr=1;
6183 prs_debug(ps, depth, desc, "spoolss_io_q_addform");
6184 depth++;
6186 if(!prs_align(ps))
6187 return False;
6188 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6189 return False;
6190 if(!prs_uint32("level", ps, depth, &q_u->level))
6191 return False;
6192 if(!prs_uint32("level2", ps, depth, &q_u->level2))
6193 return False;
6195 if (q_u->level==1)
6197 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6198 return False;
6199 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6200 return False;
6203 return True;
6206 /*******************************************************************
6207 ********************************************************************/
6209 BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
6211 prs_debug(ps, depth, desc, "spoolss_io_r_addform");
6212 depth++;
6214 if(!prs_align(ps))
6215 return False;
6216 if(!prs_werror("status", ps, depth, &r_u->status))
6217 return False;
6219 return True;
6222 /*******************************************************************
6223 ********************************************************************/
6225 BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
6227 uint32 useless_ptr=1;
6228 prs_debug(ps, depth, desc, "spoolss_io_q_setform");
6229 depth++;
6231 if(!prs_align(ps))
6232 return False;
6233 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6234 return False;
6235 if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
6236 return False;
6238 if(!prs_align(ps))
6239 return False;
6241 if(!prs_uint32("level", ps, depth, &q_u->level))
6242 return False;
6243 if(!prs_uint32("level2", ps, depth, &q_u->level2))
6244 return False;
6246 if (q_u->level==1)
6248 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6249 return False;
6250 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6251 return False;
6254 return True;
6257 /*******************************************************************
6258 ********************************************************************/
6260 BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
6262 prs_debug(ps, depth, desc, "spoolss_io_r_setform");
6263 depth++;
6265 if(!prs_align(ps))
6266 return False;
6267 if(!prs_werror("status", ps, depth, &r_u->status))
6268 return False;
6270 return True;
6273 /*******************************************************************
6274 Parse a SPOOL_R_GETJOB structure.
6275 ********************************************************************/
6277 BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
6279 prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
6280 depth++;
6282 if (!prs_align(ps))
6283 return False;
6285 if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
6286 return False;
6288 if (!prs_align(ps))
6289 return False;
6291 if (!prs_uint32("needed", ps, depth, &r_u->needed))
6292 return False;
6294 if (!prs_werror("status", ps, depth, &r_u->status))
6295 return False;
6297 return True;
6300 /*******************************************************************
6301 Parse a SPOOL_Q_GETJOB structure.
6302 ********************************************************************/
6304 BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
6306 prs_debug(ps, depth, desc, "");
6307 depth++;
6309 if(!prs_align(ps))
6310 return False;
6312 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6313 return False;
6314 if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
6315 return False;
6316 if(!prs_uint32("level", ps, depth, &q_u->level))
6317 return False;
6319 if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
6320 return False;
6322 if(!prs_align(ps))
6323 return False;
6325 if(!prs_uint32("offered", ps, depth, &q_u->offered))
6326 return False;
6328 return True;
6331 void free_devmode(DEVICEMODE *devmode)
6333 if (devmode!=NULL) {
6334 SAFE_FREE(devmode->private);
6335 SAFE_FREE(devmode);
6339 void free_printer_info_1(PRINTER_INFO_1 *printer)
6341 SAFE_FREE(printer);
6344 void free_printer_info_2(PRINTER_INFO_2 *printer)
6346 if (printer!=NULL) {
6347 free_devmode(printer->devmode);
6348 printer->devmode = NULL;
6349 SAFE_FREE(printer);
6353 void free_printer_info_3(PRINTER_INFO_3 *printer)
6355 SAFE_FREE(printer);
6358 void free_printer_info_4(PRINTER_INFO_4 *printer)
6360 SAFE_FREE(printer);
6363 void free_printer_info_5(PRINTER_INFO_5 *printer)
6365 SAFE_FREE(printer);
6368 void free_job_info_2(JOB_INFO_2 *job)
6370 if (job!=NULL)
6371 free_devmode(job->devmode);
6374 /*******************************************************************
6375 * init a structure.
6376 ********************************************************************/
6378 BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u,
6379 const fstring string, uint32 printer, uint32 type)
6381 if (q_u == NULL)
6382 return False;
6384 init_unistr2(&q_u->string, string, strlen(string)+1);
6386 q_u->printer=printer;
6387 q_u->type=type;
6389 q_u->unknown0=0x0;
6390 q_u->unknown1=0x0;
6392 return True;
6395 /*******************************************************************
6396 Parse a SPOOL_Q_REPLYOPENPRINTER structure.
6397 ********************************************************************/
6399 BOOL spoolss_io_q_replyopenprinter(char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
6401 prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
6402 depth++;
6404 if(!prs_align(ps))
6405 return False;
6407 if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
6408 return False;
6410 if(!prs_align(ps))
6411 return False;
6413 if(!prs_uint32("printer", ps, depth, &q_u->printer))
6414 return False;
6415 if(!prs_uint32("type", ps, depth, &q_u->type))
6416 return False;
6418 if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6419 return False;
6420 if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6421 return False;
6423 return True;
6426 /*******************************************************************
6427 Parse a SPOOL_R_REPLYOPENPRINTER structure.
6428 ********************************************************************/
6430 BOOL spoolss_io_r_replyopenprinter(char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
6432 prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
6433 depth++;
6435 if (!prs_align(ps))
6436 return False;
6438 if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6439 return False;
6441 if (!prs_werror("status", ps, depth, &r_u->status))
6442 return False;
6444 return True;
6447 /*******************************************************************
6448 * init a structure.
6449 ********************************************************************/
6450 BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd,
6451 uint32 condition, uint32 change_id)
6454 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6456 q_u->condition = condition;
6457 q_u->change_id = change_id;
6459 /* magic values */
6460 q_u->unknown1 = 0x1;
6461 memset(q_u->unknown2, 0x0, 5);
6462 q_u->unknown2[0] = 0x1;
6464 return True;
6467 /*******************************************************************
6468 Parse a SPOOL_Q_ROUTERREPLYPRINTER structure.
6469 ********************************************************************/
6470 BOOL spoolss_io_q_routerreplyprinter (char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth)
6473 prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter");
6474 depth++;
6476 if (!prs_align(ps))
6477 return False;
6479 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6480 return False;
6482 if (!prs_uint32("condition", ps, depth, &q_u->condition))
6483 return False;
6485 if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6486 return False;
6488 if (!prs_uint32("change_id", ps, depth, &q_u->change_id))
6489 return False;
6491 if (!prs_uint8s(False, "private", ps, depth, q_u->unknown2, 5))
6492 return False;
6494 return True;
6497 /*******************************************************************
6498 Parse a SPOOL_R_ROUTERREPLYPRINTER structure.
6499 ********************************************************************/
6500 BOOL spoolss_io_r_routerreplyprinter (char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth)
6502 prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter");
6503 depth++;
6505 if (!prs_align(ps))
6506 return False;
6508 if (!prs_werror("status", ps, depth, &r_u->status))
6509 return False;
6511 return True;
6514 /*******************************************************************
6515 * init a structure.
6516 ********************************************************************/
6518 BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
6520 if (q_u == NULL)
6521 return False;
6523 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6525 return True;
6528 /*******************************************************************
6529 Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
6530 ********************************************************************/
6532 BOOL spoolss_io_q_replycloseprinter(char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
6534 prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
6535 depth++;
6537 if(!prs_align(ps))
6538 return False;
6540 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6541 return False;
6543 return True;
6546 /*******************************************************************
6547 Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
6548 ********************************************************************/
6550 BOOL spoolss_io_r_replycloseprinter(char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
6552 prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6553 depth++;
6555 if (!prs_align(ps))
6556 return False;
6558 if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6559 return False;
6561 if (!prs_werror("status", ps, depth, &r_u->status))
6562 return False;
6564 return True;
6567 #if 0 /* JERRY - not currently used but could be :-) */
6569 /*******************************************************************
6570 Deep copy a SPOOL_NOTIFY_INFO_DATA structure
6571 ******************************************************************/
6572 static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst,
6573 SPOOL_NOTIFY_INFO_DATA *src, int n)
6575 int i;
6577 memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
6579 for (i=0; i<n; i++) {
6580 int len;
6581 uint16 *s = NULL;
6583 if (src->size != POINTER)
6584 continue;
6585 len = src->notify_data.data.length;
6586 s = malloc(sizeof(uint16)*len);
6587 if (s == NULL) {
6588 DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
6589 return False;
6592 memcpy(s, src->notify_data.data.string, len*2);
6593 dst->notify_data.data.string = s;
6596 return True;
6599 /*******************************************************************
6600 Deep copy a SPOOL_NOTIFY_INFO structure
6601 ******************************************************************/
6602 static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
6604 if (!dst) {
6605 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
6606 return False;
6609 dst->version = src->version;
6610 dst->flags = src->flags;
6611 dst->count = src->count;
6613 if (dst->count)
6615 dst->data = malloc(dst->count * sizeof(SPOOL_NOTIFY_INFO_DATA));
6617 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
6618 dst->count));
6620 if (dst->data == NULL) {
6621 DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n",
6622 dst->count));
6623 return False;
6626 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
6629 return True;
6631 #endif /* JERRY */
6633 /*******************************************************************
6634 * init a structure.
6635 ********************************************************************/
6637 BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
6638 uint32 change_low, uint32 change_high,
6639 SPOOL_NOTIFY_INFO *info)
6641 if (q_u == NULL)
6642 return False;
6644 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6646 q_u->change_low=change_low;
6647 q_u->change_high=change_high;
6649 q_u->unknown0=0x0;
6650 q_u->unknown1=0x0;
6652 q_u->info_ptr=0xaddee11e;
6654 q_u->info.version=2;
6656 if (info->count) {
6657 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
6658 info->count));
6659 q_u->info.version = info->version;
6660 q_u->info.flags = info->flags;
6661 q_u->info.count = info->count;
6662 /* pointer field - be careful! */
6663 q_u->info.data = info->data;
6665 else {
6666 q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
6667 q_u->info.count=0;
6670 return True;
6673 /*******************************************************************
6674 Parse a SPOOL_Q_REPLY_RRPCN structure.
6675 ********************************************************************/
6677 BOOL spoolss_io_q_reply_rrpcn(char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
6679 prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
6680 depth++;
6682 if(!prs_align(ps))
6683 return False;
6685 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6686 return False;
6688 if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
6689 return False;
6691 if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
6692 return False;
6694 if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6695 return False;
6697 if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6698 return False;
6700 if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
6701 return False;
6703 if(q_u->info_ptr!=0)
6704 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
6705 return False;
6707 return True;
6710 /*******************************************************************
6711 Parse a SPOOL_R_REPLY_RRPCN structure.
6712 ********************************************************************/
6714 BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
6716 prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
6717 depth++;
6719 if (!prs_align(ps))
6720 return False;
6722 if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
6723 return False;
6725 if (!prs_werror("status", ps, depth, &r_u->status))
6726 return False;
6728 return True;
6731 /*******************************************************************
6732 * read a structure.
6733 * called from spoolss_q_getprinterdataex (srv_spoolss.c)
6734 ********************************************************************/
6736 BOOL spoolss_io_q_getprinterdataex(char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6738 if (q_u == NULL)
6739 return False;
6741 prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
6742 depth++;
6744 if (!prs_align(ps))
6745 return False;
6746 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6747 return False;
6748 if (!prs_align(ps))
6749 return False;
6750 if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
6751 return False;
6752 if (!prs_align(ps))
6753 return False;
6754 if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
6755 return False;
6756 if (!prs_align(ps))
6757 return False;
6758 if (!prs_uint32("size", ps, depth, &q_u->size))
6759 return False;
6761 return True;
6764 /*******************************************************************
6765 * write a structure.
6766 * called from spoolss_r_getprinterdataex (srv_spoolss.c)
6767 ********************************************************************/
6769 BOOL spoolss_io_r_getprinterdataex(char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6771 if (r_u == NULL)
6772 return False;
6774 prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
6775 depth++;
6777 if (!prs_align(ps))
6778 return False;
6779 if (!prs_uint32("type", ps, depth, &r_u->type))
6780 return False;
6781 if (!prs_uint32("size", ps, depth, &r_u->size))
6782 return False;
6784 if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
6785 return False;
6787 if (!prs_align(ps))
6788 return False;
6790 if (!prs_uint32("needed", ps, depth, &r_u->needed))
6791 return False;
6792 if (!prs_werror("status", ps, depth, &r_u->status))
6793 return False;
6795 return True;
6798 /*******************************************************************
6799 * read a structure.
6800 ********************************************************************/
6802 BOOL spoolss_io_q_setprinterdataex(char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6804 prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
6805 depth++;
6807 if(!prs_align(ps))
6808 return False;
6809 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6810 return False;
6811 if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6812 return False;
6814 if(!prs_align(ps))
6815 return False;
6817 if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
6818 return False;
6820 if(!prs_align(ps))
6821 return False;
6823 if(!prs_uint32("type", ps, depth, &q_u->type))
6824 return False;
6826 if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
6827 return False;
6829 switch (q_u->type)
6831 case 0x1:
6832 case 0x3:
6833 case 0x4:
6834 case 0x7:
6835 if (q_u->max_len) {
6836 if (UNMARSHALLING(ps))
6837 q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
6838 if(q_u->data == NULL)
6839 return False;
6840 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6841 return False;
6843 if(!prs_align(ps))
6844 return False;
6845 break;
6848 if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6849 return False;
6851 return True;
6854 /*******************************************************************
6855 * write a structure.
6856 ********************************************************************/
6858 BOOL spoolss_io_r_setprinterdataex(char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6860 prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
6861 depth++;
6863 if(!prs_align(ps))
6864 return False;
6865 if(!prs_werror("status", ps, depth, &r_u->status))
6866 return False;
6868 return True;
6872 /*******************************************************************
6873 * read a structure.
6874 ********************************************************************/
6876 BOOL spoolss_io_q_enumprinterkey(char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
6878 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
6879 depth++;
6881 if(!prs_align(ps))
6882 return False;
6883 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6884 return False;
6886 if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6887 return False;
6889 if(!prs_align(ps))
6890 return False;
6892 if(!prs_uint32("size", ps, depth, &q_u->size))
6893 return False;
6895 return True;
6898 /*******************************************************************
6899 * write a structure.
6900 ********************************************************************/
6902 BOOL spoolss_io_r_enumprinterkey(char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
6904 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
6905 depth++;
6907 if(!prs_align(ps))
6908 return False;
6910 if (!smb_io_buffer5("", &r_u->keys, ps, depth))
6911 return False;
6913 if(!prs_align(ps))
6914 return False;
6916 if(!prs_uint32("needed", ps, depth, &r_u->needed))
6917 return False;
6919 if(!prs_werror("status", ps, depth, &r_u->status))
6920 return False;
6922 return True;
6925 /*******************************************************************
6926 * read a structure.
6927 ********************************************************************/
6929 BOOL spoolss_io_q_deleteprinterkey(char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
6931 prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
6932 depth++;
6934 if(!prs_align(ps))
6935 return False;
6936 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6937 return False;
6939 if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
6940 return False;
6942 return True;
6945 /*******************************************************************
6946 * write a structure.
6947 ********************************************************************/
6949 BOOL spoolss_io_r_deleteprinterkey(char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
6951 prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
6952 depth++;
6954 if(!prs_align(ps))
6955 return False;
6957 if(!prs_werror("status", ps, depth, &r_u->status))
6958 return False;
6960 return True;
6964 /*******************************************************************
6965 * read a structure.
6966 ********************************************************************/
6968 BOOL spoolss_io_q_enumprinterdataex(char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6970 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
6971 depth++;
6973 if(!prs_align(ps))
6974 return False;
6975 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6976 return False;
6978 if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6979 return False;
6981 if(!prs_align(ps))
6982 return False;
6984 if(!prs_uint32("size", ps, depth, &q_u->size))
6985 return False;
6987 return True;
6990 /*******************************************************************
6991 ********************************************************************/
6992 static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps,
6993 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
6995 int i;
6996 uint32 valuename_offset,
6997 data_offset,
6998 current_offset;
6999 const uint32 basic_unit = 20; /* size of static portion of enum_values */
7001 prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
7002 depth++;
7004 if (!prs_uint32("size", ps, depth, &ctr->size))
7005 return False;
7007 /* offset data begins at 20 bytes per structure * size_of_array.
7008 Don't forget the uint32 at the beginning */
7010 current_offset = basic_unit * ctr->size_of_array;
7012 /* first loop to write basic enum_value information */
7014 for (i=0; i<ctr->size_of_array; i++)
7016 valuename_offset = current_offset;
7017 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
7018 return False;
7020 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
7021 return False;
7023 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
7024 return False;
7026 data_offset = ctr->values[i].value_len + valuename_offset;
7027 if (!prs_uint32("data_offset", ps, depth, &data_offset))
7028 return False;
7030 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
7031 return False;
7033 current_offset = data_offset + ctr->values[i].data_len - basic_unit;
7036 /* loop #2 for writing the dynamically size objects
7037 while viewing conversations between Win2k -> Win2k,
7038 4-byte alignment does not seem to matter here --jerry */
7040 for (i=0; i<ctr->size_of_array; i++)
7043 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
7044 return False;
7046 if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
7047 return False;
7052 return True;
7056 /*******************************************************************
7057 * write a structure.
7058 ********************************************************************/
7060 BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
7062 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
7063 depth++;
7065 if(!prs_align(ps))
7066 return False;
7068 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
7069 return False;
7071 if(!prs_align(ps))
7072 return False;
7074 if(!prs_uint32("needed", ps, depth, &r_u->needed))
7075 return False;
7077 if(!prs_uint32("returned", ps, depth, &r_u->returned))
7078 return False;
7080 if(!prs_werror("status", ps, depth, &r_u->status))
7081 return False;
7083 return True;
7087 /*******************************************************************
7088 * write a structure.
7089 ********************************************************************/
7092 uint32 GetPrintProcessorDirectory(
7093 [in] unistr2 *name,
7094 [in] unistr2 *environment,
7095 [in] uint32 level,
7096 [in,out] NEW_BUFFER buffer,
7097 [in] uint32 offered,
7098 [out] uint32 needed,
7099 [out] uint32 returned
7104 BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered)
7106 DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
7108 init_unistr2(&q_u->name, name, strlen(name)+1);
7109 init_unistr2(&q_u->environment, environment, strlen(environment)+1);
7111 q_u->level = level;
7113 q_u->buffer = buffer;
7114 q_u->offered = offered;
7116 return True;
7119 BOOL spoolss_io_q_getprintprocessordirectory(char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
7121 uint32 ptr;
7123 prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
7124 depth++;
7126 if(!prs_align(ps))
7127 return False;
7129 if (!prs_uint32("ptr", ps, depth, &ptr))
7130 return False;
7132 if (ptr) {
7133 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
7134 return False;
7137 if (!prs_align(ps))
7138 return False;
7140 if (!prs_uint32("ptr", ps, depth, &ptr))
7141 return False;
7143 if (ptr) {
7144 if(!smb_io_unistr2("environment", &q_u->environment, True,
7145 ps, depth))
7146 return False;
7149 if (!prs_align(ps))
7150 return False;
7152 if(!prs_uint32("level", ps, depth, &q_u->level))
7153 return False;
7155 if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
7156 return False;
7158 if(!prs_align(ps))
7159 return False;
7161 if(!prs_uint32("offered", ps, depth, &q_u->offered))
7162 return False;
7164 return True;
7167 /*******************************************************************
7168 * write a structure.
7169 ********************************************************************/
7171 BOOL spoolss_io_r_getprintprocessordirectory(char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
7173 prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
7174 depth++;
7176 if(!prs_align(ps))
7177 return False;
7179 if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
7180 return False;
7182 if(!prs_align(ps))
7183 return False;
7185 if(!prs_uint32("needed", ps, depth, &r_u->needed))
7186 return False;
7188 if(!prs_werror("status", ps, depth, &r_u->status))
7189 return False;
7191 return True;
7194 BOOL smb_io_printprocessordirectory_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
7196 prs_struct *ps=&buffer->prs;
7198 prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
7199 depth++;
7201 buffer->struct_start=prs_offset(ps);
7203 if (!smb_io_unistr(desc, &info->name, ps, depth))
7204 return False;
7206 return True;
7209 /*******************************************************************
7210 * init a structure.
7211 ********************************************************************/
7213 BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle,
7214 int level, FORM *form)
7216 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7217 q_u->level = level;
7218 q_u->level2 = level;
7219 memcpy(&q_u->form, form, sizeof(FORM));
7221 return True;
7224 /*******************************************************************
7225 * init a structure.
7226 ********************************************************************/
7228 BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle,
7229 int level, char *form_name, FORM *form)
7231 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7232 q_u->level = level;
7233 q_u->level2 = level;
7234 memcpy(&q_u->form, form, sizeof(FORM));
7235 init_unistr2(&q_u->name, form_name, strlen(form_name) + 1);
7237 return True;
7240 /*******************************************************************
7241 * init a structure.
7242 ********************************************************************/
7244 BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, char *form)
7246 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7247 init_unistr2(&q_u->name, form, strlen(form) + 1);
7248 return True;
7251 /*******************************************************************
7252 * init a structure.
7253 ********************************************************************/
7255 BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle,
7256 char *formname, uint32 level, NEW_BUFFER *buffer,
7257 uint32 offered)
7259 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7260 q_u->level = level;
7261 init_unistr2(&q_u->formname, formname, strlen(formname) + 1);
7262 q_u->buffer=buffer;
7263 q_u->offered=offered;
7265 return True;
7268 /*******************************************************************
7269 * init a structure.
7270 ********************************************************************/
7272 BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
7273 uint32 level, NEW_BUFFER *buffer,
7274 uint32 offered)
7276 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7277 q_u->level = level;
7278 q_u->buffer=buffer;
7279 q_u->offered=offered;
7281 return True;
7284 /*******************************************************************
7285 * init a structure.
7286 ********************************************************************/
7288 BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle,
7289 uint32 jobid, uint32 level, uint32 command)
7291 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7292 q_u->jobid = jobid;
7293 q_u->level = level;
7295 /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
7296 the server side code has it marked as unused. */
7298 q_u->command = command;
7300 return True;
7303 /*******************************************************************
7304 * init a structure.
7305 ********************************************************************/
7307 BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle,
7308 uint32 jobid, uint32 level, NEW_BUFFER *buffer,
7309 uint32 offered)
7311 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7312 q_u->jobid = jobid;
7313 q_u->level = level;
7314 q_u->buffer = buffer;
7315 q_u->offered = offered;
7317 return True;
7320 /*******************************************************************
7321 * init a structure.
7322 ********************************************************************/
7324 BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u,
7325 POLICY_HND *handle)
7327 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7329 return True;
7332 /*******************************************************************
7333 * init a structure.
7334 ********************************************************************/
7336 BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u,
7337 POLICY_HND *handle)
7339 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7341 return True;
7344 /*******************************************************************
7345 * init a structure.
7346 ********************************************************************/
7348 BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u,
7349 POLICY_HND *handle, uint32 level,
7350 char *docname, char *outputfile,
7351 char *datatype)
7353 DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
7355 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7357 ctr->level = level;
7359 switch (level) {
7360 case 1:
7361 ctr->docinfo.switch_value = level;
7363 ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
7364 ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
7365 ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
7367 if (docname)
7368 init_unistr2(&ctr->docinfo.doc_info_1.docname, docname,
7369 strlen(docname) + 1);
7371 if (outputfile)
7372 init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile,
7373 strlen(outputfile) + 1);
7375 if (datatype)
7376 init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype,
7377 strlen(datatype) + 1);
7379 break;
7380 case 2:
7381 /* DOC_INFO_2 is only used by Windows 9x and since it
7382 doesn't do printing over RPC we don't have to worry
7383 about it. */
7384 default:
7385 DEBUG(3, ("unsupported info level %d\n", level));
7386 return False;
7389 return True;
7392 /*******************************************************************
7393 * init a structure.
7394 ********************************************************************/
7396 BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u,
7397 POLICY_HND *handle)
7399 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7401 return True;
7404 /*******************************************************************
7405 * init a structure.
7406 ********************************************************************/
7408 BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u,
7409 POLICY_HND *handle, uint32 data_size,
7410 char *data)
7412 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7413 q_u->buffer_size = q_u->buffer_size2 = data_size;
7414 q_u->buffer = data;
7415 return True;
7418 /*******************************************************************
7419 * init a structure.
7420 ********************************************************************/
7422 BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u,
7423 POLICY_HND *handle, char *valuename)
7425 memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7426 init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1);
7428 return True;