17db96d56Sopenharmony_ci/* Helper library for MSI creation with Python.
27db96d56Sopenharmony_ci * Copyright (C) 2005 Martin v. Löwis
37db96d56Sopenharmony_ci * Licensed to PSF under a contributor agreement.
47db96d56Sopenharmony_ci */
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci#include <Python.h>
77db96d56Sopenharmony_ci#include <fci.h>
87db96d56Sopenharmony_ci#include <fcntl.h>
97db96d56Sopenharmony_ci#include <windows.h>
107db96d56Sopenharmony_ci#include <msi.h>
117db96d56Sopenharmony_ci#include <msiquery.h>
127db96d56Sopenharmony_ci#include <msidefs.h>
137db96d56Sopenharmony_ci#include <rpc.h>
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci/*[clinic input]
167db96d56Sopenharmony_cimodule _msi
177db96d56Sopenharmony_ciclass _msi.Record "msiobj *" "&record_Type"
187db96d56Sopenharmony_ciclass _msi.SummaryInformation "msiobj *" "&summary_Type"
197db96d56Sopenharmony_ciclass _msi.View "msiobj *" "&msiview_Type"
207db96d56Sopenharmony_ciclass _msi.Database "msiobj *" "&msidb_Type"
217db96d56Sopenharmony_ci[clinic start generated code]*/
227db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=89a3605762cf4bdc]*/
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_cistatic PyObject *MSIError;
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci/*[clinic input]
277db96d56Sopenharmony_ci_msi.UuidCreate
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ciReturn the string representation of a new unique identifier.
307db96d56Sopenharmony_ci[clinic start generated code]*/
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_cistatic PyObject *
337db96d56Sopenharmony_ci_msi_UuidCreate_impl(PyObject *module)
347db96d56Sopenharmony_ci/*[clinic end generated code: output=534ecf36f10af98e input=168024ab4b3e832b]*/
357db96d56Sopenharmony_ci{
367db96d56Sopenharmony_ci    UUID result;
377db96d56Sopenharmony_ci    wchar_t *cresult;
387db96d56Sopenharmony_ci    PyObject *oresult;
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci    /* May return ok, local only, and no address.
417db96d56Sopenharmony_ci       For local only, the documentation says we still get a uuid.
427db96d56Sopenharmony_ci       For RPC_S_UUID_NO_ADDRESS, it's not clear whether we can
437db96d56Sopenharmony_ci       use the result. */
447db96d56Sopenharmony_ci    if (UuidCreate(&result) == RPC_S_UUID_NO_ADDRESS) {
457db96d56Sopenharmony_ci        PyErr_SetString(PyExc_NotImplementedError, "processing 'no address' result");
467db96d56Sopenharmony_ci        return NULL;
477db96d56Sopenharmony_ci    }
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci    if (UuidToStringW(&result, &cresult) == RPC_S_OUT_OF_MEMORY) {
507db96d56Sopenharmony_ci        PyErr_SetString(PyExc_MemoryError, "out of memory in uuidgen");
517db96d56Sopenharmony_ci        return NULL;
527db96d56Sopenharmony_ci    }
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci    oresult = PyUnicode_FromWideChar(cresult, wcslen(cresult));
557db96d56Sopenharmony_ci    RpcStringFreeW(&cresult);
567db96d56Sopenharmony_ci    return oresult;
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci}
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci/* Helper for converting file names from UTF-8 to wchat_t*.  */
617db96d56Sopenharmony_cistatic wchar_t *
627db96d56Sopenharmony_ciutf8_to_wchar(const char *s, int *err)
637db96d56Sopenharmony_ci{
647db96d56Sopenharmony_ci    PyObject *obj = PyUnicode_FromString(s);
657db96d56Sopenharmony_ci    if (obj == NULL) {
667db96d56Sopenharmony_ci        if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
677db96d56Sopenharmony_ci            *err = ENOMEM;
687db96d56Sopenharmony_ci        }
697db96d56Sopenharmony_ci        else {
707db96d56Sopenharmony_ci            *err = EINVAL;
717db96d56Sopenharmony_ci        }
727db96d56Sopenharmony_ci        PyErr_Clear();
737db96d56Sopenharmony_ci        return NULL;
747db96d56Sopenharmony_ci    }
757db96d56Sopenharmony_ci    wchar_t *ws = PyUnicode_AsWideCharString(obj, NULL);
767db96d56Sopenharmony_ci    if (ws == NULL) {
777db96d56Sopenharmony_ci        *err = ENOMEM;
787db96d56Sopenharmony_ci        PyErr_Clear();
797db96d56Sopenharmony_ci    }
807db96d56Sopenharmony_ci    Py_DECREF(obj);
817db96d56Sopenharmony_ci    return ws;
827db96d56Sopenharmony_ci}
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci/* FCI callback functions */
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_cistatic FNFCIALLOC(cb_alloc)
877db96d56Sopenharmony_ci{
887db96d56Sopenharmony_ci    return PyMem_RawMalloc(cb);
897db96d56Sopenharmony_ci}
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_cistatic FNFCIFREE(cb_free)
927db96d56Sopenharmony_ci{
937db96d56Sopenharmony_ci    PyMem_RawFree(memory);
947db96d56Sopenharmony_ci}
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_cistatic FNFCIOPEN(cb_open)
977db96d56Sopenharmony_ci{
987db96d56Sopenharmony_ci    wchar_t *ws = utf8_to_wchar(pszFile, err);
997db96d56Sopenharmony_ci    if (ws == NULL) {
1007db96d56Sopenharmony_ci        return -1;
1017db96d56Sopenharmony_ci    }
1027db96d56Sopenharmony_ci    int result = _wopen(ws, oflag | O_NOINHERIT, pmode);
1037db96d56Sopenharmony_ci    PyMem_Free(ws);
1047db96d56Sopenharmony_ci    if (result == -1)
1057db96d56Sopenharmony_ci        *err = errno;
1067db96d56Sopenharmony_ci    return result;
1077db96d56Sopenharmony_ci}
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_cistatic FNFCIREAD(cb_read)
1107db96d56Sopenharmony_ci{
1117db96d56Sopenharmony_ci    UINT result = (UINT)_read((int)hf, memory, cb);
1127db96d56Sopenharmony_ci    if (result != cb)
1137db96d56Sopenharmony_ci        *err = errno;
1147db96d56Sopenharmony_ci    return result;
1157db96d56Sopenharmony_ci}
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_cistatic FNFCIWRITE(cb_write)
1187db96d56Sopenharmony_ci{
1197db96d56Sopenharmony_ci    UINT result = (UINT)_write((int)hf, memory, cb);
1207db96d56Sopenharmony_ci    if (result != cb)
1217db96d56Sopenharmony_ci        *err = errno;
1227db96d56Sopenharmony_ci    return result;
1237db96d56Sopenharmony_ci}
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_cistatic FNFCICLOSE(cb_close)
1267db96d56Sopenharmony_ci{
1277db96d56Sopenharmony_ci    int result = _close((int)hf);
1287db96d56Sopenharmony_ci    if (result != 0)
1297db96d56Sopenharmony_ci        *err = errno;
1307db96d56Sopenharmony_ci    return result;
1317db96d56Sopenharmony_ci}
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_cistatic FNFCISEEK(cb_seek)
1347db96d56Sopenharmony_ci{
1357db96d56Sopenharmony_ci    long result = (long)_lseek((int)hf, dist, seektype);
1367db96d56Sopenharmony_ci    if (result == -1)
1377db96d56Sopenharmony_ci        *err = errno;
1387db96d56Sopenharmony_ci    return result;
1397db96d56Sopenharmony_ci}
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_cistatic FNFCIDELETE(cb_delete)
1427db96d56Sopenharmony_ci{
1437db96d56Sopenharmony_ci    wchar_t *ws = utf8_to_wchar(pszFile, err);
1447db96d56Sopenharmony_ci    if (ws == NULL) {
1457db96d56Sopenharmony_ci        return -1;
1467db96d56Sopenharmony_ci    }
1477db96d56Sopenharmony_ci    int result = _wremove(ws);
1487db96d56Sopenharmony_ci    PyMem_Free(ws);
1497db96d56Sopenharmony_ci    if (result != 0)
1507db96d56Sopenharmony_ci        *err = errno;
1517db96d56Sopenharmony_ci    return result;
1527db96d56Sopenharmony_ci}
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_cistatic FNFCIFILEPLACED(cb_fileplaced)
1557db96d56Sopenharmony_ci{
1567db96d56Sopenharmony_ci    return 0;
1577db96d56Sopenharmony_ci}
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_cistatic FNFCIGETTEMPFILE(cb_gettempfile)
1607db96d56Sopenharmony_ci{
1617db96d56Sopenharmony_ci    char *name = _tempnam("", "tmp");
1627db96d56Sopenharmony_ci    if ((name != NULL) && ((int)strlen(name) < cbTempName)) {
1637db96d56Sopenharmony_ci        strcpy(pszTempName, name);
1647db96d56Sopenharmony_ci        free(name);
1657db96d56Sopenharmony_ci        return TRUE;
1667db96d56Sopenharmony_ci    }
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_ci    if (name) free(name);
1697db96d56Sopenharmony_ci    return FALSE;
1707db96d56Sopenharmony_ci}
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_cistatic FNFCISTATUS(cb_status)
1737db96d56Sopenharmony_ci{
1747db96d56Sopenharmony_ci    if (pv) {
1757db96d56Sopenharmony_ci        _Py_IDENTIFIER(status);
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci        PyObject *result = _PyObject_CallMethodId(pv, &PyId_status, "iii", typeStatus, cb1, cb2);
1787db96d56Sopenharmony_ci        if (result == NULL)
1797db96d56Sopenharmony_ci            return -1;
1807db96d56Sopenharmony_ci        Py_DECREF(result);
1817db96d56Sopenharmony_ci    }
1827db96d56Sopenharmony_ci    return 0;
1837db96d56Sopenharmony_ci}
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_cistatic FNFCIGETNEXTCABINET(cb_getnextcabinet)
1867db96d56Sopenharmony_ci{
1877db96d56Sopenharmony_ci    if (pv) {
1887db96d56Sopenharmony_ci        _Py_IDENTIFIER(getnextcabinet);
1897db96d56Sopenharmony_ci
1907db96d56Sopenharmony_ci        PyObject *result = _PyObject_CallMethodId(pv, &PyId_getnextcabinet, "i", pccab->iCab);
1917db96d56Sopenharmony_ci        if (result == NULL)
1927db96d56Sopenharmony_ci            return -1;
1937db96d56Sopenharmony_ci        if (!PyBytes_Check(result)) {
1947db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
1957db96d56Sopenharmony_ci                "Incorrect return type %s from getnextcabinet",
1967db96d56Sopenharmony_ci                Py_TYPE(result)->tp_name);
1977db96d56Sopenharmony_ci            Py_DECREF(result);
1987db96d56Sopenharmony_ci            return FALSE;
1997db96d56Sopenharmony_ci        }
2007db96d56Sopenharmony_ci        strncpy(pccab->szCab, PyBytes_AsString(result), sizeof(pccab->szCab));
2017db96d56Sopenharmony_ci        return TRUE;
2027db96d56Sopenharmony_ci    }
2037db96d56Sopenharmony_ci    return FALSE;
2047db96d56Sopenharmony_ci}
2057db96d56Sopenharmony_ci
2067db96d56Sopenharmony_cistatic FNFCIGETOPENINFO(cb_getopeninfo)
2077db96d56Sopenharmony_ci{
2087db96d56Sopenharmony_ci    BY_HANDLE_FILE_INFORMATION bhfi;
2097db96d56Sopenharmony_ci    FILETIME filetime;
2107db96d56Sopenharmony_ci    HANDLE handle;
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci    wchar_t *ws = utf8_to_wchar(pszName, err);
2137db96d56Sopenharmony_ci    if (ws == NULL) {
2147db96d56Sopenharmony_ci        return -1;
2157db96d56Sopenharmony_ci    }
2167db96d56Sopenharmony_ci
2177db96d56Sopenharmony_ci    /* Need Win32 handle to get time stamps */
2187db96d56Sopenharmony_ci    handle = CreateFileW(ws, GENERIC_READ, FILE_SHARE_READ, NULL,
2197db96d56Sopenharmony_ci        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2207db96d56Sopenharmony_ci    if (handle == INVALID_HANDLE_VALUE) {
2217db96d56Sopenharmony_ci        PyMem_Free(ws);
2227db96d56Sopenharmony_ci        return -1;
2237db96d56Sopenharmony_ci    }
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ci    if (GetFileInformationByHandle(handle, &bhfi) == FALSE) {
2267db96d56Sopenharmony_ci        CloseHandle(handle);
2277db96d56Sopenharmony_ci        PyMem_Free(ws);
2287db96d56Sopenharmony_ci        return -1;
2297db96d56Sopenharmony_ci    }
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci    FileTimeToLocalFileTime(&bhfi.ftLastWriteTime, &filetime);
2327db96d56Sopenharmony_ci    FileTimeToDosDateTime(&filetime, pdate, ptime);
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci    *pattribs = (int)(bhfi.dwFileAttributes &
2357db96d56Sopenharmony_ci        (_A_RDONLY | _A_SYSTEM | _A_HIDDEN | _A_ARCH));
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_ci    CloseHandle(handle);
2387db96d56Sopenharmony_ci
2397db96d56Sopenharmony_ci    int result = _wopen(ws, _O_RDONLY | _O_BINARY | O_NOINHERIT);
2407db96d56Sopenharmony_ci    PyMem_Free(ws);
2417db96d56Sopenharmony_ci    return result;
2427db96d56Sopenharmony_ci}
2437db96d56Sopenharmony_ci
2447db96d56Sopenharmony_ci/*[clinic input]
2457db96d56Sopenharmony_ci_msi.FCICreate
2467db96d56Sopenharmony_ci    cabname: str
2477db96d56Sopenharmony_ci        the name of the CAB file
2487db96d56Sopenharmony_ci    files: object
2497db96d56Sopenharmony_ci        a list of tuples, each containing the name of the file on disk,
2507db96d56Sopenharmony_ci        and the name of the file inside the CAB file
2517db96d56Sopenharmony_ci    /
2527db96d56Sopenharmony_ci
2537db96d56Sopenharmony_ciCreate a new CAB file.
2547db96d56Sopenharmony_ci[clinic start generated code]*/
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_cistatic PyObject *
2577db96d56Sopenharmony_ci_msi_FCICreate_impl(PyObject *module, const char *cabname, PyObject *files)
2587db96d56Sopenharmony_ci/*[clinic end generated code: output=55dc05728361b799 input=1d2d75fdc8b44b71]*/
2597db96d56Sopenharmony_ci{
2607db96d56Sopenharmony_ci    const char *p;
2617db96d56Sopenharmony_ci    CCAB ccab;
2627db96d56Sopenharmony_ci    HFCI hfci;
2637db96d56Sopenharmony_ci    ERF erf;
2647db96d56Sopenharmony_ci    Py_ssize_t i;
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_ci    if (!PyList_Check(files)) {
2677db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "FCICreate expects a list");
2687db96d56Sopenharmony_ci        return NULL;
2697db96d56Sopenharmony_ci    }
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci    ccab.cb = INT_MAX; /* no need to split CAB into multiple media */
2727db96d56Sopenharmony_ci    ccab.cbFolderThresh = 1000000; /* flush directory after this many bytes */
2737db96d56Sopenharmony_ci    ccab.cbReserveCFData = 0;
2747db96d56Sopenharmony_ci    ccab.cbReserveCFFolder = 0;
2757db96d56Sopenharmony_ci    ccab.cbReserveCFHeader = 0;
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ci    ccab.iCab = 1;
2787db96d56Sopenharmony_ci    ccab.iDisk = 1;
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci    ccab.setID = 0;
2817db96d56Sopenharmony_ci    ccab.szDisk[0] = '\0';
2827db96d56Sopenharmony_ci
2837db96d56Sopenharmony_ci    for (i = 0, p = cabname; *p; p++)
2847db96d56Sopenharmony_ci        if (*p == '\\' || *p == '/')
2857db96d56Sopenharmony_ci            i = p - cabname + 1;
2867db96d56Sopenharmony_ci
2877db96d56Sopenharmony_ci    if (i >= sizeof(ccab.szCabPath) ||
2887db96d56Sopenharmony_ci        strlen(cabname+i) >= sizeof(ccab.szCab)) {
2897db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "path name too long");
2907db96d56Sopenharmony_ci        return 0;
2917db96d56Sopenharmony_ci    }
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci    if (i > 0) {
2947db96d56Sopenharmony_ci        memcpy(ccab.szCabPath, cabname, i);
2957db96d56Sopenharmony_ci        ccab.szCabPath[i] = '\0';
2967db96d56Sopenharmony_ci        strcpy(ccab.szCab, cabname+i);
2977db96d56Sopenharmony_ci    } else {
2987db96d56Sopenharmony_ci        strcpy(ccab.szCabPath, ".\\");
2997db96d56Sopenharmony_ci        strcpy(ccab.szCab, cabname);
3007db96d56Sopenharmony_ci    }
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci    hfci = FCICreate(&erf, cb_fileplaced, cb_alloc, cb_free,
3037db96d56Sopenharmony_ci        cb_open, cb_read, cb_write, cb_close, cb_seek, cb_delete,
3047db96d56Sopenharmony_ci        cb_gettempfile, &ccab, NULL);
3057db96d56Sopenharmony_ci
3067db96d56Sopenharmony_ci    if (hfci == NULL) {
3077db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper);
3087db96d56Sopenharmony_ci        return NULL;
3097db96d56Sopenharmony_ci    }
3107db96d56Sopenharmony_ci
3117db96d56Sopenharmony_ci    for (i=0; i < PyList_GET_SIZE(files); i++) {
3127db96d56Sopenharmony_ci        PyObject *item = PyList_GET_ITEM(files, i);
3137db96d56Sopenharmony_ci        char *filename, *cabname;
3147db96d56Sopenharmony_ci
3157db96d56Sopenharmony_ci        if (!PyArg_ParseTuple(item, "ss", &filename, &cabname)) {
3167db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError, "FCICreate expects a list of tuples containing two strings");
3177db96d56Sopenharmony_ci            FCIDestroy(hfci);
3187db96d56Sopenharmony_ci            return NULL;
3197db96d56Sopenharmony_ci        }
3207db96d56Sopenharmony_ci
3217db96d56Sopenharmony_ci        if (!FCIAddFile(hfci, filename, cabname, FALSE,
3227db96d56Sopenharmony_ci            cb_getnextcabinet, cb_status, cb_getopeninfo,
3237db96d56Sopenharmony_ci            tcompTYPE_MSZIP))
3247db96d56Sopenharmony_ci            goto err;
3257db96d56Sopenharmony_ci    }
3267db96d56Sopenharmony_ci
3277db96d56Sopenharmony_ci    if (!FCIFlushCabinet(hfci, FALSE, cb_getnextcabinet, cb_status))
3287db96d56Sopenharmony_ci        goto err;
3297db96d56Sopenharmony_ci
3307db96d56Sopenharmony_ci    if (!FCIDestroy(hfci))
3317db96d56Sopenharmony_ci        goto err;
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci    Py_RETURN_NONE;
3347db96d56Sopenharmony_cierr:
3357db96d56Sopenharmony_ci    if(erf.fError)
3367db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper); /* XXX better error type */
3377db96d56Sopenharmony_ci    else
3387db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "FCI general error");
3397db96d56Sopenharmony_ci
3407db96d56Sopenharmony_ci    FCIDestroy(hfci);
3417db96d56Sopenharmony_ci    return NULL;
3427db96d56Sopenharmony_ci}
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_citypedef struct msiobj{
3457db96d56Sopenharmony_ci    PyObject_HEAD
3467db96d56Sopenharmony_ci    MSIHANDLE h;
3477db96d56Sopenharmony_ci}msiobj;
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_cistatic void
3507db96d56Sopenharmony_cimsiobj_dealloc(msiobj* msidb)
3517db96d56Sopenharmony_ci{
3527db96d56Sopenharmony_ci    MsiCloseHandle(msidb->h);
3537db96d56Sopenharmony_ci    msidb->h = 0;
3547db96d56Sopenharmony_ci    PyObject_Free(msidb);
3557db96d56Sopenharmony_ci}
3567db96d56Sopenharmony_ci
3577db96d56Sopenharmony_cistatic PyObject*
3587db96d56Sopenharmony_cimsierror(int status)
3597db96d56Sopenharmony_ci{
3607db96d56Sopenharmony_ci    int code;
3617db96d56Sopenharmony_ci    char buf[2000];
3627db96d56Sopenharmony_ci    char *res = buf;
3637db96d56Sopenharmony_ci    DWORD size = Py_ARRAY_LENGTH(buf);
3647db96d56Sopenharmony_ci    MSIHANDLE err = MsiGetLastErrorRecord();
3657db96d56Sopenharmony_ci
3667db96d56Sopenharmony_ci    if (err == 0) {
3677db96d56Sopenharmony_ci        switch(status) {
3687db96d56Sopenharmony_ci        case ERROR_ACCESS_DENIED:
3697db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "access denied");
3707db96d56Sopenharmony_ci            return NULL;
3717db96d56Sopenharmony_ci        case ERROR_FUNCTION_FAILED:
3727db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "function failed");
3737db96d56Sopenharmony_ci            return NULL;
3747db96d56Sopenharmony_ci        case ERROR_INVALID_DATA:
3757db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "invalid data");
3767db96d56Sopenharmony_ci            return NULL;
3777db96d56Sopenharmony_ci        case ERROR_INVALID_HANDLE:
3787db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "invalid handle");
3797db96d56Sopenharmony_ci            return NULL;
3807db96d56Sopenharmony_ci        case ERROR_INVALID_STATE:
3817db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "invalid state");
3827db96d56Sopenharmony_ci            return NULL;
3837db96d56Sopenharmony_ci        case ERROR_INVALID_PARAMETER:
3847db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "invalid parameter");
3857db96d56Sopenharmony_ci            return NULL;
3867db96d56Sopenharmony_ci        case ERROR_OPEN_FAILED:
3877db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "open failed");
3887db96d56Sopenharmony_ci            return NULL;
3897db96d56Sopenharmony_ci        case ERROR_CREATE_FAILED:
3907db96d56Sopenharmony_ci            PyErr_SetString(MSIError, "create failed");
3917db96d56Sopenharmony_ci            return NULL;
3927db96d56Sopenharmony_ci        default:
3937db96d56Sopenharmony_ci            PyErr_Format(MSIError, "unknown error %x", status);
3947db96d56Sopenharmony_ci            return NULL;
3957db96d56Sopenharmony_ci        }
3967db96d56Sopenharmony_ci    }
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci    code = MsiRecordGetInteger(err, 1); /* XXX code */
3997db96d56Sopenharmony_ci    if (MsiFormatRecord(0, err, res, &size) == ERROR_MORE_DATA) {
4007db96d56Sopenharmony_ci        res = malloc(size+1);
4017db96d56Sopenharmony_ci        if (res == NULL) {
4027db96d56Sopenharmony_ci            MsiCloseHandle(err);
4037db96d56Sopenharmony_ci            return PyErr_NoMemory();
4047db96d56Sopenharmony_ci        }
4057db96d56Sopenharmony_ci        MsiFormatRecord(0, err, res, &size);
4067db96d56Sopenharmony_ci        res[size]='\0';
4077db96d56Sopenharmony_ci    }
4087db96d56Sopenharmony_ci    MsiCloseHandle(err);
4097db96d56Sopenharmony_ci    PyErr_SetString(MSIError, res);
4107db96d56Sopenharmony_ci    if (res != buf)
4117db96d56Sopenharmony_ci        free(res);
4127db96d56Sopenharmony_ci    return NULL;
4137db96d56Sopenharmony_ci}
4147db96d56Sopenharmony_ci
4157db96d56Sopenharmony_ci#include "clinic/_msi.c.h"
4167db96d56Sopenharmony_ci
4177db96d56Sopenharmony_ci/*[clinic input]
4187db96d56Sopenharmony_ci_msi.Database.Close
4197db96d56Sopenharmony_ci
4207db96d56Sopenharmony_ciClose the database object.
4217db96d56Sopenharmony_ci[clinic start generated code]*/
4227db96d56Sopenharmony_ci
4237db96d56Sopenharmony_cistatic PyObject *
4247db96d56Sopenharmony_ci_msi_Database_Close_impl(msiobj *self)
4257db96d56Sopenharmony_ci/*[clinic end generated code: output=ddf2d7712ea804f1 input=104330ce4a486187]*/
4267db96d56Sopenharmony_ci{
4277db96d56Sopenharmony_ci    int status;
4287db96d56Sopenharmony_ci    if ((status = MsiCloseHandle(self->h)) != ERROR_SUCCESS) {
4297db96d56Sopenharmony_ci        return msierror(status);
4307db96d56Sopenharmony_ci    }
4317db96d56Sopenharmony_ci    self->h = 0;
4327db96d56Sopenharmony_ci    Py_RETURN_NONE;
4337db96d56Sopenharmony_ci}
4347db96d56Sopenharmony_ci
4357db96d56Sopenharmony_ci/*************************** Record objects **********************/
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ci/*[clinic input]
4387db96d56Sopenharmony_ci_msi.Record.GetFieldCount
4397db96d56Sopenharmony_ci
4407db96d56Sopenharmony_ciReturn the number of fields of the record.
4417db96d56Sopenharmony_ci[clinic start generated code]*/
4427db96d56Sopenharmony_ci
4437db96d56Sopenharmony_cistatic PyObject *
4447db96d56Sopenharmony_ci_msi_Record_GetFieldCount_impl(msiobj *self)
4457db96d56Sopenharmony_ci/*[clinic end generated code: output=112795079c904398 input=5fb9d4071b28897b]*/
4467db96d56Sopenharmony_ci{
4477db96d56Sopenharmony_ci    return PyLong_FromLong(MsiRecordGetFieldCount(self->h));
4487db96d56Sopenharmony_ci}
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ci/*[clinic input]
4517db96d56Sopenharmony_ci_msi.Record.GetInteger
4527db96d56Sopenharmony_ci    field: unsigned_int(bitwise=True)
4537db96d56Sopenharmony_ci    /
4547db96d56Sopenharmony_ci
4557db96d56Sopenharmony_ciReturn the value of field as an integer where possible.
4567db96d56Sopenharmony_ci[clinic start generated code]*/
4577db96d56Sopenharmony_ci
4587db96d56Sopenharmony_cistatic PyObject *
4597db96d56Sopenharmony_ci_msi_Record_GetInteger_impl(msiobj *self, unsigned int field)
4607db96d56Sopenharmony_ci/*[clinic end generated code: output=7174ebb6e8ed1c79 input=d19209947e2bfe61]*/
4617db96d56Sopenharmony_ci{
4627db96d56Sopenharmony_ci    int status;
4637db96d56Sopenharmony_ci
4647db96d56Sopenharmony_ci    status = MsiRecordGetInteger(self->h, field);
4657db96d56Sopenharmony_ci    if (status == MSI_NULL_INTEGER){
4667db96d56Sopenharmony_ci        PyErr_SetString(MSIError, "could not convert record field to integer");
4677db96d56Sopenharmony_ci        return NULL;
4687db96d56Sopenharmony_ci    }
4697db96d56Sopenharmony_ci    return PyLong_FromLong((long) status);
4707db96d56Sopenharmony_ci}
4717db96d56Sopenharmony_ci
4727db96d56Sopenharmony_ci/*[clinic input]
4737db96d56Sopenharmony_ci_msi.Record.GetString
4747db96d56Sopenharmony_ci    field: unsigned_int(bitwise=True)
4757db96d56Sopenharmony_ci    /
4767db96d56Sopenharmony_ci
4777db96d56Sopenharmony_ciReturn the value of field as a string where possible.
4787db96d56Sopenharmony_ci[clinic start generated code]*/
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_cistatic PyObject *
4817db96d56Sopenharmony_ci_msi_Record_GetString_impl(msiobj *self, unsigned int field)
4827db96d56Sopenharmony_ci/*[clinic end generated code: output=f670d1b484cfa47c input=ffa11f21450b77d8]*/
4837db96d56Sopenharmony_ci{
4847db96d56Sopenharmony_ci    unsigned int status;
4857db96d56Sopenharmony_ci    WCHAR buf[2000];
4867db96d56Sopenharmony_ci    WCHAR *res = buf;
4877db96d56Sopenharmony_ci    DWORD size = Py_ARRAY_LENGTH(buf);
4887db96d56Sopenharmony_ci    PyObject* string;
4897db96d56Sopenharmony_ci
4907db96d56Sopenharmony_ci    status = MsiRecordGetStringW(self->h, field, res, &size);
4917db96d56Sopenharmony_ci    if (status == ERROR_MORE_DATA) {
4927db96d56Sopenharmony_ci        res = (WCHAR*) malloc((size + 1)*sizeof(WCHAR));
4937db96d56Sopenharmony_ci        if (res == NULL)
4947db96d56Sopenharmony_ci            return PyErr_NoMemory();
4957db96d56Sopenharmony_ci        status = MsiRecordGetStringW(self->h, field, res, &size);
4967db96d56Sopenharmony_ci    }
4977db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
4987db96d56Sopenharmony_ci        return msierror((int) status);
4997db96d56Sopenharmony_ci    string = PyUnicode_FromWideChar(res, size);
5007db96d56Sopenharmony_ci    if (buf != res)
5017db96d56Sopenharmony_ci        free(res);
5027db96d56Sopenharmony_ci    return string;
5037db96d56Sopenharmony_ci}
5047db96d56Sopenharmony_ci
5057db96d56Sopenharmony_ci/*[clinic input]
5067db96d56Sopenharmony_ci_msi.Record.ClearData
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ciSet all fields of the record to 0.
5097db96d56Sopenharmony_ci[clinic start generated code]*/
5107db96d56Sopenharmony_ci
5117db96d56Sopenharmony_cistatic PyObject *
5127db96d56Sopenharmony_ci_msi_Record_ClearData_impl(msiobj *self)
5137db96d56Sopenharmony_ci/*[clinic end generated code: output=1891467214b977f4 input=2a911c95aaded102]*/
5147db96d56Sopenharmony_ci{
5157db96d56Sopenharmony_ci    int status = MsiRecordClearData(self->h);
5167db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
5177db96d56Sopenharmony_ci        return msierror(status);
5187db96d56Sopenharmony_ci
5197db96d56Sopenharmony_ci    Py_RETURN_NONE;
5207db96d56Sopenharmony_ci}
5217db96d56Sopenharmony_ci
5227db96d56Sopenharmony_ci/*[clinic input]
5237db96d56Sopenharmony_ci_msi.Record.SetString
5247db96d56Sopenharmony_ci    field: int
5257db96d56Sopenharmony_ci    value: Py_UNICODE
5267db96d56Sopenharmony_ci    /
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ciSet field to a string value.
5297db96d56Sopenharmony_ci[clinic start generated code]*/
5307db96d56Sopenharmony_ci
5317db96d56Sopenharmony_cistatic PyObject *
5327db96d56Sopenharmony_ci_msi_Record_SetString_impl(msiobj *self, int field, const Py_UNICODE *value)
5337db96d56Sopenharmony_ci/*[clinic end generated code: output=2e37505b0f11f985 input=fb8ec70a2a6148e0]*/
5347db96d56Sopenharmony_ci{
5357db96d56Sopenharmony_ci    int status;
5367db96d56Sopenharmony_ci
5377db96d56Sopenharmony_ci    if ((status = MsiRecordSetStringW(self->h, field, value)) != ERROR_SUCCESS)
5387db96d56Sopenharmony_ci        return msierror(status);
5397db96d56Sopenharmony_ci
5407db96d56Sopenharmony_ci    Py_RETURN_NONE;
5417db96d56Sopenharmony_ci}
5427db96d56Sopenharmony_ci
5437db96d56Sopenharmony_ci/*[clinic input]
5447db96d56Sopenharmony_ci_msi.Record.SetStream
5457db96d56Sopenharmony_ci    field: int
5467db96d56Sopenharmony_ci    value: Py_UNICODE
5477db96d56Sopenharmony_ci    /
5487db96d56Sopenharmony_ci
5497db96d56Sopenharmony_ciSet field to the contents of the file named value.
5507db96d56Sopenharmony_ci[clinic start generated code]*/
5517db96d56Sopenharmony_ci
5527db96d56Sopenharmony_cistatic PyObject *
5537db96d56Sopenharmony_ci_msi_Record_SetStream_impl(msiobj *self, int field, const Py_UNICODE *value)
5547db96d56Sopenharmony_ci/*[clinic end generated code: output=442facac16913b48 input=a07aa19b865e8292]*/
5557db96d56Sopenharmony_ci{
5567db96d56Sopenharmony_ci    int status;
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_ci    if ((status = MsiRecordSetStreamW(self->h, field, value)) != ERROR_SUCCESS)
5597db96d56Sopenharmony_ci        return msierror(status);
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci    Py_RETURN_NONE;
5627db96d56Sopenharmony_ci}
5637db96d56Sopenharmony_ci
5647db96d56Sopenharmony_ci/*[clinic input]
5657db96d56Sopenharmony_ci_msi.Record.SetInteger
5667db96d56Sopenharmony_ci    field: int
5677db96d56Sopenharmony_ci    value: int
5687db96d56Sopenharmony_ci    /
5697db96d56Sopenharmony_ci
5707db96d56Sopenharmony_ciSet field to an integer value.
5717db96d56Sopenharmony_ci[clinic start generated code]*/
5727db96d56Sopenharmony_ci
5737db96d56Sopenharmony_cistatic PyObject *
5747db96d56Sopenharmony_ci_msi_Record_SetInteger_impl(msiobj *self, int field, int value)
5757db96d56Sopenharmony_ci/*[clinic end generated code: output=669e8647775d0ce7 input=c571aa775e7e451b]*/
5767db96d56Sopenharmony_ci{
5777db96d56Sopenharmony_ci    int status;
5787db96d56Sopenharmony_ci
5797db96d56Sopenharmony_ci    if ((status = MsiRecordSetInteger(self->h, field, value)) != ERROR_SUCCESS)
5807db96d56Sopenharmony_ci        return msierror(status);
5817db96d56Sopenharmony_ci
5827db96d56Sopenharmony_ci    Py_RETURN_NONE;
5837db96d56Sopenharmony_ci}
5847db96d56Sopenharmony_ci
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ci
5877db96d56Sopenharmony_cistatic PyMethodDef record_methods[] = {
5887db96d56Sopenharmony_ci    _MSI_RECORD_GETFIELDCOUNT_METHODDEF
5897db96d56Sopenharmony_ci    _MSI_RECORD_GETINTEGER_METHODDEF
5907db96d56Sopenharmony_ci    _MSI_RECORD_GETSTRING_METHODDEF
5917db96d56Sopenharmony_ci    _MSI_RECORD_SETSTRING_METHODDEF
5927db96d56Sopenharmony_ci    _MSI_RECORD_SETSTREAM_METHODDEF
5937db96d56Sopenharmony_ci    _MSI_RECORD_SETINTEGER_METHODDEF
5947db96d56Sopenharmony_ci    _MSI_RECORD_CLEARDATA_METHODDEF
5957db96d56Sopenharmony_ci    { NULL, NULL }
5967db96d56Sopenharmony_ci};
5977db96d56Sopenharmony_ci
5987db96d56Sopenharmony_cistatic PyTypeObject record_Type = {
5997db96d56Sopenharmony_ci        PyVarObject_HEAD_INIT(NULL, 0)
6007db96d56Sopenharmony_ci        "_msi.Record",          /*tp_name*/
6017db96d56Sopenharmony_ci        sizeof(msiobj), /*tp_basicsize*/
6027db96d56Sopenharmony_ci        0,                      /*tp_itemsize*/
6037db96d56Sopenharmony_ci        /* methods */
6047db96d56Sopenharmony_ci        (destructor)msiobj_dealloc, /*tp_dealloc*/
6057db96d56Sopenharmony_ci        0,                      /*tp_vectorcall_offset*/
6067db96d56Sopenharmony_ci        0,                      /*tp_getattr*/
6077db96d56Sopenharmony_ci        0,                      /*tp_setattr*/
6087db96d56Sopenharmony_ci        0,                      /*tp_as_async*/
6097db96d56Sopenharmony_ci        0,                      /*tp_repr*/
6107db96d56Sopenharmony_ci        0,                      /*tp_as_number*/
6117db96d56Sopenharmony_ci        0,                      /*tp_as_sequence*/
6127db96d56Sopenharmony_ci        0,                      /*tp_as_mapping*/
6137db96d56Sopenharmony_ci        0,                      /*tp_hash*/
6147db96d56Sopenharmony_ci        0,                      /*tp_call*/
6157db96d56Sopenharmony_ci        0,                      /*tp_str*/
6167db96d56Sopenharmony_ci        PyObject_GenericGetAttr,/*tp_getattro*/
6177db96d56Sopenharmony_ci        PyObject_GenericSetAttr,/*tp_setattro*/
6187db96d56Sopenharmony_ci        0,                      /*tp_as_buffer*/
6197db96d56Sopenharmony_ci        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
6207db96d56Sopenharmony_ci        0,                      /*tp_doc*/
6217db96d56Sopenharmony_ci        0,                      /*tp_traverse*/
6227db96d56Sopenharmony_ci        0,                      /*tp_clear*/
6237db96d56Sopenharmony_ci        0,                      /*tp_richcompare*/
6247db96d56Sopenharmony_ci        0,                      /*tp_weaklistoffset*/
6257db96d56Sopenharmony_ci        0,                      /*tp_iter*/
6267db96d56Sopenharmony_ci        0,                      /*tp_iternext*/
6277db96d56Sopenharmony_ci        record_methods,           /*tp_methods*/
6287db96d56Sopenharmony_ci        0,                      /*tp_members*/
6297db96d56Sopenharmony_ci        0,                      /*tp_getset*/
6307db96d56Sopenharmony_ci        0,                      /*tp_base*/
6317db96d56Sopenharmony_ci        0,                      /*tp_dict*/
6327db96d56Sopenharmony_ci        0,                      /*tp_descr_get*/
6337db96d56Sopenharmony_ci        0,                      /*tp_descr_set*/
6347db96d56Sopenharmony_ci        0,                      /*tp_dictoffset*/
6357db96d56Sopenharmony_ci        0,                      /*tp_init*/
6367db96d56Sopenharmony_ci        0,                      /*tp_alloc*/
6377db96d56Sopenharmony_ci        0,                      /*tp_new*/
6387db96d56Sopenharmony_ci        0,                      /*tp_free*/
6397db96d56Sopenharmony_ci        0,                      /*tp_is_gc*/
6407db96d56Sopenharmony_ci};
6417db96d56Sopenharmony_ci
6427db96d56Sopenharmony_cistatic PyObject*
6437db96d56Sopenharmony_cirecord_new(MSIHANDLE h)
6447db96d56Sopenharmony_ci{
6457db96d56Sopenharmony_ci    msiobj *result = PyObject_New(struct msiobj, &record_Type);
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ci    if (!result) {
6487db96d56Sopenharmony_ci        MsiCloseHandle(h);
6497db96d56Sopenharmony_ci        return NULL;
6507db96d56Sopenharmony_ci    }
6517db96d56Sopenharmony_ci
6527db96d56Sopenharmony_ci    result->h = h;
6537db96d56Sopenharmony_ci    return (PyObject*)result;
6547db96d56Sopenharmony_ci}
6557db96d56Sopenharmony_ci
6567db96d56Sopenharmony_ci/*************************** SummaryInformation objects **************/
6577db96d56Sopenharmony_ci
6587db96d56Sopenharmony_ci/*[clinic input]
6597db96d56Sopenharmony_ci_msi.SummaryInformation.GetProperty
6607db96d56Sopenharmony_ci    field: int
6617db96d56Sopenharmony_ci        the name of the property, one of the PID_* constants
6627db96d56Sopenharmony_ci    /
6637db96d56Sopenharmony_ci
6647db96d56Sopenharmony_ciReturn a property of the summary.
6657db96d56Sopenharmony_ci[clinic start generated code]*/
6667db96d56Sopenharmony_ci
6677db96d56Sopenharmony_cistatic PyObject *
6687db96d56Sopenharmony_ci_msi_SummaryInformation_GetProperty_impl(msiobj *self, int field)
6697db96d56Sopenharmony_ci/*[clinic end generated code: output=f8946a33ee14f6ef input=f8dfe2c890d6cb8b]*/
6707db96d56Sopenharmony_ci{
6717db96d56Sopenharmony_ci    int status;
6727db96d56Sopenharmony_ci    PyObject *result;
6737db96d56Sopenharmony_ci    UINT type;
6747db96d56Sopenharmony_ci    INT ival;
6757db96d56Sopenharmony_ci    FILETIME fval;
6767db96d56Sopenharmony_ci    char sbuf[1000];
6777db96d56Sopenharmony_ci    char *sval = sbuf;
6787db96d56Sopenharmony_ci    DWORD ssize = sizeof(sbuf);
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci    status = MsiSummaryInfoGetProperty(self->h, field, &type, &ival,
6817db96d56Sopenharmony_ci        &fval, sval, &ssize);
6827db96d56Sopenharmony_ci    if (status == ERROR_MORE_DATA) {
6837db96d56Sopenharmony_ci        ssize++;
6847db96d56Sopenharmony_ci        sval = malloc(ssize);
6857db96d56Sopenharmony_ci        if (sval == NULL) {
6867db96d56Sopenharmony_ci            return PyErr_NoMemory();
6877db96d56Sopenharmony_ci        }
6887db96d56Sopenharmony_ci        status = MsiSummaryInfoGetProperty(self->h, field, &type, &ival,
6897db96d56Sopenharmony_ci            &fval, sval, &ssize);
6907db96d56Sopenharmony_ci    }
6917db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS) {
6927db96d56Sopenharmony_ci        return msierror(status);
6937db96d56Sopenharmony_ci    }
6947db96d56Sopenharmony_ci
6957db96d56Sopenharmony_ci    switch(type) {
6967db96d56Sopenharmony_ci        case VT_I2:
6977db96d56Sopenharmony_ci        case VT_I4:
6987db96d56Sopenharmony_ci            result = PyLong_FromLong(ival);
6997db96d56Sopenharmony_ci            break;
7007db96d56Sopenharmony_ci        case VT_FILETIME:
7017db96d56Sopenharmony_ci            PyErr_SetString(PyExc_NotImplementedError, "FILETIME result");
7027db96d56Sopenharmony_ci            result = NULL;
7037db96d56Sopenharmony_ci            break;
7047db96d56Sopenharmony_ci        case VT_LPSTR:
7057db96d56Sopenharmony_ci            result = PyBytes_FromStringAndSize(sval, ssize);
7067db96d56Sopenharmony_ci            break;
7077db96d56Sopenharmony_ci        case VT_EMPTY:
7087db96d56Sopenharmony_ci            Py_INCREF(Py_None);
7097db96d56Sopenharmony_ci            result = Py_None;
7107db96d56Sopenharmony_ci            break;
7117db96d56Sopenharmony_ci        default:
7127db96d56Sopenharmony_ci            PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
7137db96d56Sopenharmony_ci            result = NULL;
7147db96d56Sopenharmony_ci            break;
7157db96d56Sopenharmony_ci    }
7167db96d56Sopenharmony_ci    if (sval != sbuf)
7177db96d56Sopenharmony_ci        free(sval);
7187db96d56Sopenharmony_ci    return result;
7197db96d56Sopenharmony_ci}
7207db96d56Sopenharmony_ci
7217db96d56Sopenharmony_ci/*[clinic input]
7227db96d56Sopenharmony_ci_msi.SummaryInformation.GetPropertyCount
7237db96d56Sopenharmony_ci
7247db96d56Sopenharmony_ciReturn the number of summary properties.
7257db96d56Sopenharmony_ci[clinic start generated code]*/
7267db96d56Sopenharmony_ci
7277db96d56Sopenharmony_cistatic PyObject *
7287db96d56Sopenharmony_ci_msi_SummaryInformation_GetPropertyCount_impl(msiobj *self)
7297db96d56Sopenharmony_ci/*[clinic end generated code: output=68e94b2aeee92b3d input=2e71e985586d82dc]*/
7307db96d56Sopenharmony_ci{
7317db96d56Sopenharmony_ci    int status;
7327db96d56Sopenharmony_ci    UINT result;
7337db96d56Sopenharmony_ci
7347db96d56Sopenharmony_ci    status = MsiSummaryInfoGetPropertyCount(self->h, &result);
7357db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
7367db96d56Sopenharmony_ci        return msierror(status);
7377db96d56Sopenharmony_ci
7387db96d56Sopenharmony_ci    return PyLong_FromLong(result);
7397db96d56Sopenharmony_ci}
7407db96d56Sopenharmony_ci
7417db96d56Sopenharmony_ci/*[clinic input]
7427db96d56Sopenharmony_ci_msi.SummaryInformation.SetProperty
7437db96d56Sopenharmony_ci    field: int
7447db96d56Sopenharmony_ci        the name of the property, one of the PID_* constants
7457db96d56Sopenharmony_ci    value as data: object
7467db96d56Sopenharmony_ci        the new value of the property (integer or string)
7477db96d56Sopenharmony_ci    /
7487db96d56Sopenharmony_ci
7497db96d56Sopenharmony_ciSet a property.
7507db96d56Sopenharmony_ci[clinic start generated code]*/
7517db96d56Sopenharmony_ci
7527db96d56Sopenharmony_cistatic PyObject *
7537db96d56Sopenharmony_ci_msi_SummaryInformation_SetProperty_impl(msiobj *self, int field,
7547db96d56Sopenharmony_ci                                         PyObject *data)
7557db96d56Sopenharmony_ci/*[clinic end generated code: output=3d4692c8984bb675 input=f2a7811b905abbed]*/
7567db96d56Sopenharmony_ci{
7577db96d56Sopenharmony_ci    int status;
7587db96d56Sopenharmony_ci
7597db96d56Sopenharmony_ci    if (PyUnicode_Check(data)) {
7607db96d56Sopenharmony_ci#if USE_UNICODE_WCHAR_CACHE
7617db96d56Sopenharmony_ci        const WCHAR *value = _PyUnicode_AsUnicode(data);
7627db96d56Sopenharmony_ci#else /* USE_UNICODE_WCHAR_CACHE */
7637db96d56Sopenharmony_ci        WCHAR *value = PyUnicode_AsWideCharString(data, NULL);
7647db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */
7657db96d56Sopenharmony_ci        if (value == NULL) {
7667db96d56Sopenharmony_ci            return NULL;
7677db96d56Sopenharmony_ci        }
7687db96d56Sopenharmony_ci        status = MsiSummaryInfoSetPropertyW(self->h, field, VT_LPSTR,
7697db96d56Sopenharmony_ci            0, NULL, value);
7707db96d56Sopenharmony_ci#if !USE_UNICODE_WCHAR_CACHE
7717db96d56Sopenharmony_ci        PyMem_Free(value);
7727db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */
7737db96d56Sopenharmony_ci    } else if (PyLong_CheckExact(data)) {
7747db96d56Sopenharmony_ci        long value = PyLong_AsLong(data);
7757db96d56Sopenharmony_ci        if (value == -1 && PyErr_Occurred()) {
7767db96d56Sopenharmony_ci            return NULL;
7777db96d56Sopenharmony_ci        }
7787db96d56Sopenharmony_ci        status = MsiSummaryInfoSetProperty(self->h, field, VT_I4,
7797db96d56Sopenharmony_ci            value, NULL, NULL);
7807db96d56Sopenharmony_ci    } else {
7817db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "unsupported type");
7827db96d56Sopenharmony_ci        return NULL;
7837db96d56Sopenharmony_ci    }
7847db96d56Sopenharmony_ci
7857db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
7867db96d56Sopenharmony_ci        return msierror(status);
7877db96d56Sopenharmony_ci
7887db96d56Sopenharmony_ci    Py_RETURN_NONE;
7897db96d56Sopenharmony_ci}
7907db96d56Sopenharmony_ci
7917db96d56Sopenharmony_ci
7927db96d56Sopenharmony_ci/*[clinic input]
7937db96d56Sopenharmony_ci_msi.SummaryInformation.Persist
7947db96d56Sopenharmony_ci
7957db96d56Sopenharmony_ciWrite the modified properties to the summary information stream.
7967db96d56Sopenharmony_ci[clinic start generated code]*/
7977db96d56Sopenharmony_ci
7987db96d56Sopenharmony_cistatic PyObject *
7997db96d56Sopenharmony_ci_msi_SummaryInformation_Persist_impl(msiobj *self)
8007db96d56Sopenharmony_ci/*[clinic end generated code: output=c564bd17f5e122c9 input=e3dda9d530095ef7]*/
8017db96d56Sopenharmony_ci{
8027db96d56Sopenharmony_ci    int status;
8037db96d56Sopenharmony_ci
8047db96d56Sopenharmony_ci    status = MsiSummaryInfoPersist(self->h);
8057db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
8067db96d56Sopenharmony_ci        return msierror(status);
8077db96d56Sopenharmony_ci    Py_RETURN_NONE;
8087db96d56Sopenharmony_ci}
8097db96d56Sopenharmony_ci
8107db96d56Sopenharmony_cistatic PyMethodDef summary_methods[] = {
8117db96d56Sopenharmony_ci    _MSI_SUMMARYINFORMATION_GETPROPERTY_METHODDEF
8127db96d56Sopenharmony_ci    _MSI_SUMMARYINFORMATION_GETPROPERTYCOUNT_METHODDEF
8137db96d56Sopenharmony_ci    _MSI_SUMMARYINFORMATION_SETPROPERTY_METHODDEF
8147db96d56Sopenharmony_ci    _MSI_SUMMARYINFORMATION_PERSIST_METHODDEF
8157db96d56Sopenharmony_ci    { NULL, NULL }
8167db96d56Sopenharmony_ci};
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_cistatic PyTypeObject summary_Type = {
8197db96d56Sopenharmony_ci        PyVarObject_HEAD_INIT(NULL, 0)
8207db96d56Sopenharmony_ci        "_msi.SummaryInformation",              /*tp_name*/
8217db96d56Sopenharmony_ci        sizeof(msiobj), /*tp_basicsize*/
8227db96d56Sopenharmony_ci        0,                      /*tp_itemsize*/
8237db96d56Sopenharmony_ci        /* methods */
8247db96d56Sopenharmony_ci        (destructor)msiobj_dealloc, /*tp_dealloc*/
8257db96d56Sopenharmony_ci        0,                      /*tp_vectorcall_offset*/
8267db96d56Sopenharmony_ci        0,                      /*tp_getattr*/
8277db96d56Sopenharmony_ci        0,                      /*tp_setattr*/
8287db96d56Sopenharmony_ci        0,                      /*tp_as_async*/
8297db96d56Sopenharmony_ci        0,                      /*tp_repr*/
8307db96d56Sopenharmony_ci        0,                      /*tp_as_number*/
8317db96d56Sopenharmony_ci        0,                      /*tp_as_sequence*/
8327db96d56Sopenharmony_ci        0,                      /*tp_as_mapping*/
8337db96d56Sopenharmony_ci        0,                      /*tp_hash*/
8347db96d56Sopenharmony_ci        0,                      /*tp_call*/
8357db96d56Sopenharmony_ci        0,                      /*tp_str*/
8367db96d56Sopenharmony_ci        PyObject_GenericGetAttr,/*tp_getattro*/
8377db96d56Sopenharmony_ci        PyObject_GenericSetAttr,/*tp_setattro*/
8387db96d56Sopenharmony_ci        0,                      /*tp_as_buffer*/
8397db96d56Sopenharmony_ci        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
8407db96d56Sopenharmony_ci        0,                      /*tp_doc*/
8417db96d56Sopenharmony_ci        0,                      /*tp_traverse*/
8427db96d56Sopenharmony_ci        0,                      /*tp_clear*/
8437db96d56Sopenharmony_ci        0,                      /*tp_richcompare*/
8447db96d56Sopenharmony_ci        0,                      /*tp_weaklistoffset*/
8457db96d56Sopenharmony_ci        0,                      /*tp_iter*/
8467db96d56Sopenharmony_ci        0,                      /*tp_iternext*/
8477db96d56Sopenharmony_ci        summary_methods,        /*tp_methods*/
8487db96d56Sopenharmony_ci        0,                      /*tp_members*/
8497db96d56Sopenharmony_ci        0,                      /*tp_getset*/
8507db96d56Sopenharmony_ci        0,                      /*tp_base*/
8517db96d56Sopenharmony_ci        0,                      /*tp_dict*/
8527db96d56Sopenharmony_ci        0,                      /*tp_descr_get*/
8537db96d56Sopenharmony_ci        0,                      /*tp_descr_set*/
8547db96d56Sopenharmony_ci        0,                      /*tp_dictoffset*/
8557db96d56Sopenharmony_ci        0,                      /*tp_init*/
8567db96d56Sopenharmony_ci        0,                      /*tp_alloc*/
8577db96d56Sopenharmony_ci        0,                      /*tp_new*/
8587db96d56Sopenharmony_ci        0,                      /*tp_free*/
8597db96d56Sopenharmony_ci        0,                      /*tp_is_gc*/
8607db96d56Sopenharmony_ci};
8617db96d56Sopenharmony_ci
8627db96d56Sopenharmony_ci/*************************** View objects **************/
8637db96d56Sopenharmony_ci
8647db96d56Sopenharmony_ci/*[clinic input]
8657db96d56Sopenharmony_ci_msi.View.Execute
8667db96d56Sopenharmony_ci    params as oparams: object
8677db96d56Sopenharmony_ci        a record describing actual values of the parameter tokens
8687db96d56Sopenharmony_ci        in the query or None
8697db96d56Sopenharmony_ci    /
8707db96d56Sopenharmony_ci
8717db96d56Sopenharmony_ciExecute the SQL query of the view.
8727db96d56Sopenharmony_ci[clinic start generated code]*/
8737db96d56Sopenharmony_ci
8747db96d56Sopenharmony_cistatic PyObject *
8757db96d56Sopenharmony_ci_msi_View_Execute(msiobj *self, PyObject *oparams)
8767db96d56Sopenharmony_ci/*[clinic end generated code: output=f0f65fd2900bcb4e input=cb163a15d453348e]*/
8777db96d56Sopenharmony_ci{
8787db96d56Sopenharmony_ci    int status;
8797db96d56Sopenharmony_ci    MSIHANDLE params = 0;
8807db96d56Sopenharmony_ci
8817db96d56Sopenharmony_ci    if (oparams != Py_None) {
8827db96d56Sopenharmony_ci        if (!Py_IS_TYPE(oparams, &record_Type)) {
8837db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError, "Execute argument must be a record");
8847db96d56Sopenharmony_ci            return NULL;
8857db96d56Sopenharmony_ci        }
8867db96d56Sopenharmony_ci        params = ((msiobj*)oparams)->h;
8877db96d56Sopenharmony_ci    }
8887db96d56Sopenharmony_ci
8897db96d56Sopenharmony_ci    status = MsiViewExecute(self->h, params);
8907db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
8917db96d56Sopenharmony_ci        return msierror(status);
8927db96d56Sopenharmony_ci
8937db96d56Sopenharmony_ci    Py_RETURN_NONE;
8947db96d56Sopenharmony_ci}
8957db96d56Sopenharmony_ci
8967db96d56Sopenharmony_ci/*[clinic input]
8977db96d56Sopenharmony_ci_msi.View.Fetch
8987db96d56Sopenharmony_ci
8997db96d56Sopenharmony_ciReturn a result record of the query.
9007db96d56Sopenharmony_ci[clinic start generated code]*/
9017db96d56Sopenharmony_ci
9027db96d56Sopenharmony_cistatic PyObject *
9037db96d56Sopenharmony_ci_msi_View_Fetch_impl(msiobj *self)
9047db96d56Sopenharmony_ci/*[clinic end generated code: output=ba154a3794537d4e input=7f3e3d06c449001c]*/
9057db96d56Sopenharmony_ci{
9067db96d56Sopenharmony_ci    int status;
9077db96d56Sopenharmony_ci    MSIHANDLE result;
9087db96d56Sopenharmony_ci
9097db96d56Sopenharmony_ci    status = MsiViewFetch(self->h, &result);
9107db96d56Sopenharmony_ci    if (status == ERROR_NO_MORE_ITEMS) {
9117db96d56Sopenharmony_ci        Py_RETURN_NONE;
9127db96d56Sopenharmony_ci    } else if (status != ERROR_SUCCESS) {
9137db96d56Sopenharmony_ci        return msierror(status);
9147db96d56Sopenharmony_ci    }
9157db96d56Sopenharmony_ci
9167db96d56Sopenharmony_ci    return record_new(result);
9177db96d56Sopenharmony_ci}
9187db96d56Sopenharmony_ci
9197db96d56Sopenharmony_ci/*[clinic input]
9207db96d56Sopenharmony_ci_msi.View.GetColumnInfo
9217db96d56Sopenharmony_ci    kind: int
9227db96d56Sopenharmony_ci        MSICOLINFO_NAMES or MSICOLINFO_TYPES
9237db96d56Sopenharmony_ci    /
9247db96d56Sopenharmony_ci
9257db96d56Sopenharmony_ciReturn a record describing the columns of the view.
9267db96d56Sopenharmony_ci[clinic start generated code]*/
9277db96d56Sopenharmony_ci
9287db96d56Sopenharmony_cistatic PyObject *
9297db96d56Sopenharmony_ci_msi_View_GetColumnInfo_impl(msiobj *self, int kind)
9307db96d56Sopenharmony_ci/*[clinic end generated code: output=e7c1697db9403660 input=afedb892bf564a3b]*/
9317db96d56Sopenharmony_ci{
9327db96d56Sopenharmony_ci    int status;
9337db96d56Sopenharmony_ci    MSIHANDLE result;
9347db96d56Sopenharmony_ci
9357db96d56Sopenharmony_ci    if ((status = MsiViewGetColumnInfo(self->h, kind, &result)) != ERROR_SUCCESS)
9367db96d56Sopenharmony_ci        return msierror(status);
9377db96d56Sopenharmony_ci
9387db96d56Sopenharmony_ci    return record_new(result);
9397db96d56Sopenharmony_ci}
9407db96d56Sopenharmony_ci
9417db96d56Sopenharmony_ci/*[clinic input]
9427db96d56Sopenharmony_ci_msi.View.Modify
9437db96d56Sopenharmony_ci    kind: int
9447db96d56Sopenharmony_ci        one of the MSIMODIFY_* constants
9457db96d56Sopenharmony_ci    data: object
9467db96d56Sopenharmony_ci        a record describing the new data
9477db96d56Sopenharmony_ci    /
9487db96d56Sopenharmony_ci
9497db96d56Sopenharmony_ciModify the view.
9507db96d56Sopenharmony_ci[clinic start generated code]*/
9517db96d56Sopenharmony_ci
9527db96d56Sopenharmony_cistatic PyObject *
9537db96d56Sopenharmony_ci_msi_View_Modify_impl(msiobj *self, int kind, PyObject *data)
9547db96d56Sopenharmony_ci/*[clinic end generated code: output=69aaf3ce8ddac0ba input=2828de22de0d47b4]*/
9557db96d56Sopenharmony_ci{
9567db96d56Sopenharmony_ci    int status;
9577db96d56Sopenharmony_ci
9587db96d56Sopenharmony_ci    if (!Py_IS_TYPE(data, &record_Type)) {
9597db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "Modify expects a record object");
9607db96d56Sopenharmony_ci        return NULL;
9617db96d56Sopenharmony_ci    }
9627db96d56Sopenharmony_ci
9637db96d56Sopenharmony_ci    if ((status = MsiViewModify(self->h, kind, ((msiobj*)data)->h)) != ERROR_SUCCESS)
9647db96d56Sopenharmony_ci        return msierror(status);
9657db96d56Sopenharmony_ci
9667db96d56Sopenharmony_ci    Py_RETURN_NONE;
9677db96d56Sopenharmony_ci}
9687db96d56Sopenharmony_ci
9697db96d56Sopenharmony_ci/*[clinic input]
9707db96d56Sopenharmony_ci_msi.View.Close
9717db96d56Sopenharmony_ci
9727db96d56Sopenharmony_ciClose the view.
9737db96d56Sopenharmony_ci[clinic start generated code]*/
9747db96d56Sopenharmony_ci
9757db96d56Sopenharmony_cistatic PyObject *
9767db96d56Sopenharmony_ci_msi_View_Close_impl(msiobj *self)
9777db96d56Sopenharmony_ci/*[clinic end generated code: output=488f7b8645ca104a input=de6927d1308c401c]*/
9787db96d56Sopenharmony_ci{
9797db96d56Sopenharmony_ci    int status;
9807db96d56Sopenharmony_ci
9817db96d56Sopenharmony_ci    if ((status = MsiViewClose(self->h)) != ERROR_SUCCESS)
9827db96d56Sopenharmony_ci        return msierror(status);
9837db96d56Sopenharmony_ci
9847db96d56Sopenharmony_ci    Py_RETURN_NONE;
9857db96d56Sopenharmony_ci}
9867db96d56Sopenharmony_ci
9877db96d56Sopenharmony_cistatic PyMethodDef view_methods[] = {
9887db96d56Sopenharmony_ci    _MSI_VIEW_EXECUTE_METHODDEF
9897db96d56Sopenharmony_ci    _MSI_VIEW_GETCOLUMNINFO_METHODDEF
9907db96d56Sopenharmony_ci    _MSI_VIEW_FETCH_METHODDEF
9917db96d56Sopenharmony_ci    _MSI_VIEW_MODIFY_METHODDEF
9927db96d56Sopenharmony_ci    _MSI_VIEW_CLOSE_METHODDEF
9937db96d56Sopenharmony_ci    { NULL, NULL }
9947db96d56Sopenharmony_ci};
9957db96d56Sopenharmony_ci
9967db96d56Sopenharmony_cistatic PyTypeObject msiview_Type = {
9977db96d56Sopenharmony_ci        PyVarObject_HEAD_INIT(NULL, 0)
9987db96d56Sopenharmony_ci        "_msi.View",            /*tp_name*/
9997db96d56Sopenharmony_ci        sizeof(msiobj), /*tp_basicsize*/
10007db96d56Sopenharmony_ci        0,                      /*tp_itemsize*/
10017db96d56Sopenharmony_ci        /* methods */
10027db96d56Sopenharmony_ci        (destructor)msiobj_dealloc, /*tp_dealloc*/
10037db96d56Sopenharmony_ci        0,                      /*tp_vectorcall_offset*/
10047db96d56Sopenharmony_ci        0,                      /*tp_getattr*/
10057db96d56Sopenharmony_ci        0,                      /*tp_setattr*/
10067db96d56Sopenharmony_ci        0,                      /*tp_as_async*/
10077db96d56Sopenharmony_ci        0,                      /*tp_repr*/
10087db96d56Sopenharmony_ci        0,                      /*tp_as_number*/
10097db96d56Sopenharmony_ci        0,                      /*tp_as_sequence*/
10107db96d56Sopenharmony_ci        0,                      /*tp_as_mapping*/
10117db96d56Sopenharmony_ci        0,                      /*tp_hash*/
10127db96d56Sopenharmony_ci        0,                      /*tp_call*/
10137db96d56Sopenharmony_ci        0,                      /*tp_str*/
10147db96d56Sopenharmony_ci        PyObject_GenericGetAttr,/*tp_getattro*/
10157db96d56Sopenharmony_ci        PyObject_GenericSetAttr,/*tp_setattro*/
10167db96d56Sopenharmony_ci        0,                      /*tp_as_buffer*/
10177db96d56Sopenharmony_ci        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
10187db96d56Sopenharmony_ci        0,                      /*tp_doc*/
10197db96d56Sopenharmony_ci        0,                      /*tp_traverse*/
10207db96d56Sopenharmony_ci        0,                      /*tp_clear*/
10217db96d56Sopenharmony_ci        0,                      /*tp_richcompare*/
10227db96d56Sopenharmony_ci        0,                      /*tp_weaklistoffset*/
10237db96d56Sopenharmony_ci        0,                      /*tp_iter*/
10247db96d56Sopenharmony_ci        0,                      /*tp_iternext*/
10257db96d56Sopenharmony_ci        view_methods,           /*tp_methods*/
10267db96d56Sopenharmony_ci        0,                      /*tp_members*/
10277db96d56Sopenharmony_ci        0,                      /*tp_getset*/
10287db96d56Sopenharmony_ci        0,                      /*tp_base*/
10297db96d56Sopenharmony_ci        0,                      /*tp_dict*/
10307db96d56Sopenharmony_ci        0,                      /*tp_descr_get*/
10317db96d56Sopenharmony_ci        0,                      /*tp_descr_set*/
10327db96d56Sopenharmony_ci        0,                      /*tp_dictoffset*/
10337db96d56Sopenharmony_ci        0,                      /*tp_init*/
10347db96d56Sopenharmony_ci        0,                      /*tp_alloc*/
10357db96d56Sopenharmony_ci        0,                      /*tp_new*/
10367db96d56Sopenharmony_ci        0,                      /*tp_free*/
10377db96d56Sopenharmony_ci        0,                      /*tp_is_gc*/
10387db96d56Sopenharmony_ci};
10397db96d56Sopenharmony_ci
10407db96d56Sopenharmony_ci/*************************** Database objects **************/
10417db96d56Sopenharmony_ci
10427db96d56Sopenharmony_ci/*[clinic input]
10437db96d56Sopenharmony_ci_msi.Database.OpenView
10447db96d56Sopenharmony_ci    sql: Py_UNICODE
10457db96d56Sopenharmony_ci        the SQL statement to execute
10467db96d56Sopenharmony_ci    /
10477db96d56Sopenharmony_ci
10487db96d56Sopenharmony_ciReturn a view object.
10497db96d56Sopenharmony_ci[clinic start generated code]*/
10507db96d56Sopenharmony_ci
10517db96d56Sopenharmony_cistatic PyObject *
10527db96d56Sopenharmony_ci_msi_Database_OpenView_impl(msiobj *self, const Py_UNICODE *sql)
10537db96d56Sopenharmony_ci/*[clinic end generated code: output=e712e6a11229abfd input=50f1771f37e500df]*/
10547db96d56Sopenharmony_ci{
10557db96d56Sopenharmony_ci    int status;
10567db96d56Sopenharmony_ci    MSIHANDLE hView;
10577db96d56Sopenharmony_ci    msiobj *result;
10587db96d56Sopenharmony_ci
10597db96d56Sopenharmony_ci    if ((status = MsiDatabaseOpenViewW(self->h, sql, &hView)) != ERROR_SUCCESS)
10607db96d56Sopenharmony_ci        return msierror(status);
10617db96d56Sopenharmony_ci
10627db96d56Sopenharmony_ci    result = PyObject_New(struct msiobj, &msiview_Type);
10637db96d56Sopenharmony_ci    if (!result) {
10647db96d56Sopenharmony_ci        MsiCloseHandle(hView);
10657db96d56Sopenharmony_ci        return NULL;
10667db96d56Sopenharmony_ci    }
10677db96d56Sopenharmony_ci
10687db96d56Sopenharmony_ci    result->h = hView;
10697db96d56Sopenharmony_ci    return (PyObject*)result;
10707db96d56Sopenharmony_ci}
10717db96d56Sopenharmony_ci
10727db96d56Sopenharmony_ci/*[clinic input]
10737db96d56Sopenharmony_ci_msi.Database.Commit
10747db96d56Sopenharmony_ci
10757db96d56Sopenharmony_ciCommit the changes pending in the current transaction.
10767db96d56Sopenharmony_ci[clinic start generated code]*/
10777db96d56Sopenharmony_ci
10787db96d56Sopenharmony_cistatic PyObject *
10797db96d56Sopenharmony_ci_msi_Database_Commit_impl(msiobj *self)
10807db96d56Sopenharmony_ci/*[clinic end generated code: output=f33021feb8b0cdd8 input=375bb120d402266d]*/
10817db96d56Sopenharmony_ci{
10827db96d56Sopenharmony_ci    int status;
10837db96d56Sopenharmony_ci
10847db96d56Sopenharmony_ci    if ((status = MsiDatabaseCommit(self->h)) != ERROR_SUCCESS)
10857db96d56Sopenharmony_ci        return msierror(status);
10867db96d56Sopenharmony_ci
10877db96d56Sopenharmony_ci    Py_RETURN_NONE;
10887db96d56Sopenharmony_ci}
10897db96d56Sopenharmony_ci
10907db96d56Sopenharmony_ci/*[clinic input]
10917db96d56Sopenharmony_ci_msi.Database.GetSummaryInformation
10927db96d56Sopenharmony_ci    count: int
10937db96d56Sopenharmony_ci        the maximum number of updated values
10947db96d56Sopenharmony_ci    /
10957db96d56Sopenharmony_ci
10967db96d56Sopenharmony_ciReturn a new summary information object.
10977db96d56Sopenharmony_ci[clinic start generated code]*/
10987db96d56Sopenharmony_ci
10997db96d56Sopenharmony_cistatic PyObject *
11007db96d56Sopenharmony_ci_msi_Database_GetSummaryInformation_impl(msiobj *self, int count)
11017db96d56Sopenharmony_ci/*[clinic end generated code: output=781e51a4ea4da847 input=18a899ead6521735]*/
11027db96d56Sopenharmony_ci{
11037db96d56Sopenharmony_ci    int status;
11047db96d56Sopenharmony_ci    MSIHANDLE result;
11057db96d56Sopenharmony_ci    msiobj *oresult;
11067db96d56Sopenharmony_ci
11077db96d56Sopenharmony_ci    status = MsiGetSummaryInformation(self->h, NULL, count, &result);
11087db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
11097db96d56Sopenharmony_ci        return msierror(status);
11107db96d56Sopenharmony_ci
11117db96d56Sopenharmony_ci    oresult = PyObject_New(struct msiobj, &summary_Type);
11127db96d56Sopenharmony_ci    if (!oresult) {
11137db96d56Sopenharmony_ci        MsiCloseHandle(result);
11147db96d56Sopenharmony_ci        return NULL;
11157db96d56Sopenharmony_ci    }
11167db96d56Sopenharmony_ci
11177db96d56Sopenharmony_ci    oresult->h = result;
11187db96d56Sopenharmony_ci    return (PyObject*)oresult;
11197db96d56Sopenharmony_ci}
11207db96d56Sopenharmony_ci
11217db96d56Sopenharmony_cistatic PyMethodDef db_methods[] = {
11227db96d56Sopenharmony_ci    _MSI_DATABASE_OPENVIEW_METHODDEF
11237db96d56Sopenharmony_ci    _MSI_DATABASE_COMMIT_METHODDEF
11247db96d56Sopenharmony_ci    _MSI_DATABASE_GETSUMMARYINFORMATION_METHODDEF
11257db96d56Sopenharmony_ci    _MSI_DATABASE_CLOSE_METHODDEF
11267db96d56Sopenharmony_ci    { NULL, NULL }
11277db96d56Sopenharmony_ci};
11287db96d56Sopenharmony_ci
11297db96d56Sopenharmony_cistatic PyTypeObject msidb_Type = {
11307db96d56Sopenharmony_ci        PyVarObject_HEAD_INIT(NULL, 0)
11317db96d56Sopenharmony_ci        "_msi.Database",                /*tp_name*/
11327db96d56Sopenharmony_ci        sizeof(msiobj), /*tp_basicsize*/
11337db96d56Sopenharmony_ci        0,                      /*tp_itemsize*/
11347db96d56Sopenharmony_ci        /* methods */
11357db96d56Sopenharmony_ci        (destructor)msiobj_dealloc, /*tp_dealloc*/
11367db96d56Sopenharmony_ci        0,                      /*tp_vectorcall_offset*/
11377db96d56Sopenharmony_ci        0,                      /*tp_getattr*/
11387db96d56Sopenharmony_ci        0,                      /*tp_setattr*/
11397db96d56Sopenharmony_ci        0,                      /*tp_as_async*/
11407db96d56Sopenharmony_ci        0,                      /*tp_repr*/
11417db96d56Sopenharmony_ci        0,                      /*tp_as_number*/
11427db96d56Sopenharmony_ci        0,                      /*tp_as_sequence*/
11437db96d56Sopenharmony_ci        0,                      /*tp_as_mapping*/
11447db96d56Sopenharmony_ci        0,                      /*tp_hash*/
11457db96d56Sopenharmony_ci        0,                      /*tp_call*/
11467db96d56Sopenharmony_ci        0,                      /*tp_str*/
11477db96d56Sopenharmony_ci        PyObject_GenericGetAttr,/*tp_getattro*/
11487db96d56Sopenharmony_ci        PyObject_GenericSetAttr,/*tp_setattro*/
11497db96d56Sopenharmony_ci        0,                      /*tp_as_buffer*/
11507db96d56Sopenharmony_ci        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
11517db96d56Sopenharmony_ci        0,                      /*tp_doc*/
11527db96d56Sopenharmony_ci        0,                      /*tp_traverse*/
11537db96d56Sopenharmony_ci        0,                      /*tp_clear*/
11547db96d56Sopenharmony_ci        0,                      /*tp_richcompare*/
11557db96d56Sopenharmony_ci        0,                      /*tp_weaklistoffset*/
11567db96d56Sopenharmony_ci        0,                      /*tp_iter*/
11577db96d56Sopenharmony_ci        0,                      /*tp_iternext*/
11587db96d56Sopenharmony_ci        db_methods,             /*tp_methods*/
11597db96d56Sopenharmony_ci        0,                      /*tp_members*/
11607db96d56Sopenharmony_ci        0,                      /*tp_getset*/
11617db96d56Sopenharmony_ci        0,                      /*tp_base*/
11627db96d56Sopenharmony_ci        0,                      /*tp_dict*/
11637db96d56Sopenharmony_ci        0,                      /*tp_descr_get*/
11647db96d56Sopenharmony_ci        0,                      /*tp_descr_set*/
11657db96d56Sopenharmony_ci        0,                      /*tp_dictoffset*/
11667db96d56Sopenharmony_ci        0,                      /*tp_init*/
11677db96d56Sopenharmony_ci        0,                      /*tp_alloc*/
11687db96d56Sopenharmony_ci        0,                      /*tp_new*/
11697db96d56Sopenharmony_ci        0,                      /*tp_free*/
11707db96d56Sopenharmony_ci        0,                      /*tp_is_gc*/
11717db96d56Sopenharmony_ci};
11727db96d56Sopenharmony_ci
11737db96d56Sopenharmony_ci#define Py_NOT_PERSIST(x, flag)                        \
11747db96d56Sopenharmony_ci    (x != (SIZE_T)(flag) &&                      \
11757db96d56Sopenharmony_ci    x != ((SIZE_T)(flag) | MSIDBOPEN_PATCHFILE))
11767db96d56Sopenharmony_ci
11777db96d56Sopenharmony_ci#define Py_INVALID_PERSIST(x)                \
11787db96d56Sopenharmony_ci    (Py_NOT_PERSIST(x, MSIDBOPEN_READONLY) &&  \
11797db96d56Sopenharmony_ci    Py_NOT_PERSIST(x, MSIDBOPEN_TRANSACT) &&   \
11807db96d56Sopenharmony_ci    Py_NOT_PERSIST(x, MSIDBOPEN_DIRECT) &&     \
11817db96d56Sopenharmony_ci    Py_NOT_PERSIST(x, MSIDBOPEN_CREATE) &&     \
11827db96d56Sopenharmony_ci    Py_NOT_PERSIST(x, MSIDBOPEN_CREATEDIRECT))
11837db96d56Sopenharmony_ci
11847db96d56Sopenharmony_ci/*[clinic input]
11857db96d56Sopenharmony_ci_msi.OpenDatabase
11867db96d56Sopenharmony_ci    path: Py_UNICODE
11877db96d56Sopenharmony_ci        the file name of the MSI file
11887db96d56Sopenharmony_ci    persist: int
11897db96d56Sopenharmony_ci        the persistence mode
11907db96d56Sopenharmony_ci    /
11917db96d56Sopenharmony_ci
11927db96d56Sopenharmony_ciReturn a new database object.
11937db96d56Sopenharmony_ci[clinic start generated code]*/
11947db96d56Sopenharmony_ci
11957db96d56Sopenharmony_cistatic PyObject *
11967db96d56Sopenharmony_ci_msi_OpenDatabase_impl(PyObject *module, const Py_UNICODE *path, int persist)
11977db96d56Sopenharmony_ci/*[clinic end generated code: output=d34b7202b745de05 input=1300f3b97659559b]*/
11987db96d56Sopenharmony_ci{
11997db96d56Sopenharmony_ci    int status;
12007db96d56Sopenharmony_ci    MSIHANDLE h;
12017db96d56Sopenharmony_ci    msiobj *result;
12027db96d56Sopenharmony_ci
12037db96d56Sopenharmony_ci    /* We need to validate that persist is a valid MSIDBOPEN_* value. Otherwise,
12047db96d56Sopenharmony_ci       MsiOpenDatabase may treat the value as a pointer, leading to unexpected
12057db96d56Sopenharmony_ci       behavior. */
12067db96d56Sopenharmony_ci    if (Py_INVALID_PERSIST(persist))
12077db96d56Sopenharmony_ci        return msierror(ERROR_INVALID_PARAMETER);
12087db96d56Sopenharmony_ci    status = MsiOpenDatabaseW(path, (LPCWSTR)(SIZE_T)persist, &h);
12097db96d56Sopenharmony_ci    if (status != ERROR_SUCCESS)
12107db96d56Sopenharmony_ci        return msierror(status);
12117db96d56Sopenharmony_ci
12127db96d56Sopenharmony_ci    result = PyObject_New(struct msiobj, &msidb_Type);
12137db96d56Sopenharmony_ci    if (!result) {
12147db96d56Sopenharmony_ci        MsiCloseHandle(h);
12157db96d56Sopenharmony_ci        return NULL;
12167db96d56Sopenharmony_ci    }
12177db96d56Sopenharmony_ci    result->h = h;
12187db96d56Sopenharmony_ci    return (PyObject*)result;
12197db96d56Sopenharmony_ci}
12207db96d56Sopenharmony_ci
12217db96d56Sopenharmony_ci/*[clinic input]
12227db96d56Sopenharmony_ci_msi.CreateRecord
12237db96d56Sopenharmony_ci    count: int
12247db96d56Sopenharmony_ci        the number of fields of the record
12257db96d56Sopenharmony_ci    /
12267db96d56Sopenharmony_ci
12277db96d56Sopenharmony_ciReturn a new record object.
12287db96d56Sopenharmony_ci[clinic start generated code]*/
12297db96d56Sopenharmony_ci
12307db96d56Sopenharmony_cistatic PyObject *
12317db96d56Sopenharmony_ci_msi_CreateRecord_impl(PyObject *module, int count)
12327db96d56Sopenharmony_ci/*[clinic end generated code: output=0ba0a00beea3e99e input=53f17d5b5d9b077d]*/
12337db96d56Sopenharmony_ci{
12347db96d56Sopenharmony_ci    MSIHANDLE h;
12357db96d56Sopenharmony_ci
12367db96d56Sopenharmony_ci    h = MsiCreateRecord(count);
12377db96d56Sopenharmony_ci    if (h == 0)
12387db96d56Sopenharmony_ci        return msierror(0);
12397db96d56Sopenharmony_ci
12407db96d56Sopenharmony_ci    return record_new(h);
12417db96d56Sopenharmony_ci}
12427db96d56Sopenharmony_ci
12437db96d56Sopenharmony_ci
12447db96d56Sopenharmony_cistatic PyMethodDef msi_methods[] = {
12457db96d56Sopenharmony_ci        _MSI_UUIDCREATE_METHODDEF
12467db96d56Sopenharmony_ci        _MSI_FCICREATE_METHODDEF
12477db96d56Sopenharmony_ci        _MSI_OPENDATABASE_METHODDEF
12487db96d56Sopenharmony_ci        _MSI_CREATERECORD_METHODDEF
12497db96d56Sopenharmony_ci        {NULL,          NULL}           /* sentinel */
12507db96d56Sopenharmony_ci};
12517db96d56Sopenharmony_ci
12527db96d56Sopenharmony_cistatic char msi_doc[] = "Documentation";
12537db96d56Sopenharmony_ci
12547db96d56Sopenharmony_ci
12557db96d56Sopenharmony_cistatic struct PyModuleDef _msimodule = {
12567db96d56Sopenharmony_ci        PyModuleDef_HEAD_INIT,
12577db96d56Sopenharmony_ci        "_msi",
12587db96d56Sopenharmony_ci        msi_doc,
12597db96d56Sopenharmony_ci        -1,
12607db96d56Sopenharmony_ci        msi_methods,
12617db96d56Sopenharmony_ci        NULL,
12627db96d56Sopenharmony_ci        NULL,
12637db96d56Sopenharmony_ci        NULL,
12647db96d56Sopenharmony_ci        NULL
12657db96d56Sopenharmony_ci};
12667db96d56Sopenharmony_ci
12677db96d56Sopenharmony_ciPyMODINIT_FUNC
12687db96d56Sopenharmony_ciPyInit__msi(void)
12697db96d56Sopenharmony_ci{
12707db96d56Sopenharmony_ci    PyObject *m;
12717db96d56Sopenharmony_ci
12727db96d56Sopenharmony_ci    m = PyModule_Create(&_msimodule);
12737db96d56Sopenharmony_ci    if (m == NULL)
12747db96d56Sopenharmony_ci        return NULL;
12757db96d56Sopenharmony_ci
12767db96d56Sopenharmony_ci    PyModule_AddIntConstant(m, "MSIDBOPEN_CREATEDIRECT", (long)(SIZE_T)MSIDBOPEN_CREATEDIRECT);
12777db96d56Sopenharmony_ci    PyModule_AddIntConstant(m, "MSIDBOPEN_CREATE", (long)(SIZE_T)MSIDBOPEN_CREATE);
12787db96d56Sopenharmony_ci    PyModule_AddIntConstant(m, "MSIDBOPEN_DIRECT", (long)(SIZE_T)MSIDBOPEN_DIRECT);
12797db96d56Sopenharmony_ci    PyModule_AddIntConstant(m, "MSIDBOPEN_READONLY", (long)(SIZE_T)MSIDBOPEN_READONLY);
12807db96d56Sopenharmony_ci    PyModule_AddIntConstant(m, "MSIDBOPEN_TRANSACT", (long)(SIZE_T)MSIDBOPEN_TRANSACT);
12817db96d56Sopenharmony_ci    PyModule_AddIntConstant(m, "MSIDBOPEN_PATCHFILE", (long)(SIZE_T)MSIDBOPEN_PATCHFILE);
12827db96d56Sopenharmony_ci
12837db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSICOLINFO_NAMES);
12847db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSICOLINFO_TYPES);
12857db96d56Sopenharmony_ci
12867db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_SEEK);
12877db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_REFRESH);
12887db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_INSERT);
12897db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_UPDATE);
12907db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_ASSIGN);
12917db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_REPLACE);
12927db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_MERGE);
12937db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_DELETE);
12947db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_INSERT_TEMPORARY);
12957db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE);
12967db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE_NEW);
12977db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE_FIELD);
12987db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE_DELETE);
12997db96d56Sopenharmony_ci
13007db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_CODEPAGE);
13017db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_TITLE);
13027db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_SUBJECT);
13037db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_AUTHOR);
13047db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_KEYWORDS);
13057db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_COMMENTS);
13067db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_TEMPLATE);
13077db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_LASTAUTHOR);
13087db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_REVNUMBER);
13097db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_LASTPRINTED);
13107db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_CREATE_DTM);
13117db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_LASTSAVE_DTM);
13127db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_PAGECOUNT);
13137db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_WORDCOUNT);
13147db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_CHARCOUNT);
13157db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_APPNAME);
13167db96d56Sopenharmony_ci    PyModule_AddIntMacro(m, PID_SECURITY);
13177db96d56Sopenharmony_ci
13187db96d56Sopenharmony_ci    MSIError = PyErr_NewException ("_msi.MSIError", NULL, NULL);
13197db96d56Sopenharmony_ci    if (!MSIError)
13207db96d56Sopenharmony_ci        return NULL;
13217db96d56Sopenharmony_ci    PyModule_AddObject(m, "MSIError", MSIError);
13227db96d56Sopenharmony_ci    return m;
13237db96d56Sopenharmony_ci}
1324