summaryrefslogtreecommitdiffstats
path: root/PC
diff options
context:
space:
mode:
authorAN Long <aisk@users.noreply.github.com>2023-12-07 17:26:29 (GMT)
committerGitHub <noreply@github.com>2023-12-07 17:26:29 (GMT)
commita955fd68d6451bd42199110c978e99b3d2959db2 (patch)
tree14eb0414ba650d58b64b4ee21a34ceaf6f65380e /PC
parentb2923a61a10dc2717f4662b590cc9f6d181c6983 (diff)
downloadcpython-a955fd68d6451bd42199110c978e99b3d2959db2.zip
cpython-a955fd68d6451bd42199110c978e99b3d2959db2.tar.gz
cpython-a955fd68d6451bd42199110c978e99b3d2959db2.tar.bz2
gh-112278: Disable WMI queries on Windows after they time out (GH-112658)
Diffstat (limited to 'PC')
-rw-r--r--PC/_wmimodule.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/PC/_wmimodule.cpp b/PC/_wmimodule.cpp
index fdf09ec..215350a 100644
--- a/PC/_wmimodule.cpp
+++ b/PC/_wmimodule.cpp
@@ -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