Decode info level 3 for getprinterdriver.
[samba.git] / source / python / py_spoolss_drivers.c
1 /* 
2    Python wrappers for DCERPC/SMB client routines.
3
4    Copyright (C) Tim Potter, 2002
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "python/py_spoolss.h"
22
23 /* Enumerate printer drivers */
24
25 PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args,
26                                      PyObject *kw)
27 {
28         WERROR werror;
29         PyObject *result = NULL, *creds = NULL;
30         PRINTER_DRIVER_CTR ctr;
31         int level = 1, i;
32         uint32 needed, num_drivers;
33         char *arch = "Windows NT x86", *server, *errstr;
34         static char *kwlist[] = {"server", "level", "creds", "arch", NULL};
35         struct cli_state *cli = NULL;
36         TALLOC_CTX *mem_ctx = NULL;
37         
38         /* Parse parameters */
39
40         if (!PyArg_ParseTupleAndKeywords(
41                     args, kw, "s|iO!s", kwlist, &server, &level, &PyDict_Type,
42                     &creds, &arch))
43                 return NULL;
44         
45         /* Call rpc function */
46         
47         if (!(cli = open_pipe_creds(
48                       server, creds, cli_spoolss_initialise, &errstr))) {
49                 PyErr_SetString(spoolss_error, errstr);
50                 free(errstr);
51                 goto done;
52         }
53
54         if (!(mem_ctx = talloc_init())) {
55                 PyErr_SetString(
56                         spoolss_error, "unable to init talloc context\n");
57                 goto done;
58         }       
59
60         werror = cli_spoolss_enumprinterdrivers(
61                 cli, mem_ctx, 0, &needed, level, arch,
62                 &num_drivers, &ctr);
63
64         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
65                 werror = cli_spoolss_enumprinterdrivers(
66                         cli, mem_ctx, needed, NULL, level, arch, 
67                         &num_drivers, &ctr);
68
69         if (!W_ERROR_IS_OK(werror)) {
70                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
71                 goto done;
72         }
73
74         /* Return value */
75
76         switch (level) {
77         case 1:
78                 result = PyDict_New();
79                 
80                 for (i = 0; i < num_drivers; i++) {
81                         PyObject *value;
82                         fstring name;
83                         
84                         rpcstr_pull(name, ctr.info1[i].name.buffer,
85                                     sizeof(fstring), -1, STR_TERMINATE);
86
87                         py_from_DRIVER_INFO_1(&value, &ctr.info1[i]);
88
89                         PyDict_SetItemString(
90                                 value, "level", PyInt_FromLong(1));
91
92                         PyDict_SetItemString(result, name, value);
93                 }
94                 
95                 break;
96         case 2: 
97                 result = PyDict_New();
98
99                 for(i = 0; i < num_drivers; i++) {
100                         PyObject *value;
101                         fstring name;
102
103                         rpcstr_pull(name, ctr.info2[i].name.buffer,
104                                     sizeof(fstring), -1, STR_TERMINATE);
105
106                         py_from_DRIVER_INFO_2(&value, &ctr.info2[i]);
107
108                         PyDict_SetItemString(
109                                 value, "level", PyInt_FromLong(2));
110
111                         PyDict_SetItemString(result, name, value);
112                 }
113
114                 break;
115         case 3: 
116                 result = PyDict_New();
117
118                 for(i = 0; i < num_drivers; i++) {
119                         PyObject *value;
120                         fstring name;
121
122                         rpcstr_pull(name, ctr.info3[i].name.buffer,
123                                     sizeof(fstring), -1, STR_TERMINATE);
124
125                         py_from_DRIVER_INFO_3(&value, &ctr.info3[i]);
126
127                         PyDict_SetItemString(
128                                 value, "level", PyInt_FromLong(3));
129
130                         PyDict_SetItemString(result, name, value);
131                 }
132
133                 break;
134         case 6: 
135                 result = PyDict_New();
136
137                 for(i = 0; i < num_drivers; i++) {
138                         PyObject *value;
139                         fstring name;
140
141                         rpcstr_pull(name, ctr.info6[i].name.buffer,
142                                     sizeof(fstring), -1, STR_TERMINATE);
143
144                         py_from_DRIVER_INFO_6(&value, &ctr.info6[i]);
145
146                         PyDict_SetItemString(
147                                 value, "level", PyInt_FromLong(6));
148
149                         PyList_SetItem(result, i, value);
150                 }
151
152                 break;
153         default:
154                 PyErr_SetString(spoolss_error, "unknown info level");
155                 goto done;
156         }
157         
158  done:
159         if (cli)
160                 cli_shutdown(cli);
161
162         if (mem_ctx)
163                 talloc_destroy(mem_ctx);
164
165         return result;
166 }
167
168 /* Fetch printer driver */
169
170 PyObject *spoolss_hnd_getprinterdriver(PyObject *self, PyObject *args,
171                                    PyObject *kw)
172 {
173         spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
174         WERROR werror;
175         PyObject *result = Py_None;
176         PRINTER_DRIVER_CTR ctr;
177         int level = 1;
178         uint32 needed;
179         char *arch = "Windows NT x86";
180         static char *kwlist[] = {"level", "arch", NULL};
181
182         /* Parse parameters */
183
184         if (!PyArg_ParseTupleAndKeywords(
185                     args, kw, "|is", kwlist, &level, &arch))
186                 return NULL;
187
188         /* Call rpc function */
189
190         werror = cli_spoolss_getprinterdriver(
191                 hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level,
192                 arch, &ctr);
193
194         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
195                 werror = cli_spoolss_getprinterdriver(
196                         hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
197                         level, arch, &ctr);
198
199         if (!W_ERROR_IS_OK(werror)) {
200                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
201                 return NULL;
202         }
203
204         /* Return value */
205         
206         switch (level) {
207         case 1:
208                 py_from_DRIVER_INFO_1(&result, ctr.info1);
209                 break;
210         case 2: 
211                 py_from_DRIVER_INFO_2(&result, ctr.info2);
212                 break;
213         case 3: 
214                 py_from_DRIVER_INFO_3(&result, ctr.info3);
215                 break;
216         case 6:
217                 py_from_DRIVER_INFO_6(&result,  ctr.info6);
218                 break;
219         default:
220                 PyErr_SetString(spoolss_error, "unsupported info level");
221                 return NULL;
222         }
223         
224         Py_INCREF(result);
225         return result;
226 }
227
228 /* Fetch printer driver directory */
229
230 PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args, 
231                                       PyObject *kw)
232 {
233         WERROR werror;
234         PyObject *result = NULL, *creds = NULL;
235         DRIVER_DIRECTORY_CTR ctr;
236         uint32 needed, level = 1;
237         char *arch = "Windows NT x86", *server, *errstr;
238         static char *kwlist[] = {"server", "level", "arch", "creds", NULL};
239         struct cli_state *cli = NULL;
240         TALLOC_CTX *mem_ctx = NULL;
241
242         /* Parse parameters */
243
244         if (!PyArg_ParseTupleAndKeywords(
245                     args, kw, "s|isO!", kwlist, &server, &level,
246                     &arch, &PyDict_Type, &creds))
247                 return NULL;
248
249         /* Call rpc function */
250
251         if (!(cli = open_pipe_creds(
252                       server, creds, cli_spoolss_initialise, &errstr))) {
253                 PyErr_SetString(spoolss_error, errstr);
254                 free(errstr);
255                 goto done;
256         }
257         
258         if (!(mem_ctx = talloc_init())) {
259                 PyErr_SetString(
260                         spoolss_error, "unable to init talloc context\n");
261                 goto done;
262         }       
263
264         werror = cli_spoolss_getprinterdriverdir(
265                 cli, mem_ctx, 0, &needed, level, arch, &ctr);
266
267         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
268                 werror = cli_spoolss_getprinterdriverdir(
269                         cli, mem_ctx, needed, NULL, level, arch, &ctr);
270
271         if (!W_ERROR_IS_OK(werror)) {
272                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
273                 goto done;
274         }
275
276         /* Return value */
277         
278         switch (level) {
279         case 1:
280                 py_from_DRIVER_DIRECTORY_1(&result, ctr.info1);
281                 PyDict_SetItemString(
282                         result, "level", PyInt_FromLong(1));
283                 break;
284         default:
285                 PyErr_SetString(spoolss_error, "unknown info level");
286                 goto done;      
287         }
288         
289  done:
290         if (cli)
291                 cli_shutdown(cli);
292         
293         if (mem_ctx)
294                 talloc_destroy(mem_ctx);
295
296         return result;
297 }
298
299 PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
300                                    PyObject *kw)
301 {
302         static char *kwlist[] = { "server", "info", "creds", NULL };
303         char *server, *errstr;
304         uint32 level;
305         PyObject *info, *result = NULL, *creds = NULL;
306         WERROR werror;
307         TALLOC_CTX *mem_ctx;
308         struct cli_state *cli;
309         PRINTER_DRIVER_CTR ctr;
310         union {
311                 DRIVER_INFO_3 driver_3;
312         } dinfo;
313
314         if (!PyArg_ParseTupleAndKeywords(
315                     args, kw, "sO!|O!", kwlist, &server, &PyDict_Type,
316                     &info, &PyDict_Type, &creds))
317                 return NULL;
318         
319         if (server[0] == '\\' && server[1] == '\\')
320                 server += 2;
321
322         if (!(mem_ctx = talloc_init())) {
323                 PyErr_SetString(
324                         spoolss_error, "unable to init talloc context\n");
325                 return NULL;
326         }
327
328         if (!(cli = open_pipe_creds(
329                       server, creds, cli_spoolss_initialise, &errstr))) {
330                 PyErr_SetString(spoolss_error, errstr);
331                 free(errstr);
332                 goto done;
333         }
334
335         if (!get_level_value(info, &level)) {
336                 PyErr_SetString(spoolss_error, "invalid info level");
337                 return NULL;
338         }
339
340         if (level != 3) {
341                 PyErr_SetString(spoolss_error, "unsupported info level");
342                 goto done;
343         }
344
345         ZERO_STRUCT(ctr);
346         
347         switch(level) {
348         case 3:
349                 ctr.info3 = &dinfo.driver_3;
350
351                 if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info)) {
352                         PyErr_SetString(spoolss_error,
353                                         "error converting to driver info 3");
354                         goto done;
355                 }
356
357                 break;
358         default:
359                 PyErr_SetString(spoolss_error, "unsupported info level");
360                 goto done;
361         }
362
363         werror = cli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr);
364
365         if (!W_ERROR_IS_OK(werror)) {
366                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
367                 goto done;
368         }
369
370         Py_INCREF(Py_None);
371         result = Py_None;
372
373 done:
374         cli_shutdown(cli);
375         talloc_destroy(mem_ctx);
376         
377         return result;
378         
379 }
380
381 PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
382                                              PyObject *kw)
383 {
384         /* Not supported by Samba server */
385         
386         PyErr_SetString(spoolss_error, "Not implemented");
387         return NULL;
388 }
389         
390 PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
391                                       PyObject *kw)
392 {
393         PyErr_SetString(spoolss_error, "Not implemented");
394         return NULL;
395 }
396
397 PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
398                                         PyObject *kw)
399 {
400         PyErr_SetString(spoolss_error, "Not implemented");
401         return NULL;
402 }