//
// Helper library for querying WMI using its COM-based query API.
//
// Copyright (c) Microsoft Corporation
// Licensed to PSF under a contributor agreement
//

// Version history
//  2022-08: Initial contribution (Steve Dower)

// clinic/_wmimodule.cpp.h uses internal pycore_modsupport.h API
#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#define _WIN32_DCOM
#include <Windows.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <propvarutil.h>

#include <Python.h>


#if _MSVC_LANG >= 202002L
// We can use clinic directly when the C++ compiler supports C++20
#include "clinic/_wmimodule.cpp.h"
#else
// Cannot use clinic because of missing C++20 support, so create a simpler
// API instead. This won't impact releases, so fine to omit the docstring.
static PyObject *_wmi_exec_query_impl(PyObject *module, PyObject *query);
#define _WMI_EXEC_QUERY_METHODDEF {"exec_query", _wmi_exec_query_impl, METH_O, NULL},
#endif


/*[clinic input]
module _wmi
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7ca95dad1453d10d]*/



struct _query_data {
    LPCWSTR query;
    HANDLE writePipe;
    HANDLE readPipe;
    HANDLE initEvent;
    HANDLE connectEvent;
};


static DWORD WINAPI
_query_thread(LPVOID param)
{
    IWbemLocator *locator = NULL;
    IWbemServices *services = NULL;
    IEnumWbemClassObject* enumerator = NULL;
    HRESULT hr = S_OK;
    BSTR bstrQuery = NULL;
    struct _query_data *data = (struct _query_data*)param;

    // gh-125315: Copy the query string first, so that if the main thread gives
    // up on waiting we aren't left with a dangling pointer (and a likely crash)
    bstrQuery = SysAllocString(data->query);
    if (!bstrQuery) {
        hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
    }

    if (SUCCEEDED(hr)) {
        hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
    }

    if (FAILED(hr)) {
        CloseHandle(data->writePipe);
        if (bstrQuery) {
            SysFreeString(bstrQuery);
        }
        return (DWORD)hr;
    }

    hr = CoInitializeSecurity(
        NULL, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL
    );
    // gh-96684: CoInitializeSecurity will fail if another part of the app has
    // already called it. Hopefully they passed lenient enough settings that we
    // can complete the WMI query, so keep going.
    if (hr == RPC_E_TOO_LATE) {
        hr = 0;
    }
    if (SUCCEEDED(hr)) {
        hr = CoCreateInstance(
            CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
            IID_IWbemLocator, (LPVOID *)&locator
        );
    }
    if (SUCCEEDED(hr) && !SetEvent(data->initEvent)) {
        hr = HRESULT_FROM_WIN32(GetLastError());
    }
    if (SUCCEEDED(hr)) {
        hr = locator->ConnectServer(
            bstr_t(L"ROOT\\CIMV2"),
            NULL, NULL, 0, NULL, 0, 0, &services
        );
    }
    if (SUCCEEDED(hr) && !SetEvent(data->connectEvent)) {
        hr = HRESULT_FROM_WIN32(GetLastError());
    }
    if (SUCCEEDED(hr)) {
        hr = CoSetProxyBlanket(
            services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
            RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,
            NULL, EOAC_NONE
        );
    }
    if (SUCCEEDED(hr)) {
        hr = services->ExecQuery(
            bstr_t("WQL"),
            bstrQuery,
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL,
            &enumerator
        );
    }

    // Okay, after all that, at this stage we should have an enumerator
    // to the query results and can start writing them to the pipe!
    IWbemClassObject *value = NULL;
    int startOfEnum = TRUE;
    int endOfEnum = FALSE;
    while (SUCCEEDED(hr) && !endOfEnum) {
        ULONG got = 0;
        DWORD written;
        hr = enumerator->Next(WBEM_INFINITE, 1, &value, &got);
        if (hr == WBEM_S_FALSE) {
            // Could be at the end, but still got a result this time
            endOfEnum = TRUE;
            hr = 0;
            break;
        }
        if (FAILED(hr) || got != 1 || !value) {
            continue;
        }
        if (!startOfEnum && !WriteFile(data->writePipe, (LPVOID)L"\0", 2, &written, NULL)) {
            hr = HRESULT_FROM_WIN32(GetLastError());
            break;
        }
        startOfEnum = FALSE;
        // Okay, now we have each resulting object it's time to
        // enumerate its members
        hr = value->BeginEnumeration(0);
        if (FAILED(hr)) {
            value->Release();
            break;
        }
        while (SUCCEEDED(hr)) {
            BSTR propName;
            VARIANT propValue;
            long flavor;
            hr = value->Next(0, &propName, &propValue, NULL, &flavor);
            if (hr == WBEM_S_NO_MORE_DATA) {
                hr = 0;
                break;
            }
            if (SUCCEEDED(hr) && (flavor & WBEM_FLAVOR_MASK_ORIGIN) != WBEM_FLAVOR_ORIGIN_SYSTEM) {
                WCHAR propStr[8192];
                hr = VariantToString(propValue, propStr, sizeof(propStr) / sizeof(propStr[0]));
                if (SUCCEEDED(hr)) {
                    DWORD cbStr1, cbStr2;
                    cbStr1 = (DWORD)(wcslen(propName) * sizeof(propName[0]));
                    cbStr2 = (DWORD)(wcslen(propStr) * sizeof(propStr[0]));
                    if (!WriteFile(data->writePipe, propName, cbStr1, &written, NULL) ||
                        !WriteFile(data->writePipe, (LPVOID)L"=", 2, &written, NULL) ||
                        !WriteFile(data->writePipe, propStr, cbStr2, &written, NULL) ||
                        !WriteFile(data->writePipe, (LPVOID)L"\0", 2, &written, NULL)
                    ) {
                        hr = HRESULT_FROM_WIN32(GetLastError());
                    }
                }
                VariantClear(&propValue);
                SysFreeString(propName);
            }
        }
        value->EndEnumeration();
        value->Release();
    }

    if (bstrQuery) {
        SysFreeString(bstrQuery);
    }
    if (enumerator) {
        enumerator->Release();
    }
    if (services) {
        services->Release();
    }
    if (locator) {
        locator->Release();
    }
    CoUninitialize();
    CloseHandle(data->writePipe);
    return (DWORD)hr;
}


static DWORD
wait_event(HANDLE event, DWORD timeout)
{
    DWORD err = 0;
    switch (WaitForSingleObject(event, timeout)) {
    case WAIT_OBJECT_0:
        break;
    case WAIT_TIMEOUT:
        err = WAIT_TIMEOUT;
        break;
    default:
        err = GetLastError();
        break;
    }
    return err;
}


/*[clinic input]
_wmi.exec_query

    query: unicode

Runs a WMI query against the local machine.

This returns a single string with 'name=value' pairs in a flat array separated
by null characters.
[clinic start generated code]*/

static PyObject *
_wmi_exec_query_impl(PyObject *module, PyObject *query)
/*[clinic end generated code: output=a62303d5bb5e003f input=48d2d0a1e1a7e3c2]*/

/*[clinic end generated code]*/
{
    HANDLE hThread = NULL;
    int err = 0;
    WCHAR buffer[8192];
    DWORD offset = 0;
    DWORD bytesRead;
    struct _query_data data = {0};

    if (PySys_Audit("_wmi.exec_query", "O", query) < 0) {
        return NULL;
    }

    data.query = PyUnicode_AsWideCharString(query, NULL);
    if (!data.query) {
        return NULL;
    }

    if (0 != _wcsnicmp(data.query, L"select ", 7)) {
        PyMem_Free((void *)data.query);
        PyErr_SetString(PyExc_ValueError, "only SELECT queries are supported");
        return NULL;
    }

    Py_BEGIN_ALLOW_THREADS

    data.initEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    data.connectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!data.initEvent || !data.connectEvent ||
        !CreatePipe(&data.readPipe, &data.writePipe, NULL, 0))
    {
        err = GetLastError();
    } else {
        hThread = CreateThread(NULL, 0, _query_thread, (LPVOID*)&data, 0, NULL);
        if (!hThread) {
            err = GetLastError();
            // Normally the thread proc closes this handle, but since we never started
            // we need to close it here.
            CloseHandle(data.writePipe);
        }
    }

    // gh-112278: If current user doesn't have permission to query the WMI, the
    // function IWbemLocator::ConnectServer will hang for 5 seconds, and there
    // is no way to specify the timeout. So we use an Event object to simulate
    // a timeout.  The initEvent will be set after COM initialization, it will
    // take a longer time when first initialized.  The connectEvent will be set
    // after connected to WMI.
    if (!err) {
        err = wait_event(data.initEvent, 1000);
        if (!err) {
            err = wait_event(data.connectEvent, 100);
        }
    }

    while (!err) {
        if (ReadFile(
            data.readPipe,
            (LPVOID)&buffer[offset / sizeof(buffer[0])],
            sizeof(buffer) - offset,
            &bytesRead,
            NULL
        )) {
            offset += bytesRead;
            if (offset >= sizeof(buffer)) {
                err = ERROR_MORE_DATA;
            }
        } else {
            err = GetLastError();
        }
    }

    if (data.readPipe) {
        CloseHandle(data.readPipe);
    }

    if (hThread) {
        // Allow the thread some time to clean up
        int thread_err;
        switch (WaitForSingleObject(hThread, 100)) {
        case WAIT_OBJECT_0:
            // Thread ended cleanly
            if (!GetExitCodeThread(hThread, (LPDWORD)&thread_err)) {
                thread_err = GetLastError();
            }
            break;
        case WAIT_TIMEOUT:
            // Probably stuck - there's not much we can do, unfortunately
            thread_err = WAIT_TIMEOUT;
            break;
        default:
            thread_err = GetLastError();
            break;
        }
        // An error on our side is more likely to be relevant than one from
        // the thread, but if we don't have one on our side we'll take theirs.
        if (err == 0 || err == ERROR_BROKEN_PIPE) {
            err = thread_err;
        }

        CloseHandle(hThread);
    }

    CloseHandle(data.initEvent);
    CloseHandle(data.connectEvent);
    hThread = NULL;

    Py_END_ALLOW_THREADS

    PyMem_Free((void *)data.query);

    if (err == ERROR_MORE_DATA) {
        PyErr_Format(PyExc_OSError, "Query returns more than %zd characters", Py_ARRAY_LENGTH(buffer));
        return NULL;
    } else if (err) {
        PyErr_SetFromWindowsErr(err);
        return NULL;
    }

    if (!offset) {
        return PyUnicode_FromStringAndSize(NULL, 0);
    }
    return PyUnicode_FromWideChar(buffer, offset  / sizeof(buffer[0]) - 1);
}


static PyMethodDef wmi_functions[] = {
    _WMI_EXEC_QUERY_METHODDEF
    { NULL, NULL, 0, NULL }
};

static PyModuleDef_Slot wmi_slots[] = {
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL},
};

static PyModuleDef wmi_def = {
    PyModuleDef_HEAD_INIT,
    "_wmi",
    NULL,          // doc
    0,             // m_size
    wmi_functions, // m_methods
    wmi_slots,     // m_slots
};

extern "C" {
    PyMODINIT_FUNC PyInit__wmi(void)
    {
        return PyModuleDef_Init(&wmi_def);
    }
}
