]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - setup/win32/msi/msiquery.c
ok
[xonotic/netradiant.git] / setup / win32 / msi / msiquery.c
1 /*\r
2 Copyright (C) 2001-2006 William Joseph.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 #include "Python.h"
23 #include "structmember.h"
24
25 #include <windows.h>
26 #include <msi.h>
27 #include <msiquery.h>
28 \r
29 typedef struct {\r
30   PyObject_HEAD\r
31   MSIHANDLE handle;\r
32 } MsiRecord;\r
33 \r
34 static void\r
35 MsiRecord_dealloc(MsiRecord* self)\r
36 {\r
37   if(self->handle != 0)\r
38   {\r
39     unsigned int result = MsiCloseHandle(self->handle);\r
40   }\r
41   self->ob_type->tp_free((PyObject*)self);\r
42 }\r
43 \r
44 static PyObject *\r
45 MsiRecord_new(PyTypeObject *type, PyObject *args)\r
46 {\r
47   MsiRecord *self;\r
48 \r
49   self = (MsiRecord *)type->tp_alloc(type, 0);\r
50   if (self != NULL)\r
51   {\r
52     self->handle = 0;\r
53   }\r
54 \r
55   return (PyObject *)self;\r
56 }\r
57 \r
58 static int\r
59 MsiRecord_init(MsiRecord *self, PyObject *args)\r
60 {\r
61   return 0;\r
62 }\r
63 \r
64 static PyMemberDef MsiRecord_members[] = {\r
65     {NULL}  /* Sentinel */\r
66 };\r
67 \r
68 static PyObject *\r
69 MsiRecord_getstring(MsiRecord* self, PyObject *args)\r
70 {\r
71   char string[16384];\r
72   DWORD size = 16384;\r
73   int index;\r
74   unsigned int result = 1;\r
75   if (!PyArg_ParseTuple(args, "i", &index))\r
76   {\r
77     return NULL;\r
78   }\r
79   if(self->handle != 0)\r
80   {\r
81     if(MsiRecordIsNull(self->handle, index))\r
82     {\r
83       puts("null record index");\r
84     }\r
85     result = MsiRecordGetString(self->handle, index, string, &size);\r
86     printf("string: %s, index: %i\n", string, index);\r
87     if(result != 0)\r
88     {\r
89       strcpy(string, "bleh");\r
90     }\r
91   }\r
92   return PyString_FromString(string);\r
93 }\r
94 \r
95 static PyObject *\r
96 MsiRecord_setstring(MsiRecord* self, PyObject *args)\r
97 {\r
98   char* string;\r
99   int index;\r
100   unsigned int result = 1;\r
101   if (!PyArg_ParseTuple(args, "is", &index, &string))\r
102   {\r
103     return NULL;\r
104   }\r
105   if(self->handle != 0)\r
106   {\r
107     result = MsiRecordSetString(self->handle, index, string);\r
108   }\r
109   return Py_BuildValue("i", result);\r
110 }\r
111 \r
112 static PyMethodDef MsiRecord_methods[] = {\r
113     {"getstring", (PyCFunction)MsiRecord_getstring, METH_VARARGS,\r
114      "MsiRecordGetString"\r
115     },\r
116     {"setstring", (PyCFunction)MsiRecord_setstring, METH_VARARGS,\r
117      "MsiRecordSetString"\r
118     },\r
119     {NULL}  /* Sentinel */\r
120 };\r
121 \r
122 static PyTypeObject MsiRecordType = {\r
123     PyObject_HEAD_INIT(NULL)\r
124     0,                         /*ob_size*/\r
125     "msiquery.MsiRecord",             /*tp_name*/\r
126     sizeof(MsiRecord),             /*tp_basicsize*/\r
127     0,                         /*tp_itemsize*/\r
128     (destructor)MsiRecord_dealloc, /*tp_dealloc*/\r
129     0,                         /*tp_print*/\r
130     0,                         /*tp_getattr*/\r
131     0,                         /*tp_setattr*/\r
132     0,                         /*tp_compare*/\r
133     0,                         /*tp_repr*/\r
134     0,                         /*tp_as_number*/\r
135     0,                         /*tp_as_sequence*/\r
136     0,                         /*tp_as_mapping*/\r
137     0,                         /*tp_hash */\r
138     0,                         /*tp_call*/\r
139     0,                         /*tp_str*/\r
140     0,                         /*tp_getattro*/\r
141     0,                         /*tp_setattro*/\r
142     0,                         /*tp_as_buffer*/\r
143     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/\r
144     "MsiRecord objects",           /* tp_doc */\r
145     0,                         /* tp_traverse */\r
146     0,                         /* tp_clear */\r
147     0,                         /* tp_richcompare */\r
148     0,                         /* tp_weaklistoffset */\r
149     0,                         /* tp_iter */\r
150     0,                         /* tp_iternext */\r
151     MsiRecord_methods,             /* tp_methods */\r
152     MsiRecord_members,             /* tp_members */\r
153     0,                         /* tp_getset */\r
154     0,                         /* tp_base */\r
155     0,                         /* tp_dict */\r
156     0,                         /* tp_descr_get */\r
157     0,                         /* tp_descr_set */\r
158     0,                         /* tp_dictoffset */\r
159     (initproc)MsiRecord_init,      /* tp_init */\r
160     0,                         /* tp_alloc */\r
161     (newfunc)MsiRecord_new,                 /* tp_new */\r
162 };\r
163 \r
164 PyObject*\r
165 MsiRecord_FromHandle(MSIHANDLE handle)\r
166 {\r
167   MsiRecord *record = (MsiRecord *)MsiRecordType.tp_new(&MsiRecordType, NULL, NULL);\r
168   record->handle = handle;\r
169   return (PyObject*)record;\r
170 }\r
171 \r
172 \r
173 typedef struct {\r
174   PyObject_HEAD\r
175   MSIHANDLE handle;\r
176 } MsiView;\r
177 \r
178 static void\r
179 MsiView_dealloc(MsiView* self)\r
180 {\r
181   if(self->handle != 0)\r
182   {\r
183     unsigned int result;\r
184     result = MsiViewClose(self->handle);\r
185     result = MsiCloseHandle(self->handle);\r
186   }\r
187   self->ob_type->tp_free((PyObject*)self);\r
188 }\r
189 \r
190 static PyObject *\r
191 MsiView_new(PyTypeObject *type, PyObject *args)\r
192 {\r
193   MsiView *self;\r
194 \r
195   self = (MsiView *)type->tp_alloc(type, 0);\r
196   if (self != NULL)\r
197   {\r
198     self->handle = 0;\r
199   }\r
200 \r
201   return (PyObject *)self;\r
202 }\r
203 \r
204 static int\r
205 MsiView_init(MsiView *self)\r
206 {\r
207   return 0;\r
208 }\r
209 \r
210 static PyMemberDef MsiView_members[] = {\r
211     {NULL}  /* Sentinel */\r
212 };\r
213 \r
214 static PyObject *\r
215 MsiView_fetch(MsiView* self)\r
216 {\r
217   unsigned int result = 1;\r
218   MSIHANDLE record;\r
219   result = MsiViewFetch(self->handle, &record);\r
220   if(result == 0)\r
221   {\r
222     return MsiRecord_FromHandle(record);\r
223   }\r
224   else\r
225   {\r
226     Py_INCREF(Py_None);\r
227     return Py_None;\r
228   }\r
229 }\r
230 \r
231 static PyObject *\r
232 MsiView_update(MsiView* self, PyObject *args)\r
233 {\r
234   unsigned int result = 1;\r
235   MsiRecord *record;\r
236   if(!PyArg_ParseTuple(args, "O!", &MsiRecordType, &record))\r
237   {\r
238     return NULL;\r
239   }\r
240   result = MsiViewModify(self->handle, MSIMODIFY_UPDATE, record->handle);\r
241   return Py_BuildValue("i", result);\r
242 }\r
243 \r
244 static PyMethodDef MsiView_methods[] = {\r
245     {"fetch", (PyCFunction)MsiView_fetch, METH_NOARGS,\r
246      "MsiViewFetch"\r
247     },\r
248     {"update", (PyCFunction)MsiView_update, METH_VARARGS,\r
249      "MsiViewModify(UPDATE)"\r
250     },\r
251     {NULL}  /* Sentinel */\r
252 };\r
253 \r
254 static PyTypeObject MsiViewType = {\r
255     PyObject_HEAD_INIT(NULL)\r
256     0,                         /*ob_size*/\r
257     "msiquery.MsiView",             /*tp_name*/\r
258     sizeof(MsiView),             /*tp_basicsize*/\r
259     0,                         /*tp_itemsize*/\r
260     (destructor)MsiView_dealloc, /*tp_dealloc*/\r
261     0,                         /*tp_print*/\r
262     0,                         /*tp_getattr*/\r
263     0,                         /*tp_setattr*/\r
264     0,                         /*tp_compare*/\r
265     0,                         /*tp_repr*/\r
266     0,                         /*tp_as_number*/\r
267     0,                         /*tp_as_sequence*/\r
268     0,                         /*tp_as_mapping*/\r
269     0,                         /*tp_hash */\r
270     0,                         /*tp_call*/\r
271     0,                         /*tp_str*/\r
272     0,                         /*tp_getattro*/\r
273     0,                         /*tp_setattro*/\r
274     0,                         /*tp_as_buffer*/\r
275     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/\r
276     "MsiView objects",           /* tp_doc */\r
277     0,                         /* tp_traverse */\r
278     0,                         /* tp_clear */\r
279     0,                         /* tp_richcompare */\r
280     0,                         /* tp_weaklistoffset */\r
281     0,                         /* tp_iter */\r
282     0,                         /* tp_iternext */\r
283     MsiView_methods,             /* tp_methods */\r
284     MsiView_members,             /* tp_members */\r
285     0,                         /* tp_getset */\r
286     0,                         /* tp_base */\r
287     0,                         /* tp_dict */\r
288     0,                         /* tp_descr_get */\r
289     0,                         /* tp_descr_set */\r
290     0,                         /* tp_dictoffset */\r
291     (initproc)MsiView_init,      /* tp_init */\r
292     0,                         /* tp_alloc */\r
293     (newfunc)MsiView_new,                 /* tp_new */\r
294 };\r
295 \r
296 PyObject*\r
297 MsiView_FromHandle(MSIHANDLE handle)\r
298 {\r
299   MsiView *view = (MsiView *)MsiViewType.tp_new(&MsiViewType, NULL, NULL);\r
300   view->handle = handle;\r
301   MsiViewExecute(handle, 0);\r
302   return (PyObject*)view;\r
303 }\r
304 \r
305 \r
306 typedef struct {\r
307   PyObject_HEAD\r
308   MSIHANDLE handle;\r
309 } MsiDB;\r
310 \r
311 static void\r
312 MsiDB_dealloc(MsiDB* self)\r
313 {\r
314   if(self->handle != 0)\r
315   {\r
316     unsigned int result = MsiCloseHandle(self->handle);\r
317   }\r
318   self->ob_type->tp_free((PyObject*)self);\r
319 }\r
320 \r
321 static PyObject *\r
322 MsiDB_new(PyTypeObject *type, PyObject *args)\r
323 {\r
324   MsiDB *self;\r
325 \r
326   self = (MsiDB *)type->tp_alloc(type, 0);\r
327   if (self != NULL)\r
328   {\r
329     self->handle = 0;\r
330   }\r
331 \r
332   return (PyObject *)self;\r
333 }\r
334 \r
335 static int\r
336 MsiDB_init(MsiDB *self, PyObject *args)\r
337 {\r
338   char* filename;\r
339   if(!PyArg_ParseTuple(args, "s", &filename))\r
340   {\r
341     return -1;\r
342   }\r
343 \r
344   MsiOpenDatabase(filename, MSIDBOPEN_TRANSACT, &self->handle);\r
345 \r
346   return 0;\r
347 }\r
348 \r
349 static PyMemberDef MsiDB_members[] = {\r
350     {NULL}  /* Sentinel */\r
351 };\r
352 \r
353 static PyObject *\r
354 MsiDB_openview(MsiDB* self, PyObject *args)\r
355 {\r
356   char* query;\r
357   unsigned int result = 1;\r
358   if (!PyArg_ParseTuple(args, "s", &query))\r
359   {\r
360     return NULL;\r
361   }\r
362   if(self->handle != 0)\r
363   {\r
364     MSIHANDLE view;\r
365     result = MsiDatabaseOpenView(self->handle, query, &view);\r
366     if(result == ERROR_SUCCESS)\r
367     {\r
368       return MsiView_FromHandle(view);\r
369     }\r
370   }\r
371   Py_INCREF(Py_None);\r
372   return Py_None;\r
373 }\r
374 \r
375 static PyObject *\r
376 MsiDB_commit(MsiDB* self)\r
377 {\r
378   unsigned int result = 1;\r
379   if(self->handle != 0)\r
380   {\r
381     result = MsiDatabaseCommit(self->handle);\r
382     if(result == ERROR_INVALID_HANDLE)\r
383     {\r
384       printf("invalid??\n");\r
385     }\r
386   }\r
387   return Py_BuildValue("i", result);\r
388 }\r
389 \r
390 static PyMethodDef MsiDB_methods[] = {\r
391     {"openview", (PyCFunction)MsiDB_openview, METH_VARARGS,\r
392      "MsiViewExecute SQL query"\r
393     },\r
394     {"commit", (PyCFunction)MsiDB_commit, METH_NOARGS,\r
395      "MsiDatabaseCommit"\r
396     },\r
397     {NULL}  /* Sentinel */\r
398 };\r
399 \r
400 static PyTypeObject MsiDBType = {\r
401     PyObject_HEAD_INIT(NULL)\r
402     0,                         /*ob_size*/\r
403     "msiquery.MsiDB",             /*tp_name*/\r
404     sizeof(MsiDB),             /*tp_basicsize*/\r
405     0,                         /*tp_itemsize*/\r
406     (destructor)MsiDB_dealloc, /*tp_dealloc*/\r
407     0,                         /*tp_print*/\r
408     0,                         /*tp_getattr*/\r
409     0,                         /*tp_setattr*/\r
410     0,                         /*tp_compare*/\r
411     0,                         /*tp_repr*/\r
412     0,                         /*tp_as_number*/\r
413     0,                         /*tp_as_sequence*/\r
414     0,                         /*tp_as_mapping*/\r
415     0,                         /*tp_hash */\r
416     0,                         /*tp_call*/\r
417     0,                         /*tp_str*/\r
418     0,                         /*tp_getattro*/\r
419     0,                         /*tp_setattro*/\r
420     0,                         /*tp_as_buffer*/\r
421     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/\r
422     "MsiDB objects",           /* tp_doc */\r
423     0,                         /* tp_traverse */\r
424     0,                         /* tp_clear */\r
425     0,                         /* tp_richcompare */\r
426     0,                         /* tp_weaklistoffset */\r
427     0,                         /* tp_iter */\r
428     0,                         /* tp_iternext */\r
429     MsiDB_methods,             /* tp_methods */\r
430     MsiDB_members,             /* tp_members */\r
431     0,                         /* tp_getset */\r
432     0,                         /* tp_base */\r
433     0,                         /* tp_dict */\r
434     0,                         /* tp_descr_get */\r
435     0,                         /* tp_descr_set */\r
436     0,                         /* tp_dictoffset */\r
437     (initproc)MsiDB_init,      /* tp_init */\r
438     0,                         /* tp_alloc */\r
439     (newfunc)MsiDB_new,                 /* tp_new */\r
440 };\r
441 \r
442 static PyMethodDef msiquery_methods[] = {\r
443     {NULL}  /* Sentinel */\r
444 };\r
445 \r
446 PyMODINIT_FUNC\r
447 initmsiquery(void) \r
448 {\r
449     PyObject* m;\r
450 \r
451     if (PyType_Ready(&MsiRecordType) < 0)\r
452         return;\r
453 \r
454     if (PyType_Ready(&MsiViewType) < 0)\r
455         return;\r
456 \r
457     if (PyType_Ready(&MsiDBType) < 0)\r
458         return;\r
459 \r
460     m = Py_InitModule3("msiquery", msiquery_methods, "Msi API module.");\r
461 \r
462     if (m == NULL)\r
463       return;\r
464 \r
465     Py_INCREF(&MsiRecordType);\r
466     PyModule_AddObject(m, "MsiRecord", (PyObject *)&MsiRecordType);\r
467 \r
468     Py_INCREF(&MsiViewType);\r
469     PyModule_AddObject(m, "MsiView", (PyObject *)&MsiViewType);\r
470 \r
471     Py_INCREF(&MsiDBType);\r
472     PyModule_AddObject(m, "MsiDB", (PyObject *)&MsiDBType);\r
473 }\r
474 \r