/* Helper library for MSI creation with Python.
 * Copyright (C) 2005 Martin v. Löwis
 * Licensed to PSF under a contributor agreement.
 */

#include <Python.h>
#include <fci.h>
#include <fcntl.h>
#include <windows.h>
#include <msi.h>
#include <msiquery.h>
#include <msidefs.h>
#include <rpc.h>

/*[clinic input]
module _msi
class _msi.Record "msiobj *" "&record_Type"
class _msi.SummaryInformation "msiobj *" "&summary_Type"
class _msi.View "msiobj *" "&msiview_Type"
class _msi.Database "msiobj *" "&msidb_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=89a3605762cf4bdc]*/

static PyObject *MSIError;

/*[clinic input]
_msi.UuidCreate

Return the string representation of a new unique identifier.
[clinic start generated code]*/

static PyObject *
_msi_UuidCreate_impl(PyObject *module)
/*[clinic end generated code: output=534ecf36f10af98e input=168024ab4b3e832b]*/
{
    UUID result;
    wchar_t *cresult;
    PyObject *oresult;

    /* May return ok, local only, and no address.
       For local only, the documentation says we still get a uuid.
       For RPC_S_UUID_NO_ADDRESS, it's not clear whether we can
       use the result. */
    if (UuidCreate(&result) == RPC_S_UUID_NO_ADDRESS) {
        PyErr_SetString(PyExc_NotImplementedError, "processing 'no address' result");
        return NULL;
    }

    if (UuidToStringW(&result, &cresult) == RPC_S_OUT_OF_MEMORY) {
        PyErr_SetString(PyExc_MemoryError, "out of memory in uuidgen");
        return NULL;
    }

    oresult = PyUnicode_FromWideChar(cresult, wcslen(cresult));
    RpcStringFreeW(&cresult);
    return oresult;

}

/* Helper for converting file names from UTF-8 to wchat_t*.  */
static wchar_t *
utf8_to_wchar(const char *s, int *err)
{
    PyObject *obj = PyUnicode_FromString(s);
    if (obj == NULL) {
        if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
            *err = ENOMEM;
        }
        else {
            *err = EINVAL;
        }
        PyErr_Clear();
        return NULL;
    }
    wchar_t *ws = PyUnicode_AsWideCharString(obj, NULL);
    if (ws == NULL) {
        *err = ENOMEM;
        PyErr_Clear();
    }
    Py_DECREF(obj);
    return ws;
}

/* FCI callback functions */

static FNFCIALLOC(cb_alloc)
{
    return PyMem_RawMalloc(cb);
}

static FNFCIFREE(cb_free)
{
    PyMem_RawFree(memory);
}

static FNFCIOPEN(cb_open)
{
    wchar_t *ws = utf8_to_wchar(pszFile, err);
    if (ws == NULL) {
        return -1;
    }
    int result = _wopen(ws, oflag | O_NOINHERIT, pmode);
    PyMem_Free(ws);
    if (result == -1)
        *err = errno;
    return result;
}

static FNFCIREAD(cb_read)
{
    UINT result = (UINT)_read((int)hf, memory, cb);
    if (result != cb)
        *err = errno;
    return result;
}

static FNFCIWRITE(cb_write)
{
    UINT result = (UINT)_write((int)hf, memory, cb);
    if (result != cb)
        *err = errno;
    return result;
}

static FNFCICLOSE(cb_close)
{
    int result = _close((int)hf);
    if (result != 0)
        *err = errno;
    return result;
}

static FNFCISEEK(cb_seek)
{
    long result = (long)_lseek((int)hf, dist, seektype);
    if (result == -1)
        *err = errno;
    return result;
}

static FNFCIDELETE(cb_delete)
{
    wchar_t *ws = utf8_to_wchar(pszFile, err);
    if (ws == NULL) {
        return -1;
    }
    int result = _wremove(ws);
    PyMem_Free(ws);
    if (result != 0)
        *err = errno;
    return result;
}

static FNFCIFILEPLACED(cb_fileplaced)
{
    return 0;
}

static FNFCIGETTEMPFILE(cb_gettempfile)
{
    char *name = _tempnam("", "tmp");
    if ((name != NULL) && ((int)strlen(name) < cbTempName)) {
        strcpy(pszTempName, name);
        free(name);
        return TRUE;
    }

    if (name) free(name);
    return FALSE;
}

static FNFCISTATUS(cb_status)
{
    if (pv) {
        _Py_IDENTIFIER(status);

        PyObject *result = _PyObject_CallMethodId(pv, &PyId_status, "iii", typeStatus, cb1, cb2);
        if (result == NULL)
            return -1;
        Py_DECREF(result);
    }
    return 0;
}

static FNFCIGETNEXTCABINET(cb_getnextcabinet)
{
    if (pv) {
        _Py_IDENTIFIER(getnextcabinet);

        PyObject *result = _PyObject_CallMethodId(pv, &PyId_getnextcabinet, "i", pccab->iCab);
        if (result == NULL)
            return -1;
        if (!PyBytes_Check(result)) {
            PyErr_Format(PyExc_TypeError,
                "Incorrect return type %s from getnextcabinet",
                Py_TYPE(result)->tp_name);
            Py_DECREF(result);
            return FALSE;
        }
        strncpy(pccab->szCab, PyBytes_AsString(result), sizeof(pccab->szCab));
        return TRUE;
    }
    return FALSE;
}

static FNFCIGETOPENINFO(cb_getopeninfo)
{
    BY_HANDLE_FILE_INFORMATION bhfi;
    FILETIME filetime;
    HANDLE handle;

    wchar_t *ws = utf8_to_wchar(pszName, err);
    if (ws == NULL) {
        return -1;
    }

    /* Need Win32 handle to get time stamps */
    handle = CreateFileW(ws, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (handle == INVALID_HANDLE_VALUE) {
        PyMem_Free(ws);
        return -1;
    }

    if (GetFileInformationByHandle(handle, &bhfi) == FALSE) {
        CloseHandle(handle);
        PyMem_Free(ws);
        return -1;
    }

    FileTimeToLocalFileTime(&bhfi.ftLastWriteTime, &filetime);
    FileTimeToDosDateTime(&filetime, pdate, ptime);

    *pattribs = (int)(bhfi.dwFileAttributes &
        (_A_RDONLY | _A_SYSTEM | _A_HIDDEN | _A_ARCH));

    CloseHandle(handle);

    int result = _wopen(ws, _O_RDONLY | _O_BINARY | O_NOINHERIT);
    PyMem_Free(ws);
    return result;
}

/*[clinic input]
_msi.FCICreate
    cabname: str
        the name of the CAB file
    files: object
        a list of tuples, each containing the name of the file on disk,
        and the name of the file inside the CAB file
    /

Create a new CAB file.
[clinic start generated code]*/

static PyObject *
_msi_FCICreate_impl(PyObject *module, const char *cabname, PyObject *files)
/*[clinic end generated code: output=55dc05728361b799 input=1d2d75fdc8b44b71]*/
{
    const char *p;
    CCAB ccab;
    HFCI hfci;
    ERF erf;
    Py_ssize_t i;

    if (!PyList_Check(files)) {
        PyErr_SetString(PyExc_TypeError, "FCICreate expects a list");
        return NULL;
    }

    ccab.cb = INT_MAX; /* no need to split CAB into multiple media */
    ccab.cbFolderThresh = 1000000; /* flush directory after this many bytes */
    ccab.cbReserveCFData = 0;
    ccab.cbReserveCFFolder = 0;
    ccab.cbReserveCFHeader = 0;

    ccab.iCab = 1;
    ccab.iDisk = 1;

    ccab.setID = 0;
    ccab.szDisk[0] = '\0';

    for (i = 0, p = cabname; *p; p++)
        if (*p == '\\' || *p == '/')
            i = p - cabname + 1;

    if (i >= sizeof(ccab.szCabPath) ||
        strlen(cabname+i) >= sizeof(ccab.szCab)) {
        PyErr_SetString(PyExc_ValueError, "path name too long");
        return 0;
    }

    if (i > 0) {
        memcpy(ccab.szCabPath, cabname, i);
        ccab.szCabPath[i] = '\0';
        strcpy(ccab.szCab, cabname+i);
    } else {
        strcpy(ccab.szCabPath, ".\\");
        strcpy(ccab.szCab, cabname);
    }

    hfci = FCICreate(&erf, cb_fileplaced, cb_alloc, cb_free,
        cb_open, cb_read, cb_write, cb_close, cb_seek, cb_delete,
        cb_gettempfile, &ccab, NULL);

    if (hfci == NULL) {
        PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper);
        return NULL;
    }

    for (i=0; i < PyList_GET_SIZE(files); i++) {
        PyObject *item = PyList_GET_ITEM(files, i);
        char *filename, *cabname;

        if (!PyArg_ParseTuple(item, "ss", &filename, &cabname)) {
            PyErr_SetString(PyExc_TypeError, "FCICreate expects a list of tuples containing two strings");
            FCIDestroy(hfci);
            return NULL;
        }

        if (!FCIAddFile(hfci, filename, cabname, FALSE,
            cb_getnextcabinet, cb_status, cb_getopeninfo,
            tcompTYPE_MSZIP))
            goto err;
    }

    if (!FCIFlushCabinet(hfci, FALSE, cb_getnextcabinet, cb_status))
        goto err;

    if (!FCIDestroy(hfci))
        goto err;

    Py_RETURN_NONE;
err:
    if(erf.fError)
        PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper); /* XXX better error type */
    else
        PyErr_SetString(PyExc_ValueError, "FCI general error");

    FCIDestroy(hfci);
    return NULL;
}

typedef struct msiobj{
    PyObject_HEAD
    MSIHANDLE h;
}msiobj;

static void
msiobj_dealloc(msiobj* msidb)
{
    MsiCloseHandle(msidb->h);
    msidb->h = 0;
    PyObject_Free(msidb);
}

static PyObject*
msierror(int status)
{
    int code;
    char buf[2000];
    char *res = buf;
    DWORD size = sizeof(buf);
    MSIHANDLE err = MsiGetLastErrorRecord();

    if (err == 0) {
        switch(status) {
        case ERROR_ACCESS_DENIED:
            PyErr_SetString(MSIError, "access denied");
            return NULL;
        case ERROR_FUNCTION_FAILED:
            PyErr_SetString(MSIError, "function failed");
            return NULL;
        case ERROR_INVALID_DATA:
            PyErr_SetString(MSIError, "invalid data");
            return NULL;
        case ERROR_INVALID_HANDLE:
            PyErr_SetString(MSIError, "invalid handle");
            return NULL;
        case ERROR_INVALID_STATE:
            PyErr_SetString(MSIError, "invalid state");
            return NULL;
        case ERROR_INVALID_PARAMETER:
            PyErr_SetString(MSIError, "invalid parameter");
            return NULL;
        case ERROR_OPEN_FAILED:
            PyErr_SetString(MSIError, "open failed");
            return NULL;
        case ERROR_CREATE_FAILED:
            PyErr_SetString(MSIError, "create failed");
            return NULL;
        default:
            PyErr_Format(MSIError, "unknown error %x", status);
            return NULL;
        }
    }

    code = MsiRecordGetInteger(err, 1); /* XXX code */
    if (MsiFormatRecord(0, err, res, &size) == ERROR_MORE_DATA) {
        res = malloc(size+1);
        if (res == NULL) {
            MsiCloseHandle(err);
            return PyErr_NoMemory();
        }
        MsiFormatRecord(0, err, res, &size);
        res[size]='\0';
    }
    MsiCloseHandle(err);
    PyErr_SetString(MSIError, res);
    if (res != buf)
        free(res);
    return NULL;
}

#include "clinic/_msi.c.h"

/*[clinic input]
_msi.Database.Close

Close the database object.
[clinic start generated code]*/

static PyObject *
_msi_Database_Close_impl(msiobj *self)
/*[clinic end generated code: output=ddf2d7712ea804f1 input=104330ce4a486187]*/
{
    int status;
    if ((status = MsiCloseHandle(self->h)) != ERROR_SUCCESS) {
        return msierror(status);
    }
    self->h = 0;
    Py_RETURN_NONE;
}

/*************************** Record objects **********************/

/*[clinic input]
_msi.Record.GetFieldCount

Return the number of fields of the record.
[clinic start generated code]*/

static PyObject *
_msi_Record_GetFieldCount_impl(msiobj *self)
/*[clinic end generated code: output=112795079c904398 input=5fb9d4071b28897b]*/
{
    return PyLong_FromLong(MsiRecordGetFieldCount(self->h));
}

/*[clinic input]
_msi.Record.GetInteger
    field: unsigned_int(bitwise=True)
    /

Return the value of field as an integer where possible.
[clinic start generated code]*/

static PyObject *
_msi_Record_GetInteger_impl(msiobj *self, unsigned int field)
/*[clinic end generated code: output=7174ebb6e8ed1c79 input=d19209947e2bfe61]*/
{
    int status;

    status = MsiRecordGetInteger(self->h, field);
    if (status == MSI_NULL_INTEGER){
        PyErr_SetString(MSIError, "could not convert record field to integer");
        return NULL;
    }
    return PyLong_FromLong((long) status);
}

/*[clinic input]
_msi.Record.GetString
    field: unsigned_int(bitwise=True)
    /

Return the value of field as a string where possible.
[clinic start generated code]*/

static PyObject *
_msi_Record_GetString_impl(msiobj *self, unsigned int field)
/*[clinic end generated code: output=f670d1b484cfa47c input=ffa11f21450b77d8]*/
{
    unsigned int status;
    WCHAR buf[2000];
    WCHAR *res = buf;
    DWORD size = sizeof(buf);
    PyObject* string;

    status = MsiRecordGetStringW(self->h, field, res, &size);
    if (status == ERROR_MORE_DATA) {
        res = (WCHAR*) malloc((size + 1)*sizeof(WCHAR));
        if (res == NULL)
            return PyErr_NoMemory();
        status = MsiRecordGetStringW(self->h, field, res, &size);
    }
    if (status != ERROR_SUCCESS)
        return msierror((int) status);
    string = PyUnicode_FromWideChar(res, size);
    if (buf != res)
        free(res);
    return string;
}

/*[clinic input]
_msi.Record.ClearData

Set all fields of the record to 0.
[clinic start generated code]*/

static PyObject *
_msi_Record_ClearData_impl(msiobj *self)
/*[clinic end generated code: output=1891467214b977f4 input=2a911c95aaded102]*/
{
    int status = MsiRecordClearData(self->h);
    if (status != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}

/*[clinic input]
_msi.Record.SetString
    field: int
    value: Py_UNICODE
    /

Set field to a string value.
[clinic start generated code]*/

static PyObject *
_msi_Record_SetString_impl(msiobj *self, int field, const Py_UNICODE *value)
/*[clinic end generated code: output=2e37505b0f11f985 input=fb8ec70a2a6148e0]*/
{
    int status;

    if ((status = MsiRecordSetStringW(self->h, field, value)) != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}

/*[clinic input]
_msi.Record.SetStream
    field: int
    value: Py_UNICODE
    /

Set field to the contents of the file named value.
[clinic start generated code]*/

static PyObject *
_msi_Record_SetStream_impl(msiobj *self, int field, const Py_UNICODE *value)
/*[clinic end generated code: output=442facac16913b48 input=a07aa19b865e8292]*/
{
    int status;

    if ((status = MsiRecordSetStreamW(self->h, field, value)) != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}

/*[clinic input]
_msi.Record.SetInteger
    field: int
    value: int
    /

Set field to an integer value.
[clinic start generated code]*/

static PyObject *
_msi_Record_SetInteger_impl(msiobj *self, int field, int value)
/*[clinic end generated code: output=669e8647775d0ce7 input=c571aa775e7e451b]*/
{
    int status;

    if ((status = MsiRecordSetInteger(self->h, field, value)) != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}



static PyMethodDef record_methods[] = {
    _MSI_RECORD_GETFIELDCOUNT_METHODDEF
    _MSI_RECORD_GETINTEGER_METHODDEF
    _MSI_RECORD_GETSTRING_METHODDEF
    _MSI_RECORD_SETSTRING_METHODDEF
    _MSI_RECORD_SETSTREAM_METHODDEF
    _MSI_RECORD_SETINTEGER_METHODDEF
    _MSI_RECORD_CLEARDATA_METHODDEF
    { NULL, NULL }
};

static PyTypeObject record_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "_msi.Record",          /*tp_name*/
        sizeof(msiobj), /*tp_basicsize*/
        0,                      /*tp_itemsize*/
        /* methods */
        (destructor)msiobj_dealloc, /*tp_dealloc*/
        0,                      /*tp_vectorcall_offset*/
        0,                      /*tp_getattr*/
        0,                      /*tp_setattr*/
        0,                      /*tp_as_async*/
        0,                      /*tp_repr*/
        0,                      /*tp_as_number*/
        0,                      /*tp_as_sequence*/
        0,                      /*tp_as_mapping*/
        0,                      /*tp_hash*/
        0,                      /*tp_call*/
        0,                      /*tp_str*/
        PyObject_GenericGetAttr,/*tp_getattro*/
        PyObject_GenericSetAttr,/*tp_setattro*/
        0,                      /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
        0,                      /*tp_doc*/
        0,                      /*tp_traverse*/
        0,                      /*tp_clear*/
        0,                      /*tp_richcompare*/
        0,                      /*tp_weaklistoffset*/
        0,                      /*tp_iter*/
        0,                      /*tp_iternext*/
        record_methods,           /*tp_methods*/
        0,                      /*tp_members*/
        0,                      /*tp_getset*/
        0,                      /*tp_base*/
        0,                      /*tp_dict*/
        0,                      /*tp_descr_get*/
        0,                      /*tp_descr_set*/
        0,                      /*tp_dictoffset*/
        0,                      /*tp_init*/
        0,                      /*tp_alloc*/
        0,                      /*tp_new*/
        0,                      /*tp_free*/
        0,                      /*tp_is_gc*/
};

static PyObject*
record_new(MSIHANDLE h)
{
    msiobj *result = PyObject_New(struct msiobj, &record_Type);

    if (!result) {
        MsiCloseHandle(h);
        return NULL;
    }

    result->h = h;
    return (PyObject*)result;
}

/*************************** SummaryInformation objects **************/

/*[clinic input]
_msi.SummaryInformation.GetProperty
    field: int
        the name of the property, one of the PID_* constants
    /

Return a property of the summary.
[clinic start generated code]*/

static PyObject *
_msi_SummaryInformation_GetProperty_impl(msiobj *self, int field)
/*[clinic end generated code: output=f8946a33ee14f6ef input=f8dfe2c890d6cb8b]*/
{
    int status;
    PyObject *result;
    UINT type;
    INT ival;
    FILETIME fval;
    char sbuf[1000];
    char *sval = sbuf;
    DWORD ssize = sizeof(sbuf);

    status = MsiSummaryInfoGetProperty(self->h, field, &type, &ival,
        &fval, sval, &ssize);
    if (status == ERROR_MORE_DATA) {
        ssize++;
        sval = malloc(ssize);
        if (sval == NULL) {
            return PyErr_NoMemory();
        }
        status = MsiSummaryInfoGetProperty(self->h, field, &type, &ival,
            &fval, sval, &ssize);
    }
    if (status != ERROR_SUCCESS) {
        return msierror(status);
    }

    switch(type) {
        case VT_I2:
        case VT_I4:
            result = PyLong_FromLong(ival);
            break;
        case VT_FILETIME:
            PyErr_SetString(PyExc_NotImplementedError, "FILETIME result");
            result = NULL;
            break;
        case VT_LPSTR:
            result = PyBytes_FromStringAndSize(sval, ssize);
            break;
        case VT_EMPTY:
            Py_INCREF(Py_None);
            result = Py_None;
            break;
        default:
            PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
            result = NULL;
            break;
    }
    if (sval != sbuf)
        free(sval);
    return result;
}

/*[clinic input]
_msi.SummaryInformation.GetPropertyCount

Return the number of summary properties.
[clinic start generated code]*/

static PyObject *
_msi_SummaryInformation_GetPropertyCount_impl(msiobj *self)
/*[clinic end generated code: output=68e94b2aeee92b3d input=2e71e985586d82dc]*/
{
    int status;
    UINT result;

    status = MsiSummaryInfoGetPropertyCount(self->h, &result);
    if (status != ERROR_SUCCESS)
        return msierror(status);

    return PyLong_FromLong(result);
}

/*[clinic input]
_msi.SummaryInformation.SetProperty
    field: int
        the name of the property, one of the PID_* constants
    value as data: object
        the new value of the property (integer or string)
    /

Set a property.
[clinic start generated code]*/

static PyObject *
_msi_SummaryInformation_SetProperty_impl(msiobj *self, int field,
                                         PyObject *data)
/*[clinic end generated code: output=3d4692c8984bb675 input=f2a7811b905abbed]*/
{
    int status;

    if (PyUnicode_Check(data)) {
#if USE_UNICODE_WCHAR_CACHE
        const WCHAR *value = _PyUnicode_AsUnicode(data);
#else /* USE_UNICODE_WCHAR_CACHE */
        WCHAR *value = PyUnicode_AsWideCharString(data, NULL);
#endif /* USE_UNICODE_WCHAR_CACHE */
        if (value == NULL) {
            return NULL;
        }
        status = MsiSummaryInfoSetPropertyW(self->h, field, VT_LPSTR,
            0, NULL, value);
#if !USE_UNICODE_WCHAR_CACHE
        PyMem_Free(value);
#endif /* USE_UNICODE_WCHAR_CACHE */
    } else if (PyLong_CheckExact(data)) {
        long value = PyLong_AsLong(data);
        if (value == -1 && PyErr_Occurred()) {
            return NULL;
        }
        status = MsiSummaryInfoSetProperty(self->h, field, VT_I4,
            value, NULL, NULL);
    } else {
        PyErr_SetString(PyExc_TypeError, "unsupported type");
        return NULL;
    }

    if (status != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}


/*[clinic input]
_msi.SummaryInformation.Persist

Write the modified properties to the summary information stream.
[clinic start generated code]*/

static PyObject *
_msi_SummaryInformation_Persist_impl(msiobj *self)
/*[clinic end generated code: output=c564bd17f5e122c9 input=e3dda9d530095ef7]*/
{
    int status;

    status = MsiSummaryInfoPersist(self->h);
    if (status != ERROR_SUCCESS)
        return msierror(status);
    Py_RETURN_NONE;
}

static PyMethodDef summary_methods[] = {
    _MSI_SUMMARYINFORMATION_GETPROPERTY_METHODDEF
    _MSI_SUMMARYINFORMATION_GETPROPERTYCOUNT_METHODDEF
    _MSI_SUMMARYINFORMATION_SETPROPERTY_METHODDEF
    _MSI_SUMMARYINFORMATION_PERSIST_METHODDEF
    { NULL, NULL }
};

static PyTypeObject summary_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "_msi.SummaryInformation",              /*tp_name*/
        sizeof(msiobj), /*tp_basicsize*/
        0,                      /*tp_itemsize*/
        /* methods */
        (destructor)msiobj_dealloc, /*tp_dealloc*/
        0,                      /*tp_vectorcall_offset*/
        0,                      /*tp_getattr*/
        0,                      /*tp_setattr*/
        0,                      /*tp_as_async*/
        0,                      /*tp_repr*/
        0,                      /*tp_as_number*/
        0,                      /*tp_as_sequence*/
        0,                      /*tp_as_mapping*/
        0,                      /*tp_hash*/
        0,                      /*tp_call*/
        0,                      /*tp_str*/
        PyObject_GenericGetAttr,/*tp_getattro*/
        PyObject_GenericSetAttr,/*tp_setattro*/
        0,                      /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
        0,                      /*tp_doc*/
        0,                      /*tp_traverse*/
        0,                      /*tp_clear*/
        0,                      /*tp_richcompare*/
        0,                      /*tp_weaklistoffset*/
        0,                      /*tp_iter*/
        0,                      /*tp_iternext*/
        summary_methods,        /*tp_methods*/
        0,                      /*tp_members*/
        0,                      /*tp_getset*/
        0,                      /*tp_base*/
        0,                      /*tp_dict*/
        0,                      /*tp_descr_get*/
        0,                      /*tp_descr_set*/
        0,                      /*tp_dictoffset*/
        0,                      /*tp_init*/
        0,                      /*tp_alloc*/
        0,                      /*tp_new*/
        0,                      /*tp_free*/
        0,                      /*tp_is_gc*/
};

/*************************** View objects **************/

/*[clinic input]
_msi.View.Execute
    params as oparams: object
        a record describing actual values of the parameter tokens
        in the query or None
    /

Execute the SQL query of the view.
[clinic start generated code]*/

static PyObject *
_msi_View_Execute(msiobj *self, PyObject *oparams)
/*[clinic end generated code: output=f0f65fd2900bcb4e input=cb163a15d453348e]*/
{
    int status;
    MSIHANDLE params = 0;

    if (oparams != Py_None) {
        if (!Py_IS_TYPE(oparams, &record_Type)) {
            PyErr_SetString(PyExc_TypeError, "Execute argument must be a record");
            return NULL;
        }
        params = ((msiobj*)oparams)->h;
    }

    status = MsiViewExecute(self->h, params);
    if (status != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}

/*[clinic input]
_msi.View.Fetch

Return a result record of the query.
[clinic start generated code]*/

static PyObject *
_msi_View_Fetch_impl(msiobj *self)
/*[clinic end generated code: output=ba154a3794537d4e input=7f3e3d06c449001c]*/
{
    int status;
    MSIHANDLE result;

    status = MsiViewFetch(self->h, &result);
    if (status == ERROR_NO_MORE_ITEMS) {
        Py_RETURN_NONE;
    } else if (status != ERROR_SUCCESS) {
        return msierror(status);
    }

    return record_new(result);
}

/*[clinic input]
_msi.View.GetColumnInfo
    kind: int
        MSICOLINFO_NAMES or MSICOLINFO_TYPES
    /

Return a record describing the columns of the view.
[clinic start generated code]*/

static PyObject *
_msi_View_GetColumnInfo_impl(msiobj *self, int kind)
/*[clinic end generated code: output=e7c1697db9403660 input=afedb892bf564a3b]*/
{
    int status;
    MSIHANDLE result;

    if ((status = MsiViewGetColumnInfo(self->h, kind, &result)) != ERROR_SUCCESS)
        return msierror(status);

    return record_new(result);
}

/*[clinic input]
_msi.View.Modify
    kind: int
        one of the MSIMODIFY_* constants
    data: object
        a record describing the new data
    /

Modify the view.
[clinic start generated code]*/

static PyObject *
_msi_View_Modify_impl(msiobj *self, int kind, PyObject *data)
/*[clinic end generated code: output=69aaf3ce8ddac0ba input=2828de22de0d47b4]*/
{
    int status;

    if (!Py_IS_TYPE(data, &record_Type)) {
        PyErr_SetString(PyExc_TypeError, "Modify expects a record object");
        return NULL;
    }

    if ((status = MsiViewModify(self->h, kind, ((msiobj*)data)->h)) != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}

/*[clinic input]
_msi.View.Close

Close the view.
[clinic start generated code]*/

static PyObject *
_msi_View_Close_impl(msiobj *self)
/*[clinic end generated code: output=488f7b8645ca104a input=de6927d1308c401c]*/
{
    int status;

    if ((status = MsiViewClose(self->h)) != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}

static PyMethodDef view_methods[] = {
    _MSI_VIEW_EXECUTE_METHODDEF
    _MSI_VIEW_GETCOLUMNINFO_METHODDEF
    _MSI_VIEW_FETCH_METHODDEF
    _MSI_VIEW_MODIFY_METHODDEF
    _MSI_VIEW_CLOSE_METHODDEF
    { NULL, NULL }
};

static PyTypeObject msiview_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "_msi.View",            /*tp_name*/
        sizeof(msiobj), /*tp_basicsize*/
        0,                      /*tp_itemsize*/
        /* methods */
        (destructor)msiobj_dealloc, /*tp_dealloc*/
        0,                      /*tp_vectorcall_offset*/
        0,                      /*tp_getattr*/
        0,                      /*tp_setattr*/
        0,                      /*tp_as_async*/
        0,                      /*tp_repr*/
        0,                      /*tp_as_number*/
        0,                      /*tp_as_sequence*/
        0,                      /*tp_as_mapping*/
        0,                      /*tp_hash*/
        0,                      /*tp_call*/
        0,                      /*tp_str*/
        PyObject_GenericGetAttr,/*tp_getattro*/
        PyObject_GenericSetAttr,/*tp_setattro*/
        0,                      /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
        0,                      /*tp_doc*/
        0,                      /*tp_traverse*/
        0,                      /*tp_clear*/
        0,                      /*tp_richcompare*/
        0,                      /*tp_weaklistoffset*/
        0,                      /*tp_iter*/
        0,                      /*tp_iternext*/
        view_methods,           /*tp_methods*/
        0,                      /*tp_members*/
        0,                      /*tp_getset*/
        0,                      /*tp_base*/
        0,                      /*tp_dict*/
        0,                      /*tp_descr_get*/
        0,                      /*tp_descr_set*/
        0,                      /*tp_dictoffset*/
        0,                      /*tp_init*/
        0,                      /*tp_alloc*/
        0,                      /*tp_new*/
        0,                      /*tp_free*/
        0,                      /*tp_is_gc*/
};

/*************************** Database objects **************/

/*[clinic input]
_msi.Database.OpenView
    sql: Py_UNICODE
        the SQL statement to execute
    /

Return a view object.
[clinic start generated code]*/

static PyObject *
_msi_Database_OpenView_impl(msiobj *self, const Py_UNICODE *sql)
/*[clinic end generated code: output=e712e6a11229abfd input=50f1771f37e500df]*/
{
    int status;
    MSIHANDLE hView;
    msiobj *result;

    if ((status = MsiDatabaseOpenViewW(self->h, sql, &hView)) != ERROR_SUCCESS)
        return msierror(status);

    result = PyObject_New(struct msiobj, &msiview_Type);
    if (!result) {
        MsiCloseHandle(hView);
        return NULL;
    }

    result->h = hView;
    return (PyObject*)result;
}

/*[clinic input]
_msi.Database.Commit

Commit the changes pending in the current transaction.
[clinic start generated code]*/

static PyObject *
_msi_Database_Commit_impl(msiobj *self)
/*[clinic end generated code: output=f33021feb8b0cdd8 input=375bb120d402266d]*/
{
    int status;

    if ((status = MsiDatabaseCommit(self->h)) != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}

/*[clinic input]
_msi.Database.GetSummaryInformation
    count: int
        the maximum number of updated values
    /

Return a new summary information object.
[clinic start generated code]*/

static PyObject *
_msi_Database_GetSummaryInformation_impl(msiobj *self, int count)
/*[clinic end generated code: output=781e51a4ea4da847 input=18a899ead6521735]*/
{
    int status;
    MSIHANDLE result;
    msiobj *oresult;

    status = MsiGetSummaryInformation(self->h, NULL, count, &result);
    if (status != ERROR_SUCCESS)
        return msierror(status);

    oresult = PyObject_New(struct msiobj, &summary_Type);
    if (!oresult) {
        MsiCloseHandle(result);
        return NULL;
    }

    oresult->h = result;
    return (PyObject*)oresult;
}

static PyMethodDef db_methods[] = {
    _MSI_DATABASE_OPENVIEW_METHODDEF
    _MSI_DATABASE_COMMIT_METHODDEF
    _MSI_DATABASE_GETSUMMARYINFORMATION_METHODDEF
    _MSI_DATABASE_CLOSE_METHODDEF
    { NULL, NULL }
};

static PyTypeObject msidb_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "_msi.Database",                /*tp_name*/
        sizeof(msiobj), /*tp_basicsize*/
        0,                      /*tp_itemsize*/
        /* methods */
        (destructor)msiobj_dealloc, /*tp_dealloc*/
        0,                      /*tp_vectorcall_offset*/
        0,                      /*tp_getattr*/
        0,                      /*tp_setattr*/
        0,                      /*tp_as_async*/
        0,                      /*tp_repr*/
        0,                      /*tp_as_number*/
        0,                      /*tp_as_sequence*/
        0,                      /*tp_as_mapping*/
        0,                      /*tp_hash*/
        0,                      /*tp_call*/
        0,                      /*tp_str*/
        PyObject_GenericGetAttr,/*tp_getattro*/
        PyObject_GenericSetAttr,/*tp_setattro*/
        0,                      /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
        0,                      /*tp_doc*/
        0,                      /*tp_traverse*/
        0,                      /*tp_clear*/
        0,                      /*tp_richcompare*/
        0,                      /*tp_weaklistoffset*/
        0,                      /*tp_iter*/
        0,                      /*tp_iternext*/
        db_methods,             /*tp_methods*/
        0,                      /*tp_members*/
        0,                      /*tp_getset*/
        0,                      /*tp_base*/
        0,                      /*tp_dict*/
        0,                      /*tp_descr_get*/
        0,                      /*tp_descr_set*/
        0,                      /*tp_dictoffset*/
        0,                      /*tp_init*/
        0,                      /*tp_alloc*/
        0,                      /*tp_new*/
        0,                      /*tp_free*/
        0,                      /*tp_is_gc*/
};

#define Py_NOT_PERSIST(x, flag)                        \
    (x != (SIZE_T)(flag) &&                      \
    x != ((SIZE_T)(flag) | MSIDBOPEN_PATCHFILE))

#define Py_INVALID_PERSIST(x)                \
    (Py_NOT_PERSIST(x, MSIDBOPEN_READONLY) &&  \
    Py_NOT_PERSIST(x, MSIDBOPEN_TRANSACT) &&   \
    Py_NOT_PERSIST(x, MSIDBOPEN_DIRECT) &&     \
    Py_NOT_PERSIST(x, MSIDBOPEN_CREATE) &&     \
    Py_NOT_PERSIST(x, MSIDBOPEN_CREATEDIRECT))

/*[clinic input]
_msi.OpenDatabase
    path: Py_UNICODE
        the file name of the MSI file
    persist: int
        the persistence mode
    /

Return a new database object.
[clinic start generated code]*/

static PyObject *
_msi_OpenDatabase_impl(PyObject *module, const Py_UNICODE *path, int persist)
/*[clinic end generated code: output=d34b7202b745de05 input=1300f3b97659559b]*/
{
    int status;
    MSIHANDLE h;
    msiobj *result;

    /* We need to validate that persist is a valid MSIDBOPEN_* value. Otherwise,
       MsiOpenDatabase may treat the value as a pointer, leading to unexpected
       behavior. */
    if (Py_INVALID_PERSIST(persist))
        return msierror(ERROR_INVALID_PARAMETER);
    status = MsiOpenDatabaseW(path, (LPCWSTR)(SIZE_T)persist, &h);
    if (status != ERROR_SUCCESS)
        return msierror(status);

    result = PyObject_New(struct msiobj, &msidb_Type);
    if (!result) {
        MsiCloseHandle(h);
        return NULL;
    }
    result->h = h;
    return (PyObject*)result;
}

/*[clinic input]
_msi.CreateRecord
    count: int
        the number of fields of the record
    /

Return a new record object.
[clinic start generated code]*/

static PyObject *
_msi_CreateRecord_impl(PyObject *module, int count)
/*[clinic end generated code: output=0ba0a00beea3e99e input=53f17d5b5d9b077d]*/
{
    MSIHANDLE h;

    h = MsiCreateRecord(count);
    if (h == 0)
        return msierror(0);

    return record_new(h);
}


static PyMethodDef msi_methods[] = {
        _MSI_UUIDCREATE_METHODDEF
        _MSI_FCICREATE_METHODDEF
        _MSI_OPENDATABASE_METHODDEF
        _MSI_CREATERECORD_METHODDEF
        {NULL,          NULL}           /* sentinel */
};

static char msi_doc[] = "Documentation";


static struct PyModuleDef _msimodule = {
        PyModuleDef_HEAD_INIT,
        "_msi",
        msi_doc,
        -1,
        msi_methods,
        NULL,
        NULL,
        NULL,
        NULL
};

PyMODINIT_FUNC
PyInit__msi(void)
{
    PyObject *m;

    m = PyModule_Create(&_msimodule);
    if (m == NULL)
        return NULL;

    PyModule_AddIntConstant(m, "MSIDBOPEN_CREATEDIRECT", (long)(SIZE_T)MSIDBOPEN_CREATEDIRECT);
    PyModule_AddIntConstant(m, "MSIDBOPEN_CREATE", (long)(SIZE_T)MSIDBOPEN_CREATE);
    PyModule_AddIntConstant(m, "MSIDBOPEN_DIRECT", (long)(SIZE_T)MSIDBOPEN_DIRECT);
    PyModule_AddIntConstant(m, "MSIDBOPEN_READONLY", (long)(SIZE_T)MSIDBOPEN_READONLY);
    PyModule_AddIntConstant(m, "MSIDBOPEN_TRANSACT", (long)(SIZE_T)MSIDBOPEN_TRANSACT);
    PyModule_AddIntConstant(m, "MSIDBOPEN_PATCHFILE", (long)(SIZE_T)MSIDBOPEN_PATCHFILE);

    PyModule_AddIntMacro(m, MSICOLINFO_NAMES);
    PyModule_AddIntMacro(m, MSICOLINFO_TYPES);

    PyModule_AddIntMacro(m, MSIMODIFY_SEEK);
    PyModule_AddIntMacro(m, MSIMODIFY_REFRESH);
    PyModule_AddIntMacro(m, MSIMODIFY_INSERT);
    PyModule_AddIntMacro(m, MSIMODIFY_UPDATE);
    PyModule_AddIntMacro(m, MSIMODIFY_ASSIGN);
    PyModule_AddIntMacro(m, MSIMODIFY_REPLACE);
    PyModule_AddIntMacro(m, MSIMODIFY_MERGE);
    PyModule_AddIntMacro(m, MSIMODIFY_DELETE);
    PyModule_AddIntMacro(m, MSIMODIFY_INSERT_TEMPORARY);
    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE);
    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE_NEW);
    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE_FIELD);
    PyModule_AddIntMacro(m, MSIMODIFY_VALIDATE_DELETE);

    PyModule_AddIntMacro(m, PID_CODEPAGE);
    PyModule_AddIntMacro(m, PID_TITLE);
    PyModule_AddIntMacro(m, PID_SUBJECT);
    PyModule_AddIntMacro(m, PID_AUTHOR);
    PyModule_AddIntMacro(m, PID_KEYWORDS);
    PyModule_AddIntMacro(m, PID_COMMENTS);
    PyModule_AddIntMacro(m, PID_TEMPLATE);
    PyModule_AddIntMacro(m, PID_LASTAUTHOR);
    PyModule_AddIntMacro(m, PID_REVNUMBER);
    PyModule_AddIntMacro(m, PID_LASTPRINTED);
    PyModule_AddIntMacro(m, PID_CREATE_DTM);
    PyModule_AddIntMacro(m, PID_LASTSAVE_DTM);
    PyModule_AddIntMacro(m, PID_PAGECOUNT);
    PyModule_AddIntMacro(m, PID_WORDCOUNT);
    PyModule_AddIntMacro(m, PID_CHARCOUNT);
    PyModule_AddIntMacro(m, PID_APPNAME);
    PyModule_AddIntMacro(m, PID_SECURITY);

    MSIError = PyErr_NewException ("_msi.MSIError", NULL, NULL);
    if (!MSIError)
        return NULL;
    PyModule_AddObject(m, "MSIError", MSIError);
    return m;
}
