| 254 | } |
| 255 | |
| 256 | HRESULT GlassService::RunInjectionThread() |
| 257 | { |
| 258 | RETURN_IF_FAILED(SetThreadDescription(GetCurrentThread(), L"OpenGlass Injection Thread")); |
| 259 | |
| 260 | RETURN_IF_FAILED(RoInitialize(RO_INIT_MULTITHREADED)); |
| 261 | const wil::unique_rouninitialize_call wrtScope{}; |
| 262 | |
| 263 | g_dwmInjectionMap.clear(); |
| 264 | g_injectionThreadStatus = ThreadStatus::Running; |
| 265 | g_injectionThreadId = GetCurrentThreadId(); |
| 266 | const auto injectionThreadScope = wil::scope_exit([] |
| 267 | { |
| 268 | g_injectionThreadId = 0; |
| 269 | g_injectionThreadStatus = ThreadStatus::Stopped; |
| 270 | }); |
| 271 | |
| 272 | while (!WaitNamedPipeW(c_pipeName, NMPWAIT_NOWAIT)) |
| 273 | { |
| 274 | Sleep(1); |
| 275 | } |
| 276 | |
| 277 | auto WalkDwmProcesses = [](std::function<bool(DWORD)>&& callback) static |
| 278 | { |
| 279 | wil::unique_handle snapshot{ CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) }; |
| 280 | PROCESSENTRY32W pe{ sizeof(pe) }; |
| 281 | RETURN_IF_WIN32_BOOL_FALSE(Process32FirstW(snapshot.get(), &pe)); |
| 282 | |
| 283 | do |
| 284 | { |
| 285 | if (!_wcsicmp(pe.szExeFile, L"dwm.exe")) |
| 286 | { |
| 287 | if (!callback(pe.th32ProcessID)) |
| 288 | { |
| 289 | break; |
| 290 | } |
| 291 | } |
| 292 | } |
| 293 | while (Process32NextW(snapshot.get(), &pe)); |
| 294 | return S_OK; |
| 295 | }; |
| 296 | |
| 297 | HRESULT hr{ S_OK }; |
| 298 | do |
| 299 | { |
| 300 | // cleanup unused session records |
| 301 | auto currentTimeStamp = std::chrono::steady_clock::now(); |
| 302 | for (auto it = g_dwmInjectionMap.begin(); it != g_dwmInjectionMap.end(); ) |
| 303 | { |
| 304 | const auto& [injectionTimeStamp, _] = it->second; |
| 305 | if (currentTimeStamp - injectionTimeStamp >= std::chrono::minutes{ 3 }) |
| 306 | { |
| 307 | it = g_dwmInjectionMap.erase(it); |
| 308 | } |
| 309 | else |
| 310 | { |
| 311 | it++; |
| 312 | } |
| 313 | } |