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