mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
gh-112278: Disable WMI queries on Windows after they time out (GH-112658)
This commit is contained in:
parent
b2923a61a1
commit
a955fd68d6
3 changed files with 44 additions and 15 deletions
|
@ -44,6 +44,7 @@ struct _query_data {
|
|||
LPCWSTR query;
|
||||
HANDLE writePipe;
|
||||
HANDLE readPipe;
|
||||
HANDLE connectEvent;
|
||||
};
|
||||
|
||||
|
||||
|
@ -86,6 +87,9 @@ _query_thread(LPVOID param)
|
|||
NULL, NULL, 0, NULL, 0, 0, &services
|
||||
);
|
||||
}
|
||||
if (!SetEvent(data->connectEvent)) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = CoSetProxyBlanket(
|
||||
services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
|
||||
|
@ -231,7 +235,8 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
|
|||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
|
||||
if (!CreatePipe(&data.readPipe, &data.writePipe, NULL, 0)) {
|
||||
data.connectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!data.connectEvent || !CreatePipe(&data.readPipe, &data.writePipe, NULL, 0)) {
|
||||
err = GetLastError();
|
||||
} else {
|
||||
hThread = CreateThread(NULL, 0, _query_thread, (LPVOID*)&data, 0, NULL);
|
||||
|
@ -243,6 +248,21 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
|
|||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
switch (WaitForSingleObject(data.connectEvent, 100)) {
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
err = WAIT_TIMEOUT;
|
||||
break;
|
||||
default:
|
||||
err = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
while (!err) {
|
||||
if (ReadFile(
|
||||
data.readPipe,
|
||||
|
@ -265,7 +285,7 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
|
|||
}
|
||||
|
||||
// Allow the thread some time to clean up
|
||||
switch (WaitForSingleObject(hThread, 1000)) {
|
||||
switch (WaitForSingleObject(hThread, 100)) {
|
||||
case WAIT_OBJECT_0:
|
||||
// Thread ended cleanly
|
||||
if (!GetExitCodeThread(hThread, (LPDWORD)&err)) {
|
||||
|
@ -286,6 +306,7 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
|
|||
}
|
||||
|
||||
CloseHandle(hThread);
|
||||
CloseHandle(data.connectEvent);
|
||||
hThread = NULL;
|
||||
|
||||
Py_END_ALLOW_THREADS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue