r12558: Support [flag(NULLTERM)] on [charset()] arrays
[samba.git] / source4 / librpc / ndr / ndr_spoolss_buf.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    routines for marshalling/unmarshalling spoolss subcontext buffer structures
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Tim Potter 2003
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24
25 #include "includes.h"
26 #include "librpc/gen_ndr/ndr_spoolss.h"
27
28 #define NDR_SPOOLSS_PUSH_ENUM_IN(fn) do { \
29         if (!r->in.buffer && r->in.offered != 0) {\
30                 return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
31                         "SPOOLSS Buffer: r->in.offered[%u] but there's no buffer",\
32                         (unsigned)r->in.offered);\
33         } else if (r->in.buffer && r->in.buffer->length != r->in.offered) {\
34                 return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
35                         "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of r->in.buffer[%u]",\
36                         (unsigned)r->in.offered, (unsigned)r->in.buffer->length);\
37         }\
38         _r.in.level     = r->in.level;\
39         _r.in.buffer    = r->in.buffer;\
40         _r.in.offered   = r->in.offered;\
41         NDR_CHECK(ndr_push__##fn(ndr, flags, &_r));\
42 } while(0)
43
44 #define NDR_SPOOLSS_PUSH_ENUM_OUT(fn) do { \
45         struct ndr_push *_ndr_info;\
46         _r.in.level     = r->in.level;\
47         _r.in.buffer    = r->in.buffer;\
48         _r.in.offered   = r->in.offered;\
49         _r.out.info     = NULL;\
50         _r.out.needed   = r->out.needed;\
51         _r.out.count    = r->out.count;\
52         _r.out.result   = r->out.result;\
53         if (r->out.info && !r->in.buffer) {\
54                 return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
55                         "SPOOLSS Buffer: r->out.info but there's no r->in.buffer");\
56         }\
57         if (r->in.buffer) {\
58                 DATA_BLOB _data_blob_info;\
59                 _ndr_info = ndr_push_init_ctx(ndr);\
60                 if (!_ndr_info) return NT_STATUS_NO_MEMORY;\
61                 _ndr_info->flags= ndr->flags;\
62                 if (r->out.info) {\
63                         struct __##fn __r;\
64                         __r.in.level    = r->in.level;\
65                         __r.in.count    = r->out.count;\
66                         __r.out.info    = r->out.info;\
67                         NDR_CHECK(ndr_push___##fn(_ndr_info, flags, &__r)); \
68                 }\
69                 if (r->in.offered > _ndr_info->offset) {\
70                         uint32_t _padding_len = r->in.offered - _ndr_info->offset;\
71                         NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len));\
72                 } else if (r->in.offered < _ndr_info->offset) {\
73                         return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
74                                 "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of out buffer[%u]!",\
75                                 (unsigned)r->in.offered, (unsigned)_ndr_info->offset);\
76                 }\
77                 _data_blob_info = ndr_push_blob(_ndr_info);\
78                 _r.out.info     = &_data_blob_info;\
79         }\
80         NDR_CHECK(ndr_push__##fn(ndr, flags, &_r));\
81 } while(0)
82
83 #define NDR_SPOOLSS_PUSH_ENUM(fn,in,out) do { \
84         struct _##fn _r;\
85         if (flags & NDR_IN) {\
86                 in;\
87                 NDR_SPOOLSS_PUSH_ENUM_IN(fn);\
88         }\
89         if (flags & NDR_OUT) {\
90                 out;\
91                 NDR_SPOOLSS_PUSH_ENUM_OUT(fn);\
92         }\
93 } while(0)
94
95 #define NDR_SPOOLSS_PULL_ENUM_IN(fn) do { \
96         ZERO_STRUCT(r->out);\
97         NDR_CHECK(ndr_pull__##fn(ndr, flags, &_r));\
98         r->in.level     = _r.in.level;\
99         r->in.buffer    = _r.in.buffer;\
100         r->in.offered   = _r.in.offered;\
101         r->out.needed   = _r.out.needed;\
102         if (!r->in.buffer && r->in.offered != 0) {\
103                 return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
104                         "SPOOLSS Buffer: r->in.offered[%u] but there's no buffer",\
105                         r->in.offered);\
106         } else if (r->in.buffer && r->in.buffer->length != r->in.offered) {\
107                 return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
108                         "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of r->in.buffer[%u]",\
109                         r->in.offered, r->in.buffer->length);\
110         }\
111 } while(0)
112
113 #define NDR_SPOOLSS_PULL_ENUM_OUT(fn) do { \
114         _r.in.level     = r->in.level;\
115         _r.in.buffer    = r->in.buffer;\
116         _r.in.offered   = r->in.offered;\
117         _r.out.needed   = r->out.needed;\
118         NDR_CHECK(ndr_pull__##fn(ndr, flags, &_r));\
119         r->out.info     = NULL;\
120         r->out.needed   = _r.out.needed;\
121         r->out.count    = _r.out.count;\
122         r->out.result   = _r.out.result;\
123         if (_r.out.info) {\
124                 struct ndr_pull *_ndr_info = ndr_pull_init_blob(_r.out.info, ndr);\
125                 if (!_ndr_info) return NT_STATUS_NO_MEMORY;\
126                 _ndr_info->flags= ndr->flags;\
127                 if (r->in.offered != _ndr_info->data_size) {\
128                         return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
129                                 "SPOOLSS Buffer: offered[%u] doesn't match length of buffer[%u]",\
130                                 r->in.offered, (unsigned)_ndr_info->data_size);\
131                 }\
132                 if (r->out.needed <= _ndr_info->data_size) {\
133                         struct __##fn __r;\
134                         __r.in.level    = r->in.level;\
135                         __r.in.count    = r->out.count;\
136                         __r.out.info    = NULL;\
137                         NDR_CHECK(ndr_pull___##fn(_ndr_info, flags, &__r));\
138                         r->out.info     = __r.out.info;\
139                 }\
140         }\
141 } while(0)
142
143 #define NDR_SPOOLSS_PULL_ENUM(fn,in,out) do { \
144         struct _##fn _r;\
145         if (flags & NDR_IN) {\
146                 out;\
147                 NDR_SPOOLSS_PULL_ENUM_IN(fn);\
148                 in;\
149         }\
150         if (flags & NDR_OUT) {\
151                 out;\
152                 NDR_SPOOLSS_PULL_ENUM_OUT(fn);\
153         }\
154 } while(0)
155
156 #define _NDR_CHECK_UINT32(call) do {\
157         NTSTATUS _status; \
158         _status = call; \
159         if (!NT_STATUS_IS_OK(_status)) {\
160                 return 0; \
161         }\
162 } while (0)
163
164 /* TODO: set _ndr_info->flags correct */
165 #define NDR_SPOOLSS_SIZE_ENUM(fn) do { \
166         struct __##fn __r;\
167         DATA_BLOB _data_blob_info;\
168         struct ndr_push *_ndr_info = ndr_push_init_ctx(mem_ctx);\
169         if (!_ndr_info) return 0;\
170         _ndr_info->flags|=0;\
171         __r.in.level    = level;\
172         __r.in.count    = count;\
173         __r.out.info    = info;\
174         _NDR_CHECK_UINT32(ndr_push___##fn(_ndr_info, NDR_OUT, &__r)); \
175         _data_blob_info = ndr_push_blob(_ndr_info);\
176         return _data_blob_info.length;\
177 } while(0)
178
179 /*
180   spoolss_EnumPrinters
181 */
182 NTSTATUS ndr_push_spoolss_EnumPrinters(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinters *r)
183 {
184         NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPrinters,{
185                 _r.in.flags     = r->in.flags;
186                 _r.in.server    = r->in.server;
187         },{
188                 _r.in.flags     = r->in.flags;
189                 _r.in.server    = r->in.server;
190         });
191         return NT_STATUS_OK;
192 }
193
194 NTSTATUS ndr_pull_spoolss_EnumPrinters(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinters *r)
195 {
196         NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPrinters,{
197                 r->in.flags     = _r.in.flags;
198                 r->in.server    = _r.in.server;
199         },{
200                 _r.in.flags     = r->in.flags;
201                 _r.in.server    = r->in.server;
202         });
203         return NT_STATUS_OK;
204 }
205
206 uint32_t ndr_size_spoolss_EnumPrinters_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_PrinterInfo *info)
207 {
208         NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrinters);
209 }
210
211 /*
212   spoolss_EnumJobs
213 */
214 NTSTATUS ndr_push_spoolss_EnumJobs(struct ndr_push *ndr, int flags, const struct spoolss_EnumJobs *r)
215 {
216         NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumJobs,{
217                 _r.in.handle    = r->in.handle;
218                 _r.in.firstjob  = r->in.firstjob;
219                 _r.in.numjobs   = r->in.numjobs;
220         },{
221                 _r.in.handle    = r->in.handle;
222                 _r.in.firstjob  = r->in.firstjob;
223                 _r.in.numjobs   = r->in.numjobs;
224         });
225         return NT_STATUS_OK;
226 }
227
228 NTSTATUS ndr_pull_spoolss_EnumJobs(struct ndr_pull *ndr, int flags, struct spoolss_EnumJobs *r)
229 {
230         NDR_SPOOLSS_PULL_ENUM(spoolss_EnumJobs,{
231                 r->in.handle    = _r.in.handle;
232                 r->in.firstjob  = _r.in.firstjob;
233                 r->in.numjobs   = _r.in.numjobs;
234         },{
235                 _r.in.handle    = r->in.handle;
236                 _r.in.firstjob  = r->in.firstjob;
237                 _r.in.numjobs   = r->in.numjobs;
238         });
239         return NT_STATUS_OK;
240 }
241
242 uint32_t ndr_size_spoolss_EnumJobss_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_JobInfo *info)
243 {
244         NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumJobs);
245 }
246
247 /*
248   spoolss_EnumPrinterDrivers
249 */
250 NTSTATUS ndr_push_spoolss_EnumPrinterDrivers(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterDrivers *r)
251 {
252         NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPrinterDrivers,{
253                 _r.in.server            = r->in.server;
254                 _r.in.environment       = r->in.environment;
255         },{
256                 _r.in.server            = r->in.server;
257                 _r.in.environment       = r->in.environment;
258         });
259         return NT_STATUS_OK;
260 }
261
262 NTSTATUS ndr_pull_spoolss_EnumPrinterDrivers(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDrivers *r)
263 {
264         NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPrinterDrivers,{
265                 r->in.server            = _r.in.server;
266                 r->in.environment       = _r.in.environment;
267         },{
268                 _r.in.server            = r->in.server;
269                 _r.in.environment       = r->in.environment;
270         });
271         return NT_STATUS_OK;
272 }
273
274 uint32_t ndr_size_spoolss_EnumPrinterDrivers_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_DriverInfo *info)
275 {
276         NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrinterDrivers);
277 }
278
279 /*
280   spoolss_EnumForms
281 */
282 NTSTATUS ndr_push_spoolss_EnumForms(struct ndr_push *ndr, int flags, const struct spoolss_EnumForms *r)
283 {
284         NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumForms,{
285                 _r.in.handle    = r->in.handle;
286         },{
287                 _r.in.handle    = r->in.handle;
288         });
289         return NT_STATUS_OK;
290 }
291
292 NTSTATUS ndr_pull_spoolss_EnumForms(struct ndr_pull *ndr, int flags, struct spoolss_EnumForms *r)
293 {
294         NDR_SPOOLSS_PULL_ENUM(spoolss_EnumForms,{
295                 r->in.handle    = _r.in.handle;
296         },{
297                 _r.in.handle    = r->in.handle;
298         });
299         return NT_STATUS_OK;
300 }
301
302 uint32_t ndr_size_spoolss_EnumForms_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_FormInfo *info)
303 {
304         NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumForms);
305 }
306
307 /*
308   spoolss_EnumPorts
309 */
310 NTSTATUS ndr_push_spoolss_EnumPorts(struct ndr_push *ndr, int flags, const struct spoolss_EnumPorts *r)
311 {
312         NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPorts,{
313                 _r.in.servername= r->in.servername;
314         },{
315                 _r.in.servername= r->in.servername;
316         });
317         return NT_STATUS_OK;
318 }
319
320 NTSTATUS ndr_pull_spoolss_EnumPorts(struct ndr_pull *ndr, int flags, struct spoolss_EnumPorts *r)
321 {
322         NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPorts,{
323                 r->in.servername= _r.in.servername;
324         },{
325                 _r.in.servername= r->in.servername;
326         });
327         return NT_STATUS_OK;
328 }
329
330 uint32_t ndr_size_spoolss_EnumPorts_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_PortInfo *info)
331 {
332         NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPorts);
333 }
334
335 /*
336   spoolss_EnumMonitors
337 */
338 NTSTATUS ndr_push_spoolss_EnumMonitors(struct ndr_push *ndr, int flags, const struct spoolss_EnumMonitors *r)
339 {
340         NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumMonitors,{
341                 _r.in.servername= r->in.servername;
342         },{
343                 _r.in.servername= r->in.servername;
344         });
345         return NT_STATUS_OK;
346 }
347
348 NTSTATUS ndr_pull_spoolss_EnumMonitors(struct ndr_pull *ndr, int flags, struct spoolss_EnumMonitors *r)
349 {
350         NDR_SPOOLSS_PULL_ENUM(spoolss_EnumMonitors,{
351                 r->in.servername= _r.in.servername;
352         },{
353                 _r.in.servername= r->in.servername;
354         });
355         return NT_STATUS_OK;
356 }
357
358 uint32_t ndr_size_spoolss_EnumMonitors_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_MonitorInfo *info)
359 {
360         NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumMonitors);
361 }
362
363 /*
364   spoolss_EnumPrintProcessors
365 */
366 NTSTATUS ndr_push_spoolss_EnumPrintProcessors(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrintProcessors *r)
367 {
368         NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPrintProcessors,{
369                 _r.in.servername        = r->in.servername;
370                 _r.in.environment       = r->in.environment;
371         },{
372                 _r.in.servername        = r->in.servername;
373                 _r.in.environment       = r->in.environment;
374         });
375         return NT_STATUS_OK;
376 }
377
378 NTSTATUS ndr_pull_spoolss_EnumPrintProcessors(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrintProcessors *r)
379 {
380         NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPrintProcessors,{
381                 r->in.servername        = _r.in.servername;
382                 r->in.environment       = _r.in.environment;
383         },{
384                 _r.in.servername        = r->in.servername;
385                 _r.in.environment       = r->in.environment;
386         });
387         return NT_STATUS_OK;
388 }
389
390 uint32_t ndr_size_spoolss_EnumPrinterProcessors_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_PrintProcessorInfo *info)
391 {
392         NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrintProcessors);
393 }
394
395 /*
396   spoolss_GetPrinterData
397 */
398 NTSTATUS ndr_push_spoolss_GetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_GetPrinterData *r)
399 {
400         struct _spoolss_GetPrinterData _r;
401         if (flags & NDR_IN) {
402                 _r.in.handle    = r->in.handle;
403                 _r.in.value_name= r->in.value_name;
404                 _r.in.offered   = r->in.offered;
405                 NDR_CHECK(ndr_push__spoolss_GetPrinterData(ndr, flags, &_r));
406         }
407         if (flags & NDR_OUT) {
408                 struct ndr_push *_ndr_info;\
409                 _r.in.handle    = r->in.handle;
410                 _r.in.value_name= r->in.value_name;
411                 _r.in.offered   = r->in.offered;
412                 _r.out.type     = r->out.type;
413                 _r.out.data     = data_blob(NULL, 0);
414                 _r.out.needed   = r->out.needed;
415                 _r.out.result   = r->out.result;
416                 {
417                         struct __spoolss_GetPrinterData __r;
418                         _ndr_info = ndr_push_init_ctx(ndr);
419                         if (!_ndr_info) return NT_STATUS_NO_MEMORY;
420                         _ndr_info->flags= ndr->flags;
421                         __r.in.type     = r->out.type;
422                         __r.out.data    = r->out.data;
423                         NDR_CHECK(ndr_push___spoolss_GetPrinterData(_ndr_info, flags, &__r));
424                         if (r->in.offered > _ndr_info->offset) {
425                                 uint32_t _padding_len = r->in.offered - _ndr_info->offset;
426                                 NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len));
427                         }
428                         _r.out.data = ndr_push_blob(_ndr_info);
429                 }
430                 NDR_CHECK(ndr_push__spoolss_GetPrinterData(ndr, flags, &_r));
431         }
432         return NT_STATUS_OK;
433 }
434
435 NTSTATUS ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flags, struct spoolss_GetPrinterData *r)
436 {
437         struct _spoolss_GetPrinterData _r;
438         if (flags & NDR_IN) {
439                 ZERO_STRUCT(r->out);
440
441                 _r.in.handle    = r->in.handle;
442                 _r.in.value_name= r->in.value_name;
443                 _r.in.offered   = r->in.offered;
444                 _r.out.type     = r->out.type;
445                 _r.out.data     = data_blob(NULL,0),
446                 _r.out.needed   = r->out.needed;
447                 NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r));
448                 r->in.handle    = _r.in.handle;
449                 r->in.value_name= _r.in.value_name;
450                 r->in.offered   = _r.in.offered;
451                 r->out.needed   = _r.out.needed;
452         }
453         if (flags & NDR_OUT) {
454                 _r.in.handle    = r->in.handle;
455                 _r.in.value_name= r->in.value_name;
456                 _r.in.offered   = r->in.offered;
457                 _r.out.type     = r->out.type;
458                 _r.out.data     = data_blob(NULL,0),
459                 _r.out.needed   = r->out.needed;
460                 _r.out.result   = r->out.result;
461                 NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r));
462                 r->out.type     = _r.out.type;
463                 ZERO_STRUCT(r->out.data);
464                 r->out.needed   = _r.out.needed;
465                 r->out.result   = _r.out.result;
466                 if (_r.out.data.length != r->in.offered) {
467                         return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
468                                 "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of out buffer[%u]",\
469                                 (unsigned)r->in.offered, (unsigned)_r.out.data.length);\
470                 }
471                 if (_r.out.data.length > 0 && r->out.needed <= _r.out.data.length) {
472                         struct __spoolss_GetPrinterData __r;
473                         struct ndr_pull *_ndr_data = ndr_pull_init_blob(&_r.out.data, ndr);
474                         if (!_ndr_data) return NT_STATUS_NO_MEMORY;
475                         _ndr_data->flags= ndr->flags;
476                         __r.in.type     = r->out.type;
477                         __r.out.data    = r->out.data;
478                         NDR_CHECK(ndr_pull___spoolss_GetPrinterData(_ndr_data, flags, &__r));
479                         r->out.data     = __r.out.data;
480                 } else {
481                         r->out.type     = SPOOLSS_PRINTER_DATA_TYPE_NULL;
482                 }
483         }
484         return NT_STATUS_OK;
485 }
486
487 /*
488   spoolss_SetPrinterData
489 */
490 NTSTATUS ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r)
491 {
492         struct _spoolss_SetPrinterData _r;
493         if (flags & NDR_IN) {
494                 struct ndr_push *_ndr_data;
495                 struct __spoolss_SetPrinterData __r;
496                 DATA_BLOB _data_blob_data;
497
498                 _ndr_data = ndr_push_init_ctx(ndr);\
499                 if (!_ndr_data) return NT_STATUS_NO_MEMORY;\
500                 _ndr_data->flags= ndr->flags;\
501
502                 __r.in.type     = r->in.type;
503                 __r.out.data    = r->in.data;
504                 NDR_CHECK(ndr_push___spoolss_SetPrinterData(_ndr_data, NDR_OUT, &__r));
505                 _data_blob_data = ndr_push_blob(_ndr_data);
506
507                 _r.in.handle    = r->in.handle;
508                 _r.in.value_name= r->in.value_name;
509                 _r.in.type      = r->in.type;
510                 _r.in.data      = _data_blob_data;
511                 _r.in._offered  = _data_blob_data.length;
512                 _r.out.result   = r->out.result;
513                 NDR_CHECK(ndr_push__spoolss_SetPrinterData(ndr, flags, &_r));
514         }
515         if (flags & NDR_OUT) {
516                 _r.in.handle    = r->in.handle;
517                 _r.in.value_name= r->in.value_name;
518                 _r.in.type      = r->in.type;
519                 _r.in.data      = data_blob(NULL,0),
520                 _r.in._offered  = r->in._offered;
521                 _r.out.result   = r->out.result;
522                 NDR_CHECK(ndr_push__spoolss_SetPrinterData(ndr, flags, &_r));
523         }
524         return NT_STATUS_OK;
525 }
526
527 uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, uint32_t flags)
528 {
529         if (!devmode) return 0;
530         return ndr_size_spoolss_DeviceMode(devmode,flags);
531 }