// Force DWM process to recreate all its Direct3D objects. static void restartDwmComposition(HANDLE hProcess) { HRESULT hr; HMODULE hModule = LoadLibraryA("dwmapi"); assert(hModule); if (!hModule) { return; } typedef HRESULT (WINAPI *PFNDWMISCOMPOSITIONENABLED)(BOOL *pfEnabled); PFNDWMISCOMPOSITIONENABLED pfnDwmIsCompositionEnabled = (PFNDWMISCOMPOSITIONENABLED)GetProcAddress(hModule, "DwmIsCompositionEnabled"); assert(pfnDwmIsCompositionEnabled); if (!pfnDwmIsCompositionEnabled) { return; } typedef HRESULT (WINAPI *PFNDWMENABLECOMPOSITION)(UINT uCompositionAction); PFNDWMENABLECOMPOSITION pfnDwmEnableComposition = (PFNDWMENABLECOMPOSITION)GetProcAddress(hModule, "DwmEnableComposition"); assert(pfnDwmEnableComposition); if (!pfnDwmEnableComposition) { return; } BOOL bIsWindows8OrGreater = IsWindows8OrGreater(); if (bIsWindows8OrGreater) { // Windows 8 ignores DwmEnableComposition(DWM_EC_DISABLECOMPOSITION). // It is however possible to force DWM to restart by restarting the // display device via the devcon utility devconEnable(DEVCON_CLASS_DISPLAY); } else { BOOL fEnabled = FALSE; hr = pfnDwmIsCompositionEnabled(&fEnabled); if (FAILED(hr) || !fEnabled) { return; } fprintf(stderr, "info: restarting DWM composition\n"); hr = pfnDwmEnableComposition(DWM_EC_DISABLECOMPOSITION); assert(SUCCEEDED(hr)); if (FAILED(hr)) { return; } Sleep(1000/30); hr = pfnDwmEnableComposition(DWM_EC_ENABLECOMPOSITION); assert(SUCCEEDED(hr)); (void)hr; } fprintf(stderr, "Press any key when finished tracing\n"); getchar(); DWORD dwExitCode; if (GetExitCodeProcess(hProcess, &dwExitCode) && dwExitCode != STILL_ACTIVE) { // DWM process has already terminated return; } fprintf(stderr, "info: restarting DWM process\n"); if (bIsWindows8OrGreater) { // From Windows 8 onwards DWM no longer runs as a service. We just // kill it and winlogon parent process will respawn it. if (!TerminateProcess(hProcess, 0)) { logLastError("failed to terminate DWM process"); } } else { hr = pfnDwmEnableComposition(DWM_EC_DISABLECOMPOSITION); assert(SUCCEEDED(hr)); restartService("uxsms"); } }
DWORD StartSkimbadRun() { restartService(); return 0; }