@@ -44,6 +44,7 @@ struct _query_data {
4444 LPCWSTR query;
4545 HANDLE writePipe;
4646 HANDLE readPipe;
47+ HANDLE connectEvent;
4748};
4849
4950
@@ -86,6 +87,9 @@ _query_thread(LPVOID param)
8687 NULL , NULL , 0 , NULL , 0 , 0 , &services
8788 );
8889 }
90+ if (!SetEvent (data->connectEvent )) {
91+ hr = HRESULT_FROM_WIN32 (GetLastError ());
92+ }
8993 if (SUCCEEDED (hr)) {
9094 hr = CoSetProxyBlanket (
9195 services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL ,
@@ -231,7 +235,8 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
231235
232236 Py_BEGIN_ALLOW_THREADS
233237
234- if (!CreatePipe (&data.readPipe , &data.writePipe , NULL , 0 )) {
238+ data.connectEvent = CreateEvent (NULL , TRUE , FALSE , NULL );
239+ if (!data.connectEvent || !CreatePipe (&data.readPipe , &data.writePipe , NULL , 0 )) {
235240 err = GetLastError ();
236241 } else {
237242 hThread = CreateThread (NULL , 0 , _query_thread, (LPVOID*)&data, 0 , NULL );
@@ -243,6 +248,21 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
243248 }
244249 }
245250
251+ // gh-112278: If current user doesn't have permission to query the WMI, the
252+ // function IWbemLocator::ConnectServer will hang for 5 seconds, and there
253+ // is no way to specify the timeout. So we use an Event object to simulate
254+ // a timeout.
255+ switch (WaitForSingleObject (data.connectEvent , 100 )) {
256+ case WAIT_OBJECT_0:
257+ break ;
258+ case WAIT_TIMEOUT:
259+ err = WAIT_TIMEOUT;
260+ break ;
261+ default :
262+ err = GetLastError ();
263+ break ;
264+ }
265+
246266 while (!err) {
247267 if (ReadFile (
248268 data.readPipe ,
@@ -265,7 +285,7 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
265285 }
266286
267287 // Allow the thread some time to clean up
268- switch (WaitForSingleObject (hThread, 1000 )) {
288+ switch (WaitForSingleObject (hThread, 100 )) {
269289 case WAIT_OBJECT_0:
270290 // Thread ended cleanly
271291 if (!GetExitCodeThread (hThread, (LPDWORD)&err)) {
@@ -286,6 +306,7 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
286306 }
287307
288308 CloseHandle (hThread);
309+ CloseHandle (data.connectEvent );
289310 hThread = NULL ;
290311
291312 Py_END_ALLOW_THREADS
0 commit comments