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