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.
9 *
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.
14 *
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.
19 *
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.
23 */
24
25#include "includes.h"
26
27#undef DBGC_CLASS
28#define DBGC_CLASS DBGC_RPC_PARSE
29
30/*******************************************************************
31return the length of a UNISTR string.
32********************************************************************/
33
34static uint32 str_len_uni(UNISTR *source)
35{
36 	uint32 i=0;
37
38	if (!source->buffer)
39		return 0;
40
41	while (source->buffer[i])
42		i++;
43
44	return i;
45}
46
47/*******************************************************************
48This should be moved in a more generic lib.
49********************************************************************/
50
51BOOL spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
52{
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;
69
70	return True;
71}
72
73/*******************************************************************
74********************************************************************/
75
76BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
77{
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;
86
87	return True;
88}
89
90/*******************************************************************
91reads or writes an DOC_INFO structure.
92********************************************************************/
93
94static BOOL smb_io_doc_info_1(const char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
95{
96	if (info_1 == NULL) return False;
97
98	prs_debug(ps, depth, desc, "smb_io_doc_info_1");
99	depth++;
100
101	if(!prs_align(ps))
102		return False;
103
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;
110
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;
117
118	return True;
119}
120
121/*******************************************************************
122reads or writes an DOC_INFO structure.
123********************************************************************/
124
125static BOOL smb_io_doc_info(const char *desc, DOC_INFO *info, prs_struct *ps, int depth)
126{
127	uint32 useless_ptr=0;
128
129	if (info == NULL) return False;
130
131	prs_debug(ps, depth, desc, "smb_io_doc_info");
132	depth++;
133
134	if(!prs_align(ps))
135		return False;
136
137	if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
138		return False;
139
140	if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
141		return False;
142
143	switch (info->switch_value)
144	{
145		case 1:
146			if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
147				return False;
148			break;
149		case 2:
150			/*
151			  this is just a placeholder
152
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
156
157			  Maybe one day with Windows for dishwasher 2037 ...
158
159			*/
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;
165	}
166
167	return True;
168}
169
170/*******************************************************************
171reads or writes an DOC_INFO_CONTAINER structure.
172********************************************************************/
173
174static BOOL smb_io_doc_info_container(const char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
175{
176	if (cont == NULL) return False;
177
178	prs_debug(ps, depth, desc, "smb_io_doc_info_container");
179	depth++;
180
181	if(!prs_align(ps))
182		return False;
183
184	if(!prs_uint32("level", ps, depth, &cont->level))
185		return False;
186
187	if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
188		return False;
189
190	return True;
191}
192
193/*******************************************************************
194reads or writes an NOTIFY OPTION TYPE structure.
195********************************************************************/
196
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 */
200
201static BOOL smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
202{
203	prs_debug(ps, depth, desc, "smb_io_notify_option_type");
204	depth++;
205
206	if (!prs_align(ps))
207		return False;
208
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;
221
222	return True;
223}
224
225/*******************************************************************
226reads or writes an NOTIFY OPTION TYPE DATA.
227********************************************************************/
228
229static BOOL smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
230{
231	int i;
232
233	prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
234	depth++;
235
236 	/* if there are no fields just return */
237	if (type->fields_ptr==0)
238		return True;
239
240	if(!prs_align(ps))
241		return False;
242
243	if(!prs_uint32("count2", ps, depth, &type->count2))
244		return False;
245
246	if (type->count2 != type->count)
247		DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
248
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;
254}
255
256/*******************************************************************
257reads or writes an NOTIFY OPTION structure.
258********************************************************************/
259
260static BOOL smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
261{
262	int i;
263
264	prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
265	depth++;
266
267	if(!prs_uint32("count", ps, depth, &ctr->count))
268		return False;
269
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;
274
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;
279
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;
284
285	return True;
286}
287
288/*******************************************************************
289reads or writes an NOTIFY OPTION structure.
290********************************************************************/
291
292static BOOL smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
293{
294	prs_debug(ps, depth, desc, "smb_io_notify_option");
295	depth++;
296
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;
305
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;
310	}
311	else {
312		option->ctr.type=NULL;
313		option->ctr.count=0;
314	}
315
316	return True;
317}
318
319/*******************************************************************
320reads or writes an NOTIFY INFO DATA structure.
321********************************************************************/
322
323static BOOL smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
324{
325	uint32 useless_ptr=0x0FF0ADDE;
326
327	prs_debug(ps, depth, desc, "smb_io_notify_info_data");
328	depth++;
329
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;
336
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;
343
344	switch (data->enc_type) {
345
346		/* One and two value data has two uint32 values */
347
348	case NOTIFY_ONE_VALUE:
349	case NOTIFY_TWO_VALUE:
350
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;
356
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. */
361
362	case NOTIFY_POINTER:
363
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;
368
369		break;
370
371	case NOTIFY_STRING:
372
373		if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
374			return False;
375
376		if(!prs_uint32("pointer", ps, depth, &useless_ptr))
377			return False;
378
379		break;
380
381	case NOTIFY_SECDESC:
382		if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
383			return False;
384		if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
385			return False;
386
387		break;
388
389	default:
390		DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
391			  data->enc_type));
392		break;
393	}
394
395	return True;
396}
397
398/*******************************************************************
399reads or writes an NOTIFY INFO DATA structure.
400********************************************************************/
401
402BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
403                                     prs_struct *ps, int depth)
404{
405	prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
406	depth++;
407
408	if(!prs_align(ps))
409		return False;
410
411	switch(data->enc_type) {
412
413		/* No data for values */
414
415	case NOTIFY_ONE_VALUE:
416	case NOTIFY_TWO_VALUE:
417
418		break;
419
420		/* Strings start with a length in uint16s */
421
422	case NOTIFY_STRING:
423
424		if (UNMARSHALLING(ps)) {
425			data->notify_data.data.string =
426				(uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
427
428			if (!data->notify_data.data.string)
429				return False;
430		}
431
432		if (MARSHALLING(ps))
433			data->notify_data.data.length /= 2;
434
435		if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
436			return False;
437
438		if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
439				   data->notify_data.data.length))
440			return False;
441
442		if (MARSHALLING(ps))
443			data->notify_data.data.length *= 2;
444
445		break;
446
447	case NOTIFY_POINTER:
448
449		if (UNMARSHALLING(ps)) {
450			data->notify_data.data.string =
451				(uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
452
453			if (!data->notify_data.data.string)
454				return False;
455		}
456
457		if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
458			return False;
459
460		break;
461
462	case NOTIFY_SECDESC:
463		if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
464			return False;
465		if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
466			return False;
467		break;
468
469	default:
470		DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
471			  data->enc_type));
472		break;
473	}
474
475#if 0
476	if (isvalue==False) {
477
478		/* length of string in unicode include \0 */
479		x=data->notify_data.data.length+1;
480
481		if (data->field != 16)
482		if(!prs_uint32("string length", ps, depth, &x ))
483			return False;
484
485		if (MARSHALLING(ps)) {
486			/* These are already in little endian format. Don't byte swap. */
487			if (x == 1) {
488
489				/* No memory allocated for this string
490				   therefore following the data.string
491				   pointer is a bad idea.  Use a pointer to
492				   the uint32 length union member to
493				   provide a source for a unicode NULL */
494
495				if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2))
496					return False;
497			} else {
498
499				if (data->field == 16)
500					x /= 2;
501
502				if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
503					return False;
504			}
505		} else {
506
507			/* Tallocate memory for string */
508
509			data->notify_data.data.string = (uint16 *)prs_alloc_mem(ps, x * 2);
510			if (!data->notify_data.data.string)
511				return False;
512
513			if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
514				return False;
515		}
516	}
517
518#endif
519
520#if 0	/* JERRY */
521	/* Win2k does not seem to put this parse align here */
522	if(!prs_align(ps))
523		return False;
524#endif
525
526	return True;
527}
528
529/*******************************************************************
530reads or writes an NOTIFY INFO structure.
531********************************************************************/
532
533static BOOL smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
534{
535	int i;
536
537	prs_debug(ps, depth, desc, "smb_io_notify_info");
538	depth++;
539
540	if(!prs_align(ps))
541		return False;
542
543	if(!prs_uint32("count", ps, depth, &info->count))
544		return False;
545	if(!prs_uint32("version", ps, depth, &info->version))
546		return False;
547	if(!prs_uint32("flags", ps, depth, &info->flags))
548		return False;
549	if(!prs_uint32("count", ps, depth, &info->count))
550		return False;
551
552	for (i=0;i<info->count;i++) {
553		if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
554			return False;
555	}
556
557	/* now do the strings at the end of the stream */
558	for (i=0;i<info->count;i++) {
559		if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
560			return False;
561	}
562
563	return True;
564}
565
566/*******************************************************************
567********************************************************************/
568
569static BOOL spool_io_user_level_1(const char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth)
570{
571	prs_debug(ps, depth, desc, "");
572	depth++;
573
574	/* reading */
575	if (UNMARSHALLING(ps))
576		ZERO_STRUCTP(q_u);
577
578	if (!prs_align(ps))
579		return False;
580	if (!prs_uint32("size", ps, depth, &q_u->size))
581		return False;
582	if (!prs_uint32("client_name_ptr", ps, depth, &q_u->client_name_ptr))
583		return False;
584	if (!prs_uint32("user_name_ptr", ps, depth, &q_u->user_name_ptr))
585		return False;
586	if (!prs_uint32("build", ps, depth, &q_u->build))
587		return False;
588	if (!prs_uint32("major", ps, depth, &q_u->major))
589		return False;
590	if (!prs_uint32("minor", ps, depth, &q_u->minor))
591		return False;
592	if (!prs_uint32("processor", ps, depth, &q_u->processor))
593		return False;
594
595	if (!smb_io_unistr2("", &q_u->client_name, q_u->client_name_ptr, ps, depth))
596		return False;
597	if (!prs_align(ps))
598		return False;
599	if (!smb_io_unistr2("", &q_u->user_name,   q_u->user_name_ptr,   ps, depth))
600		return False;
601
602	return True;
603}
604
605/*******************************************************************
606********************************************************************/
607
608static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
609{
610	if (q_u==NULL)
611		return False;
612
613	prs_debug(ps, depth, desc, "spool_io_user_level");
614	depth++;
615
616	if (!prs_align(ps))
617		return False;
618
619	/* From looking at many captures in ethereal, it looks like
620	   the level and ptr fields should be transposed.  -tpot */
621
622	if (!prs_uint32("level", ps, depth, &q_u->level))
623		return False;
624	if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
625		return False;
626
627	switch (q_u->level) {
628	case 1:
629		if (!spool_io_user_level_1("", &q_u->user1, ps, depth))
630			return False;
631		break;
632	default:
633		return False;
634	}
635
636	return True;
637}
638
639/*******************************************************************
640 * read or write a DEVICEMODE struct.
641 * on reading allocate memory for the private member
642 ********************************************************************/
643
644#define DM_NUM_OPTIONAL_FIELDS 		8
645
646BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
647{
648	int available_space;		/* size of the device mode left to parse */
649					/* only important on unmarshalling       */
650	int i = 0;
651
652	struct optional_fields {
653		fstring		name;
654		uint32*		field;
655	} opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
656		{ "icmmethod",		NULL },
657		{ "icmintent",		NULL },
658		{ "mediatype",		NULL },
659		{ "dithertype",		NULL },
660		{ "reserved1",		NULL },
661		{ "reserved2",		NULL },
662		{ "panningwidth",	NULL },
663		{ "panningheight",	NULL }
664	};
665
666	/* assign at run time to keep non-gcc compilers happy */
667
668	opt_fields[0].field = &devmode->icmmethod;
669	opt_fields[1].field = &devmode->icmintent;
670	opt_fields[2].field = &devmode->mediatype;
671	opt_fields[3].field = &devmode->dithertype;
672	opt_fields[4].field = &devmode->reserved1;
673	opt_fields[5].field = &devmode->reserved2;
674	opt_fields[6].field = &devmode->panningwidth;
675	opt_fields[7].field = &devmode->panningheight;
676
677
678	prs_debug(ps, depth, desc, "spoolss_io_devmode");
679	depth++;
680
681	if (UNMARSHALLING(ps)) {
682		devmode->devicename.buffer = (uint16 *)prs_alloc_mem(ps, 32 * sizeof(uint16) );
683		if (devmode->devicename.buffer == NULL)
684			return False;
685	}
686
687	if (!prs_uint16uni(True,"devicename", ps, depth, devmode->devicename.buffer, MAXDEVICENAME))
688		return False;
689
690	if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
691		return False;
692
693	/* Sanity Check - look for unknown specversions, but don't fail if we see one.
694	   Let the size determine that */
695
696	switch (devmode->specversion) {
697		/* list of observed spec version's */
698		case 0x0320:
699		case 0x0400:
700		case 0x0401:
701		case 0x040d:
702			break;
703
704		default:
705			DEBUG(0,("spoolss_io_devmode: Unknown specversion in devicemode [0x%x]\n",
706				devmode->specversion));
707			DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
708			break;
709	}
710
711
712	if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
713		return False;
714	if (!prs_uint16("size",             ps, depth, &devmode->size))
715		return False;
716	if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
717		return False;
718	if (!prs_uint32("fields",           ps, depth, &devmode->fields))
719		return False;
720	if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
721		return False;
722	if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
723		return False;
724	if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
725		return False;
726	if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
727		return False;
728	if (!prs_uint16("scale",            ps, depth, &devmode->scale))
729		return False;
730	if (!prs_uint16("copies",           ps, depth, &devmode->copies))
731		return False;
732	if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
733		return False;
734	if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
735		return False;
736	if (!prs_uint16("color",            ps, depth, &devmode->color))
737		return False;
738	if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
739		return False;
740	if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
741		return False;
742	if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
743		return False;
744	if (!prs_uint16("collate",          ps, depth, &devmode->collate))
745		return False;
746
747	if (UNMARSHALLING(ps)) {
748		devmode->formname.buffer = (uint16 *)prs_alloc_mem(ps, 32 * sizeof(uint16) );
749		if (devmode->formname.buffer == NULL)
750			return False;
751	}
752
753	if (!prs_uint16uni(True, "formname",  ps, depth, devmode->formname.buffer, 32))
754		return False;
755	if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
756		return False;
757	if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
758		return False;
759	if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
760		return False;
761	if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
762		return False;
763	if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
764		return False;
765	if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
766		return False;
767	/*
768	 * every device mode I've ever seen on the wire at least has up
769	 * to the displayfrequency field.   --jerry (05-09-2002)
770	 */
771
772	/* add uint32's + uint16's + two UNICODE strings */
773
774	available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
775
776	/* Sanity check - we only have uint32's left tp parse */
777
778	if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
779		DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
780			available_space, devmode->size));
781		DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
782		return False;
783	}
784
785	/*
786	 * Conditional parsing.  Assume that the DeviceMode has been
787	 * zero'd by the caller.
788	 */
789
790	while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
791	{
792		DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
793		if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
794			return False;
795		available_space -= sizeof(uint32);
796		i++;
797	}
798
799	/* Sanity Check - we should no available space at this point unless
800	   MS changes the device mode structure */
801
802	if (available_space) {
803		DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
804		DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
805			available_space, devmode->size));
806		DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
807		return False;
808	}
809
810
811	if (devmode->driverextra!=0) {
812		if (UNMARSHALLING(ps)) {
813			devmode->private=(uint8 *)prs_alloc_mem(ps, devmode->driverextra*sizeof(uint8));
814			if(devmode->private == NULL)
815				return False;
816			DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra));
817		}
818
819		DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra));
820		if (!prs_uint8s(False, "private",  ps, depth,
821				devmode->private, devmode->driverextra))
822			return False;
823	}
824
825	return True;
826}
827
828/*******************************************************************
829 Read or write a DEVICEMODE container
830********************************************************************/
831
832static BOOL spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
833{
834	if (dm_c==NULL)
835		return False;
836
837	prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
838	depth++;
839
840	if(!prs_align(ps))
841		return False;
842
843	if (!prs_uint32("size", ps, depth, &dm_c->size))
844		return False;
845
846	if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
847		return False;
848
849	if (dm_c->size==0 || dm_c->devmode_ptr==0) {
850		if (UNMARSHALLING(ps))
851			/* if while reading there is no DEVMODE ... */
852			dm_c->devmode=NULL;
853		return True;
854	}
855
856	/* so we have a DEVICEMODE to follow */
857	if (UNMARSHALLING(ps)) {
858		DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
859		dm_c->devmode=(DEVICEMODE *)prs_alloc_mem(ps,sizeof(DEVICEMODE));
860		if(dm_c->devmode == NULL)
861			return False;
862	}
863
864	/* this is bad code, shouldn't be there */
865	if (!prs_uint32("size", ps, depth, &dm_c->size))
866		return False;
867
868	if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
869		return False;
870
871	return True;
872}
873
874/*******************************************************************
875********************************************************************/
876
877static BOOL spoolss_io_printer_default(const char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
878{
879	if (pd==NULL)
880		return False;
881
882	prs_debug(ps, depth, desc, "spoolss_io_printer_default");
883	depth++;
884
885	if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
886		return False;
887
888	if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
889		return False;
890
891	if (!prs_align(ps))
892		return False;
893
894	if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
895		return False;
896
897	if (!prs_align(ps))
898		return False;
899
900	if (!prs_uint32("access_required", ps, depth, &pd->access_required))
901		return False;
902
903	return True;
904}
905
906/*******************************************************************
907 * init a structure.
908 ********************************************************************/
909
910BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
911		const fstring printername,
912		const fstring datatype,
913		uint32 access_required,
914		const fstring clientname,
915		const fstring user_name)
916{
917	DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
918	q_u->printername_ptr = (printername!=NULL)?1:0;
919	init_unistr2(&q_u->printername, printername, UNI_STR_TERMINATE);
920
921	q_u->printer_default.datatype_ptr = 0;
922/*
923	q_u->printer_default.datatype_ptr = (datatype!=NULL)?1:0;
924	init_unistr2(&q_u->printer_default.datatype, datatype, UNI_FLAGS_NONE);
925*/
926	q_u->printer_default.devmode_cont.size=0;
927	q_u->printer_default.devmode_cont.devmode_ptr=0;
928	q_u->printer_default.devmode_cont.devmode=NULL;
929	q_u->printer_default.access_required=access_required;
930	q_u->user_switch=1;
931	q_u->user_ctr.level=1;
932	q_u->user_ctr.ptr=1;
933	q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+10;
934	q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
935	q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
936	q_u->user_ctr.user1.build=1381;
937	q_u->user_ctr.user1.major=2;
938	q_u->user_ctr.user1.minor=0;
939	q_u->user_ctr.user1.processor=0;
940	init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
941	init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
942
943	return True;
944}
945
946/*******************************************************************
947 * init a structure.
948 ********************************************************************/
949
950BOOL make_spoolss_q_addprinterex(
951	TALLOC_CTX *mem_ctx,
952	SPOOL_Q_ADDPRINTEREX *q_u,
953	const char *srv_name,
954	const char* clientname,
955	const char* user_name,
956	uint32 level,
957	PRINTER_INFO_CTR *ctr)
958{
959	DEBUG(5,("make_spoolss_q_addprinterex\n"));
960
961	if (!ctr) return False;
962
963	ZERO_STRUCTP(q_u);
964
965	q_u->server_name_ptr = (srv_name!=NULL)?1:0;
966	init_unistr2(&q_u->server_name, srv_name, UNI_FLAGS_NONE);
967
968	q_u->level = level;
969
970	q_u->info.level = level;
971	q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
972	switch (level) {
973		case 2:
974			/* init q_u->info.info2 from *info */
975			if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
976				DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
977				return False;
978			}
979			break;
980		default :
981			break;
982	}
983
984	q_u->user_switch=1;
985
986	q_u->user_ctr.level=1;
987	q_u->user_ctr.ptr=1;
988	q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
989	q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
990	q_u->user_ctr.user1.build=1381;
991	q_u->user_ctr.user1.major=2;
992	q_u->user_ctr.user1.minor=0;
993	q_u->user_ctr.user1.processor=0;
994	init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
995	init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
996	q_u->user_ctr.user1.size=q_u->user_ctr.user1.user_name.uni_str_len +
997	                         q_u->user_ctr.user1.client_name.uni_str_len + 2;
998
999	return True;
1000}
1001
1002/*******************************************************************
1003create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
1004*******************************************************************/
1005
1006BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
1007				PRINTER_INFO_2 *info)
1008{
1009
1010	SPOOL_PRINTER_INFO_LEVEL_2 *inf;
1011
1012	/* allocate the necessary memory */
1013	if (!(inf=(SPOOL_PRINTER_INFO_LEVEL_2*)talloc(mem_ctx, sizeof(SPOOL_PRINTER_INFO_LEVEL_2)))) {
1014		DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
1015		return False;
1016	}
1017
1018	inf->servername_ptr 	= (info->servername.buffer!=NULL)?1:0;
1019	inf->printername_ptr 	= (info->printername.buffer!=NULL)?1:0;
1020	inf->sharename_ptr 	= (info->sharename.buffer!=NULL)?1:0;
1021	inf->portname_ptr 	= (info->portname.buffer!=NULL)?1:0;
1022	inf->drivername_ptr 	= (info->drivername.buffer!=NULL)?1:0;
1023	inf->comment_ptr 	= (info->comment.buffer!=NULL)?1:0;
1024	inf->location_ptr 	= (info->location.buffer!=NULL)?1:0;
1025	inf->devmode_ptr 	= (info->devmode!=NULL)?1:0;
1026	inf->sepfile_ptr 	= (info->sepfile.buffer!=NULL)?1:0;
1027	inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
1028	inf->datatype_ptr 	= (info->datatype.buffer!=NULL)?1:0;
1029	inf->parameters_ptr 	= (info->parameters.buffer!=NULL)?1:0;
1030	inf->secdesc_ptr 	= (info->secdesc!=NULL)?1:0;
1031	inf->attributes 	= info->attributes;
1032	inf->priority 		= info->priority;
1033	inf->default_priority 	= info->defaultpriority;
1034	inf->starttime		= info->starttime;
1035	inf->untiltime		= info->untiltime;
1036	inf->cjobs		= info->cjobs;
1037	inf->averageppm	= info->averageppm;
1038	init_unistr2_from_unistr(&inf->servername, 	&info->servername);
1039	init_unistr2_from_unistr(&inf->printername, 	&info->printername);
1040	init_unistr2_from_unistr(&inf->sharename, 	&info->sharename);
1041	init_unistr2_from_unistr(&inf->portname, 	&info->portname);
1042	init_unistr2_from_unistr(&inf->drivername, 	&info->drivername);
1043	init_unistr2_from_unistr(&inf->comment, 	&info->comment);
1044	init_unistr2_from_unistr(&inf->location, 	&info->location);
1045	init_unistr2_from_unistr(&inf->sepfile, 	&info->sepfile);
1046	init_unistr2_from_unistr(&inf->printprocessor,	&info->printprocessor);
1047	init_unistr2_from_unistr(&inf->datatype, 	&info->datatype);
1048	init_unistr2_from_unistr(&inf->parameters, 	&info->parameters);
1049	init_unistr2_from_unistr(&inf->datatype, 	&info->datatype);
1050
1051	*spool_info2 = inf;
1052
1053	return True;
1054}
1055
1056
1057/*******************************************************************
1058 * read a structure.
1059 * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1060 ********************************************************************/
1061
1062BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
1063{
1064	if (q_u == NULL)
1065		return False;
1066
1067	prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
1068	depth++;
1069
1070	if (!prs_align(ps))
1071		return False;
1072
1073	if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
1074		return False;
1075	if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
1076		return False;
1077
1078	if (!prs_align(ps))
1079		return False;
1080
1081	if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1082		return False;
1083
1084	return True;
1085}
1086
1087/*******************************************************************
1088 * write a structure.
1089 * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1090 * called from spoolss_open_printer_ex (cli_spoolss.c)
1091 ********************************************************************/
1092
1093BOOL spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
1094{
1095	if (r_u == NULL) return False;
1096
1097	prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
1098	depth++;
1099
1100	if (!prs_align(ps))
1101		return False;
1102
1103	if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1104		return False;
1105
1106	if (!prs_werror("status code", ps, depth, &(r_u->status)))
1107		return False;
1108
1109	return True;
1110}
1111
1112
1113/*******************************************************************
1114 * read a structure.
1115 * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1116 ********************************************************************/
1117
1118BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
1119{
1120	if (q_u == NULL)
1121		return False;
1122
1123	prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
1124	depth++;
1125
1126	if (!prs_align(ps))
1127		return False;
1128
1129	if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
1130		return False;
1131	if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
1132		return False;
1133
1134	if (!prs_align(ps))
1135		return False;
1136
1137	if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1138		return False;
1139
1140	if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
1141		return False;
1142	if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
1143		return False;
1144
1145	return True;
1146}
1147
1148/*******************************************************************
1149 * write a structure.
1150 * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1151 * called from spoolss_open_printer_ex (cli_spoolss.c)
1152 ********************************************************************/
1153
1154BOOL spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1155{
1156	if (r_u == NULL) return False;
1157
1158	prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1159	depth++;
1160
1161	if (!prs_align(ps))
1162		return False;
1163
1164	if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1165		return False;
1166
1167	if (!prs_werror("status code", ps, depth, &(r_u->status)))
1168		return False;
1169
1170	return True;
1171}
1172
1173/*******************************************************************
1174 * init a structure.
1175 ********************************************************************/
1176BOOL make_spoolss_q_deleteprinterdriver(
1177	TALLOC_CTX *mem_ctx,
1178	SPOOL_Q_DELETEPRINTERDRIVER *q_u,
1179	const char *server,
1180	const char* arch,
1181	const char* driver
1182)
1183{
1184	DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
1185
1186	q_u->server_ptr = (server!=NULL)?1:0;
1187
1188	/* these must be NULL terminated or else NT4 will
1189	   complain about invalid parameters --jerry */
1190	init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1191	init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1192	init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1193
1194	return True;
1195}
1196
1197/*******************************************************************
1198 * make a structure.
1199 ********************************************************************/
1200
1201BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1202				   const POLICY_HND *handle,
1203				   const char *valuename, uint32 size)
1204{
1205        if (q_u == NULL) return False;
1206
1207        DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1208
1209        q_u->handle = *handle;
1210	init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1211        q_u->size = size;
1212
1213        return True;
1214}
1215
1216/*******************************************************************
1217 * make a structure.
1218 ********************************************************************/
1219
1220BOOL make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
1221				     const POLICY_HND *handle,
1222				     const char *keyname,
1223				     const char *valuename, uint32 size)
1224{
1225        if (q_u == NULL) return False;
1226
1227        DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
1228
1229        q_u->handle = *handle;
1230	init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1231	init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
1232        q_u->size = size;
1233
1234        return True;
1235}
1236
1237/*******************************************************************
1238 * read a structure.
1239 * called from spoolss_q_getprinterdata (srv_spoolss.c)
1240 ********************************************************************/
1241
1242BOOL spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1243{
1244	if (q_u == NULL)
1245		return False;
1246
1247	prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1248	depth++;
1249
1250	if (!prs_align(ps))
1251		return False;
1252	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1253		return False;
1254	if (!prs_align(ps))
1255		return False;
1256	if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1257		return False;
1258	if (!prs_align(ps))
1259		return False;
1260	if (!prs_uint32("size", ps, depth, &q_u->size))
1261		return False;
1262
1263	return True;
1264}
1265
1266/*******************************************************************
1267 * read a structure.
1268 * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
1269 ********************************************************************/
1270
1271BOOL spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
1272{
1273	if (q_u == NULL)
1274		return False;
1275
1276	prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
1277	depth++;
1278
1279	if (!prs_align(ps))
1280		return False;
1281	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1282		return False;
1283	if (!prs_align(ps))
1284		return False;
1285	if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1286		return False;
1287
1288	return True;
1289}
1290
1291/*******************************************************************
1292 * write a structure.
1293 * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
1294 ********************************************************************/
1295
1296BOOL spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
1297{
1298	prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
1299	depth++;
1300	if(!prs_werror("status", ps, depth, &r_u->status))
1301		return False;
1302
1303	return True;
1304}
1305
1306/*******************************************************************
1307 * read a structure.
1308 * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
1309 ********************************************************************/
1310
1311BOOL spoolss_io_q_deleteprinterdataex(const char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1312{
1313	if (q_u == NULL)
1314		return False;
1315
1316	prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
1317	depth++;
1318
1319	if (!prs_align(ps))
1320		return False;
1321	if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1322		return False;
1323
1324	if (!smb_io_unistr2("keyname  ", &q_u->keyname, True, ps, depth))
1325		return False;
1326	if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
1327		return False;
1328
1329	return True;
1330}
1331
1332/*******************************************************************
1333 * write a structure.
1334 * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
1335 ********************************************************************/
1336
1337BOOL spoolss_io_r_deleteprinterdataex(const char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
1338{
1339	prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
1340	depth++;
1341
1342	if(!prs_werror("status", ps, depth, &r_u->status))
1343		return False;
1344
1345	return True;
1346}
1347
1348/*******************************************************************
1349 * write a structure.
1350 * called from spoolss_r_getprinterdata (srv_spoolss.c)
1351 ********************************************************************/
1352
1353BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1354{
1355	if (r_u == NULL)
1356		return False;
1357
1358	prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1359	depth++;
1360
1361	if (!prs_align(ps))
1362		return False;
1363	if (!prs_uint32("type", ps, depth, &r_u->type))
1364		return False;
1365	if (!prs_uint32("size", ps, depth, &r_u->size))
1366		return False;
1367
1368	if (UNMARSHALLING(ps) && r_u->size) {
1369		r_u->data = (unsigned char *)prs_alloc_mem(ps, r_u->size);
1370		if(!r_u->data)
1371			return False;
1372	}
1373
1374	if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
1375		return False;
1376
1377	if (!prs_align(ps))
1378		return False;
1379
1380	if (!prs_uint32("needed", ps, depth, &r_u->needed))
1381		return False;
1382	if (!prs_werror("status", ps, depth, &r_u->status))
1383		return False;
1384
1385	return True;
1386}
1387
1388/*******************************************************************
1389 * make a structure.
1390 ********************************************************************/
1391
1392BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
1393{
1394	if (q_u == NULL) return False;
1395
1396	DEBUG(5,("make_spoolss_q_closeprinter\n"));
1397
1398	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1399
1400	return True;
1401}
1402
1403/*******************************************************************
1404 * read a structure.
1405 * called from static spoolss_q_abortprinter (srv_spoolss.c)
1406 * called from spoolss_abortprinter (cli_spoolss.c)
1407 ********************************************************************/
1408
1409BOOL spoolss_io_q_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
1410{
1411	if (q_u == NULL) return False;
1412
1413	prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
1414	depth++;
1415
1416	if (!prs_align(ps))
1417		return False;
1418
1419	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1420		return False;
1421
1422	return True;
1423}
1424
1425/*******************************************************************
1426 * write a structure.
1427 * called from spoolss_r_abortprinter (srv_spoolss.c)
1428 ********************************************************************/
1429
1430BOOL spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
1431{
1432	prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
1433	depth++;
1434	if(!prs_werror("status", ps, depth, &r_u->status))
1435		return False;
1436
1437	return True;
1438}
1439
1440/*******************************************************************
1441 * read a structure.
1442 * called from static spoolss_q_deleteprinter (srv_spoolss.c)
1443 * called from spoolss_deleteprinter (cli_spoolss.c)
1444 ********************************************************************/
1445
1446BOOL spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
1447{
1448	if (q_u == NULL) return False;
1449
1450	prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
1451	depth++;
1452
1453	if (!prs_align(ps))
1454		return False;
1455
1456	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1457		return False;
1458
1459	return True;
1460}
1461
1462/*******************************************************************
1463 * write a structure.
1464 * called from static spoolss_r_deleteprinter (srv_spoolss.c)
1465 * called from spoolss_deleteprinter (cli_spoolss.c)
1466 ********************************************************************/
1467
1468BOOL spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
1469{
1470	prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
1471	depth++;
1472
1473	if (!prs_align(ps))
1474		return False;
1475
1476	if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1477		return False;
1478	if (!prs_werror("status", ps, depth, &r_u->status))
1479		return False;
1480
1481	return True;
1482}
1483
1484
1485/*******************************************************************
1486 * read a structure.
1487 * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1488 * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1489 ********************************************************************/
1490
1491BOOL spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
1492{
1493	if (q_u == NULL) return False;
1494
1495	prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
1496	depth++;
1497
1498	if (!prs_align(ps))
1499		return False;
1500
1501	if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1502		return False;
1503	if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1504		return False;
1505	if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1506		return False;
1507	if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1508		return False;
1509
1510
1511	return True;
1512}
1513
1514
1515/*******************************************************************
1516 * write a structure.
1517 ********************************************************************/
1518BOOL spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
1519{
1520	if (r_u == NULL) return False;
1521
1522	prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
1523	depth++;
1524
1525	if (!prs_align(ps))
1526		return False;
1527
1528	if (!prs_werror("status", ps, depth, &r_u->status))
1529		return False;
1530
1531	return True;
1532}
1533
1534
1535/*******************************************************************
1536 * read a structure.
1537 * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1538 * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1539 ********************************************************************/
1540
1541BOOL spoolss_io_q_deleteprinterdriverex(const char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
1542{
1543	if (q_u == NULL) return False;
1544
1545	prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
1546	depth++;
1547
1548	if (!prs_align(ps))
1549		return False;
1550
1551	if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1552		return False;
1553	if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1554		return False;
1555	if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1556		return False;
1557	if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1558		return False;
1559
1560	if (!prs_align(ps))
1561		return False;
1562
1563	if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
1564		return False;
1565	if(!prs_uint32("version      ", ps, depth, &q_u->version))
1566		return False;
1567
1568
1569	return True;
1570}
1571
1572
1573/*******************************************************************
1574 * write a structure.
1575 ********************************************************************/
1576BOOL spoolss_io_r_deleteprinterdriverex(const char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
1577{
1578	if (r_u == NULL) return False;
1579
1580	prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
1581	depth++;
1582
1583	if (!prs_align(ps))
1584		return False;
1585
1586	if (!prs_werror("status", ps, depth, &r_u->status))
1587		return False;
1588
1589	return True;
1590}
1591
1592
1593
1594/*******************************************************************
1595 * read a structure.
1596 * called from static spoolss_q_closeprinter (srv_spoolss.c)
1597 * called from spoolss_closeprinter (cli_spoolss.c)
1598 ********************************************************************/
1599
1600BOOL spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
1601{
1602	if (q_u == NULL) return False;
1603
1604	prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
1605	depth++;
1606
1607	if (!prs_align(ps))
1608		return False;
1609
1610	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1611		return False;
1612
1613	return True;
1614}
1615
1616/*******************************************************************
1617 * write a structure.
1618 * called from static spoolss_r_closeprinter (srv_spoolss.c)
1619 * called from spoolss_closeprinter (cli_spoolss.c)
1620 ********************************************************************/
1621
1622BOOL spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
1623{
1624	prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
1625	depth++;
1626
1627	if (!prs_align(ps))
1628		return False;
1629
1630	if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1631		return False;
1632	if (!prs_werror("status", ps, depth, &r_u->status))
1633		return False;
1634
1635	return True;
1636}
1637
1638/*******************************************************************
1639 * read a structure.
1640 * called from spoolss_q_startdocprinter (srv_spoolss.c)
1641 ********************************************************************/
1642
1643BOOL spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
1644{
1645	if (q_u == NULL) return False;
1646
1647	prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
1648	depth++;
1649
1650	if(!prs_align(ps))
1651		return False;
1652
1653	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1654		return False;
1655
1656	if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
1657		return False;
1658
1659	return True;
1660}
1661
1662/*******************************************************************
1663 * write a structure.
1664 * called from spoolss_r_startdocprinter (srv_spoolss.c)
1665 ********************************************************************/
1666
1667BOOL spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
1668{
1669	prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
1670	depth++;
1671	if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
1672		return False;
1673	if(!prs_werror("status", ps, depth, &r_u->status))
1674		return False;
1675
1676	return True;
1677}
1678
1679/*******************************************************************
1680 * read a structure.
1681 * called from spoolss_q_enddocprinter (srv_spoolss.c)
1682 ********************************************************************/
1683
1684BOOL spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
1685{
1686	if (q_u == NULL) return False;
1687
1688	prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1689	depth++;
1690
1691	if(!prs_align(ps))
1692		return False;
1693
1694	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1695		return False;
1696
1697	return True;
1698}
1699
1700/*******************************************************************
1701 * write a structure.
1702 * called from spoolss_r_enddocprinter (srv_spoolss.c)
1703 ********************************************************************/
1704
1705BOOL spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1706{
1707	prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1708	depth++;
1709	if(!prs_werror("status", ps, depth, &r_u->status))
1710		return False;
1711
1712	return True;
1713}
1714
1715/*******************************************************************
1716 * read a structure.
1717 * called from spoolss_q_startpageprinter (srv_spoolss.c)
1718 ********************************************************************/
1719
1720BOOL spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1721{
1722	if (q_u == NULL) return False;
1723
1724	prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1725	depth++;
1726
1727	if(!prs_align(ps))
1728		return False;
1729
1730	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1731		return False;
1732
1733	return True;
1734}
1735
1736/*******************************************************************
1737 * write a structure.
1738 * called from spoolss_r_startpageprinter (srv_spoolss.c)
1739 ********************************************************************/
1740
1741BOOL spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1742{
1743	prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1744	depth++;
1745	if(!prs_werror("status", ps, depth, &r_u->status))
1746		return False;
1747
1748	return True;
1749}
1750
1751/*******************************************************************
1752 * read a structure.
1753 * called from spoolss_q_endpageprinter (srv_spoolss.c)
1754 ********************************************************************/
1755
1756BOOL spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1757{
1758	if (q_u == NULL) return False;
1759
1760	prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1761	depth++;
1762
1763	if(!prs_align(ps))
1764		return False;
1765
1766	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1767		return False;
1768
1769	return True;
1770}
1771
1772/*******************************************************************
1773 * write a structure.
1774 * called from spoolss_r_endpageprinter (srv_spoolss.c)
1775 ********************************************************************/
1776
1777BOOL spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1778{
1779	prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1780	depth++;
1781	if(!prs_werror("status", ps, depth, &r_u->status))
1782		return False;
1783
1784	return True;
1785}
1786
1787/*******************************************************************
1788 * read a structure.
1789 * called from spoolss_q_writeprinter (srv_spoolss.c)
1790 ********************************************************************/
1791
1792BOOL spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1793{
1794	if (q_u == NULL) return False;
1795
1796	prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1797	depth++;
1798
1799	if(!prs_align(ps))
1800		return False;
1801
1802	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1803		return False;
1804	if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
1805		return False;
1806
1807	if (q_u->buffer_size!=0)
1808	{
1809		if (UNMARSHALLING(ps))
1810			q_u->buffer=(uint8 *)prs_alloc_mem(ps,q_u->buffer_size*sizeof(uint8));
1811		if(q_u->buffer == NULL)
1812			return False;
1813		if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1814			return False;
1815	}
1816	if(!prs_align(ps))
1817		return False;
1818	if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
1819		return False;
1820
1821	return True;
1822}
1823
1824/*******************************************************************
1825 * write a structure.
1826 * called from spoolss_r_writeprinter (srv_spoolss.c)
1827 ********************************************************************/
1828
1829BOOL spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1830{
1831	prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1832	depth++;
1833	if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
1834		return False;
1835	if(!prs_werror("status", ps, depth, &r_u->status))
1836		return False;
1837
1838	return True;
1839}
1840
1841/*******************************************************************
1842 * read a structure.
1843 * called from spoolss_q_rffpcnex (srv_spoolss.c)
1844 ********************************************************************/
1845
1846BOOL spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1847{
1848	prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1849	depth++;
1850
1851	if(!prs_align(ps))
1852		return False;
1853
1854	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1855		return False;
1856	if(!prs_uint32("flags", ps, depth, &q_u->flags))
1857		return False;
1858	if(!prs_uint32("options", ps, depth, &q_u->options))
1859		return False;
1860	if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1861		return False;
1862	if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1863		return False;
1864
1865	if(!prs_align(ps))
1866		return False;
1867
1868	if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1869		return False;
1870
1871	if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1872		return False;
1873
1874	if (q_u->option_ptr!=0) {
1875
1876		if (UNMARSHALLING(ps))
1877			if((q_u->option=(SPOOL_NOTIFY_OPTION *)prs_alloc_mem(ps,sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1878				return False;
1879
1880		if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1881			return False;
1882	}
1883
1884	return True;
1885}
1886
1887/*******************************************************************
1888 * write a structure.
1889 * called from spoolss_r_rffpcnex (srv_spoolss.c)
1890 ********************************************************************/
1891
1892BOOL spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1893{
1894	prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1895	depth++;
1896
1897	if(!prs_werror("status", ps, depth, &r_u->status))
1898		return False;
1899
1900	return True;
1901}
1902
1903/*******************************************************************
1904 * read a structure.
1905 * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1906 ********************************************************************/
1907
1908BOOL spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1909{
1910	prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1911	depth++;
1912
1913	if(!prs_align(ps))
1914		return False;
1915
1916	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1917		return False;
1918
1919	if(!prs_uint32("change", ps, depth, &q_u->change))
1920		return False;
1921
1922	if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1923		return False;
1924
1925	if (q_u->option_ptr!=0) {
1926
1927		if (UNMARSHALLING(ps))
1928			if((q_u->option=(SPOOL_NOTIFY_OPTION *)prs_alloc_mem(ps,sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1929				return False;
1930
1931		if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1932			return False;
1933	}
1934
1935	return True;
1936}
1937
1938/*******************************************************************
1939 * write a structure.
1940 * called from spoolss_r_rfnpcnex (srv_spoolss.c)
1941 ********************************************************************/
1942
1943BOOL spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
1944{
1945	prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
1946	depth++;
1947
1948	if(!prs_align(ps))
1949		return False;
1950
1951	if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
1952		return False;
1953
1954	if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
1955		return False;
1956
1957	if(!prs_align(ps))
1958		return False;
1959	if(!prs_werror("status", ps, depth, &r_u->status))
1960		return False;
1961
1962	return True;
1963}
1964
1965/*******************************************************************
1966 * return the length of a uint16 (obvious, but the code is clean)
1967 ********************************************************************/
1968
1969static uint32 size_of_uint16(uint16 *value)
1970{
1971	return (sizeof(*value));
1972}
1973
1974/*******************************************************************
1975 * return the length of a uint32 (obvious, but the code is clean)
1976 ********************************************************************/
1977
1978static uint32 size_of_uint32(uint32 *value)
1979{
1980	return (sizeof(*value));
1981}
1982
1983/*******************************************************************
1984 * return the length of a NTTIME (obvious, but the code is clean)
1985 ********************************************************************/
1986
1987static uint32 size_of_nttime(NTTIME *value)
1988{
1989	return (sizeof(*value));
1990}
1991
1992/*******************************************************************
1993 * return the length of a UNICODE string in number of char, includes:
1994 * - the leading zero
1995 * - the relative pointer size
1996 ********************************************************************/
1997
1998static uint32 size_of_relative_string(UNISTR *string)
1999{
2000	uint32 size=0;
2001
2002	size=str_len_uni(string);	/* the string length       */
2003	size=size+1;			/* add the trailing zero   */
2004	size=size*2;			/* convert in char         */
2005	size=size+4;			/* add the size of the ptr */
2006
2007#if 0	/* JERRY */
2008	/*
2009	 * Do not include alignment as Win2k does not align relative
2010	 * strings within a buffer   --jerry
2011	 */
2012	/* Ensure size is 4 byte multiple (prs_align is being called...). */
2013	/* size += ((4 - (size & 3)) & 3); */
2014#endif
2015
2016	return size;
2017}
2018
2019/*******************************************************************
2020 * return the length of a uint32 (obvious, but the code is clean)
2021 ********************************************************************/
2022
2023static uint32 size_of_device_mode(DEVICEMODE *devmode)
2024{
2025	if (devmode==NULL)
2026		return (4);
2027	else
2028		return (4+devmode->size+devmode->driverextra);
2029}
2030
2031/*******************************************************************
2032 * return the length of a uint32 (obvious, but the code is clean)
2033 ********************************************************************/
2034
2035static uint32 size_of_systemtime(SYSTEMTIME *systime)
2036{
2037	if (systime==NULL)
2038		return (4);
2039	else
2040		return (sizeof(SYSTEMTIME) +4);
2041}
2042
2043/*******************************************************************
2044 * write a UNICODE string and its relative pointer.
2045 * used by all the RPC structs passing a buffer
2046 *
2047 * As I'm a nice guy, I'm forcing myself to explain this code.
2048 * MS did a good job in the overall spoolss code except in some
2049 * functions where they are passing the API buffer directly in the
2050 * RPC request/reply. That's to maintain compatiility at the API level.
2051 * They could have done it the good way the first time.
2052 *
2053 * So what happen is: the strings are written at the buffer's end,
2054 * in the reverse order of the original structure. Some pointers to
2055 * the strings are also in the buffer. Those are relative to the
2056 * buffer's start.
2057 *
2058 * If you don't understand or want to change that function,
2059 * first get in touch with me: jfm@samba.org
2060 *
2061 ********************************************************************/
2062
2063static BOOL smb_io_relstr(const char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
2064{
2065	prs_struct *ps=&buffer->prs;
2066
2067	if (MARSHALLING(ps)) {
2068		uint32 struct_offset = prs_offset(ps);
2069		uint32 relative_offset;
2070
2071		buffer->string_at_end -= (size_of_relative_string(string) - 4);
2072		if(!prs_set_offset(ps, buffer->string_at_end))
2073			return False;
2074#if 0	/* JERRY */
2075		/*
2076		 * Win2k does not align strings in a buffer
2077		 * Tested against WinNT 4.0 SP 6a & 2k SP2  --jerry
2078		 */
2079		if (!prs_align(ps))
2080			return False;
2081#endif
2082		buffer->string_at_end = prs_offset(ps);
2083
2084		/* write the string */
2085		if (!smb_io_unistr(desc, string, ps, depth))
2086			return False;
2087
2088		if(!prs_set_offset(ps, struct_offset))
2089			return False;
2090
2091		relative_offset=buffer->string_at_end - buffer->struct_start;
2092		/* write its offset */
2093		if (!prs_uint32("offset", ps, depth, &relative_offset))
2094			return False;
2095	}
2096	else {
2097		uint32 old_offset;
2098
2099		/* read the offset */
2100		if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
2101			return False;
2102
2103		if (buffer->string_at_end == 0)
2104			return True;
2105
2106		old_offset = prs_offset(ps);
2107		if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
2108			return False;
2109
2110		/* read the string */
2111		if (!smb_io_unistr(desc, string, ps, depth))
2112			return False;
2113
2114		if(!prs_set_offset(ps, old_offset))
2115			return False;
2116	}
2117	return True;
2118}
2119
2120/*******************************************************************
2121 * write a array of UNICODE strings and its relative pointer.
2122 * used by 2 RPC structs
2123 ********************************************************************/
2124
2125static BOOL smb_io_relarraystr(const char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
2126{
2127	UNISTR chaine;
2128
2129	prs_struct *ps=&buffer->prs;
2130
2131	if (MARSHALLING(ps)) {
2132		uint32 struct_offset = prs_offset(ps);
2133		uint32 relative_offset;
2134		uint16 *p;
2135		uint16 *q;
2136		uint16 zero=0;
2137		p=*string;
2138		q=*string;
2139
2140		/* first write the last 0 */
2141		buffer->string_at_end -= 2;
2142		if(!prs_set_offset(ps, buffer->string_at_end))
2143			return False;
2144
2145		if(!prs_uint16("leading zero", ps, depth, &zero))
2146			return False;
2147
2148		while (p && (*p!=0)) {
2149			while (*q!=0)
2150				q++;
2151
2152			/* Yes this should be malloc not talloc. Don't change. */
2153
2154			chaine.buffer = malloc((q-p+1)*sizeof(uint16));
2155			if (chaine.buffer == NULL)
2156				return False;
2157
2158			memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
2159
2160			buffer->string_at_end -= (q-p+1)*sizeof(uint16);
2161
2162			if(!prs_set_offset(ps, buffer->string_at_end)) {
2163				SAFE_FREE(chaine.buffer);
2164				return False;
2165			}
2166
2167			/* write the string */
2168			if (!smb_io_unistr(desc, &chaine, ps, depth)) {
2169				SAFE_FREE(chaine.buffer);
2170				return False;
2171			}
2172			q++;
2173			p=q;
2174
2175			SAFE_FREE(chaine.buffer);
2176		}
2177
2178		if(!prs_set_offset(ps, struct_offset))
2179			return False;
2180
2181		relative_offset=buffer->string_at_end - buffer->struct_start;
2182		/* write its offset */
2183		if (!prs_uint32("offset", ps, depth, &relative_offset))
2184			return False;
2185
2186	} else {
2187
2188		/* UNMARSHALLING */
2189
2190		uint32 old_offset;
2191		uint16 *chaine2=NULL;
2192		int l_chaine=0;
2193		int l_chaine2=0;
2194		size_t realloc_size = 0;
2195
2196		*string=NULL;
2197
2198		/* read the offset */
2199		if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2200			return False;
2201
2202		old_offset = prs_offset(ps);
2203		if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2204			return False;
2205
2206		do {
2207			if (!smb_io_unistr(desc, &chaine, ps, depth))
2208				return False;
2209
2210			l_chaine=str_len_uni(&chaine);
2211
2212			/* we're going to add two more bytes here in case this
2213			   is the last string in the array and we need to add
2214			   an extra NULL for termination */
2215			if (l_chaine > 0)
2216			{
2217				uint16 *tc2;
2218
2219				realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
2220
2221				/* Yes this should be realloc - it's freed below. JRA */
2222
2223				if((tc2=(uint16 *)Realloc(chaine2, realloc_size)) == NULL) {
2224					SAFE_FREE(chaine2);
2225					return False;
2226				}
2227				else chaine2 = tc2;
2228				memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
2229				l_chaine2+=l_chaine+1;
2230			}
2231
2232		} while(l_chaine!=0);
2233
2234		/* the end should be bould NULL terminated so add
2235		   the second one here */
2236		if (chaine2)
2237		{
2238			chaine2[l_chaine2] = '\0';
2239			*string=(uint16 *)talloc_memdup(prs_get_mem_context(ps),chaine2,realloc_size);
2240			SAFE_FREE(chaine2);
2241		}
2242
2243		if(!prs_set_offset(ps, old_offset))
2244			return False;
2245	}
2246	return True;
2247}
2248
2249/*******************************************************************
2250 Parse a DEVMODE structure and its relative pointer.
2251********************************************************************/
2252
2253static BOOL smb_io_relsecdesc(const char *desc, NEW_BUFFER *buffer, int depth, SEC_DESC **secdesc)
2254{
2255	prs_struct *ps= &buffer->prs;
2256
2257	prs_debug(ps, depth, desc, "smb_io_relsecdesc");
2258	depth++;
2259
2260	if (MARSHALLING(ps)) {
2261		uint32 struct_offset = prs_offset(ps);
2262		uint32 relative_offset;
2263
2264		if (! *secdesc) {
2265			relative_offset = 0;
2266			if (!prs_uint32("offset", ps, depth, &relative_offset))
2267				return False;
2268			return True;
2269		}
2270
2271		if (*secdesc != NULL) {
2272			buffer->string_at_end -= sec_desc_size(*secdesc);
2273
2274			if(!prs_set_offset(ps, buffer->string_at_end))
2275				return False;
2276			/* write the secdesc */
2277			if (!sec_io_desc(desc, secdesc, ps, depth))
2278				return False;
2279
2280			if(!prs_set_offset(ps, struct_offset))
2281				return False;
2282		}
2283
2284		relative_offset=buffer->string_at_end - buffer->struct_start;
2285		/* write its offset */
2286
2287		if (!prs_uint32("offset", ps, depth, &relative_offset))
2288			return False;
2289	} else {
2290		uint32 old_offset;
2291
2292		/* read the offset */
2293		if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2294			return False;
2295
2296		old_offset = prs_offset(ps);
2297		if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2298			return False;
2299
2300		/* read the sd */
2301		if (!sec_io_desc(desc, secdesc, ps, depth))
2302			return False;
2303
2304		if(!prs_set_offset(ps, old_offset))
2305			return False;
2306	}
2307	return True;
2308}
2309
2310/*******************************************************************
2311 Parse a DEVMODE structure and its relative pointer.
2312********************************************************************/
2313
2314static BOOL smb_io_reldevmode(const char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
2315{
2316	prs_struct *ps=&buffer->prs;
2317
2318	prs_debug(ps, depth, desc, "smb_io_reldevmode");
2319	depth++;
2320
2321	if (MARSHALLING(ps)) {
2322		uint32 struct_offset = prs_offset(ps);
2323		uint32 relative_offset;
2324
2325		if (*devmode == NULL) {
2326			relative_offset=0;
2327			if (!prs_uint32("offset", ps, depth, &relative_offset))
2328				return False;
2329			DEBUG(8, ("boing, the devmode was NULL\n"));
2330
2331			return True;
2332		}
2333
2334		buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
2335
2336		if(!prs_set_offset(ps, buffer->string_at_end))
2337			return False;
2338
2339		/* write the DEVMODE */
2340		if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2341			return False;
2342
2343		if(!prs_set_offset(ps, struct_offset))
2344			return False;
2345
2346		relative_offset=buffer->string_at_end - buffer->struct_start;
2347		/* write its offset */
2348		if (!prs_uint32("offset", ps, depth, &relative_offset))
2349			return False;
2350	}
2351	else {
2352		uint32 old_offset;
2353
2354		/* read the offset */
2355		if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2356			return False;
2357		if (buffer->string_at_end == 0) {
2358			*devmode = NULL;
2359			return True;
2360		}
2361
2362		old_offset = prs_offset(ps);
2363		if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2364			return False;
2365
2366		/* read the string */
2367		if((*devmode=(DEVICEMODE *)prs_alloc_mem(ps,sizeof(DEVICEMODE))) == NULL)
2368			return False;
2369		if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2370			return False;
2371
2372		if(!prs_set_offset(ps, old_offset))
2373			return False;
2374	}
2375	return True;
2376}
2377
2378/*******************************************************************
2379 Parse a PRINTER_INFO_0 structure.
2380********************************************************************/
2381
2382BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2383{
2384	prs_struct *ps=&buffer->prs;
2385
2386	prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2387	depth++;
2388
2389	buffer->struct_start=prs_offset(ps);
2390
2391	if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2392		return False;
2393	if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2394		return False;
2395
2396	if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2397		return False;
2398	if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2399		return False;
2400	if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2401		return False;
2402
2403	if(!prs_uint16("year", ps, depth, &info->year))
2404		return False;
2405	if(!prs_uint16("month", ps, depth, &info->month))
2406		return False;
2407	if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2408		return False;
2409	if(!prs_uint16("day", ps, depth, &info->day))
2410		return False;
2411	if(!prs_uint16("hour", ps, depth, &info->hour))
2412		return False;
2413	if(!prs_uint16("minute", ps, depth, &info->minute))
2414		return False;
2415	if(!prs_uint16("second", ps, depth, &info->second))
2416		return False;
2417	if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2418		return False;
2419
2420	if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2421		return False;
2422	if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2423		return False;
2424
2425	if(!prs_uint16("major_version", ps, depth, &info->major_version))
2426		return False;
2427	if(!prs_uint16("build_version", ps, depth, &info->build_version))
2428		return False;
2429	if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2430		return False;
2431	if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2432		return False;
2433	if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2434		return False;
2435	if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2436		return False;
2437	if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2438		return False;
2439	if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2440		return False;
2441	if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2442		return False;
2443	if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2444		return False;
2445	if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2446		return False;
2447	if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2448		return False;
2449	if(!prs_uint32("change_id", ps, depth, &info->change_id))
2450		return False;
2451	if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2452		return False;
2453	if(!prs_uint32("status"   , ps, depth, &info->status))
2454		return False;
2455	if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2456		return False;
2457	if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2458		return False;
2459	if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2460		return False;
2461	if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2462		return False;
2463	if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2464		return False;
2465	if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2466		return False;
2467	if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2468		return False;
2469	if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2470		return False;
2471	if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2472		return False;
2473	if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2474		return False;
2475
2476	return True;
2477}
2478
2479/*******************************************************************
2480 Parse a PRINTER_INFO_1 structure.
2481********************************************************************/
2482
2483BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2484{
2485	prs_struct *ps=&buffer->prs;
2486
2487	prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2488	depth++;
2489
2490	buffer->struct_start=prs_offset(ps);
2491
2492	if (!prs_uint32("flags", ps, depth, &info->flags))
2493		return False;
2494	if (!smb_io_relstr("description", buffer, depth, &info->description))
2495		return False;
2496	if (!smb_io_relstr("name", buffer, depth, &info->name))
2497		return False;
2498	if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2499		return False;
2500
2501	return True;
2502}
2503
2504/*******************************************************************
2505 Parse a PRINTER_INFO_2 structure.
2506********************************************************************/
2507
2508BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2509{
2510	prs_struct *ps=&buffer->prs;
2511	uint32 dm_offset, sd_offset, current_offset;
2512	uint32 dummy_value = 0, has_secdesc = 0;
2513
2514	prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2515	depth++;
2516
2517	buffer->struct_start=prs_offset(ps);
2518
2519	if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2520		return False;
2521	if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2522		return False;
2523	if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2524		return False;
2525	if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2526		return False;
2527	if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2528		return False;
2529	if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2530		return False;
2531	if (!smb_io_relstr("location", buffer, depth, &info->location))
2532		return False;
2533
2534	/* save current offset and wind forwared by a uint32 */
2535	dm_offset = prs_offset(ps);
2536	if (!prs_uint32("devmode", ps, depth, &dummy_value))
2537		return False;
2538
2539	if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2540		return False;
2541	if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2542		return False;
2543	if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2544		return False;
2545	if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2546		return False;
2547
2548	/* save current offset for the sec_desc */
2549	sd_offset = prs_offset(ps);
2550	if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
2551		return False;
2552
2553
2554	/* save current location so we can pick back up here */
2555	current_offset = prs_offset(ps);
2556
2557	/* parse the devmode */
2558	if (!prs_set_offset(ps, dm_offset))
2559		return False;
2560	if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2561		return False;
2562
2563	/* parse the sec_desc */
2564	if (has_secdesc) {
2565		if (!prs_set_offset(ps, sd_offset))
2566			return False;
2567		if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2568			return False;
2569	}
2570
2571	/* pick up where we left off */
2572	if (!prs_set_offset(ps, current_offset))
2573		return False;
2574
2575	if (!prs_uint32("attributes", ps, depth, &info->attributes))
2576		return False;
2577	if (!prs_uint32("priority", ps, depth, &info->priority))
2578		return False;
2579	if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2580		return False;
2581	if (!prs_uint32("starttime", ps, depth, &info->starttime))
2582		return False;
2583	if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2584		return False;
2585	if (!prs_uint32("status", ps, depth, &info->status))
2586		return False;
2587	if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2588		return False;
2589	if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2590		return False;
2591
2592	return True;
2593}
2594
2595/*******************************************************************
2596 Parse a PRINTER_INFO_3 structure.
2597********************************************************************/
2598
2599BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2600{
2601	prs_struct *ps=&buffer->prs;
2602
2603	prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2604	depth++;
2605
2606	buffer->struct_start=prs_offset(ps);
2607
2608	if (!prs_uint32("flags", ps, depth, &info->flags))
2609		return False;
2610	if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2611		return False;
2612
2613	return True;
2614}
2615
2616/*******************************************************************
2617 Parse a PRINTER_INFO_4 structure.
2618********************************************************************/
2619
2620BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
2621{
2622	prs_struct *ps=&buffer->prs;
2623
2624	prs_debug(ps, depth, desc, "smb_io_printer_info_4");
2625	depth++;
2626
2627	buffer->struct_start=prs_offset(ps);
2628
2629	if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2630		return False;
2631	if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2632		return False;
2633	if (!prs_uint32("attributes", ps, depth, &info->attributes))
2634		return False;
2635	return True;
2636}
2637
2638/*******************************************************************
2639 Parse a PRINTER_INFO_5 structure.
2640********************************************************************/
2641
2642BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
2643{
2644	prs_struct *ps=&buffer->prs;
2645
2646	prs_debug(ps, depth, desc, "smb_io_printer_info_5");
2647	depth++;
2648
2649	buffer->struct_start=prs_offset(ps);
2650
2651	if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2652		return False;
2653	if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2654		return False;
2655	if (!prs_uint32("attributes", ps, depth, &info->attributes))
2656		return False;
2657	if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
2658		return False;
2659	if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
2660		return False;
2661	return True;
2662}
2663
2664/*******************************************************************
2665 Parse a PRINTER_INFO_7 structure.
2666********************************************************************/
2667
2668BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
2669{
2670	prs_struct *ps=&buffer->prs;
2671
2672	prs_debug(ps, depth, desc, "smb_io_printer_info_7");
2673	depth++;
2674
2675	buffer->struct_start=prs_offset(ps);
2676
2677	if (!smb_io_relstr("guid", buffer, depth, &info->guid))
2678		return False;
2679	if (!prs_uint32("action", ps, depth, &info->action))
2680		return False;
2681	return True;
2682}
2683
2684/*******************************************************************
2685 Parse a PORT_INFO_1 structure.
2686********************************************************************/
2687
2688BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2689{
2690	prs_struct *ps=&buffer->prs;
2691
2692	prs_debug(ps, depth, desc, "smb_io_port_info_1");
2693	depth++;
2694
2695	buffer->struct_start=prs_offset(ps);
2696
2697	if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2698		return False;
2699
2700	return True;
2701}
2702
2703/*******************************************************************
2704 Parse a PORT_INFO_2 structure.
2705********************************************************************/
2706
2707BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2708{
2709	prs_struct *ps=&buffer->prs;
2710
2711	prs_debug(ps, depth, desc, "smb_io_port_info_2");
2712	depth++;
2713
2714	buffer->struct_start=prs_offset(ps);
2715
2716	if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2717		return False;
2718	if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2719		return False;
2720	if (!smb_io_relstr("description", buffer, depth, &info->description))
2721		return False;
2722	if (!prs_uint32("port_type", ps, depth, &info->port_type))
2723		return False;
2724	if (!prs_uint32("reserved", ps, depth, &info->reserved))
2725		return False;
2726
2727	return True;
2728}
2729
2730/*******************************************************************
2731 Parse a DRIVER_INFO_1 structure.
2732********************************************************************/
2733
2734BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth)
2735{
2736	prs_struct *ps=&buffer->prs;
2737
2738	prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2739	depth++;
2740
2741	buffer->struct_start=prs_offset(ps);
2742
2743	if (!smb_io_relstr("name", buffer, depth, &info->name))
2744		return False;
2745
2746	return True;
2747}
2748
2749/*******************************************************************
2750 Parse a DRIVER_INFO_2 structure.
2751********************************************************************/
2752
2753BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth)
2754{
2755	prs_struct *ps=&buffer->prs;
2756
2757	prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2758	depth++;
2759
2760	buffer->struct_start=prs_offset(ps);
2761
2762	if (!prs_uint32("version", ps, depth, &info->version))
2763		return False;
2764	if (!smb_io_relstr("name", buffer, depth, &info->name))
2765		return False;
2766	if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2767		return False;
2768	if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2769		return False;
2770	if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2771		return False;
2772	if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2773		return False;
2774
2775	return True;
2776}
2777
2778/*******************************************************************
2779 Parse a DRIVER_INFO_3 structure.
2780********************************************************************/
2781
2782BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2783{
2784	prs_struct *ps=&buffer->prs;
2785
2786	prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2787	depth++;
2788
2789	buffer->struct_start=prs_offset(ps);
2790
2791	if (!prs_uint32("version", ps, depth, &info->version))
2792		return False;
2793	if (!smb_io_relstr("name", buffer, depth, &info->name))
2794		return False;
2795	if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2796		return False;
2797	if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2798		return False;
2799	if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2800		return False;
2801	if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2802		return False;
2803	if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2804		return False;
2805
2806	if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2807		return False;
2808
2809	if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2810		return False;
2811	if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2812		return False;
2813
2814	return True;
2815}
2816
2817/*******************************************************************
2818 Parse a DRIVER_INFO_6 structure.
2819********************************************************************/
2820
2821BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2822{
2823	prs_struct *ps=&buffer->prs;
2824
2825	prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2826	depth++;
2827
2828	buffer->struct_start=prs_offset(ps);
2829
2830	if (!prs_uint32("version", ps, depth, &info->version))
2831		return False;
2832	if (!smb_io_relstr("name", buffer, depth, &info->name))
2833		return False;
2834	if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2835		return False;
2836	if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2837		return False;
2838	if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2839		return False;
2840	if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2841		return False;
2842	if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2843		return False;
2844
2845	if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2846		return False;
2847
2848	if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2849		return False;
2850	if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2851		return False;
2852
2853	if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2854		return False;
2855
2856	if (!prs_uint32("date.low", ps, depth, &info->driver_date.low))
2857		return False;
2858	if (!prs_uint32("date.high", ps, depth, &info->driver_date.high))
2859		return False;
2860
2861	if (!prs_uint32("padding", ps, depth, &info->padding))
2862		return False;
2863
2864	if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2865		return False;
2866
2867	if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2868		return False;
2869
2870	if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2871		return False;
2872	if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2873		return False;
2874	if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2875		return False;
2876	if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2877		return False;
2878
2879	return True;
2880}
2881
2882/*******************************************************************
2883 Parse a JOB_INFO_1 structure.
2884********************************************************************/
2885
2886BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2887{
2888	prs_struct *ps=&buffer->prs;
2889
2890	prs_debug(ps, depth, desc, "smb_io_job_info_1");
2891	depth++;
2892
2893	buffer->struct_start=prs_offset(ps);
2894
2895	if (!prs_uint32("jobid", ps, depth, &info->jobid))
2896		return False;
2897	if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2898		return False;
2899	if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2900		return False;
2901	if (!smb_io_relstr("username", buffer, depth, &info->username))
2902		return False;
2903	if (!smb_io_relstr("document", buffer, depth, &info->document))
2904		return False;
2905	if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2906		return False;
2907	if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2908		return False;
2909	if (!prs_uint32("status", ps, depth, &info->status))
2910		return False;
2911	if (!prs_uint32("priority", ps, depth, &info->priority))
2912		return False;
2913	if (!prs_uint32("position", ps, depth, &info->position))
2914		return False;
2915	if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2916		return False;
2917	if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2918		return False;
2919	if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2920		return False;
2921
2922	return True;
2923}
2924
2925/*******************************************************************
2926 Parse a JOB_INFO_2 structure.
2927********************************************************************/
2928
2929BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2930{
2931	uint32 pipo=0;
2932	prs_struct *ps=&buffer->prs;
2933
2934	prs_debug(ps, depth, desc, "smb_io_job_info_2");
2935	depth++;
2936
2937	buffer->struct_start=prs_offset(ps);
2938
2939	if (!prs_uint32("jobid",ps, depth, &info->jobid))
2940		return False;
2941	if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2942		return False;
2943	if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2944		return False;
2945	if (!smb_io_relstr("username", buffer, depth, &info->username))
2946		return False;
2947	if (!smb_io_relstr("document", buffer, depth, &info->document))
2948		return False;
2949	if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2950		return False;
2951	if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2952		return False;
2953
2954	if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2955		return False;
2956	if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2957		return False;
2958	if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2959		return False;
2960	if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2961		return False;
2962	if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2963		return False;
2964
2965/*	SEC_DESC sec_desc;*/
2966	if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2967		return False;
2968
2969	if (!prs_uint32("status",ps, depth, &info->status))
2970		return False;
2971	if (!prs_uint32("priority",ps, depth, &info->priority))
2972		return False;
2973	if (!prs_uint32("position",ps, depth, &info->position))
2974		return False;
2975	if (!prs_uint32("starttime",ps, depth, &info->starttime))
2976		return False;
2977	if (!prs_uint32("untiltime",ps, depth, &info->untiltime))
2978		return False;
2979	if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2980		return False;
2981	if (!prs_uint32("size",ps, depth, &info->size))
2982		return False;
2983	if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2984		return False;
2985	if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2986		return False;
2987	if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2988		return False;
2989
2990	return True;
2991}
2992
2993/*******************************************************************
2994********************************************************************/
2995
2996BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
2997{
2998	prs_struct *ps=&buffer->prs;
2999
3000	prs_debug(ps, depth, desc, "smb_io_form_1");
3001	depth++;
3002
3003	buffer->struct_start=prs_offset(ps);
3004
3005	if (!prs_uint32("flag", ps, depth, &info->flag))
3006		return False;
3007
3008	if (!smb_io_relstr("name", buffer, depth, &info->name))
3009		return False;
3010
3011	if (!prs_uint32("width", ps, depth, &info->width))
3012		return False;
3013	if (!prs_uint32("length", ps, depth, &info->length))
3014		return False;
3015	if (!prs_uint32("left", ps, depth, &info->left))
3016		return False;
3017	if (!prs_uint32("top", ps, depth, &info->top))
3018		return False;
3019	if (!prs_uint32("right", ps, depth, &info->right))
3020		return False;
3021	if (!prs_uint32("bottom", ps, depth, &info->bottom))
3022		return False;
3023
3024	return True;
3025}
3026
3027/*******************************************************************
3028 Read/write a BUFFER struct.
3029********************************************************************/
3030
3031static BOOL spoolss_io_buffer(const char *desc, prs_struct *ps, int depth, NEW_BUFFER **pp_buffer)
3032{
3033	NEW_BUFFER *buffer = *pp_buffer;
3034
3035	prs_debug(ps, depth, desc, "spoolss_io_buffer");
3036	depth++;
3037
3038	if (UNMARSHALLING(ps))
3039		buffer = *pp_buffer = (NEW_BUFFER *)prs_alloc_mem(ps, sizeof(NEW_BUFFER));
3040
3041	if (buffer == NULL)
3042		return False;
3043
3044	if (!prs_uint32("ptr", ps, depth, &buffer->ptr))
3045		return False;
3046
3047	/* reading */
3048	if (UNMARSHALLING(ps)) {
3049		buffer->size=0;
3050		buffer->string_at_end=0;
3051
3052		if (buffer->ptr==0) {
3053			/*
3054			 * JRA. I'm not sure if the data in here is in big-endian format if
3055			 * the client is big-endian. Leave as default (little endian) for now.
3056			 */
3057
3058			if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL))
3059				return False;
3060			return True;
3061		}
3062
3063		if (!prs_uint32("size", ps, depth, &buffer->size))
3064			return False;
3065
3066		/*
3067		 * JRA. I'm not sure if the data in here is in big-endian format if
3068		 * the client is big-endian. Leave as default (little endian) for now.
3069		 */
3070
3071		if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
3072			return False;
3073
3074		if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
3075			return False;
3076
3077		if (!prs_set_offset(&buffer->prs, 0))
3078			return False;
3079
3080		if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
3081			return False;
3082
3083		buffer->string_at_end=buffer->size;
3084
3085		return True;
3086	}
3087	else {
3088		BOOL ret = False;
3089
3090		/* writing */
3091		if (buffer->ptr==0) {
3092			/* We have finished with the data in buffer->prs - free it. */
3093			prs_mem_free(&buffer->prs);
3094			return True;
3095		}
3096
3097		if (!prs_uint32("size", ps, depth, &buffer->size))
3098			goto out;
3099
3100		if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
3101			goto out;
3102
3103		ret = True;
3104	out:
3105
3106		/* We have finished with the data in buffer->prs - free it. */
3107		prs_mem_free(&buffer->prs);
3108
3109		return ret;
3110	}
3111}
3112
3113/*******************************************************************
3114 move a BUFFER from the query to the reply.
3115 As the data pointers in NEW_BUFFER are malloc'ed, not talloc'ed,
3116 this is ok. This is an OPTIMIZATION and is not strictly neccessary.
3117 Clears the memory to zero also.
3118********************************************************************/
3119
3120void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
3121{
3122	prs_switch_type(&src->prs, MARSHALL);
3123	if(!prs_set_offset(&src->prs, 0))
3124		return;
3125	prs_force_dynamic(&src->prs);
3126	prs_mem_clear(&src->prs);
3127	*dest=src;
3128}
3129
3130/*******************************************************************
3131 Get the size of a BUFFER struct.
3132********************************************************************/
3133
3134uint32 new_get_buffer_size(NEW_BUFFER *buffer)
3135{
3136	return (buffer->size);
3137}
3138
3139/*******************************************************************
3140 Parse a DRIVER_DIRECTORY_1 structure.
3141********************************************************************/
3142
3143BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
3144{
3145	prs_struct *ps=&buffer->prs;
3146
3147	prs_debug(ps, depth, desc, "smb_io_driverdir_1");
3148	depth++;
3149
3150	buffer->struct_start=prs_offset(ps);
3151
3152	if (!smb_io_unistr(desc, &info->name, ps, depth))
3153		return False;
3154
3155	return True;
3156}
3157
3158/*******************************************************************
3159 Parse a PORT_INFO_1 structure.
3160********************************************************************/
3161
3162BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
3163{
3164	prs_struct *ps=&buffer->prs;
3165
3166	prs_debug(ps, depth, desc, "smb_io_port_1");
3167	depth++;
3168
3169	buffer->struct_start=prs_offset(ps);
3170
3171	if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
3172		return False;
3173
3174	return True;
3175}
3176
3177/*******************************************************************
3178 Parse a PORT_INFO_2 structure.
3179********************************************************************/
3180
3181BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
3182{
3183	prs_struct *ps=&buffer->prs;
3184
3185	prs_debug(ps, depth, desc, "smb_io_port_2");
3186	depth++;
3187
3188	buffer->struct_start=prs_offset(ps);
3189
3190	if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
3191		return False;
3192	if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
3193		return False;
3194	if(!smb_io_relstr("description", buffer, depth, &info->description))
3195		return False;
3196	if(!prs_uint32("port_type", ps, depth, &info->port_type))
3197		return False;
3198	if(!prs_uint32("reserved", ps, depth, &info->reserved))
3199		return False;
3200
3201	return True;
3202}
3203
3204/*******************************************************************
3205********************************************************************/
3206
3207BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
3208{
3209	prs_struct *ps=&buffer->prs;
3210
3211	prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
3212	depth++;
3213
3214	buffer->struct_start=prs_offset(ps);
3215
3216	if (smb_io_relstr("name", buffer, depth, &info->name))
3217		return False;
3218
3219	return True;
3220}
3221
3222/*******************************************************************
3223********************************************************************/
3224
3225BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
3226{
3227	prs_struct *ps=&buffer->prs;
3228
3229	prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
3230	depth++;
3231
3232	buffer->struct_start=prs_offset(ps);
3233
3234	if (smb_io_relstr("name", buffer, depth, &info->name))
3235		return False;
3236
3237	return True;
3238}
3239
3240/*******************************************************************
3241********************************************************************/
3242
3243BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
3244{
3245	prs_struct *ps=&buffer->prs;
3246
3247	prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
3248	depth++;
3249
3250	buffer->struct_start=prs_offset(ps);
3251
3252	if (!smb_io_relstr("name", buffer, depth, &info->name))
3253		return False;
3254
3255	return True;
3256}
3257
3258/*******************************************************************
3259********************************************************************/
3260
3261BOOL smb_io_printmonitor_info_2(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
3262{
3263	prs_struct *ps=&buffer->prs;
3264
3265	prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
3266	depth++;
3267
3268	buffer->struct_start=prs_offset(ps);
3269
3270	if (!smb_io_relstr("name", buffer, depth, &info->name))
3271		return False;
3272	if (!smb_io_relstr("environment", buffer, depth, &info->environment))
3273		return False;
3274	if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
3275		return False;
3276
3277	return True;
3278}
3279
3280/*******************************************************************
3281return the size required by a struct in the stream
3282********************************************************************/
3283
3284uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
3285{
3286	int size=0;
3287
3288	size+=size_of_relative_string( &info->printername );
3289	size+=size_of_relative_string( &info->servername );
3290
3291	size+=size_of_uint32( &info->cjobs);
3292	size+=size_of_uint32( &info->total_jobs);
3293	size+=size_of_uint32( &info->total_bytes);
3294
3295	size+=size_of_uint16( &info->year);
3296	size+=size_of_uint16( &info->month);
3297	size+=size_of_uint16( &info->dayofweek);
3298	size+=size_of_uint16( &info->day);
3299	size+=size_of_uint16( &info->hour);
3300	size+=size_of_uint16( &info->minute);
3301	size+=size_of_uint16( &info->second);
3302	size+=size_of_uint16( &info->milliseconds);
3303
3304	size+=size_of_uint32( &info->global_counter);
3305	size+=size_of_uint32( &info->total_pages);
3306
3307	size+=size_of_uint16( &info->major_version);
3308	size+=size_of_uint16( &info->build_version);
3309
3310	size+=size_of_uint32( &info->unknown7);
3311	size+=size_of_uint32( &info->unknown8);
3312	size+=size_of_uint32( &info->unknown9);
3313	size+=size_of_uint32( &info->session_counter);
3314	size+=size_of_uint32( &info->unknown11);
3315	size+=size_of_uint32( &info->printer_errors);
3316	size+=size_of_uint32( &info->unknown13);
3317	size+=size_of_uint32( &info->unknown14);
3318	size+=size_of_uint32( &info->unknown15);
3319	size+=size_of_uint32( &info->unknown16);
3320	size+=size_of_uint32( &info->change_id);
3321	size+=size_of_uint32( &info->unknown18);
3322	size+=size_of_uint32( &info->status);
3323	size+=size_of_uint32( &info->unknown20);
3324	size+=size_of_uint32( &info->c_setprinter);
3325
3326	size+=size_of_uint16( &info->unknown22);
3327	size+=size_of_uint16( &info->unknown23);
3328	size+=size_of_uint16( &info->unknown24);
3329	size+=size_of_uint16( &info->unknown25);
3330	size+=size_of_uint16( &info->unknown26);
3331	size+=size_of_uint16( &info->unknown27);
3332	size+=size_of_uint16( &info->unknown28);
3333	size+=size_of_uint16( &info->unknown29);
3334
3335	return size;
3336}
3337
3338/*******************************************************************
3339return the size required by a struct in the stream
3340********************************************************************/
3341
3342uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
3343{
3344	int size=0;
3345
3346	size+=size_of_uint32( &info->flags );
3347	size+=size_of_relative_string( &info->description );
3348	size+=size_of_relative_string( &info->name );
3349	size+=size_of_relative_string( &info->comment );
3350
3351	return size;
3352}
3353
3354/*******************************************************************
3355return the size required by a struct in the stream
3356********************************************************************/
3357
3358uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
3359{
3360	uint32 size=0;
3361
3362	size += 4;
3363
3364	size += sec_desc_size( info->secdesc );
3365
3366	size+=size_of_device_mode( info->devmode );
3367
3368	size+=size_of_relative_string( &info->servername );
3369	size+=size_of_relative_string( &info->printername );
3370	size+=size_of_relative_string( &info->sharename );
3371	size+=size_of_relative_string( &info->portname );
3372	size+=size_of_relative_string( &info->drivername );
3373	size+=size_of_relative_string( &info->comment );
3374	size+=size_of_relative_string( &info->location );
3375
3376	size+=size_of_relative_string( &info->sepfile );
3377	size+=size_of_relative_string( &info->printprocessor );
3378	size+=size_of_relative_string( &info->datatype );
3379	size+=size_of_relative_string( &info->parameters );
3380
3381	size+=size_of_uint32( &info->attributes );
3382	size+=size_of_uint32( &info->priority );
3383	size+=size_of_uint32( &info->defaultpriority );
3384	size+=size_of_uint32( &info->starttime );
3385	size+=size_of_uint32( &info->untiltime );
3386	size+=size_of_uint32( &info->status );
3387	size+=size_of_uint32( &info->cjobs );
3388	size+=size_of_uint32( &info->averageppm );
3389
3390	/*
3391	 * add any adjustments for alignment.  This is
3392	 * not optimal since we could be calling this
3393	 * function from a loop (e.g. enumprinters), but
3394	 * it is easier to maintain the calculation here and
3395	 * not place the burden on the caller to remember.   --jerry
3396	 */
3397	if ((size % 4) != 0)
3398		size += 4 - (size % 4);
3399
3400	return size;
3401}
3402
3403/*******************************************************************
3404return the size required by a struct in the stream
3405********************************************************************/
3406
3407uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
3408{
3409	uint32 size=0;
3410
3411	size+=size_of_relative_string( &info->printername );
3412	size+=size_of_relative_string( &info->servername );
3413
3414	size+=size_of_uint32( &info->attributes );
3415	return size;
3416}
3417
3418/*******************************************************************
3419return the size required by a struct in the stream
3420********************************************************************/
3421
3422uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
3423{
3424	uint32 size=0;
3425
3426	size+=size_of_relative_string( &info->printername );
3427	size+=size_of_relative_string( &info->portname );
3428
3429	size+=size_of_uint32( &info->attributes );
3430	size+=size_of_uint32( &info->device_not_selected_timeout );
3431	size+=size_of_uint32( &info->transmission_retry_timeout );
3432	return size;
3433}
3434
3435
3436/*******************************************************************
3437return the size required by a struct in the stream
3438********************************************************************/
3439
3440uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
3441{
3442	/* The 4 is for the self relative pointer.. */
3443	/* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
3444	return 4 + (uint32)sec_desc_size( info->secdesc );
3445}
3446
3447/*******************************************************************
3448return the size required by a struct in the stream
3449********************************************************************/
3450
3451uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
3452{
3453	uint32 size=0;
3454
3455	size+=size_of_relative_string( &info->guid );
3456	size+=size_of_uint32( &info->action );
3457	return size;
3458}
3459
3460/*******************************************************************
3461return the size required by a struct in the stream
3462********************************************************************/
3463
3464uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
3465{
3466	int size=0;
3467	size+=size_of_relative_string( &info->name );
3468
3469	return size;
3470}
3471
3472/*******************************************************************
3473return the size required by a struct in the stream
3474********************************************************************/
3475
3476uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
3477{
3478	int size=0;
3479	size+=size_of_uint32( &info->version );
3480	size+=size_of_relative_string( &info->name );
3481	size+=size_of_relative_string( &info->architecture );
3482	size+=size_of_relative_string( &info->driverpath );
3483	size+=size_of_relative_string( &info->datafile );
3484	size+=size_of_relative_string( &info->configfile );
3485
3486	return size;
3487}
3488
3489/*******************************************************************
3490return the size required by a string array.
3491********************************************************************/
3492
3493uint32 spoolss_size_string_array(uint16 *string)
3494{
3495	uint32 i = 0;
3496
3497	if (string) {
3498		for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
3499	}
3500	i=i+2; /* to count all chars including the leading zero */
3501	i=2*i; /* because we need the value in bytes */
3502	i=i+4; /* the offset pointer size */
3503
3504	return i;
3505}
3506
3507/*******************************************************************
3508return the size required by a struct in the stream
3509********************************************************************/
3510
3511uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3512{
3513	int size=0;
3514
3515	size+=size_of_uint32( &info->version );
3516	size+=size_of_relative_string( &info->name );
3517	size+=size_of_relative_string( &info->architecture );
3518	size+=size_of_relative_string( &info->driverpath );
3519	size+=size_of_relative_string( &info->datafile );
3520	size+=size_of_relative_string( &info->configfile );
3521	size+=size_of_relative_string( &info->helpfile );
3522	size+=size_of_relative_string( &info->monitorname );
3523	size+=size_of_relative_string( &info->defaultdatatype );
3524
3525	size+=spoolss_size_string_array(info->dependentfiles);
3526
3527	return size;
3528}
3529
3530/*******************************************************************
3531return the size required by a struct in the stream
3532********************************************************************/
3533
3534uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3535{
3536	uint32 size=0;
3537
3538	size+=size_of_uint32( &info->version );
3539	size+=size_of_relative_string( &info->name );
3540	size+=size_of_relative_string( &info->architecture );
3541	size+=size_of_relative_string( &info->driverpath );
3542	size+=size_of_relative_string( &info->datafile );
3543	size+=size_of_relative_string( &info->configfile );
3544	size+=size_of_relative_string( &info->helpfile );
3545
3546	size+=spoolss_size_string_array(info->dependentfiles);
3547
3548	size+=size_of_relative_string( &info->monitorname );
3549	size+=size_of_relative_string( &info->defaultdatatype );
3550
3551	size+=spoolss_size_string_array(info->previousdrivernames);
3552
3553	size+=size_of_nttime(&info->driver_date);
3554	size+=size_of_uint32( &info->padding );
3555	size+=size_of_uint32( &info->driver_version_low );
3556	size+=size_of_uint32( &info->driver_version_high );
3557	size+=size_of_relative_string( &info->mfgname );
3558	size+=size_of_relative_string( &info->oem_url );
3559	size+=size_of_relative_string( &info->hardware_id );
3560	size+=size_of_relative_string( &info->provider );
3561
3562	return size;
3563}
3564
3565/*******************************************************************
3566return the size required by a struct in the stream
3567********************************************************************/
3568
3569uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3570{
3571	int size=0;
3572	size+=size_of_uint32( &info->jobid );
3573	size+=size_of_relative_string( &info->printername );
3574	size+=size_of_relative_string( &info->machinename );
3575	size+=size_of_relative_string( &info->username );
3576	size+=size_of_relative_string( &info->document );
3577	size+=size_of_relative_string( &info->datatype );
3578	size+=size_of_relative_string( &info->text_status );
3579	size+=size_of_uint32( &info->status );
3580	size+=size_of_uint32( &info->priority );
3581	size+=size_of_uint32( &info->position );
3582	size+=size_of_uint32( &info->totalpages );
3583	size+=size_of_uint32( &info->pagesprinted );
3584	size+=size_of_systemtime( &info->submitted );
3585
3586	return size;
3587}
3588
3589/*******************************************************************
3590return the size required by a struct in the stream
3591********************************************************************/
3592
3593uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3594{
3595	int size=0;
3596
3597	size+=4; /* size of sec desc ptr */
3598
3599	size+=size_of_uint32( &info->jobid );
3600	size+=size_of_relative_string( &info->printername );
3601	size+=size_of_relative_string( &info->machinename );
3602	size+=size_of_relative_string( &info->username );
3603	size+=size_of_relative_string( &info->document );
3604	size+=size_of_relative_string( &info->notifyname );
3605	size+=size_of_relative_string( &info->datatype );
3606	size+=size_of_relative_string( &info->printprocessor );
3607	size+=size_of_relative_string( &info->parameters );
3608	size+=size_of_relative_string( &info->drivername );
3609	size+=size_of_device_mode( info->devmode );
3610	size+=size_of_relative_string( &info->text_status );
3611/*	SEC_DESC sec_desc;*/
3612	size+=size_of_uint32( &info->status );
3613	size+=size_of_uint32( &info->priority );
3614	size+=size_of_uint32( &info->position );
3615	size+=size_of_uint32( &info->starttime );
3616	size+=size_of_uint32( &info->untiltime );
3617	size+=size_of_uint32( &info->totalpages );
3618	size+=size_of_uint32( &info->size );
3619	size+=size_of_systemtime( &info->submitted );
3620	size+=size_of_uint32( &info->timeelapsed );
3621	size+=size_of_uint32( &info->pagesprinted );
3622
3623	return size;
3624}
3625
3626/*******************************************************************
3627return the size required by a struct in the stream
3628********************************************************************/
3629
3630uint32 spoolss_size_form_1(FORM_1 *info)
3631{
3632	int size=0;
3633
3634	size+=size_of_uint32( &info->flag );
3635	size+=size_of_relative_string( &info->name );
3636	size+=size_of_uint32( &info->width );
3637	size+=size_of_uint32( &info->length );
3638	size+=size_of_uint32( &info->left );
3639	size+=size_of_uint32( &info->top );
3640	size+=size_of_uint32( &info->right );
3641	size+=size_of_uint32( &info->bottom );
3642
3643	return size;
3644}
3645
3646/*******************************************************************
3647return the size required by a struct in the stream
3648********************************************************************/
3649
3650uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3651{
3652	int size=0;
3653
3654	size+=size_of_relative_string( &info->port_name );
3655
3656	return size;
3657}
3658
3659/*******************************************************************
3660return the size required by a struct in the stream
3661********************************************************************/
3662
3663uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3664{
3665	int size=0;
3666
3667	size=str_len_uni(&info->name);	/* the string length       */
3668	size=size+1;			/* add the leading zero    */
3669	size=size*2;			/* convert in char         */
3670
3671	return size;
3672}
3673
3674/*******************************************************************
3675return the size required by a struct in the stream
3676********************************************************************/
3677
3678uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
3679{
3680	int size=0;
3681
3682	size=str_len_uni(&info->name);	/* the string length       */
3683	size=size+1;			/* add the leading zero    */
3684	size=size*2;			/* convert in char         */
3685
3686	return size;
3687}
3688
3689/*******************************************************************
3690return the size required by a struct in the stream
3691********************************************************************/
3692
3693uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3694{
3695	int size=0;
3696
3697	size+=size_of_relative_string( &info->port_name );
3698	size+=size_of_relative_string( &info->monitor_name );
3699	size+=size_of_relative_string( &info->description );
3700
3701	size+=size_of_uint32( &info->port_type );
3702	size+=size_of_uint32( &info->reserved );
3703
3704	return size;
3705}
3706
3707/*******************************************************************
3708return the size required by a struct in the stream
3709********************************************************************/
3710
3711uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
3712{
3713	int size=0;
3714	size+=size_of_relative_string( &info->name );
3715
3716	return size;
3717}
3718
3719/*******************************************************************
3720return the size required by a struct in the stream
3721********************************************************************/
3722
3723uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
3724{
3725	int size=0;
3726	size+=size_of_relative_string( &info->name );
3727
3728	return size;
3729}
3730
3731/*******************************************************************
3732return the size required by a struct in the stream
3733********************************************************************/
3734uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
3735{
3736	uint32 	size = 0;
3737
3738	if (!p)
3739		return 0;
3740
3741	/* uint32(offset) + uint32(length) + length) */
3742	size += (size_of_uint32(&p->value_len)*2) + p->value_len;
3743	size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
3744
3745	size += size_of_uint32(&p->type);
3746
3747	return size;
3748}
3749
3750/*******************************************************************
3751return the size required by a struct in the stream
3752********************************************************************/
3753
3754uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
3755{
3756	int size=0;
3757	size+=size_of_relative_string( &info->name );
3758
3759	return size;
3760}
3761
3762/*******************************************************************
3763return the size required by a struct in the stream
3764********************************************************************/
3765
3766uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
3767{
3768	int size=0;
3769	size+=size_of_relative_string( &info->name);
3770	size+=size_of_relative_string( &info->environment);
3771	size+=size_of_relative_string( &info->dll_name);
3772
3773	return size;
3774}
3775
3776/*******************************************************************
3777 * init a structure.
3778 ********************************************************************/
3779
3780BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
3781			       const POLICY_HND *hnd,
3782			       const fstring architecture,
3783			       uint32 level, uint32 clientmajor, uint32 clientminor,
3784			       NEW_BUFFER *buffer, uint32 offered)
3785{
3786	if (q_u == NULL)
3787		return False;
3788
3789	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3790
3791	init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
3792
3793	q_u->level=level;
3794	q_u->clientmajorversion=clientmajor;
3795	q_u->clientminorversion=clientminor;
3796
3797	q_u->buffer=buffer;
3798	q_u->offered=offered;
3799
3800	return True;
3801}
3802
3803/*******************************************************************
3804 * read a structure.
3805 * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3806 ********************************************************************/
3807
3808BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
3809{
3810	prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
3811	depth++;
3812
3813	if(!prs_align(ps))
3814		return False;
3815
3816	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3817		return False;
3818	if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
3819		return False;
3820	if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
3821		return False;
3822
3823	if(!prs_align(ps))
3824		return False;
3825	if(!prs_uint32("level", ps, depth, &q_u->level))
3826		return False;
3827
3828	if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3829		return False;
3830
3831	if(!prs_align(ps))
3832		return False;
3833
3834	if(!prs_uint32("offered", ps, depth, &q_u->offered))
3835		return False;
3836
3837	if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
3838		return False;
3839	if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
3840		return False;
3841
3842	return True;
3843}
3844
3845/*******************************************************************
3846 * read a structure.
3847 * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3848 ********************************************************************/
3849
3850BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
3851{
3852	prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
3853	depth++;
3854
3855	if (!prs_align(ps))
3856		return False;
3857
3858	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3859		return False;
3860
3861	if (!prs_align(ps))
3862		return False;
3863	if (!prs_uint32("needed", ps, depth, &r_u->needed))
3864		return False;
3865	if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
3866		return False;
3867	if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
3868		return False;
3869	if (!prs_werror("status", ps, depth, &r_u->status))
3870		return False;
3871
3872	return True;
3873}
3874
3875/*******************************************************************
3876 * init a structure.
3877 ********************************************************************/
3878
3879BOOL make_spoolss_q_enumprinters(
3880	SPOOL_Q_ENUMPRINTERS *q_u,
3881	uint32 flags,
3882	char *servername,
3883	uint32 level,
3884	NEW_BUFFER *buffer,
3885	uint32 offered
3886)
3887{
3888	q_u->flags=flags;
3889
3890	q_u->servername_ptr = (servername != NULL) ? 1 : 0;
3891	init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
3892
3893	q_u->level=level;
3894	q_u->buffer=buffer;
3895	q_u->offered=offered;
3896
3897	return True;
3898}
3899
3900/*******************************************************************
3901 * init a structure.
3902 ********************************************************************/
3903
3904BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u,
3905				fstring servername, uint32 level,
3906				NEW_BUFFER *buffer, uint32 offered)
3907{
3908	q_u->name_ptr = (servername != NULL) ? 1 : 0;
3909	init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
3910
3911	q_u->level=level;
3912	q_u->buffer=buffer;
3913	q_u->offered=offered;
3914
3915	return True;
3916}
3917
3918/*******************************************************************
3919 * read a structure.
3920 * called from spoolss_enumprinters (srv_spoolss.c)
3921 ********************************************************************/
3922
3923BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
3924{
3925	prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
3926	depth++;
3927
3928	if (!prs_align(ps))
3929		return False;
3930
3931	if (!prs_uint32("flags", ps, depth, &q_u->flags))
3932		return False;
3933	if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
3934		return False;
3935
3936	if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
3937		return False;
3938
3939	if (!prs_align(ps))
3940		return False;
3941	if (!prs_uint32("level", ps, depth, &q_u->level))
3942		return False;
3943
3944	if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3945		return False;
3946
3947	if (!prs_align(ps))
3948		return False;
3949	if (!prs_uint32("offered", ps, depth, &q_u->offered))
3950		return False;
3951
3952	return True;
3953}
3954
3955/*******************************************************************
3956 Parse a SPOOL_R_ENUMPRINTERS structure.
3957 ********************************************************************/
3958
3959BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3960{
3961	prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3962	depth++;
3963
3964	if (!prs_align(ps))
3965		return False;
3966
3967	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3968		return False;
3969
3970	if (!prs_align(ps))
3971		return False;
3972
3973	if (!prs_uint32("needed", ps, depth, &r_u->needed))
3974		return False;
3975
3976	if (!prs_uint32("returned", ps, depth, &r_u->returned))
3977		return False;
3978
3979	if (!prs_werror("status", ps, depth, &r_u->status))
3980		return False;
3981
3982	return True;
3983}
3984
3985/*******************************************************************
3986 * write a structure.
3987 * called from spoolss_r_enum_printers (srv_spoolss.c)
3988 *
3989 ********************************************************************/
3990
3991BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3992{
3993	prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3994	depth++;
3995
3996	if (!prs_align(ps))
3997		return False;
3998
3999	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4000		return False;
4001
4002	if (!prs_align(ps))
4003		return False;
4004
4005	if (!prs_uint32("needed", ps, depth, &r_u->needed))
4006		return False;
4007
4008	if (!prs_werror("status", ps, depth, &r_u->status))
4009		return False;
4010
4011	return True;
4012}
4013
4014/*******************************************************************
4015 * read a structure.
4016 * called from spoolss_getprinter (srv_spoolss.c)
4017 ********************************************************************/
4018
4019BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
4020{
4021	prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
4022	depth++;
4023
4024	if (!prs_align(ps))
4025		return False;
4026
4027	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4028		return False;
4029	if (!prs_uint32("level", ps, depth, &q_u->level))
4030		return False;
4031
4032	if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4033		return False;
4034
4035	if (!prs_align(ps))
4036		return False;
4037	if (!prs_uint32("offered", ps, depth, &q_u->offered))
4038		return False;
4039
4040	return True;
4041}
4042
4043/*******************************************************************
4044 * init a structure.
4045 ********************************************************************/
4046
4047BOOL make_spoolss_q_getprinter(
4048	TALLOC_CTX *mem_ctx,
4049	SPOOL_Q_GETPRINTER *q_u,
4050	const POLICY_HND *hnd,
4051	uint32 level,
4052	NEW_BUFFER *buffer,
4053	uint32 offered
4054)
4055{
4056	if (q_u == NULL)
4057	{
4058		return False;
4059	}
4060	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4061
4062	q_u->level=level;
4063	q_u->buffer=buffer;
4064	q_u->offered=offered;
4065
4066	return True;
4067}
4068
4069/*******************************************************************
4070 * init a structure.
4071 ********************************************************************/
4072BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
4073				const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info,
4074				uint32 command)
4075{
4076	SEC_DESC *secdesc;
4077	DEVICEMODE *devmode;
4078
4079	if (q_u == NULL)
4080		return False;
4081
4082	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4083
4084	q_u->level = level;
4085	q_u->info.level = level;
4086	q_u->info.info_ptr = (info != NULL) ? 1 : 0;
4087	switch (level) {
4088
4089	  /* There's no such thing as a setprinter level 1 */
4090
4091	case 2:
4092		secdesc = info->printers_2->secdesc;
4093		devmode = info->printers_2->devmode;
4094
4095		make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
4096#if 1	/* JERRY TEST */
4097		q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF));
4098		if (!q_u->secdesc_ctr)
4099			return False;
4100		q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
4101		q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
4102		q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
4103		q_u->secdesc_ctr->sec = secdesc;
4104
4105		q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
4106		q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
4107		q_u->devmode_ctr.devmode = devmode;
4108#else
4109		q_u->secdesc_ctr = NULL;
4110
4111		q_u->devmode_ctr.devmode_ptr = 0;
4112		q_u->devmode_ctr.size = 0;
4113		q_u->devmode_ctr.devmode = NULL;
4114#endif
4115		break;
4116	default:
4117		DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
4118			break;
4119	}
4120
4121
4122	q_u->command = command;
4123
4124	return True;
4125}
4126
4127
4128/*******************************************************************
4129********************************************************************/
4130
4131BOOL spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
4132{
4133	prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
4134	depth++;
4135
4136	if(!prs_align(ps))
4137		return False;
4138
4139	if(!prs_werror("status", ps, depth, &r_u->status))
4140		return False;
4141
4142	return True;
4143}
4144
4145/*******************************************************************
4146 Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
4147********************************************************************/
4148
4149BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
4150{
4151	uint32 ptr_sec_desc = 0;
4152
4153	prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
4154	depth++;
4155
4156	if(!prs_align(ps))
4157		return False;
4158
4159	if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
4160		return False;
4161	if(!prs_uint32("level", ps, depth, &q_u->level))
4162		return False;
4163
4164	if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4165		return False;
4166
4167	if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4168		return False;
4169
4170	if(!prs_align(ps))
4171		return False;
4172
4173	switch (q_u->level)
4174	{
4175		case 2:
4176		{
4177			ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4178			break;
4179		}
4180		case 3:
4181		{
4182			ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4183			break;
4184		}
4185	}
4186	if (ptr_sec_desc)
4187	{
4188		if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4189			return False;
4190	} else {
4191		uint32 dummy = 0;
4192
4193		/* Parse a NULL security descriptor.  This should really
4194		   happen inside the sec_io_desc_buf() function. */
4195
4196		prs_debug(ps, depth, "", "sec_io_desc_buf");
4197		if (!prs_uint32("size", ps, depth + 1, &dummy))
4198			return False;
4199		if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
4200								       False;
4201	}
4202
4203	if(!prs_uint32("command", ps, depth, &q_u->command))
4204		return False;
4205
4206	return True;
4207}
4208
4209/*******************************************************************
4210********************************************************************/
4211
4212BOOL spoolss_io_r_fcpn(const char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
4213{
4214	prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
4215	depth++;
4216
4217	if(!prs_align(ps))
4218		return False;
4219
4220	if(!prs_werror("status", ps, depth, &r_u->status))
4221		return False;
4222
4223	return True;
4224}
4225
4226/*******************************************************************
4227********************************************************************/
4228
4229BOOL spoolss_io_q_fcpn(const char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
4230{
4231
4232	prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
4233	depth++;
4234
4235	if(!prs_align(ps))
4236		return False;
4237
4238	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4239		return False;
4240
4241	return True;
4242}
4243
4244
4245/*******************************************************************
4246********************************************************************/
4247
4248BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
4249{
4250	prs_debug(ps, depth, desc, "");
4251	depth++;
4252
4253	if(!prs_align(ps))
4254		return False;
4255
4256	if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4257		return False;
4258
4259	if(!prs_align(ps))
4260		return False;
4261
4262	if(!prs_uint32("needed", ps, depth, &r_u->needed))
4263		return False;
4264
4265	if(!prs_werror("status", ps, depth, &r_u->status))
4266		return False;
4267
4268	return True;
4269}
4270
4271/*******************************************************************
4272********************************************************************/
4273
4274BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
4275{
4276	prs_debug(ps, depth, desc, "");
4277	depth++;
4278
4279	if(!prs_align(ps))
4280		return False;
4281
4282	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4283		return False;
4284	if(!prs_uint32("level", ps, depth, &q_u->level))
4285		return False;
4286
4287	if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4288		return False;
4289
4290	if(!prs_align(ps))
4291		return False;
4292
4293	if(!prs_uint32("offered", ps, depth, &q_u->offered))
4294		return False;
4295
4296	return True;
4297}
4298
4299/*******************************************************************
4300********************************************************************/
4301
4302BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
4303{
4304	prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
4305	depth++;
4306
4307	if (!prs_align(ps))
4308		return False;
4309
4310	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4311		return False;
4312
4313	if (!prs_align(ps))
4314		return False;
4315
4316	if (!prs_uint32("needed", ps, depth, &r_u->needed))
4317		return False;
4318
4319	if (!prs_uint32("returned", ps, depth, &r_u->returned))
4320		return False;
4321
4322	if (!prs_werror("status", ps, depth, &r_u->status))
4323		return False;
4324
4325	return True;
4326}
4327
4328/*******************************************************************
4329********************************************************************/
4330
4331BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
4332				uint32 firstjob,
4333				uint32 numofjobs,
4334				uint32 level,
4335				NEW_BUFFER *buffer,
4336				uint32 offered)
4337{
4338	if (q_u == NULL)
4339	{
4340		return False;
4341	}
4342	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4343	q_u->firstjob = firstjob;
4344	q_u->numofjobs = numofjobs;
4345	q_u->level = level;
4346	q_u->buffer= buffer;
4347	q_u->offered = offered;
4348	return True;
4349}
4350
4351/*******************************************************************
4352********************************************************************/
4353
4354BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
4355{
4356	prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
4357	depth++;
4358
4359	if (!prs_align(ps))
4360		return False;
4361
4362	if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
4363		return False;
4364
4365	if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
4366		return False;
4367	if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
4368		return False;
4369	if (!prs_uint32("level", ps, depth, &q_u->level))
4370		return False;
4371
4372	if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4373		return False;
4374
4375	if(!prs_align(ps))
4376		return False;
4377
4378	if (!prs_uint32("offered", ps, depth, &q_u->offered))
4379		return False;
4380
4381	return True;
4382}
4383
4384/*******************************************************************
4385********************************************************************/
4386
4387BOOL spoolss_io_r_schedulejob(const char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
4388{
4389	prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
4390	depth++;
4391
4392	if(!prs_align(ps))
4393		return False;
4394
4395	if(!prs_werror("status", ps, depth, &r_u->status))
4396		return False;
4397
4398	return True;
4399}
4400
4401/*******************************************************************
4402********************************************************************/
4403
4404BOOL spoolss_io_q_schedulejob(const char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
4405{
4406	prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
4407	depth++;
4408
4409	if(!prs_align(ps))
4410		return False;
4411
4412	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4413		return False;
4414	if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4415		return False;
4416
4417	return True;
4418}
4419
4420/*******************************************************************
4421********************************************************************/
4422
4423BOOL spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
4424{
4425	prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
4426	depth++;
4427
4428	if(!prs_align(ps))
4429		return False;
4430
4431	if(!prs_werror("status", ps, depth, &r_u->status))
4432		return False;
4433
4434	return True;
4435}
4436
4437/*******************************************************************
4438********************************************************************/
4439
4440BOOL spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
4441{
4442	prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
4443	depth++;
4444
4445	if(!prs_align(ps))
4446		return False;
4447
4448	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4449		return False;
4450	if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4451		return False;
4452	/*
4453	 * level is usually 0. If (level!=0) then I'm in trouble !
4454	 * I will try to generate setjob command with level!=0, one day.
4455	 */
4456	if(!prs_uint32("level", ps, depth, &q_u->level))
4457		return False;
4458	if(!prs_uint32("command", ps, depth, &q_u->command))
4459		return False;
4460
4461	return True;
4462}
4463
4464/*******************************************************************
4465 Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
4466********************************************************************/
4467
4468BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
4469{
4470	prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
4471	depth++;
4472
4473	if (!prs_align(ps))
4474		return False;
4475
4476	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4477		return False;
4478
4479	if (!prs_align(ps))
4480		return False;
4481
4482	if (!prs_uint32("needed", ps, depth, &r_u->needed))
4483		return False;
4484
4485	if (!prs_uint32("returned", ps, depth, &r_u->returned))
4486		return False;
4487
4488	if (!prs_werror("status", ps, depth, &r_u->status))
4489		return False;
4490
4491	return True;
4492}
4493
4494/*******************************************************************
4495 * init a structure.
4496 ********************************************************************/
4497
4498BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
4499                                const char *name,
4500                                const char *environment,
4501                                uint32 level,
4502                                NEW_BUFFER *buffer, uint32 offered)
4503{
4504        init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
4505        init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
4506
4507        q_u->level=level;
4508        q_u->buffer=buffer;
4509        q_u->offered=offered;
4510
4511        return True;
4512}
4513
4514/*******************************************************************
4515 Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
4516********************************************************************/
4517
4518BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
4519{
4520
4521	prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
4522	depth++;
4523
4524	if (!prs_align(ps))
4525		return False;
4526
4527	if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4528		return False;
4529	if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
4530		return False;
4531
4532	if (!prs_align(ps))
4533		return False;
4534	if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4535		return False;
4536	if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4537		return False;
4538
4539	if (!prs_align(ps))
4540		return False;
4541	if (!prs_uint32("level", ps, depth, &q_u->level))
4542		return False;
4543
4544	if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4545		return False;
4546
4547	if (!prs_align(ps))
4548		return False;
4549
4550	if (!prs_uint32("offered", ps, depth, &q_u->offered))
4551		return False;
4552
4553	return True;
4554}
4555
4556/*******************************************************************
4557********************************************************************/
4558
4559BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4560{
4561
4562	prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4563	depth++;
4564
4565	if (!prs_align(ps))
4566		return False;
4567	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4568		return False;
4569	if (!prs_uint32("level", ps, depth, &q_u->level))
4570		return False;
4571
4572	if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4573		return False;
4574
4575	if (!prs_align(ps))
4576		return False;
4577	if (!prs_uint32("offered", ps, depth, &q_u->offered))
4578		return False;
4579
4580	return True;
4581}
4582
4583/*******************************************************************
4584********************************************************************/
4585
4586BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4587{
4588	prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4589	depth++;
4590
4591	if (!prs_align(ps))
4592		return False;
4593
4594	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4595		return False;
4596
4597	if (!prs_align(ps))
4598		return False;
4599
4600	if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4601		return False;
4602
4603	if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4604		return False;
4605
4606	if (!prs_werror("status", ps, depth, &r_u->status))
4607		return False;
4608
4609	return True;
4610}
4611
4612/*******************************************************************
4613********************************************************************/
4614
4615BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4616{
4617
4618	prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4619	depth++;
4620
4621	if (!prs_align(ps))
4622		return False;
4623	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4624		return False;
4625	if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4626		return False;
4627
4628	if (!prs_align(ps))
4629		return False;
4630
4631	if (!prs_uint32("level", ps, depth, &q_u->level))
4632		return False;
4633
4634	if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4635		return False;
4636
4637	if (!prs_align(ps))
4638		return False;
4639	if (!prs_uint32("offered", ps, depth, &q_u->offered))
4640		return False;
4641
4642	return True;
4643}
4644
4645/*******************************************************************
4646********************************************************************/
4647
4648BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4649{
4650	prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4651	depth++;
4652
4653	if (!prs_align(ps))
4654		return False;
4655
4656	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4657		return False;
4658
4659	if (!prs_align(ps))
4660		return False;
4661
4662	if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4663		return False;
4664
4665	if (!prs_werror("status", ps, depth, &r_u->status))
4666		return False;
4667
4668	return True;
4669}
4670
4671/*******************************************************************
4672 Parse a SPOOL_R_ENUMPORTS structure.
4673********************************************************************/
4674
4675BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4676{
4677	prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
4678	depth++;
4679
4680	if (!prs_align(ps))
4681		return False;
4682
4683	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4684		return False;
4685
4686	if (!prs_align(ps))
4687		return False;
4688
4689	if (!prs_uint32("needed", ps, depth, &r_u->needed))
4690		return False;
4691
4692	if (!prs_uint32("returned", ps, depth, &r_u->returned))
4693		return False;
4694
4695	if (!prs_werror("status", ps, depth, &r_u->status))
4696		return False;
4697
4698	return True;
4699}
4700
4701/*******************************************************************
4702********************************************************************/
4703
4704BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4705{
4706	prs_debug(ps, depth, desc, "");
4707	depth++;
4708
4709	if (!prs_align(ps))
4710		return False;
4711
4712	if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4713		return False;
4714	if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4715		return False;
4716
4717	if (!prs_align(ps))
4718		return False;
4719	if (!prs_uint32("level", ps, depth, &q_u->level))
4720		return False;
4721
4722	if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4723		return False;
4724
4725	if (!prs_align(ps))
4726		return False;
4727	if (!prs_uint32("offered", ps, depth, &q_u->offered))
4728		return False;
4729
4730	return True;
4731}
4732
4733/*******************************************************************
4734 Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4735********************************************************************/
4736
4737BOOL spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4738{
4739	prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4740	depth++;
4741
4742	if(!prs_align(ps))
4743		return False;
4744
4745	if(!prs_uint32("flags", ps, depth, &il->flags))
4746		return False;
4747	if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4748		return False;
4749	if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4750		return False;
4751	if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4752		return False;
4753
4754	if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4755		return False;
4756	if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4757		return False;
4758	if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4759		return False;
4760
4761	return True;
4762}
4763
4764/*******************************************************************
4765 Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4766********************************************************************/
4767
4768BOOL spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4769{
4770	prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4771	depth++;
4772
4773	if(!prs_align(ps))
4774		return False;
4775
4776	if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4777		return False;
4778
4779	return True;
4780}
4781
4782/*******************************************************************
4783 Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4784********************************************************************/
4785
4786BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4787{
4788	prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4789	depth++;
4790
4791	if(!prs_align(ps))
4792		return False;
4793
4794	if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4795		return False;
4796	if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4797		return False;
4798	if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4799		return False;
4800	if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4801		return False;
4802
4803	if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4804		return False;
4805	if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4806		return False;
4807	if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4808		return False;
4809	if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4810		return False;
4811	if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4812		return False;
4813	if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4814		return False;
4815	if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4816		return False;
4817	if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4818		return False;
4819	if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4820		return False;
4821
4822	if(!prs_uint32("attributes", ps, depth, &il->attributes))
4823		return False;
4824	if(!prs_uint32("priority", ps, depth, &il->priority))
4825		return False;
4826	if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4827		return False;
4828	if(!prs_uint32("starttime", ps, depth, &il->starttime))
4829		return False;
4830	if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4831		return False;
4832	if(!prs_uint32("status", ps, depth, &il->status))
4833		return False;
4834	if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4835		return False;
4836	if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4837		return False;
4838
4839	if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4840		return False;
4841	if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4842		return False;
4843	if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4844		return False;
4845	if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4846		return False;
4847	if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4848		return False;
4849	if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4850		return False;
4851	if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4852		return False;
4853	if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4854		return False;
4855	if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4856		return False;
4857	if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4858		return False;
4859	if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4860		return False;
4861
4862	return True;
4863}
4864
4865BOOL spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
4866{
4867	prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
4868	depth++;
4869
4870	if(!prs_align(ps))
4871		return False;
4872
4873	if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
4874		return False;
4875	if(!prs_uint32("action", ps, depth, &il->action))
4876		return False;
4877
4878	if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
4879		return False;
4880	return True;
4881}
4882
4883/*******************************************************************
4884********************************************************************/
4885
4886BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4887{
4888	prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4889	depth++;
4890
4891	if(!prs_align(ps))
4892		return False;
4893	if(!prs_uint32("level", ps, depth, &il->level))
4894		return False;
4895	if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4896		return False;
4897
4898	/* if no struct inside just return */
4899	if (il->info_ptr==0) {
4900		if (UNMARSHALLING(ps)) {
4901			il->info_1=NULL;
4902			il->info_2=NULL;
4903		}
4904		return True;
4905	}
4906
4907	switch (il->level) {
4908		/*
4909		 * level 0 is used by setprinter when managing the queue
4910		 * (hold, stop, start a queue)
4911		 */
4912		case 0:
4913			break;
4914		/* DOCUMENT ME!!! What is level 1 used for? */
4915		case 1:
4916		{
4917			if (UNMARSHALLING(ps)) {
4918				if ((il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_1))) == NULL)
4919					return False;
4920			}
4921			if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4922				return False;
4923			break;
4924		}
4925		/*
4926		 * level 2 is used by addprinter
4927		 * and by setprinter when updating printer's info
4928		 */
4929		case 2:
4930			if (UNMARSHALLING(ps)) {
4931				if ((il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_2))) == NULL)
4932					return False;
4933			}
4934			if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4935				return False;
4936			break;
4937		/* DOCUMENT ME!!! What is level 3 used for? */
4938		case 3:
4939		{
4940			if (UNMARSHALLING(ps)) {
4941				if ((il->info_3=(SPOOL_PRINTER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_3))) == NULL)
4942					return False;
4943			}
4944			if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4945				return False;
4946			break;
4947		}
4948		case 7:
4949			if (UNMARSHALLING(ps))
4950				if ((il->info_7=(SPOOL_PRINTER_INFO_LEVEL_7 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_7))) == NULL)
4951					return False;
4952			if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
4953				return False;
4954			break;
4955	}
4956
4957	return True;
4958}
4959
4960/*******************************************************************
4961********************************************************************/
4962
4963BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4964{
4965	uint32 ptr_sec_desc = 0;
4966
4967	prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4968	depth++;
4969
4970	if(!prs_align(ps))
4971		return False;
4972	if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
4973		return False;
4974	if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4975		return False;
4976
4977	if(!prs_align(ps))
4978		return False;
4979
4980	if(!prs_uint32("info_level", ps, depth, &q_u->level))
4981		return False;
4982
4983	if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4984		return False;
4985
4986	if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4987		return False;
4988
4989	if(!prs_align(ps))
4990		return False;
4991
4992	switch (q_u->level) {
4993		case 2:
4994			ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4995			break;
4996		case 3:
4997			ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4998			break;
4999	}
5000	if (ptr_sec_desc) {
5001		if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
5002			return False;
5003	} else {
5004		uint32 dummy;
5005
5006		/* Parse a NULL security descriptor.  This should really
5007			happen inside the sec_io_desc_buf() function. */
5008
5009		prs_debug(ps, depth, "", "sec_io_desc_buf");
5010		if (!prs_uint32("size", ps, depth + 1, &dummy))
5011			return False;
5012		if (!prs_uint32("ptr", ps, depth + 1, &dummy))
5013			return False;
5014	}
5015
5016	if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
5017		return False;
5018	if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
5019		return False;
5020
5021	return True;
5022}
5023
5024/*******************************************************************
5025********************************************************************/
5026
5027BOOL spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u,
5028			       prs_struct *ps, int depth)
5029{
5030	prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
5031	depth++;
5032
5033	if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
5034		return False;
5035
5036	if(!prs_werror("status", ps, depth, &r_u->status))
5037		return False;
5038
5039	return True;
5040}
5041
5042/*******************************************************************
5043********************************************************************/
5044
5045BOOL spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
5046                                          prs_struct *ps, int depth)
5047{
5048	SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
5049
5050	prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
5051	depth++;
5052
5053	/* reading */
5054	if (UNMARSHALLING(ps)) {
5055		il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
5056		if(il == NULL)
5057			return False;
5058		*q_u=il;
5059	}
5060	else {
5061		il=*q_u;
5062	}
5063
5064	if(!prs_align(ps))
5065		return False;
5066
5067	if(!prs_uint32("cversion", ps, depth, &il->cversion))
5068		return False;
5069	if(!prs_uint32("name", ps, depth, &il->name_ptr))
5070		return False;
5071	if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
5072		return False;
5073	if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
5074		return False;
5075	if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
5076		return False;
5077	if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
5078		return False;
5079	if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
5080		return False;
5081	if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
5082		return False;
5083	if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
5084		return False;
5085	if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
5086		return False;
5087	if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
5088		return False;
5089
5090	if(!prs_align(ps))
5091		return False;
5092
5093	if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
5094		return False;
5095	if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
5096		return False;
5097	if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
5098		return False;
5099	if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
5100		return False;
5101	if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
5102		return False;
5103	if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
5104		return False;
5105	if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
5106		return False;
5107	if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
5108		return False;
5109
5110	if(!prs_align(ps))
5111		return False;
5112
5113	if (il->dependentfiles_ptr)
5114		smb_io_buffer5("", &il->dependentfiles, ps, depth);
5115
5116	return True;
5117}
5118
5119/*******************************************************************
5120parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
5121********************************************************************/
5122
5123BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u,
5124                                          prs_struct *ps, int depth)
5125{
5126	SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
5127
5128	prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
5129	depth++;
5130
5131	/* reading */
5132	if (UNMARSHALLING(ps)) {
5133		il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6));
5134		if(il == NULL)
5135			return False;
5136		*q_u=il;
5137	}
5138	else {
5139		il=*q_u;
5140	}
5141
5142	if(!prs_align(ps))
5143		return False;
5144
5145	/*
5146	 * I know this seems weird, but I have no other explanation.
5147	 * This is observed behavior on both NT4 and 2K servers.
5148	 * --jerry
5149	 */
5150
5151	if (!prs_align_uint64(ps))
5152		return False;
5153
5154	/* parse the main elements the packet */
5155
5156	if(!prs_uint32("cversion       ", ps, depth, &il->version))
5157		return False;
5158	if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
5159		return False;
5160	if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
5161		return False;
5162	if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
5163		return False;
5164	if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
5165		return False;
5166	if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
5167		return False;
5168	if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
5169		return False;
5170	if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
5171		return False;
5172	if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
5173		return False;
5174	if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
5175		return False;
5176	if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
5177		return False;
5178	if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
5179		return False;
5180	if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
5181		return False;
5182	if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
5183		return False;
5184	if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
5185		return False;
5186	if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
5187		return False;
5188	if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
5189		return False;
5190	if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
5191		return False;
5192	if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
5193		return False;
5194	if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
5195		return False;
5196
5197	/* parse the structures in the packet */
5198
5199	if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
5200		return False;
5201	if(!prs_align(ps))
5202		return False;
5203
5204	if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
5205		return False;
5206	if(!prs_align(ps))
5207		return False;
5208
5209	if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
5210		return False;
5211	if(!prs_align(ps))
5212		return False;
5213
5214	if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
5215		return False;
5216	if(!prs_align(ps))
5217		return False;
5218
5219	if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
5220		return False;
5221	if(!prs_align(ps))
5222		return False;
5223
5224	if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
5225		return False;
5226	if(!prs_align(ps))
5227		return False;
5228
5229	if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
5230		return False;
5231	if(!prs_align(ps))
5232		return False;
5233
5234	if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
5235		return False;
5236	if(!prs_align(ps))
5237		return False;
5238	if (il->dependentfiles_ptr) {
5239		if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
5240			return False;
5241		if(!prs_align(ps))
5242			return False;
5243	}
5244	if (il->previousnames_ptr) {
5245		if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
5246			return False;
5247		if(!prs_align(ps))
5248			return False;
5249	}
5250	if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
5251		return False;
5252	if(!prs_align(ps))
5253		return False;
5254	if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
5255		return False;
5256	if(!prs_align(ps))
5257		return False;
5258	if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
5259		return False;
5260	if(!prs_align(ps))
5261		return False;
5262	if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
5263		return False;
5264
5265	return True;
5266}
5267
5268/*******************************************************************
5269 convert a buffer of UNICODE strings null terminated
5270 the buffer is terminated by a NULL
5271
5272 convert to an dos codepage array (null terminated)
5273
5274 dynamically allocate memory
5275
5276********************************************************************/
5277static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
5278{
5279	fstring f, *tar;
5280	int n = 0;
5281	char *src;
5282
5283	if (buf5==NULL)
5284		return False;
5285
5286	src = (char *)buf5->buffer;
5287	*ar = NULL;
5288
5289	while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
5290		rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
5291		src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
5292		tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
5293		if (!tar)
5294			return False;
5295		else
5296			*ar = tar;
5297		fstrcpy((*ar)[n], f);
5298		n++;
5299	}
5300	fstrcpy((*ar)[n], "");
5301
5302	return True;
5303}
5304
5305
5306
5307
5308/*******************************************************************
5309 read a UNICODE array with null terminated strings
5310 and null terminated array
5311 and size of array at beginning
5312********************************************************************/
5313
5314BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
5315{
5316	if (buffer==NULL) return False;
5317
5318	buffer->offset=0;
5319	buffer->uni_str_len=buffer->uni_max_len;
5320
5321	if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
5322		return False;
5323
5324	if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
5325		return False;
5326
5327	return True;
5328}
5329
5330/*******************************************************************
5331********************************************************************/
5332
5333BOOL spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
5334{
5335	prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
5336	depth++;
5337
5338	if(!prs_align(ps))
5339		return False;
5340	if(!prs_uint32("level", ps, depth, &il->level))
5341		return False;
5342	if(!prs_uint32("ptr", ps, depth, &il->ptr))
5343		return False;
5344
5345	if (il->ptr==0)
5346		return True;
5347
5348	switch (il->level) {
5349		case 3:
5350			if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
5351				return False;
5352			break;
5353		case 6:
5354			if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
5355				return False;
5356			break;
5357	default:
5358		return False;
5359	}
5360
5361	return True;
5362}
5363
5364/*******************************************************************
5365 init a SPOOL_Q_ADDPRINTERDRIVER struct
5366 ******************************************************************/
5367
5368BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
5369				SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name,
5370				uint32 level, PRINTER_DRIVER_CTR *info)
5371{
5372	DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
5373
5374	q_u->server_name_ptr = (srv_name!=NULL)?1:0;
5375	init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
5376
5377	q_u->level = level;
5378
5379	q_u->info.level = level;
5380	q_u->info.ptr = (info!=NULL)?1:0;
5381	switch (level)
5382	{
5383	/* info level 3 is supported by Windows 95/98, WinNT and Win2k */
5384	case 3 :
5385		make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
5386		break;
5387
5388	default:
5389		DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
5390		break;
5391	}
5392
5393	return True;
5394}
5395
5396BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
5397	SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
5398				DRIVER_INFO_3 *info3)
5399{
5400	uint32		len = 0;
5401	uint16		*ptr = info3->dependentfiles;
5402	BOOL		done = False;
5403	BOOL		null_char = False;
5404	SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
5405
5406	if (!(inf=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3*)talloc_zero(mem_ctx, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3))))
5407		return False;
5408
5409	inf->cversion	= info3->version;
5410	inf->name_ptr	= (info3->name.buffer!=NULL)?1:0;
5411	inf->environment_ptr	= (info3->architecture.buffer!=NULL)?1:0;
5412	inf->driverpath_ptr	= (info3->driverpath.buffer!=NULL)?1:0;
5413	inf->datafile_ptr	= (info3->datafile.buffer!=NULL)?1:0;
5414	inf->configfile_ptr	= (info3->configfile.buffer!=NULL)?1:0;
5415	inf->helpfile_ptr	= (info3->helpfile.buffer!=NULL)?1:0;
5416	inf->monitorname_ptr	= (info3->monitorname.buffer!=NULL)?1:0;
5417	inf->defaultdatatype_ptr	= (info3->defaultdatatype.buffer!=NULL)?1:0;
5418
5419	init_unistr2_from_unistr(&inf->name, &info3->name);
5420	init_unistr2_from_unistr(&inf->environment, &info3->architecture);
5421	init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
5422	init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
5423	init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
5424	init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
5425	init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
5426	init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
5427
5428	while (!done)
5429	{
5430		switch (*ptr)
5431		{
5432			case 0:
5433				/* the null_char BOOL is used to help locate
5434				   two '\0's back to back */
5435				if (null_char)
5436					done = True;
5437				else
5438					null_char = True;
5439				break;
5440
5441			default:
5442				null_char = False;
5443				;;
5444				break;
5445		}
5446		len++;
5447		ptr++;
5448	}
5449	inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
5450	inf->dependentfilessize = len;
5451	if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles))
5452	{
5453		SAFE_FREE(inf);
5454		return False;
5455	}
5456
5457	*spool_drv_info = inf;
5458
5459	return True;
5460}
5461
5462/*******************************************************************
5463 make a BUFFER5 struct from a uint16*
5464 ******************************************************************/
5465BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
5466{
5467
5468	buf5->buf_len = len;
5469	if((buf5->buffer=(uint16*)talloc_memdup(mem_ctx, src, sizeof(uint16)*len)) == NULL)
5470	{
5471		DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
5472		return False;
5473	}
5474
5475	return True;
5476}
5477
5478/*******************************************************************
5479 fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5480 ********************************************************************/
5481
5482BOOL spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5483{
5484	prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
5485	depth++;
5486
5487	if(!prs_align(ps))
5488		return False;
5489
5490	if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5491		return False;
5492	if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5493		return False;
5494
5495	if(!prs_align(ps))
5496		return False;
5497	if(!prs_uint32("info_level", ps, depth, &q_u->level))
5498		return False;
5499
5500	if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5501		return False;
5502
5503	return True;
5504}
5505
5506/*******************************************************************
5507********************************************************************/
5508
5509BOOL spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5510{
5511	prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
5512	depth++;
5513
5514	if(!prs_werror("status", ps, depth, &q_u->status))
5515		return False;
5516
5517	return True;
5518}
5519
5520/*******************************************************************
5521 fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5522 ********************************************************************/
5523
5524BOOL spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5525{
5526	prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
5527	depth++;
5528
5529	if(!prs_align(ps))
5530		return False;
5531
5532	if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5533		return False;
5534	if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5535		return False;
5536
5537	if(!prs_align(ps))
5538		return False;
5539	if(!prs_uint32("info_level", ps, depth, &q_u->level))
5540		return False;
5541
5542	if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5543		return False;
5544
5545	if(!prs_align(ps))
5546		return False;
5547	if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
5548		return False;
5549
5550	return True;
5551}
5552
5553/*******************************************************************
5554********************************************************************/
5555
5556BOOL spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5557{
5558	prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
5559	depth++;
5560
5561	if(!prs_werror("status", ps, depth, &q_u->status))
5562		return False;
5563
5564	return True;
5565}
5566
5567/*******************************************************************
5568********************************************************************/
5569
5570BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
5571                                NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
5572{
5573	NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
5574
5575	DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
5576
5577	if (*asc==NULL)
5578	{
5579		*asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3));
5580		if(*asc == NULL)
5581			return False;
5582		ZERO_STRUCTP(*asc);
5583	}
5584
5585	d=*asc;
5586
5587	d->cversion=uni->cversion;
5588
5589	unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5590	unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5591	unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5592	unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5593	unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5594	unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5595	unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5596	unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5597
5598	DEBUGADD(8,( "version:         %d\n", d->cversion));
5599	DEBUGADD(8,( "name:            %s\n", d->name));
5600	DEBUGADD(8,( "environment:     %s\n", d->environment));
5601	DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5602	DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5603	DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5604	DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5605	DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5606	DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5607
5608	if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5609		return True;
5610
5611	SAFE_FREE(*asc);
5612	return False;
5613}
5614
5615/*******************************************************************
5616********************************************************************/
5617BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5618                                NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5619{
5620	NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5621
5622	DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5623
5624	if (*asc==NULL)
5625	{
5626		*asc=(NT_PRINTER_DRIVER_INFO_LEVEL_6 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_6));
5627		if(*asc == NULL)
5628			return False;
5629		ZERO_STRUCTP(*asc);
5630	}
5631
5632	d=*asc;
5633
5634	d->version=uni->version;
5635
5636	unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5637	unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5638	unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5639	unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5640	unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5641	unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5642	unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5643	unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5644
5645	DEBUGADD(8,( "version:         %d\n", d->version));
5646	DEBUGADD(8,( "name:            %s\n", d->name));
5647	DEBUGADD(8,( "environment:     %s\n", d->environment));
5648	DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5649	DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5650	DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5651	DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5652	DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5653	DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5654
5655	if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5656		goto error;
5657	if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5658		goto error;
5659
5660	return True;
5661
5662error:
5663	SAFE_FREE(*asc);
5664	return False;
5665}
5666
5667BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5668                              NT_PRINTER_INFO_LEVEL_2  **asc)
5669{
5670	NT_PRINTER_INFO_LEVEL_2 *d;
5671	time_t time_unix;
5672
5673	DEBUG(7,("Converting from UNICODE to ASCII\n"));
5674	time_unix=time(NULL);
5675
5676	if (*asc==NULL) {
5677		DEBUGADD(8,("allocating memory\n"));
5678
5679		*asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
5680		if(*asc == NULL)
5681			return False;
5682		ZERO_STRUCTP(*asc);
5683
5684		/* we allocate memory iff called from
5685		 * addprinter(ex) so we can do one time stuff here.
5686		 */
5687		(*asc)->setuptime=time_unix;
5688
5689	}
5690	DEBUGADD(8,("start converting\n"));
5691
5692	d=*asc;
5693
5694	d->attributes=uni->attributes;
5695	d->priority=uni->priority;
5696	d->default_priority=uni->default_priority;
5697	d->starttime=uni->starttime;
5698	d->untiltime=uni->untiltime;
5699	d->status=uni->status;
5700	d->cjobs=uni->cjobs;
5701
5702	unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5703	unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5704	unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5705	unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5706	unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5707	unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5708	unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5709	unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5710	unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5711	unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5712	unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5713
5714	return True;
5715}
5716
5717/*******************************************************************
5718 * init a structure.
5719 ********************************************************************/
5720
5721BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5722                                fstring servername, fstring env_name, uint32 level,
5723                                NEW_BUFFER *buffer, uint32 offered)
5724{
5725	init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5726	init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5727
5728	q_u->level=level;
5729	q_u->buffer=buffer;
5730	q_u->offered=offered;
5731
5732	return True;
5733}
5734
5735/*******************************************************************
5736 Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5737********************************************************************/
5738
5739BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5740{
5741	prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5742	depth++;
5743
5744	if(!prs_align(ps))
5745		return False;
5746	if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5747		return False;
5748	if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5749		return False;
5750
5751	if(!prs_align(ps))
5752		return False;
5753
5754	if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5755		return False;
5756	if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5757		return False;
5758
5759	if(!prs_align(ps))
5760		return False;
5761
5762	if(!prs_uint32("level", ps, depth, &q_u->level))
5763		return False;
5764
5765	if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5766		return False;
5767
5768	if(!prs_align(ps))
5769		return False;
5770
5771	if(!prs_uint32("offered", ps, depth, &q_u->offered))
5772		return False;
5773
5774	return True;
5775}
5776
5777/*******************************************************************
5778 Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5779********************************************************************/
5780
5781BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5782{
5783	prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5784	depth++;
5785
5786	if (!prs_align(ps))
5787		return False;
5788
5789	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5790		return False;
5791
5792	if (!prs_align(ps))
5793		return False;
5794
5795	if (!prs_uint32("needed", ps, depth, &r_u->needed))
5796		return False;
5797
5798	if (!prs_werror("status", ps, depth, &r_u->status))
5799		return False;
5800
5801	return True;
5802}
5803
5804/*******************************************************************
5805********************************************************************/
5806
5807BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5808{
5809	prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5810	depth++;
5811
5812	if (!prs_align(ps))
5813		return False;
5814
5815	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5816		return False;
5817
5818	if (!prs_align(ps))
5819		return False;
5820
5821	if (!prs_uint32("needed", ps, depth, &r_u->needed))
5822		return False;
5823
5824	if (!prs_uint32("returned", ps, depth, &r_u->returned))
5825		return False;
5826
5827	if (!prs_werror("status", ps, depth, &r_u->status))
5828		return False;
5829
5830	return True;
5831}
5832
5833/*******************************************************************
5834********************************************************************/
5835
5836BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5837{
5838	prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5839	depth++;
5840
5841	if (!prs_align(ps))
5842		return False;
5843
5844	if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5845		return False;
5846	if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5847		return False;
5848
5849	if (!prs_align(ps))
5850		return False;
5851
5852	if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
5853		return False;
5854	if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5855		return False;
5856
5857	if (!prs_align(ps))
5858		return False;
5859
5860	if (!prs_uint32("level", ps, depth, &q_u->level))
5861		return False;
5862
5863	if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5864		return False;
5865
5866	if (!prs_align(ps))
5867		return False;
5868
5869	if (!prs_uint32("offered", ps, depth, &q_u->offered))
5870		return False;
5871
5872	return True;
5873}
5874
5875/*******************************************************************
5876********************************************************************/
5877
5878BOOL spoolss_io_q_addprintprocessor(const char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5879{
5880	prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5881	depth++;
5882
5883	if (!prs_align(ps))
5884		return False;
5885
5886	if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5887		return False;
5888	if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5889		return False;
5890
5891	if (!prs_align(ps))
5892		return False;
5893	if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5894		return False;
5895
5896	if (!prs_align(ps))
5897		return False;
5898	if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5899		return False;
5900
5901	if (!prs_align(ps))
5902		return False;
5903	if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5904		return False;
5905
5906	return True;
5907}
5908
5909/*******************************************************************
5910********************************************************************/
5911
5912BOOL spoolss_io_r_addprintprocessor(const char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5913{
5914	prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
5915	depth++;
5916
5917	if (!prs_align(ps))
5918		return False;
5919
5920	if (!prs_werror("status", ps, depth, &r_u->status))
5921		return False;
5922
5923	return True;
5924}
5925
5926/*******************************************************************
5927********************************************************************/
5928
5929BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
5930{
5931	prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
5932	depth++;
5933
5934	if (!prs_align(ps))
5935		return False;
5936
5937	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5938		return False;
5939
5940	if (!prs_align(ps))
5941		return False;
5942
5943	if (!prs_uint32("needed", ps, depth, &r_u->needed))
5944		return False;
5945
5946	if (!prs_uint32("returned", ps, depth, &r_u->returned))
5947		return False;
5948
5949	if (!prs_werror("status", ps, depth, &r_u->status))
5950		return False;
5951
5952	return True;
5953}
5954
5955/*******************************************************************
5956********************************************************************/
5957
5958BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
5959{
5960	prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
5961	depth++;
5962
5963	if (!prs_align(ps))
5964		return False;
5965
5966	if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5967		return False;
5968	if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5969		return False;
5970
5971	if (!prs_align(ps))
5972		return False;
5973
5974	if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
5975		return False;
5976	if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
5977		return False;
5978
5979	if (!prs_align(ps))
5980		return False;
5981
5982	if (!prs_uint32("level", ps, depth, &q_u->level))
5983		return False;
5984
5985	if(!spoolss_io_buffer("buffer", ps, depth, &q_u->buffer))
5986		return False;
5987
5988	if (!prs_align(ps))
5989		return False;
5990
5991	if (!prs_uint32("offered", ps, depth, &q_u->offered))
5992		return False;
5993
5994	return True;
5995}
5996
5997/*******************************************************************
5998 Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
5999********************************************************************/
6000
6001BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
6002{
6003	prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
6004	depth++;
6005
6006	if (!prs_align(ps))
6007		return False;
6008
6009	if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
6010		return False;
6011	if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
6012		return False;
6013
6014	if (!prs_align(ps))
6015		return False;
6016
6017	if (!prs_uint32("level", ps, depth, &q_u->level))
6018		return False;
6019
6020	if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
6021		return False;
6022
6023	if (!prs_align(ps))
6024		return False;
6025
6026	if (!prs_uint32("offered", ps, depth, &q_u->offered))
6027		return False;
6028
6029	return True;
6030}
6031
6032/*******************************************************************
6033********************************************************************/
6034
6035BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
6036{
6037	prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
6038	depth++;
6039
6040	if (!prs_align(ps))
6041		return False;
6042
6043	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
6044		return False;
6045
6046	if (!prs_align(ps))
6047		return False;
6048
6049	if (!prs_uint32("needed", ps, depth, &r_u->needed))
6050		return False;
6051
6052	if (!prs_uint32("returned", ps, depth, &r_u->returned))
6053		return False;
6054
6055	if (!prs_werror("status", ps, depth, &r_u->status))
6056		return False;
6057
6058	return True;
6059}
6060
6061/*******************************************************************
6062********************************************************************/
6063
6064BOOL spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
6065{
6066	prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
6067	depth++;
6068
6069	if(!prs_align(ps))
6070		return False;
6071	if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
6072		return False;
6073
6074	if (UNMARSHALLING(ps) && r_u->valuesize) {
6075		r_u->value = (uint16 *)prs_alloc_mem(ps, r_u->valuesize * 2);
6076		if (!r_u->value) {
6077			DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
6078			return False;
6079		}
6080	}
6081
6082	if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
6083		return False;
6084
6085	if(!prs_align(ps))
6086		return False;
6087
6088	if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
6089		return False;
6090
6091	if(!prs_uint32("type", ps, depth, &r_u->type))
6092		return False;
6093
6094	if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
6095		return False;
6096
6097	if (UNMARSHALLING(ps) && r_u->datasize) {
6098		r_u->data = (uint8 *)prs_alloc_mem(ps, r_u->datasize);
6099		if (!r_u->data) {
6100			DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
6101			return False;
6102		}
6103	}
6104
6105	if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
6106		return False;
6107	if(!prs_align(ps))
6108		return False;
6109
6110	if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
6111		return False;
6112	if(!prs_werror("status", ps, depth, &r_u->status))
6113		return False;
6114
6115	return True;
6116}
6117
6118/*******************************************************************
6119********************************************************************/
6120
6121BOOL spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
6122{
6123	prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
6124	depth++;
6125
6126	if(!prs_align(ps))
6127		return False;
6128	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6129		return False;
6130	if(!prs_uint32("index", ps, depth, &q_u->index))
6131		return False;
6132	if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
6133		return False;
6134	if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
6135		return False;
6136
6137	return True;
6138}
6139
6140/*******************************************************************
6141********************************************************************/
6142
6143BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
6144		const POLICY_HND *hnd,
6145		uint32 idx, uint32 valuelen, uint32 datalen)
6146{
6147	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6148	q_u->index=idx;
6149	q_u->valuesize=valuelen;
6150	q_u->datasize=datalen;
6151
6152	return True;
6153}
6154
6155/*******************************************************************
6156********************************************************************/
6157
6158BOOL make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
6159				      const POLICY_HND *hnd, const char *key,
6160				      uint32 size)
6161{
6162	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6163	init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
6164	q_u->size = size;
6165
6166	return True;
6167}
6168
6169/*******************************************************************
6170********************************************************************/
6171BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
6172				   char* value, uint32 data_type, char* data, uint32 data_size)
6173{
6174	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6175	q_u->type = data_type;
6176	init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
6177
6178	q_u->max_len = q_u->real_len = data_size;
6179	q_u->data = (unsigned char *)data;
6180
6181	return True;
6182}
6183
6184/*******************************************************************
6185********************************************************************/
6186BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd,
6187				     char *key, char* value, uint32 data_type, char* data,
6188				     uint32 data_size)
6189{
6190	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6191	q_u->type = data_type;
6192	init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
6193	init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
6194
6195	q_u->max_len = q_u->real_len = data_size;
6196	q_u->data = (unsigned char *)data;
6197
6198	return True;
6199}
6200
6201/*******************************************************************
6202********************************************************************/
6203
6204BOOL spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
6205{
6206	prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
6207	depth++;
6208
6209	if(!prs_align(ps))
6210		return False;
6211	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6212		return False;
6213	if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
6214		return False;
6215
6216	if(!prs_align(ps))
6217		return False;
6218
6219	if(!prs_uint32("type", ps, depth, &q_u->type))
6220		return False;
6221
6222	if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
6223		return False;
6224
6225	switch (q_u->type)
6226	{
6227		case REG_SZ:
6228		case REG_BINARY:
6229		case REG_DWORD:
6230		case REG_MULTI_SZ:
6231            if (q_u->max_len) {
6232                if (UNMARSHALLING(ps))
6233    				q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
6234    			if(q_u->data == NULL)
6235    				return False;
6236    			if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6237    				return False;
6238            }
6239			if(!prs_align(ps))
6240				return False;
6241			break;
6242	}
6243
6244	if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6245		return False;
6246
6247	return True;
6248}
6249
6250/*******************************************************************
6251********************************************************************/
6252
6253BOOL spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
6254{
6255	prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
6256	depth++;
6257
6258	if(!prs_align(ps))
6259		return False;
6260	if(!prs_werror("status",     ps, depth, &r_u->status))
6261		return False;
6262
6263	return True;
6264}
6265
6266/*******************************************************************
6267********************************************************************/
6268BOOL spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
6269{
6270	prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
6271	depth++;
6272
6273	if (!prs_align(ps))
6274		return False;
6275	if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6276		return False;
6277
6278	if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
6279		return False;
6280
6281	if (q_u->datatype_ptr) {
6282		if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
6283		return False;
6284	}
6285
6286	if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
6287		return False;
6288
6289	return True;
6290}
6291
6292
6293/*******************************************************************
6294********************************************************************/
6295BOOL spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
6296{
6297	prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
6298	depth++;
6299
6300	if(!prs_align(ps))
6301		return False;
6302	if(!prs_werror("status",     ps, depth, &r_u->status))
6303		return False;
6304
6305	return True;
6306}
6307
6308/*******************************************************************
6309********************************************************************/
6310
6311static BOOL spoolss_io_addform(const char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
6312{
6313	prs_debug(ps, depth, desc, "spoolss_io_addform");
6314	depth++;
6315	if(!prs_align(ps))
6316		return False;
6317
6318	if (ptr!=0)
6319	{
6320		if(!prs_uint32("flags",    ps, depth, &f->flags))
6321			return False;
6322		if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
6323			return False;
6324		if(!prs_uint32("size_x",   ps, depth, &f->size_x))
6325			return False;
6326		if(!prs_uint32("size_y",   ps, depth, &f->size_y))
6327			return False;
6328		if(!prs_uint32("left",     ps, depth, &f->left))
6329			return False;
6330		if(!prs_uint32("top",      ps, depth, &f->top))
6331			return False;
6332		if(!prs_uint32("right",    ps, depth, &f->right))
6333			return False;
6334		if(!prs_uint32("bottom",   ps, depth, &f->bottom))
6335			return False;
6336
6337		if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
6338			return False;
6339	}
6340
6341	return True;
6342}
6343
6344/*******************************************************************
6345********************************************************************/
6346
6347BOOL spoolss_io_q_deleteform(const char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
6348{
6349	prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
6350	depth++;
6351
6352	if(!prs_align(ps))
6353		return False;
6354	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6355		return False;
6356	if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
6357		return False;
6358
6359	return True;
6360}
6361
6362/*******************************************************************
6363********************************************************************/
6364
6365BOOL spoolss_io_r_deleteform(const char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
6366{
6367	prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
6368	depth++;
6369
6370	if(!prs_align(ps))
6371		return False;
6372	if(!prs_werror("status",	ps, depth, &r_u->status))
6373		return False;
6374
6375	return True;
6376}
6377
6378/*******************************************************************
6379********************************************************************/
6380
6381BOOL spoolss_io_q_addform(const char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
6382{
6383	uint32 useless_ptr=1;
6384	prs_debug(ps, depth, desc, "spoolss_io_q_addform");
6385	depth++;
6386
6387	if(!prs_align(ps))
6388		return False;
6389	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6390		return False;
6391	if(!prs_uint32("level",  ps, depth, &q_u->level))
6392		return False;
6393	if(!prs_uint32("level2", ps, depth, &q_u->level2))
6394		return False;
6395
6396	if (q_u->level==1)
6397	{
6398		if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6399			return False;
6400		if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6401			return False;
6402	}
6403
6404	return True;
6405}
6406
6407/*******************************************************************
6408********************************************************************/
6409
6410BOOL spoolss_io_r_addform(const char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
6411{
6412	prs_debug(ps, depth, desc, "spoolss_io_r_addform");
6413	depth++;
6414
6415	if(!prs_align(ps))
6416		return False;
6417	if(!prs_werror("status",	ps, depth, &r_u->status))
6418		return False;
6419
6420	return True;
6421}
6422
6423/*******************************************************************
6424********************************************************************/
6425
6426BOOL spoolss_io_q_setform(const char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
6427{
6428	uint32 useless_ptr=1;
6429	prs_debug(ps, depth, desc, "spoolss_io_q_setform");
6430	depth++;
6431
6432	if(!prs_align(ps))
6433		return False;
6434	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6435		return False;
6436	if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
6437		return False;
6438
6439	if(!prs_align(ps))
6440		return False;
6441
6442	if(!prs_uint32("level",  ps, depth, &q_u->level))
6443		return False;
6444	if(!prs_uint32("level2", ps, depth, &q_u->level2))
6445		return False;
6446
6447	if (q_u->level==1)
6448	{
6449		if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6450			return False;
6451		if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6452			return False;
6453	}
6454
6455	return True;
6456}
6457
6458/*******************************************************************
6459********************************************************************/
6460
6461BOOL spoolss_io_r_setform(const char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
6462{
6463	prs_debug(ps, depth, desc, "spoolss_io_r_setform");
6464	depth++;
6465
6466	if(!prs_align(ps))
6467		return False;
6468	if(!prs_werror("status",	ps, depth, &r_u->status))
6469		return False;
6470
6471	return True;
6472}
6473
6474/*******************************************************************
6475 Parse a SPOOL_R_GETJOB structure.
6476********************************************************************/
6477
6478BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
6479{
6480	prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
6481	depth++;
6482
6483	if (!prs_align(ps))
6484		return False;
6485
6486	if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
6487		return False;
6488
6489	if (!prs_align(ps))
6490		return False;
6491
6492	if (!prs_uint32("needed", ps, depth, &r_u->needed))
6493		return False;
6494
6495	if (!prs_werror("status", ps, depth, &r_u->status))
6496		return False;
6497
6498	return True;
6499}
6500
6501/*******************************************************************
6502 Parse a SPOOL_Q_GETJOB structure.
6503********************************************************************/
6504
6505BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
6506{
6507	prs_debug(ps, depth, desc, "");
6508	depth++;
6509
6510	if(!prs_align(ps))
6511		return False;
6512
6513	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6514		return False;
6515	if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
6516		return False;
6517	if(!prs_uint32("level", ps, depth, &q_u->level))
6518		return False;
6519
6520	if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
6521		return False;
6522
6523	if(!prs_align(ps))
6524		return False;
6525
6526	if(!prs_uint32("offered", ps, depth, &q_u->offered))
6527		return False;
6528
6529	return True;
6530}
6531
6532void free_devmode(DEVICEMODE *devmode)
6533{
6534	if (devmode!=NULL) {
6535		SAFE_FREE(devmode->private);
6536		SAFE_FREE(devmode);
6537	}
6538}
6539
6540void free_printer_info_1(PRINTER_INFO_1 *printer)
6541{
6542	SAFE_FREE(printer);
6543}
6544
6545void free_printer_info_2(PRINTER_INFO_2 *printer)
6546{
6547	if (printer!=NULL) {
6548		free_devmode(printer->devmode);
6549		printer->devmode = NULL;
6550		SAFE_FREE(printer);
6551	}
6552}
6553
6554void free_printer_info_3(PRINTER_INFO_3 *printer)
6555{
6556	SAFE_FREE(printer);
6557}
6558
6559void free_printer_info_4(PRINTER_INFO_4 *printer)
6560{
6561	SAFE_FREE(printer);
6562}
6563
6564void free_printer_info_5(PRINTER_INFO_5 *printer)
6565{
6566	SAFE_FREE(printer);
6567}
6568
6569void free_printer_info_7(PRINTER_INFO_7 *printer)
6570{
6571	SAFE_FREE(printer);
6572}
6573
6574void free_job_info_2(JOB_INFO_2 *job)
6575{
6576    if (job!=NULL)
6577        free_devmode(job->devmode);
6578}
6579
6580/*******************************************************************
6581 * init a structure.
6582 ********************************************************************/
6583
6584BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u,
6585			       const fstring string, uint32 printer, uint32 type)
6586{
6587	if (q_u == NULL)
6588		return False;
6589
6590	init_unistr2(&q_u->string, string, UNI_STR_TERMINATE);
6591
6592	q_u->printer=printer;
6593	q_u->type=type;
6594
6595	q_u->unknown0=0x0;
6596	q_u->unknown1=0x0;
6597
6598	return True;
6599}
6600
6601/*******************************************************************
6602 Parse a SPOOL_Q_REPLYOPENPRINTER structure.
6603********************************************************************/
6604
6605BOOL spoolss_io_q_replyopenprinter(const char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
6606{
6607	prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
6608	depth++;
6609
6610	if(!prs_align(ps))
6611		return False;
6612
6613	if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
6614		return False;
6615
6616	if(!prs_align(ps))
6617		return False;
6618
6619	if(!prs_uint32("printer", ps, depth, &q_u->printer))
6620		return False;
6621	if(!prs_uint32("type", ps, depth, &q_u->type))
6622		return False;
6623
6624	if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6625		return False;
6626	if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6627		return False;
6628
6629	return True;
6630}
6631
6632/*******************************************************************
6633 Parse a SPOOL_R_REPLYOPENPRINTER structure.
6634********************************************************************/
6635
6636BOOL spoolss_io_r_replyopenprinter(const char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
6637{
6638	prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
6639	depth++;
6640
6641	if (!prs_align(ps))
6642		return False;
6643
6644	if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6645		return False;
6646
6647	if (!prs_werror("status", ps, depth, &r_u->status))
6648		return False;
6649
6650	return True;
6651}
6652
6653/*******************************************************************
6654 * init a structure.
6655 ********************************************************************/
6656BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd,
6657					uint32 condition, uint32 change_id)
6658{
6659
6660	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6661
6662	q_u->condition = condition;
6663	q_u->change_id = change_id;
6664
6665	/* magic values */
6666	q_u->unknown1 = 0x1;
6667	memset(q_u->unknown2, 0x0, 5);
6668	q_u->unknown2[0] = 0x1;
6669
6670	return True;
6671}
6672
6673/*******************************************************************
6674 Parse a SPOOL_Q_ROUTERREPLYPRINTER structure.
6675********************************************************************/
6676BOOL spoolss_io_q_routerreplyprinter (const char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth)
6677{
6678
6679	prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter");
6680	depth++;
6681
6682	if (!prs_align(ps))
6683		return False;
6684
6685	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6686		return False;
6687
6688	if (!prs_uint32("condition", ps, depth, &q_u->condition))
6689		return False;
6690
6691	if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6692		return False;
6693
6694	if (!prs_uint32("change_id", ps, depth, &q_u->change_id))
6695		return False;
6696
6697	if (!prs_uint8s(False, "private",  ps, depth, q_u->unknown2, 5))
6698		return False;
6699
6700	return True;
6701}
6702
6703/*******************************************************************
6704 Parse a SPOOL_R_ROUTERREPLYPRINTER structure.
6705********************************************************************/
6706BOOL spoolss_io_r_routerreplyprinter (const char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth)
6707{
6708	prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter");
6709	depth++;
6710
6711	if (!prs_align(ps))
6712		return False;
6713
6714	if (!prs_werror("status", ps, depth, &r_u->status))
6715		return False;
6716
6717	return True;
6718}
6719
6720/*******************************************************************
6721 * init a structure.
6722 ********************************************************************/
6723
6724BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
6725{
6726	if (q_u == NULL)
6727		return False;
6728
6729	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6730
6731	return True;
6732}
6733
6734/*******************************************************************
6735 Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
6736********************************************************************/
6737
6738BOOL spoolss_io_q_replycloseprinter(const char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
6739{
6740	prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
6741	depth++;
6742
6743	if(!prs_align(ps))
6744		return False;
6745
6746	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6747		return False;
6748
6749	return True;
6750}
6751
6752/*******************************************************************
6753 Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
6754********************************************************************/
6755
6756BOOL spoolss_io_r_replycloseprinter(const char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
6757{
6758	prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6759	depth++;
6760
6761	if (!prs_align(ps))
6762		return False;
6763
6764	if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6765		return False;
6766
6767	if (!prs_werror("status", ps, depth, &r_u->status))
6768		return False;
6769
6770	return True;
6771}
6772
6773#if 0	/* JERRY - not currently used but could be :-) */
6774
6775/*******************************************************************
6776 Deep copy a SPOOL_NOTIFY_INFO_DATA structure
6777 ******************************************************************/
6778static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst,
6779				SPOOL_NOTIFY_INFO_DATA *src, int n)
6780{
6781	int i;
6782
6783	memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
6784
6785	for (i=0; i<n; i++) {
6786		int len;
6787		uint16 *s = NULL;
6788
6789		if (src->size != POINTER)
6790			continue;
6791		len = src->notify_data.data.length;
6792		s = malloc(sizeof(uint16)*len);
6793		if (s == NULL) {
6794			DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
6795			return False;
6796		}
6797
6798		memcpy(s, src->notify_data.data.string, len*2);
6799		dst->notify_data.data.string = s;
6800	}
6801
6802	return True;
6803}
6804
6805/*******************************************************************
6806 Deep copy a SPOOL_NOTIFY_INFO structure
6807 ******************************************************************/
6808static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
6809{
6810	if (!dst) {
6811		DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
6812		return False;
6813	}
6814
6815	dst->version = src->version;
6816	dst->flags   = src->flags;
6817	dst->count   = src->count;
6818
6819	if (dst->count)
6820	{
6821		dst->data = malloc(dst->count * sizeof(SPOOL_NOTIFY_INFO_DATA));
6822
6823		DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
6824			dst->count));
6825
6826		if (dst->data == NULL) {
6827			DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n",
6828				dst->count));
6829			return False;
6830		}
6831
6832		return (copy_spool_notify_info_data(dst->data, src->data, src->count));
6833	}
6834
6835	return True;
6836}
6837#endif	/* JERRY */
6838
6839/*******************************************************************
6840 * init a structure.
6841 ********************************************************************/
6842
6843BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
6844			        uint32 change_low, uint32 change_high,
6845				SPOOL_NOTIFY_INFO *info)
6846{
6847	if (q_u == NULL)
6848		return False;
6849
6850	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6851
6852	q_u->change_low=change_low;
6853	q_u->change_high=change_high;
6854
6855	q_u->unknown0=0x0;
6856	q_u->unknown1=0x0;
6857
6858	q_u->info_ptr=0x0FF0ADDE;
6859
6860	q_u->info.version=2;
6861
6862	if (info->count) {
6863		DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
6864			info->count));
6865		q_u->info.version = info->version;
6866		q_u->info.flags   = info->flags;
6867		q_u->info.count   = info->count;
6868		/* pointer field - be careful! */
6869		q_u->info.data    = info->data;
6870	}
6871	else  {
6872	q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
6873	q_u->info.count=0;
6874	}
6875
6876	return True;
6877}
6878
6879/*******************************************************************
6880 Parse a SPOOL_Q_REPLY_RRPCN structure.
6881********************************************************************/
6882
6883BOOL spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
6884{
6885	prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
6886	depth++;
6887
6888	if(!prs_align(ps))
6889		return False;
6890
6891	if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6892		return False;
6893
6894	if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
6895		return False;
6896
6897	if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
6898		return False;
6899
6900	if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6901		return False;
6902
6903	if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6904		return False;
6905
6906	if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
6907		return False;
6908
6909	if(q_u->info_ptr!=0)
6910		if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
6911			return False;
6912
6913	return True;
6914}
6915
6916/*******************************************************************
6917 Parse a SPOOL_R_REPLY_RRPCN structure.
6918********************************************************************/
6919
6920BOOL spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
6921{
6922	prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
6923	depth++;
6924
6925	if (!prs_align(ps))
6926		return False;
6927
6928	if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
6929		return False;
6930
6931	if (!prs_werror("status", ps, depth, &r_u->status))
6932		return False;
6933
6934	return True;
6935}
6936
6937/*******************************************************************
6938 * read a structure.
6939 * called from spoolss_q_getprinterdataex (srv_spoolss.c)
6940 ********************************************************************/
6941
6942BOOL spoolss_io_q_getprinterdataex(const char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6943{
6944	if (q_u == NULL)
6945		return False;
6946
6947	prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
6948	depth++;
6949
6950	if (!prs_align(ps))
6951		return False;
6952	if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6953		return False;
6954	if (!prs_align(ps))
6955		return False;
6956	if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
6957		return False;
6958	if (!prs_align(ps))
6959		return False;
6960	if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
6961		return False;
6962	if (!prs_align(ps))
6963		return False;
6964	if (!prs_uint32("size", ps, depth, &q_u->size))
6965		return False;
6966
6967	return True;
6968}
6969
6970/*******************************************************************
6971 * write a structure.
6972 * called from spoolss_r_getprinterdataex (srv_spoolss.c)
6973 ********************************************************************/
6974
6975BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6976{
6977	if (r_u == NULL)
6978		return False;
6979
6980	prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
6981	depth++;
6982
6983	if (!prs_align(ps))
6984		return False;
6985	if (!prs_uint32("type", ps, depth, &r_u->type))
6986		return False;
6987	if (!prs_uint32("size", ps, depth, &r_u->size))
6988		return False;
6989
6990	if (UNMARSHALLING(ps) && r_u->size) {
6991		r_u->data = (unsigned char *)prs_alloc_mem(ps, r_u->size);
6992		if(!r_u->data)
6993			return False;
6994	}
6995
6996	if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
6997		return False;
6998
6999	if (!prs_align(ps))
7000		return False;
7001
7002	if (!prs_uint32("needed", ps, depth, &r_u->needed))
7003		return False;
7004	if (!prs_werror("status", ps, depth, &r_u->status))
7005		return False;
7006
7007	return True;
7008}
7009
7010/*******************************************************************
7011 * read a structure.
7012 ********************************************************************/
7013
7014BOOL spoolss_io_q_setprinterdataex(const char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
7015{
7016	prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
7017	depth++;
7018
7019	if(!prs_align(ps))
7020		return False;
7021	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7022		return False;
7023	if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
7024		return False;
7025
7026	if(!prs_align(ps))
7027		return False;
7028
7029	if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
7030		return False;
7031
7032	if(!prs_align(ps))
7033		return False;
7034
7035	if(!prs_uint32("type", ps, depth, &q_u->type))
7036		return False;
7037
7038	if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
7039		return False;
7040
7041	switch (q_u->type)
7042	{
7043		case 0x1:
7044		case 0x3:
7045		case 0x4:
7046		case 0x7:
7047			if (q_u->max_len) {
7048				if (UNMARSHALLING(ps))
7049    					q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
7050    				if(q_u->data == NULL)
7051    					return False;
7052    				if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
7053    					return False;
7054			}
7055			if(!prs_align(ps))
7056				return False;
7057			break;
7058	}
7059
7060	if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
7061		return False;
7062
7063	return True;
7064}
7065
7066/*******************************************************************
7067 * write a structure.
7068 ********************************************************************/
7069
7070BOOL spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
7071{
7072	prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
7073	depth++;
7074
7075	if(!prs_align(ps))
7076		return False;
7077	if(!prs_werror("status",     ps, depth, &r_u->status))
7078		return False;
7079
7080	return True;
7081}
7082
7083/*******************************************************************
7084 * read a structure.
7085 ********************************************************************/
7086BOOL make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u,
7087				   POLICY_HND *hnd, const char *key,
7088				   uint32 size)
7089{
7090	DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
7091
7092	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
7093	init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
7094	q_u->size = size;
7095
7096	return True;
7097}
7098
7099/*******************************************************************
7100 * read a structure.
7101 ********************************************************************/
7102
7103BOOL spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
7104{
7105	prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
7106	depth++;
7107
7108	if(!prs_align(ps))
7109		return False;
7110	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7111		return False;
7112
7113	if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
7114		return False;
7115
7116	if(!prs_align(ps))
7117		return False;
7118
7119	if(!prs_uint32("size", ps, depth, &q_u->size))
7120		return False;
7121
7122	return True;
7123}
7124
7125/*******************************************************************
7126 * write a structure.
7127 ********************************************************************/
7128
7129BOOL spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
7130{
7131	prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
7132	depth++;
7133
7134	if(!prs_align(ps))
7135		return False;
7136
7137	if (!smb_io_buffer5("", &r_u->keys, ps, depth))
7138		return False;
7139
7140	if(!prs_align(ps))
7141		return False;
7142
7143	if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7144		return False;
7145
7146	if(!prs_werror("status",     ps, depth, &r_u->status))
7147		return False;
7148
7149	return True;
7150}
7151
7152/*******************************************************************
7153 * read a structure.
7154 ********************************************************************/
7155
7156BOOL make_spoolss_q_deleteprinterkey(SPOOL_Q_DELETEPRINTERKEY *q_u,
7157				     POLICY_HND *hnd, char *keyname)
7158{
7159	DEBUG(5,("make_spoolss_q_deleteprinterkey\n"));
7160
7161	memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
7162	init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
7163
7164	return True;
7165}
7166
7167/*******************************************************************
7168 * read a structure.
7169 ********************************************************************/
7170
7171BOOL spoolss_io_q_deleteprinterkey(const char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
7172{
7173	prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
7174	depth++;
7175
7176	if(!prs_align(ps))
7177		return False;
7178	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7179		return False;
7180
7181	if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
7182		return False;
7183
7184	return True;
7185}
7186
7187/*******************************************************************
7188 * write a structure.
7189 ********************************************************************/
7190
7191BOOL spoolss_io_r_deleteprinterkey(const char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
7192{
7193	prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
7194	depth++;
7195
7196	if(!prs_align(ps))
7197		return False;
7198
7199	if(!prs_werror("status",     ps, depth, &r_u->status))
7200		return False;
7201
7202	return True;
7203}
7204
7205
7206/*******************************************************************
7207 * read a structure.
7208 ********************************************************************/
7209
7210BOOL spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
7211{
7212	prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
7213	depth++;
7214
7215	if(!prs_align(ps))
7216		return False;
7217	if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7218		return False;
7219
7220	if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
7221		return False;
7222
7223	if(!prs_align(ps))
7224		return False;
7225
7226	if(!prs_uint32("size", ps, depth, &q_u->size))
7227		return False;
7228
7229	return True;
7230}
7231
7232/*******************************************************************
7233********************************************************************/
7234
7235static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps,
7236				PRINTER_ENUM_VALUES_CTR *ctr, int depth)
7237{
7238	int 	i;
7239	uint32	valuename_offset,
7240		data_offset,
7241		current_offset;
7242	const uint32 basic_unit = 20; /* size of static portion of enum_values */
7243
7244	prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
7245	depth++;
7246
7247	/*
7248	 * offset data begins at 20 bytes per structure * size_of_array.
7249	 * Don't forget the uint32 at the beginning
7250	 * */
7251
7252	current_offset = basic_unit * ctr->size_of_array;
7253
7254	/* first loop to write basic enum_value information */
7255
7256	if (UNMARSHALLING(ps)) {
7257		ctr->values = (PRINTER_ENUM_VALUES *)prs_alloc_mem(
7258			ps, ctr->size_of_array * sizeof(PRINTER_ENUM_VALUES));
7259		if (!ctr->values)
7260			return False;
7261	}
7262
7263	for (i=0; i<ctr->size_of_array; i++) {
7264		valuename_offset = current_offset;
7265		if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
7266			return False;
7267
7268		if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
7269			return False;
7270
7271		if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
7272			return False;
7273
7274		data_offset = ctr->values[i].value_len + valuename_offset;
7275
7276		if (!prs_uint32("data_offset", ps, depth, &data_offset))
7277			return False;
7278
7279		if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
7280			return False;
7281
7282		current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
7283		/* account for 2 byte alignment */
7284		current_offset += (current_offset % 2);
7285	}
7286
7287	/*
7288	 * loop #2 for writing the dynamically size objects; pay
7289	 * attention to 2-byte alignment here....
7290	 */
7291
7292	for (i=0; i<ctr->size_of_array; i++) {
7293
7294		if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
7295			return False;
7296
7297		if ( ctr->values[i].data_len ) {
7298			if ( UNMARSHALLING(ps) ) {
7299				ctr->values[i].data = (uint8 *)prs_alloc_mem(
7300					ps, ctr->values[i].data_len);
7301				if (!ctr->values[i].data)
7302					return False;
7303			}
7304			if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
7305				return False;
7306		}
7307
7308		if ( !prs_align_uint16(ps) )
7309			return False;
7310	}
7311
7312	return True;
7313}
7314
7315/*******************************************************************
7316 * write a structure.
7317 ********************************************************************/
7318
7319BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
7320{
7321	uint32 data_offset, end_offset;
7322	prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
7323	depth++;
7324
7325	if(!prs_align(ps))
7326		return False;
7327
7328	if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
7329		return False;
7330
7331	data_offset = prs_offset(ps);
7332
7333	if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
7334		return False;
7335
7336	if(!prs_align(ps))
7337		return False;
7338
7339	if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7340		return False;
7341
7342	if(!prs_uint32("returned",   ps, depth, &r_u->returned))
7343		return False;
7344
7345	if(!prs_werror("status",     ps, depth, &r_u->status))
7346		return False;
7347
7348	r_u->ctr.size_of_array = r_u->returned;
7349
7350	end_offset = prs_offset(ps);
7351
7352	if (!prs_set_offset(ps, data_offset))
7353		return False;
7354
7355	if (r_u->ctr.size)
7356		if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
7357			return False;
7358
7359	if (!prs_set_offset(ps, end_offset))
7360		return False;
7361																	        	return True;
7362}
7363
7364/*******************************************************************
7365 * write a structure.
7366 ********************************************************************/
7367
7368/*
7369   uint32 GetPrintProcessorDirectory(
7370       [in] unistr2 *name,
7371       [in] unistr2 *environment,
7372       [in] uint32 level,
7373       [in,out] NEW_BUFFER buffer,
7374       [in] uint32 offered,
7375       [out] uint32 needed,
7376       [out] uint32 returned
7377   );
7378
7379*/
7380
7381BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered)
7382{
7383	DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
7384
7385	init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
7386	init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
7387
7388	q_u->level = level;
7389
7390	q_u->buffer = buffer;
7391	q_u->offered = offered;
7392
7393	return True;
7394}
7395
7396BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
7397{
7398	uint32 ptr;
7399
7400	prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
7401	depth++;
7402
7403	if(!prs_align(ps))
7404		return False;
7405
7406	if (!prs_uint32("ptr", ps, depth, &ptr))
7407		return False;
7408
7409	if (ptr) {
7410		if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
7411			return False;
7412	}
7413
7414	if (!prs_align(ps))
7415		return False;
7416
7417	if (!prs_uint32("ptr", ps, depth, &ptr))
7418		return False;
7419
7420	if (ptr) {
7421		if(!smb_io_unistr2("environment", &q_u->environment, True,
7422				   ps, depth))
7423			return False;
7424	}
7425
7426	if (!prs_align(ps))
7427		return False;
7428
7429	if(!prs_uint32("level",   ps, depth, &q_u->level))
7430		return False;
7431
7432	if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
7433		return False;
7434
7435	if(!prs_align(ps))
7436		return False;
7437
7438	if(!prs_uint32("offered", ps, depth, &q_u->offered))
7439		return False;
7440
7441	return True;
7442}
7443
7444/*******************************************************************
7445 * write a structure.
7446 ********************************************************************/
7447
7448BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
7449{
7450	prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
7451	depth++;
7452
7453	if(!prs_align(ps))
7454		return False;
7455
7456	if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
7457		return False;
7458
7459	if(!prs_align(ps))
7460		return False;
7461
7462	if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7463		return False;
7464
7465	if(!prs_werror("status",     ps, depth, &r_u->status))
7466		return False;
7467
7468	return True;
7469}
7470
7471BOOL smb_io_printprocessordirectory_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
7472{
7473	prs_struct *ps=&buffer->prs;
7474
7475	prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
7476	depth++;
7477
7478	buffer->struct_start=prs_offset(ps);
7479
7480	if (!smb_io_unistr(desc, &info->name, ps, depth))
7481		return False;
7482
7483	return True;
7484}
7485
7486/*******************************************************************
7487 * init a structure.
7488 ********************************************************************/
7489
7490BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle,
7491			    int level, FORM *form)
7492{
7493	memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7494	q_u->level = level;
7495	q_u->level2 = level;
7496	memcpy(&q_u->form, form, sizeof(FORM));
7497
7498	return True;
7499}
7500
7501/*******************************************************************
7502 * init a structure.
7503 ********************************************************************/
7504
7505BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle,
7506			    int level, const char *form_name, FORM *form)
7507{
7508	memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7509	q_u->level = level;
7510	q_u->level2 = level;
7511	memcpy(&q_u->form, form, sizeof(FORM));
7512	init_unistr2(&q_u->name, form_name, UNI_STR_TERMINATE);
7513
7514	return True;
7515}
7516
7517/*******************************************************************
7518 * init a structure.
7519 ********************************************************************/
7520
7521BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle,
7522			       const char *form)
7523{
7524	memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7525	init_unistr2(&q_u->name, form, UNI_STR_TERMINATE);
7526	return True;
7527}
7528
7529/*******************************************************************
7530 * init a structure.
7531 ********************************************************************/
7532
7533BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle,
7534                            const char *formname, uint32 level,
7535			    NEW_BUFFER *buffer, uint32 offered)
7536{
7537        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7538        q_u->level = level;
7539        init_unistr2(&q_u->formname, formname, UNI_STR_TERMINATE);
7540        q_u->buffer=buffer;
7541        q_u->offered=offered;
7542
7543        return True;
7544}
7545
7546/*******************************************************************
7547 * init a structure.
7548 ********************************************************************/
7549
7550BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
7551			      uint32 level, NEW_BUFFER *buffer,
7552			      uint32 offered)
7553{
7554        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7555        q_u->level = level;
7556        q_u->buffer=buffer;
7557        q_u->offered=offered;
7558
7559	return True;
7560}
7561
7562/*******************************************************************
7563 * init a structure.
7564 ********************************************************************/
7565
7566BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle,
7567			   uint32 jobid, uint32 level, uint32 command)
7568{
7569        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7570	q_u->jobid = jobid;
7571        q_u->level = level;
7572
7573	/* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
7574	   the server side code has it marked as unused. */
7575
7576        q_u->command = command;
7577
7578	return True;
7579}
7580
7581/*******************************************************************
7582 * init a structure.
7583 ********************************************************************/
7584
7585BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle,
7586			   uint32 jobid, uint32 level, NEW_BUFFER *buffer,
7587			   uint32 offered)
7588{
7589        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7590        q_u->jobid = jobid;
7591        q_u->level = level;
7592        q_u->buffer = buffer;
7593        q_u->offered = offered;
7594
7595	return True;
7596}
7597
7598/*******************************************************************
7599 * init a structure.
7600 ********************************************************************/
7601
7602BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u,
7603				     POLICY_HND *handle)
7604{
7605        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7606
7607	return True;
7608}
7609
7610/*******************************************************************
7611 * init a structure.
7612 ********************************************************************/
7613
7614BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u,
7615				   POLICY_HND *handle)
7616{
7617        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7618
7619	return True;
7620}
7621
7622/*******************************************************************
7623 * init a structure.
7624 ********************************************************************/
7625
7626BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u,
7627				    POLICY_HND *handle, uint32 level,
7628				    char *docname, char *outputfile,
7629				    char *datatype)
7630{
7631	DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
7632
7633        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7634
7635	ctr->level = level;
7636
7637	switch (level) {
7638	case 1:
7639		ctr->docinfo.switch_value = level;
7640
7641		ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
7642		ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
7643		ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
7644
7645		init_unistr2(&ctr->docinfo.doc_info_1.docname, docname, UNI_STR_TERMINATE);
7646		init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile, UNI_STR_TERMINATE);
7647		init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype, UNI_STR_TERMINATE);
7648
7649		break;
7650	case 2:
7651		/* DOC_INFO_2 is only used by Windows 9x and since it
7652	           doesn't do printing over RPC we don't have to worry
7653  	           about it. */
7654	default:
7655		DEBUG(3, ("unsupported info level %d\n", level));
7656		return False;
7657	}
7658
7659	return True;
7660}
7661
7662/*******************************************************************
7663 * init a structure.
7664 ********************************************************************/
7665
7666BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u,
7667				  POLICY_HND *handle)
7668{
7669        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7670
7671	return True;
7672}
7673
7674/*******************************************************************
7675 * init a structure.
7676 ********************************************************************/
7677
7678BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u,
7679				 POLICY_HND *handle, uint32 data_size,
7680				 char *data)
7681{
7682        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7683	q_u->buffer_size = q_u->buffer_size2 = data_size;
7684	q_u->buffer = (unsigned char *)data;
7685	return True;
7686}
7687
7688/*******************************************************************
7689 * init a structure.
7690 ********************************************************************/
7691
7692BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u,
7693				 POLICY_HND *handle, char *valuename)
7694{
7695        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7696	init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
7697
7698	return True;
7699}
7700
7701/*******************************************************************
7702 * init a structure.
7703 ********************************************************************/
7704
7705BOOL make_spoolss_q_deleteprinterdataex(SPOOL_Q_DELETEPRINTERDATAEX *q_u,
7706					POLICY_HND *handle, char *key,
7707					char *value)
7708{
7709        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7710	init_unistr2(&q_u->valuename, value, UNI_STR_TERMINATE);
7711	init_unistr2(&q_u->keyname, key, UNI_STR_TERMINATE);
7712
7713	return True;
7714}
7715
7716/*******************************************************************
7717 * init a structure.
7718 ********************************************************************/
7719
7720BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
7721			     uint32 flags, uint32 options, const char *localmachine,
7722			     uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
7723{
7724        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7725
7726	q_u->flags = flags;
7727	q_u->options = options;
7728
7729	q_u->localmachine_ptr = 1;
7730
7731	init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
7732
7733	q_u->printerlocal = printerlocal;
7734
7735	if (option)
7736		q_u->option_ptr = 1;
7737
7738	q_u->option = option;
7739
7740	return True;
7741}
7742