/* 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) {
        PyObject *result = PyObject_CallMethod(pv, "status", "iii", typeStatus, cb1, cb2);
        if (result == NULL)
            return -1;
        Py_DECREF(result);
    }
    return 0;
}

static FNFCIGETNEXTCABINET(cb_getnextcabinet)
{
    if (pv) {
        PyObject *result = PyObject_CallMethod(pv, "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 = Py_ARRAY_LENGTH(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 = Py_ARRAY_LENGTH(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:
            result = Py_NewRef(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)) {
        WCHAR *value = PyUnicode_AsWideCharString(data, NULL);
        if (value == NULL) {
            return NULL;
        }
        status = MsiSummaryInfoSetPropertyW(self->h, field, VT_LPSTR,
            0, NULL, value);
        PyMem_Free(value);
    } 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;
}
