blob: 574dddec0582098b8872cd25e5c3582a47bef9b3 [file] [log] [blame]
Martin v. Löwisfbab90e2006-03-05 13:36:04 +00001/* Helper library for MSI creation with Python.
2 * Copyright (C) 2005 Martin v. Löwis
Martin v. Löwisdd860ca2006-03-05 13:39:10 +00003 * Licensed to PSF under a contributor agreement.
Martin v. Löwisfbab90e2006-03-05 13:36:04 +00004 */
5
6#include <Python.h>
7#include <fci.h>
8#include <fcntl.h>
9#include <windows.h>
10#include <msi.h>
11#include <msiquery.h>
12#include <msidefs.h>
13#include <rpc.h>
14
15static PyObject *MSIError;
16
17static PyObject*
18uuidcreate(PyObject* obj, PyObject*args)
19{
20 UUID result;
21 char *cresult;
22 PyObject *oresult;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000023
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000024 /* May return ok, local only, and no address.
25 For local only, the documentation says we still get a uuid.
26 For RPC_S_UUID_NO_ADDRESS, it's not clear whether we can
27 use the result. */
28 if (UuidCreate(&result) == RPC_S_UUID_NO_ADDRESS) {
Antoine Pitrou86171612010-05-09 15:15:11 +000029 PyErr_SetString(PyExc_NotImplementedError, "processing 'no address' result");
30 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000031 }
32
33 if (UuidToString(&result, &cresult) == RPC_S_OUT_OF_MEMORY) {
Antoine Pitrou86171612010-05-09 15:15:11 +000034 PyErr_SetString(PyExc_MemoryError, "out of memory in uuidgen");
35 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000036 }
37
Gregory P. Smithdd96db62008-06-09 04:58:54 +000038 oresult = PyString_FromString(cresult);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000039 RpcStringFree(&cresult);
40 return oresult;
41
42}
43
44/* FCI callback functions */
45
46static FNFCIALLOC(cb_alloc)
47{
48 return malloc(cb);
49}
50
51static FNFCIFREE(cb_free)
52{
53 free(memory);
54}
55
56static FNFCIOPEN(cb_open)
57{
58 int result = _open(pszFile, oflag, pmode);
59 if (result == -1)
Antoine Pitrou86171612010-05-09 15:15:11 +000060 *err = errno;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000061 return result;
62}
63
64static FNFCIREAD(cb_read)
65{
66 UINT result = (UINT)_read(hf, memory, cb);
67 if (result != cb)
Antoine Pitrou86171612010-05-09 15:15:11 +000068 *err = errno;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000069 return result;
70}
71
72static FNFCIWRITE(cb_write)
73{
74 UINT result = (UINT)_write(hf, memory, cb);
75 if (result != cb)
Antoine Pitrou86171612010-05-09 15:15:11 +000076 *err = errno;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000077 return result;
78}
79
80static FNFCICLOSE(cb_close)
81{
82 int result = _close(hf);
83 if (result != 0)
Antoine Pitrou86171612010-05-09 15:15:11 +000084 *err = errno;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000085 return result;
86}
87
88static FNFCISEEK(cb_seek)
89{
90 long result = (long)_lseek(hf, dist, seektype);
91 if (result == -1)
Antoine Pitrou86171612010-05-09 15:15:11 +000092 *err = errno;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +000093 return result;
94}
95
96static FNFCIDELETE(cb_delete)
97{
98 int result = remove(pszFile);
99 if (result != 0)
Antoine Pitrou86171612010-05-09 15:15:11 +0000100 *err = errno;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000101 return result;
102}
103
104static FNFCIFILEPLACED(cb_fileplaced)
105{
106 return 0;
107}
108
109static FNFCIGETTEMPFILE(cb_gettempfile)
110{
111 char *name = _tempnam("", "tmp");
112 if ((name != NULL) && ((int)strlen(name) < cbTempName)) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000113 strcpy(pszTempName, name);
114 free(name);
115 return TRUE;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000116 }
117
118 if (name) free(name);
119 return FALSE;
120}
121
122static FNFCISTATUS(cb_status)
123{
124 if (pv) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000125 PyObject *result = PyObject_CallMethod(pv, "status", "iii", typeStatus, cb1, cb2);
126 if (result == NULL)
127 return -1;
128 Py_DECREF(result);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000129 }
130 return 0;
131}
132
133static FNFCIGETNEXTCABINET(cb_getnextcabinet)
134{
135 if (pv) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000136 PyObject *result = PyObject_CallMethod(pv, "getnextcabinet", "i", pccab->iCab);
137 if (result == NULL)
138 return -1;
139 if (!PyString_Check(result)) {
140 PyErr_Format(PyExc_TypeError,
141 "Incorrect return type %s from getnextcabinet",
142 result->ob_type->tp_name);
143 Py_DECREF(result);
144 return FALSE;
145 }
146 strncpy(pccab->szCab, PyString_AsString(result), sizeof(pccab->szCab));
147 return TRUE;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000148 }
149 return FALSE;
150}
151
152static FNFCIGETOPENINFO(cb_getopeninfo)
153{
154 BY_HANDLE_FILE_INFORMATION bhfi;
155 FILETIME filetime;
156 HANDLE handle;
157
158 /* Need Win32 handle to get time stamps */
159 handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
Antoine Pitrou86171612010-05-09 15:15:11 +0000160 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000161 if (handle == INVALID_HANDLE_VALUE)
Antoine Pitrou86171612010-05-09 15:15:11 +0000162 return -1;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000163
164 if (GetFileInformationByHandle(handle, &bhfi) == FALSE)
165 {
Antoine Pitrou86171612010-05-09 15:15:11 +0000166 CloseHandle(handle);
167 return -1;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000168 }
169
170 FileTimeToLocalFileTime(&bhfi.ftLastWriteTime, &filetime);
171 FileTimeToDosDateTime(&filetime, pdate, ptime);
172
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000173 *pattribs = (int)(bhfi.dwFileAttributes &
Antoine Pitrou86171612010-05-09 15:15:11 +0000174 (_A_RDONLY | _A_SYSTEM | _A_HIDDEN | _A_ARCH));
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000175
176 CloseHandle(handle);
177
178 return _open(pszName, _O_RDONLY | _O_BINARY);
179}
180
181static PyObject* fcicreate(PyObject* obj, PyObject* args)
182{
Martin v. Löwise0d30ef2008-02-12 13:47:26 +0000183 char *cabname, *p;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000184 PyObject *files;
185 CCAB ccab;
186 HFCI hfci;
187 ERF erf;
Martin v. Löwise0d30ef2008-02-12 13:47:26 +0000188 Py_ssize_t i;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000189
190
191 if (!PyArg_ParseTuple(args, "sO:FCICreate", &cabname, &files))
Antoine Pitrou86171612010-05-09 15:15:11 +0000192 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000193
194 if (!PyList_Check(files)) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000195 PyErr_SetString(PyExc_TypeError, "FCICreate expects a list");
196 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000197 }
198
199 ccab.cb = INT_MAX; /* no need to split CAB into multiple media */
200 ccab.cbFolderThresh = 1000000; /* flush directory after this many bytes */
201 ccab.cbReserveCFData = 0;
202 ccab.cbReserveCFFolder = 0;
203 ccab.cbReserveCFHeader = 0;
204
205 ccab.iCab = 1;
206 ccab.iDisk = 1;
207
208 ccab.setID = 0;
209 ccab.szDisk[0] = '\0';
210
Martin v. Löwise0d30ef2008-02-12 13:47:26 +0000211 for (i = 0, p = cabname; *p; p = CharNext(p))
Antoine Pitrou86171612010-05-09 15:15:11 +0000212 if (*p == '\\' || *p == '/')
213 i = p - cabname + 1;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000214
Martin v. Löwise0d30ef2008-02-12 13:47:26 +0000215 if (i >= sizeof(ccab.szCabPath) ||
Antoine Pitrou86171612010-05-09 15:15:11 +0000216 strlen(cabname+i) >= sizeof(ccab.szCab)) {
217 PyErr_SetString(PyExc_ValueError, "path name too long");
218 return 0;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000219 }
220
Martin v. Löwise0d30ef2008-02-12 13:47:26 +0000221 if (i > 0) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000222 memcpy(ccab.szCabPath, cabname, i);
223 ccab.szCabPath[i] = '\0';
224 strcpy(ccab.szCab, cabname+i);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000225 } else {
Antoine Pitrou86171612010-05-09 15:15:11 +0000226 strcpy(ccab.szCabPath, ".\\");
227 strcpy(ccab.szCab, cabname);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000228 }
229
230 hfci = FCICreate(&erf, cb_fileplaced, cb_alloc, cb_free,
Antoine Pitrou86171612010-05-09 15:15:11 +0000231 cb_open, cb_read, cb_write, cb_close, cb_seek, cb_delete,
232 cb_gettempfile, &ccab, NULL);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000233
234 if (hfci == NULL) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000235 PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper);
236 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000237 }
238
239 for (i=0; i < PyList_GET_SIZE(files); i++) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000240 PyObject *item = PyList_GET_ITEM(files, i);
241 char *filename, *cabname;
242 if (!PyArg_ParseTuple(item, "ss", &filename, &cabname))
243 goto err;
244 if (!FCIAddFile(hfci, filename, cabname, FALSE,
245 cb_getnextcabinet, cb_status, cb_getopeninfo,
246 tcompTYPE_MSZIP))
247 goto err;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000248 }
249
250 if (!FCIFlushCabinet(hfci, FALSE, cb_getnextcabinet, cb_status))
Antoine Pitrou86171612010-05-09 15:15:11 +0000251 goto err;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000252
253 if (!FCIDestroy(hfci))
Antoine Pitrou86171612010-05-09 15:15:11 +0000254 goto err;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000255
256 Py_INCREF(Py_None);
257 return Py_None;
258err:
259 PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper); /* XXX better error type */
260 FCIDestroy(hfci);
261 return NULL;
262}
263
264typedef struct msiobj{
265 PyObject_HEAD
266 MSIHANDLE h;
267}msiobj;
268
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000269static void
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000270msiobj_dealloc(msiobj* msidb)
271{
272 MsiCloseHandle(msidb->h);
273 msidb->h = 0;
274}
275
276static PyObject*
277msiobj_close(msiobj* msidb, PyObject *args)
278{
279 MsiCloseHandle(msidb->h);
280 msidb->h = 0;
281 Py_INCREF(Py_None);
282 return Py_None;
283}
284
285static PyObject*
286msierror(int status)
287{
288 int code;
289 char buf[2000];
290 char *res = buf;
291 DWORD size = sizeof(buf);
292 MSIHANDLE err = MsiGetLastErrorRecord();
293
294 if (err == 0) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000295 switch(status) {
296 case ERROR_ACCESS_DENIED:
297 PyErr_SetString(MSIError, "access denied");
298 return NULL;
299 case ERROR_FUNCTION_FAILED:
300 PyErr_SetString(MSIError, "function failed");
301 return NULL;
302 case ERROR_INVALID_DATA:
303 PyErr_SetString(MSIError, "invalid data");
304 return NULL;
305 case ERROR_INVALID_HANDLE:
306 PyErr_SetString(MSIError, "invalid handle");
307 return NULL;
308 case ERROR_INVALID_STATE:
309 PyErr_SetString(MSIError, "invalid state");
310 return NULL;
311 case ERROR_INVALID_PARAMETER:
312 PyErr_SetString(MSIError, "invalid parameter");
313 return NULL;
314 default:
315 PyErr_Format(MSIError, "unknown error %x", status);
316 return NULL;
317 }
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000318 }
319
320 code = MsiRecordGetInteger(err, 1); /* XXX code */
321 if (MsiFormatRecord(0, err, res, &size) == ERROR_MORE_DATA) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000322 res = malloc(size+1);
323 MsiFormatRecord(0, err, res, &size);
324 res[size]='\0';
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000325 }
326 MsiCloseHandle(err);
327 PyErr_SetString(MSIError, res);
328 if (res != buf)
Antoine Pitrou86171612010-05-09 15:15:11 +0000329 free(res);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000330 return NULL;
331}
332
333/*************************** Record objects **********************/
334
335static PyObject*
336record_getfieldcount(msiobj* record, PyObject* args)
337{
338 return PyInt_FromLong(MsiRecordGetFieldCount(record->h));
339}
340
341static PyObject*
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000342record_getinteger(msiobj* record, PyObject* args)
343{
344 unsigned int field;
345 int status;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000346
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000347 if (!PyArg_ParseTuple(args, "I:GetInteger", &field))
Antoine Pitrou86171612010-05-09 15:15:11 +0000348 return NULL;
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000349 status = MsiRecordGetInteger(record->h, field);
350 if (status == MSI_NULL_INTEGER){
Antoine Pitrou86171612010-05-09 15:15:11 +0000351 PyErr_SetString(MSIError, "could not convert record field to integer");
352 return NULL;
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000353 }
354 return PyInt_FromLong((long) status);
355}
356
357static PyObject*
358record_getstring(msiobj* record, PyObject* args)
359{
360 unsigned int field;
361 unsigned int status;
362 char buf[2000];
363 char *res = buf;
364 DWORD size = sizeof(buf);
365 PyObject* string;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000366
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000367 if (!PyArg_ParseTuple(args, "I:GetString", &field))
Antoine Pitrou86171612010-05-09 15:15:11 +0000368 return NULL;
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000369 status = MsiRecordGetString(record->h, field, res, &size);
370 if (status == ERROR_MORE_DATA) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000371 res = (char*) malloc(size + 1);
372 if (res == NULL)
373 return PyErr_NoMemory();
374 status = MsiRecordGetString(record->h, field, res, &size);
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000375 }
376 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000377 return msierror((int) status);
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000378 string = PyString_FromString(res);
379 if (buf != res)
Antoine Pitrou86171612010-05-09 15:15:11 +0000380 free(res);
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000381 return string;
382}
383
384static PyObject*
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000385record_cleardata(msiobj* record, PyObject *args)
386{
387 int status = MsiRecordClearData(record->h);
388 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000389 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000390
391 Py_INCREF(Py_None);
392 return Py_None;
393}
394
395static PyObject*
396record_setstring(msiobj* record, PyObject *args)
397{
398 int status;
399 int field;
400 char *data;
401
402 if (!PyArg_ParseTuple(args, "is:SetString", &field, &data))
Antoine Pitrou86171612010-05-09 15:15:11 +0000403 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000404
405 if ((status = MsiRecordSetString(record->h, field, data)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000406 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000407
408 Py_INCREF(Py_None);
409 return Py_None;
410}
411
412static PyObject*
413record_setstream(msiobj* record, PyObject *args)
414{
415 int status;
416 int field;
417 char *data;
418
419 if (!PyArg_ParseTuple(args, "is:SetStream", &field, &data))
Antoine Pitrou86171612010-05-09 15:15:11 +0000420 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000421
422 if ((status = MsiRecordSetStream(record->h, field, data)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000423 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000424
425 Py_INCREF(Py_None);
426 return Py_None;
427}
428
429static PyObject*
430record_setinteger(msiobj* record, PyObject *args)
431{
432 int status;
433 int field;
434 int data;
435
436 if (!PyArg_ParseTuple(args, "ii:SetInteger", &field, &data))
Antoine Pitrou86171612010-05-09 15:15:11 +0000437 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000438
439 if ((status = MsiRecordSetInteger(record->h, field, data)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000440 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000441
442 Py_INCREF(Py_None);
443 return Py_None;
444}
445
446
447
448static PyMethodDef record_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000449 { "GetFieldCount", (PyCFunction)record_getfieldcount, METH_NOARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000450 PyDoc_STR("GetFieldCount() -> int\nWraps MsiRecordGetFieldCount")},
Martin v. Löwisffe62ed2008-06-02 08:40:06 +0000451 { "GetInteger", (PyCFunction)record_getinteger, METH_VARARGS,
452 PyDoc_STR("GetInteger(field) -> int\nWraps MsiRecordGetInteger")},
453 { "GetString", (PyCFunction)record_getstring, METH_VARARGS,
454 PyDoc_STR("GetString(field) -> string\nWraps MsiRecordGetString")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000455 { "SetString", (PyCFunction)record_setstring, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000456 PyDoc_STR("SetString(field,str) -> None\nWraps MsiRecordSetString")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000457 { "SetStream", (PyCFunction)record_setstream, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000458 PyDoc_STR("SetStream(field,filename) -> None\nWraps MsiRecordSetInteger")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000459 { "SetInteger", (PyCFunction)record_setinteger, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000460 PyDoc_STR("SetInteger(field,int) -> None\nWraps MsiRecordSetInteger")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000461 { "ClearData", (PyCFunction)record_cleardata, METH_NOARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000462 PyDoc_STR("ClearData() -> int\nWraps MsiRecordGClearData")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000463 { NULL, NULL }
464};
465
466static PyTypeObject record_Type = {
Antoine Pitrou86171612010-05-09 15:15:11 +0000467 PyVarObject_HEAD_INIT(NULL, 0)
468 "_msi.Record", /*tp_name*/
469 sizeof(msiobj), /*tp_basicsize*/
470 0, /*tp_itemsize*/
471 /* methods */
472 (destructor)msiobj_dealloc, /*tp_dealloc*/
473 0, /*tp_print*/
474 0, /*tp_getattr*/
475 0, /*tp_setattr*/
476 0, /*tp_compare*/
477 0, /*tp_repr*/
478 0, /*tp_as_number*/
479 0, /*tp_as_sequence*/
480 0, /*tp_as_mapping*/
481 0, /*tp_hash*/
482 0, /*tp_call*/
483 0, /*tp_str*/
484 PyObject_GenericGetAttr,/*tp_getattro*/
485 PyObject_GenericSetAttr,/*tp_setattro*/
486 0, /*tp_as_buffer*/
487 Py_TPFLAGS_DEFAULT, /*tp_flags*/
488 0, /*tp_doc*/
489 0, /*tp_traverse*/
490 0, /*tp_clear*/
491 0, /*tp_richcompare*/
492 0, /*tp_weaklistoffset*/
493 0, /*tp_iter*/
494 0, /*tp_iternext*/
495 record_methods, /*tp_methods*/
496 0, /*tp_members*/
497 0, /*tp_getset*/
498 0, /*tp_base*/
499 0, /*tp_dict*/
500 0, /*tp_descr_get*/
501 0, /*tp_descr_set*/
502 0, /*tp_dictoffset*/
503 0, /*tp_init*/
504 0, /*tp_alloc*/
505 0, /*tp_new*/
506 0, /*tp_free*/
507 0, /*tp_is_gc*/
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000508};
509
510static PyObject*
511record_new(MSIHANDLE h)
512{
513 msiobj *result = PyObject_NEW(struct msiobj, &record_Type);
514
515 if (!result) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000516 MsiCloseHandle(h);
517 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000518 }
519
520 result->h = h;
521 return (PyObject*)result;
522}
523
524/*************************** SummaryInformation objects **************/
525
526static PyObject*
527summary_getproperty(msiobj* si, PyObject *args)
528{
529 int status;
530 int field;
531 PyObject *result;
532 UINT type;
533 INT ival;
534 FILETIME fval;
535 char sbuf[1000];
536 char *sval = sbuf;
537 DWORD ssize = sizeof(sval);
538
539 if (!PyArg_ParseTuple(args, "i:GetProperty", &field))
Antoine Pitrou86171612010-05-09 15:15:11 +0000540 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000541
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000542 status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000543 &fval, sval, &ssize);
Antoine Pitrou86171612010-05-09 15:15:11 +0000544 if (status == ERROR_MORE_DATA) {
545 sval = malloc(ssize);
546 status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival,
547 &fval, sval, &ssize);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000548 }
549
550 switch(type) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000551 case VT_I2: case VT_I4:
552 return PyInt_FromLong(ival);
553 case VT_FILETIME:
554 PyErr_SetString(PyExc_NotImplementedError, "FILETIME result");
555 return NULL;
556 case VT_LPSTR:
557 result = PyString_FromStringAndSize(sval, ssize);
558 if (sval != sbuf)
559 free(sval);
560 return result;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000561 }
562 PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
563 return NULL;
564}
565
566static PyObject*
567summary_getpropertycount(msiobj* si, PyObject *args)
568{
569 int status;
570 UINT result;
571
572 status = MsiSummaryInfoGetPropertyCount(si->h, &result);
573 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000574 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000575
576 return PyInt_FromLong(result);
577}
578
579static PyObject*
580summary_setproperty(msiobj* si, PyObject *args)
581{
582 int status;
583 int field;
584 PyObject* data;
585
586 if (!PyArg_ParseTuple(args, "iO:SetProperty", &field, &data))
Antoine Pitrou86171612010-05-09 15:15:11 +0000587 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000588
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000589 if (PyString_Check(data)) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000590 status = MsiSummaryInfoSetProperty(si->h, field, VT_LPSTR,
591 0, NULL, PyString_AsString(data));
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000592 } else if (PyInt_Check(data)) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000593 status = MsiSummaryInfoSetProperty(si->h, field, VT_I4,
594 PyInt_AsLong(data), NULL, NULL);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000595 } else {
Antoine Pitrou86171612010-05-09 15:15:11 +0000596 PyErr_SetString(PyExc_TypeError, "unsupported type");
597 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000598 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000599
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000600 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000601 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000602
603 Py_INCREF(Py_None);
604 return Py_None;
605}
606
607
608static PyObject*
609summary_persist(msiobj* si, PyObject *args)
610{
611 int status;
612
613 status = MsiSummaryInfoPersist(si->h);
614 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000615 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000616 Py_INCREF(Py_None);
617 return Py_None;
618}
619
620static PyMethodDef summary_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000621 { "GetProperty", (PyCFunction)summary_getproperty, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000622 PyDoc_STR("GetProperty(propid) -> value\nWraps MsiSummaryInfoGetProperty")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000623 { "GetPropertyCount", (PyCFunction)summary_getpropertycount, METH_NOARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000624 PyDoc_STR("GetProperty() -> int\nWraps MsiSummaryInfoGetPropertyCount")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000625 { "SetProperty", (PyCFunction)summary_setproperty, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000626 PyDoc_STR("SetProperty(value) -> None\nWraps MsiSummaryInfoProperty")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000627 { "Persist", (PyCFunction)summary_persist, METH_NOARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000628 PyDoc_STR("Persist() -> None\nWraps MsiSummaryInfoPersist")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000629 { NULL, NULL }
630};
631
632static PyTypeObject summary_Type = {
Antoine Pitrou86171612010-05-09 15:15:11 +0000633 PyVarObject_HEAD_INIT(NULL, 0)
634 "_msi.SummaryInformation", /*tp_name*/
635 sizeof(msiobj), /*tp_basicsize*/
636 0, /*tp_itemsize*/
637 /* methods */
638 (destructor)msiobj_dealloc, /*tp_dealloc*/
639 0, /*tp_print*/
640 0, /*tp_getattr*/
641 0, /*tp_setattr*/
642 0, /*tp_compare*/
643 0, /*tp_repr*/
644 0, /*tp_as_number*/
645 0, /*tp_as_sequence*/
646 0, /*tp_as_mapping*/
647 0, /*tp_hash*/
648 0, /*tp_call*/
649 0, /*tp_str*/
650 PyObject_GenericGetAttr,/*tp_getattro*/
651 PyObject_GenericSetAttr,/*tp_setattro*/
652 0, /*tp_as_buffer*/
653 Py_TPFLAGS_DEFAULT, /*tp_flags*/
654 0, /*tp_doc*/
655 0, /*tp_traverse*/
656 0, /*tp_clear*/
657 0, /*tp_richcompare*/
658 0, /*tp_weaklistoffset*/
659 0, /*tp_iter*/
660 0, /*tp_iternext*/
661 summary_methods, /*tp_methods*/
662 0, /*tp_members*/
663 0, /*tp_getset*/
664 0, /*tp_base*/
665 0, /*tp_dict*/
666 0, /*tp_descr_get*/
667 0, /*tp_descr_set*/
668 0, /*tp_dictoffset*/
669 0, /*tp_init*/
670 0, /*tp_alloc*/
671 0, /*tp_new*/
672 0, /*tp_free*/
673 0, /*tp_is_gc*/
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000674};
675
676/*************************** View objects **************/
677
678static PyObject*
679view_execute(msiobj *view, PyObject*args)
680{
681 int status;
682 MSIHANDLE params = 0;
683 PyObject *oparams = Py_None;
684
685 if (!PyArg_ParseTuple(args, "O:Execute", &oparams))
Antoine Pitrou86171612010-05-09 15:15:11 +0000686 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000687
688 if (oparams != Py_None) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000689 if (oparams->ob_type != &record_Type) {
690 PyErr_SetString(PyExc_TypeError, "Execute argument must be a record");
691 return NULL;
692 }
693 params = ((msiobj*)oparams)->h;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000694 }
695
696 status = MsiViewExecute(view->h, params);
697 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000698 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000699
700 Py_INCREF(Py_None);
701 return Py_None;
702}
703
704static PyObject*
705view_fetch(msiobj *view, PyObject*args)
706{
707 int status;
708 MSIHANDLE result;
709
710 if ((status = MsiViewFetch(view->h, &result)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000711 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000712
713 return record_new(result);
714}
715
716static PyObject*
717view_getcolumninfo(msiobj *view, PyObject *args)
718{
719 int status;
720 int kind;
721 MSIHANDLE result;
722
723 if (!PyArg_ParseTuple(args, "i:GetColumnInfo", &kind))
Antoine Pitrou86171612010-05-09 15:15:11 +0000724 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000725
726 if ((status = MsiViewGetColumnInfo(view->h, kind, &result)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000727 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000728
729 return record_new(result);
730}
731
732static PyObject*
733view_modify(msiobj *view, PyObject *args)
734{
735 int kind;
736 PyObject *data;
737 int status;
738
739 if (!PyArg_ParseTuple(args, "iO:Modify", &kind, &data))
Antoine Pitrou86171612010-05-09 15:15:11 +0000740 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000741
742 if (data->ob_type != &record_Type) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000743 PyErr_SetString(PyExc_TypeError, "Modify expects a record object");
744 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000745 }
746
747 if ((status = MsiViewModify(view->h, kind, ((msiobj*)data)->h)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000748 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000749
750 Py_INCREF(Py_None);
751 return Py_None;
752}
753
754static PyObject*
755view_close(msiobj *view, PyObject*args)
756{
757 int status;
758
759 if ((status = MsiViewClose(view->h)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000760 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000761
762 Py_INCREF(Py_None);
763 return Py_None;
764}
765
766static PyMethodDef view_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000767 { "Execute", (PyCFunction)view_execute, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000768 PyDoc_STR("Execute(params=None) -> None\nWraps MsiViewExecute")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000769 { "GetColumnInfo", (PyCFunction)view_getcolumninfo, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000770 PyDoc_STR("GetColumnInfo() -> result\nWraps MsiGetColumnInfo")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000771 { "Fetch", (PyCFunction)view_fetch, METH_NOARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000772 PyDoc_STR("Fetch() -> result\nWraps MsiViewFetch")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000773 { "Modify", (PyCFunction)view_modify, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000774 PyDoc_STR("Modify(mode,record) -> None\nWraps MsiViewModify")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000775 { "Close", (PyCFunction)view_close, METH_NOARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000776 PyDoc_STR("Close() -> result\nWraps MsiViewClose")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000777 { NULL, NULL }
778};
779
780static PyTypeObject msiview_Type = {
Antoine Pitrou86171612010-05-09 15:15:11 +0000781 PyVarObject_HEAD_INIT(NULL, 0)
782 "_msi.View", /*tp_name*/
783 sizeof(msiobj), /*tp_basicsize*/
784 0, /*tp_itemsize*/
785 /* methods */
786 (destructor)msiobj_dealloc, /*tp_dealloc*/
787 0, /*tp_print*/
788 0, /*tp_getattr*/
789 0, /*tp_setattr*/
790 0, /*tp_compare*/
791 0, /*tp_repr*/
792 0, /*tp_as_number*/
793 0, /*tp_as_sequence*/
794 0, /*tp_as_mapping*/
795 0, /*tp_hash*/
796 0, /*tp_call*/
797 0, /*tp_str*/
798 PyObject_GenericGetAttr,/*tp_getattro*/
799 PyObject_GenericSetAttr,/*tp_setattro*/
800 0, /*tp_as_buffer*/
801 Py_TPFLAGS_DEFAULT, /*tp_flags*/
802 0, /*tp_doc*/
803 0, /*tp_traverse*/
804 0, /*tp_clear*/
805 0, /*tp_richcompare*/
806 0, /*tp_weaklistoffset*/
807 0, /*tp_iter*/
808 0, /*tp_iternext*/
809 view_methods, /*tp_methods*/
810 0, /*tp_members*/
811 0, /*tp_getset*/
812 0, /*tp_base*/
813 0, /*tp_dict*/
814 0, /*tp_descr_get*/
815 0, /*tp_descr_set*/
816 0, /*tp_dictoffset*/
817 0, /*tp_init*/
818 0, /*tp_alloc*/
819 0, /*tp_new*/
820 0, /*tp_free*/
821 0, /*tp_is_gc*/
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000822};
823
824/*************************** Database objects **************/
825
826static PyObject*
827msidb_openview(msiobj *msidb, PyObject *args)
828{
829 int status;
830 char *sql;
831 MSIHANDLE hView;
832 msiobj *result;
833
834 if (!PyArg_ParseTuple(args, "s:OpenView", &sql))
Antoine Pitrou86171612010-05-09 15:15:11 +0000835 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000836
837 if ((status = MsiDatabaseOpenView(msidb->h, sql, &hView)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000838 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000839
840 result = PyObject_NEW(struct msiobj, &msiview_Type);
841 if (!result) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000842 MsiCloseHandle(hView);
843 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000844 }
845
846 result->h = hView;
847 return (PyObject*)result;
848}
849
850static PyObject*
851msidb_commit(msiobj *msidb, PyObject *args)
852{
853 int status;
854
855 if ((status = MsiDatabaseCommit(msidb->h)) != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000856 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000857
858 Py_INCREF(Py_None);
859 return Py_None;
860}
861
862static PyObject*
863msidb_getsummaryinformation(msiobj *db, PyObject *args)
864{
865 int status;
866 int count;
867 MSIHANDLE result;
868 msiobj *oresult;
869
870 if (!PyArg_ParseTuple(args, "i:GetSummaryInformation", &count))
Antoine Pitrou86171612010-05-09 15:15:11 +0000871 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000872
873 status = MsiGetSummaryInformation(db->h, NULL, count, &result);
874 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000875 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000876
877 oresult = PyObject_NEW(struct msiobj, &summary_Type);
878 if (!result) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000879 MsiCloseHandle(result);
880 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000881 }
882
883 oresult->h = result;
884 return (PyObject*)oresult;
885}
886
887static PyMethodDef db_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000888 { "OpenView", (PyCFunction)msidb_openview, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000889 PyDoc_STR("OpenView(sql) -> viewobj\nWraps MsiDatabaseOpenView")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000890 { "Commit", (PyCFunction)msidb_commit, METH_NOARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000891 PyDoc_STR("Commit() -> None\nWraps MsiDatabaseCommit")},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000892 { "GetSummaryInformation", (PyCFunction)msidb_getsummaryinformation, METH_VARARGS,
Antoine Pitrou86171612010-05-09 15:15:11 +0000893 PyDoc_STR("GetSummaryInformation(updateCount) -> viewobj\nWraps MsiGetSummaryInformation")},
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000894 { NULL, NULL }
895};
896
897static PyTypeObject msidb_Type = {
Antoine Pitrou86171612010-05-09 15:15:11 +0000898 PyVarObject_HEAD_INIT(NULL, 0)
899 "_msi.Database", /*tp_name*/
900 sizeof(msiobj), /*tp_basicsize*/
901 0, /*tp_itemsize*/
902 /* methods */
903 (destructor)msiobj_dealloc, /*tp_dealloc*/
904 0, /*tp_print*/
905 0, /*tp_getattr*/
906 0, /*tp_setattr*/
907 0, /*tp_compare*/
908 0, /*tp_repr*/
909 0, /*tp_as_number*/
910 0, /*tp_as_sequence*/
911 0, /*tp_as_mapping*/
912 0, /*tp_hash*/
913 0, /*tp_call*/
914 0, /*tp_str*/
915 PyObject_GenericGetAttr,/*tp_getattro*/
916 PyObject_GenericSetAttr,/*tp_setattro*/
917 0, /*tp_as_buffer*/
918 Py_TPFLAGS_DEFAULT, /*tp_flags*/
919 0, /*tp_doc*/
920 0, /*tp_traverse*/
921 0, /*tp_clear*/
922 0, /*tp_richcompare*/
923 0, /*tp_weaklistoffset*/
924 0, /*tp_iter*/
925 0, /*tp_iternext*/
926 db_methods, /*tp_methods*/
927 0, /*tp_members*/
928 0, /*tp_getset*/
929 0, /*tp_base*/
930 0, /*tp_dict*/
931 0, /*tp_descr_get*/
932 0, /*tp_descr_set*/
933 0, /*tp_dictoffset*/
934 0, /*tp_init*/
935 0, /*tp_alloc*/
936 0, /*tp_new*/
937 0, /*tp_free*/
938 0, /*tp_is_gc*/
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000939};
940
941static PyObject* msiopendb(PyObject *obj, PyObject *args)
942{
943 int status;
944 char *path;
945 int persist;
946 MSIHANDLE h;
947 msiobj *result;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000948
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000949 if (!PyArg_ParseTuple(args, "si:MSIOpenDatabase", &path, &persist))
Antoine Pitrou86171612010-05-09 15:15:11 +0000950 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000951
Antoine Pitrou86171612010-05-09 15:15:11 +0000952 status = MsiOpenDatabase(path, (LPCSTR)persist, &h);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000953 if (status != ERROR_SUCCESS)
Antoine Pitrou86171612010-05-09 15:15:11 +0000954 return msierror(status);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000955
956 result = PyObject_NEW(struct msiobj, &msidb_Type);
957 if (!result) {
Antoine Pitrou86171612010-05-09 15:15:11 +0000958 MsiCloseHandle(h);
959 return NULL;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000960 }
961 result->h = h;
962 return (PyObject*)result;
963}
964
965static PyObject*
966createrecord(PyObject *o, PyObject *args)
967{
968 int count;
969 MSIHANDLE h;
970
971 if (!PyArg_ParseTuple(args, "i:CreateRecord", &count))
Antoine Pitrou86171612010-05-09 15:15:11 +0000972 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000973
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000974 h = MsiCreateRecord(count);
975 if (h == 0)
Antoine Pitrou86171612010-05-09 15:15:11 +0000976 return msierror(0);
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000977
978 return record_new(h);
979}
980
981
982static PyMethodDef msi_methods[] = {
Antoine Pitrou86171612010-05-09 15:15:11 +0000983 {"UuidCreate", (PyCFunction)uuidcreate, METH_NOARGS,
984 PyDoc_STR("UuidCreate() -> string")},
985 {"FCICreate", (PyCFunction)fcicreate, METH_VARARGS,
986 PyDoc_STR("fcicreate(cabname,files) -> None")},
987 {"OpenDatabase", (PyCFunction)msiopendb, METH_VARARGS,
988 PyDoc_STR("OpenDatabase(name, flags) -> dbobj\nWraps MsiOpenDatabase")},
989 {"CreateRecord", (PyCFunction)createrecord, METH_VARARGS,
990 PyDoc_STR("OpenDatabase(name, flags) -> dbobj\nWraps MsiCreateRecord")},
991 {NULL, NULL} /* sentinel */
Martin v. Löwisfbab90e2006-03-05 13:36:04 +0000992};
993
994static char msi_doc[] = "Documentation";
995
996PyMODINIT_FUNC
997init_msi(void)
998{
999 PyObject *m;
1000
1001 m = Py_InitModule3("_msi", msi_methods, msi_doc);
1002 if (m == NULL)
Antoine Pitrou86171612010-05-09 15:15:11 +00001003 return;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +00001004
1005 PyModule_AddIntConstant(m, "MSIDBOPEN_CREATEDIRECT", (int)MSIDBOPEN_CREATEDIRECT);
1006 PyModule_AddIntConstant(m, "MSIDBOPEN_CREATE", (int)MSIDBOPEN_CREATE);
1007 PyModule_AddIntConstant(m, "MSIDBOPEN_DIRECT", (int)MSIDBOPEN_DIRECT);
1008 PyModule_AddIntConstant(m, "MSIDBOPEN_READONLY", (int)MSIDBOPEN_READONLY);
1009 PyModule_AddIntConstant(m, "MSIDBOPEN_TRANSACT", (int)MSIDBOPEN_TRANSACT);
1010 PyModule_AddIntConstant(m, "MSIDBOPEN_PATCHFILE", (int)MSIDBOPEN_PATCHFILE);
1011
1012 PyModule_AddIntConstant(m, "MSICOLINFO_NAMES", MSICOLINFO_NAMES);
1013 PyModule_AddIntConstant(m, "MSICOLINFO_TYPES", MSICOLINFO_TYPES);
1014
1015 PyModule_AddIntConstant(m, "MSIMODIFY_SEEK", MSIMODIFY_SEEK);
1016 PyModule_AddIntConstant(m, "MSIMODIFY_REFRESH", MSIMODIFY_REFRESH);
1017 PyModule_AddIntConstant(m, "MSIMODIFY_INSERT", MSIMODIFY_INSERT);
1018 PyModule_AddIntConstant(m, "MSIMODIFY_UPDATE", MSIMODIFY_UPDATE);
1019 PyModule_AddIntConstant(m, "MSIMODIFY_ASSIGN", MSIMODIFY_ASSIGN);
1020 PyModule_AddIntConstant(m, "MSIMODIFY_REPLACE", MSIMODIFY_REPLACE);
1021 PyModule_AddIntConstant(m, "MSIMODIFY_MERGE", MSIMODIFY_MERGE);
1022 PyModule_AddIntConstant(m, "MSIMODIFY_DELETE", MSIMODIFY_DELETE);
1023 PyModule_AddIntConstant(m, "MSIMODIFY_INSERT_TEMPORARY", MSIMODIFY_INSERT_TEMPORARY);
1024 PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE", MSIMODIFY_VALIDATE);
1025 PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE_NEW", MSIMODIFY_VALIDATE_NEW);
1026 PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE_FIELD", MSIMODIFY_VALIDATE_FIELD);
1027 PyModule_AddIntConstant(m, "MSIMODIFY_VALIDATE_DELETE", MSIMODIFY_VALIDATE_DELETE);
1028
1029 PyModule_AddIntConstant(m, "PID_CODEPAGE", PID_CODEPAGE);
1030 PyModule_AddIntConstant(m, "PID_TITLE", PID_TITLE);
1031 PyModule_AddIntConstant(m, "PID_SUBJECT", PID_SUBJECT);
1032 PyModule_AddIntConstant(m, "PID_AUTHOR", PID_AUTHOR);
1033 PyModule_AddIntConstant(m, "PID_KEYWORDS", PID_KEYWORDS);
1034 PyModule_AddIntConstant(m, "PID_COMMENTS", PID_COMMENTS);
1035 PyModule_AddIntConstant(m, "PID_TEMPLATE", PID_TEMPLATE);
1036 PyModule_AddIntConstant(m, "PID_LASTAUTHOR", PID_LASTAUTHOR);
1037 PyModule_AddIntConstant(m, "PID_REVNUMBER", PID_REVNUMBER);
1038 PyModule_AddIntConstant(m, "PID_LASTPRINTED", PID_LASTPRINTED);
1039 PyModule_AddIntConstant(m, "PID_CREATE_DTM", PID_CREATE_DTM);
1040 PyModule_AddIntConstant(m, "PID_LASTSAVE_DTM", PID_LASTSAVE_DTM);
1041 PyModule_AddIntConstant(m, "PID_PAGECOUNT", PID_PAGECOUNT);
1042 PyModule_AddIntConstant(m, "PID_WORDCOUNT", PID_WORDCOUNT);
1043 PyModule_AddIntConstant(m, "PID_CHARCOUNT", PID_CHARCOUNT);
1044 PyModule_AddIntConstant(m, "PID_APPNAME", PID_APPNAME);
1045 PyModule_AddIntConstant(m, "PID_SECURITY", PID_SECURITY);
1046
1047 MSIError = PyErr_NewException ("_msi.MSIError", NULL, NULL);
1048 if (!MSIError)
Antoine Pitrou86171612010-05-09 15:15:11 +00001049 return;
Martin v. Löwisfbab90e2006-03-05 13:36:04 +00001050 PyModule_AddObject(m, "MSIError", MSIError);
1051}