BOOL DoStartStartupItems(ITrayWindow *Tray) { DWORD dwWait; if (!bExplorerIsShell) return FALSE; if (!s_hStartupMutex) { // Accidentally, there is possibility that the system starts multiple Explorers // before startup of shell. We use a mutex to match the timing of shell initialization. s_hStartupMutex = CreateMutexW(NULL, FALSE, L"ExplorerIsShellMutex"); if (s_hStartupMutex == NULL) return FALSE; } dwWait = WaitForSingleObject(s_hStartupMutex, INFINITE); TRACE("dwWait: 0x%08lX\n", dwWait); if (dwWait != WAIT_OBJECT_0) { TRACE("LastError: %ld\n", GetLastError()); DoFinishStartupItems(); return FALSE; } const DWORD dwWaitTotal = 3000; // in milliseconds DWORD dwTick = GetTickCount(); while (GetShellWindow() == NULL && GetTickCount() - dwTick < dwWaitTotal) { TrayProcessMessages(Tray); } if (GetShellWindow() == NULL) { DoFinishStartupItems(); return FALSE; } // Check the volatile "StartupHasBeenRun" key HKEY hSessionKey, hKey; HRESULT hr = SHCreateSessionKey(KEY_WRITE, &hSessionKey); if (SUCCEEDED(hr)) { ASSERT(hSessionKey); DWORD dwDisp; LONG Error = RegCreateKeyExW(hSessionKey, L"StartupHasBeenRun", 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp); RegCloseKey(hSessionKey); RegCloseKey(hKey); if (Error == ERROR_SUCCESS && dwDisp == REG_OPENED_EXISTING_KEY) { return FALSE; // Startup programs has already been run } } return TRUE; }
HANDLE DesktopCreateWindow(IN OUT ITrayWindow *Tray) { HANDLE hThread; HANDLE hEvent; DWORD DesktopThreadId; HANDLE hDesktop = NULL; HANDLE Handles[2]; DWORD WaitResult; hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hEvent != NULL) { volatile DESKCREATEINFO DeskCreateInfo; DeskCreateInfo.hEvent = hEvent; DeskCreateInfo.Tray = Tray; DeskCreateInfo.hDesktop = NULL; hThread = CreateThread(NULL, 0, DesktopThreadProc, (PVOID)&DeskCreateInfo, 0, &DesktopThreadId); if (hThread != NULL) { Handles[0] = hThread; Handles[1] = hEvent; for (;;) { WaitResult = MsgWaitForMultipleObjects(sizeof(Handles) / sizeof(Handles[0]), Handles, FALSE, INFINITE, QS_ALLEVENTS); if (WaitResult == WAIT_OBJECT_0 + (sizeof(Handles) / sizeof(Handles[0]))) TrayProcessMessages(Tray); else if (WaitResult != WAIT_FAILED && WaitResult != WAIT_OBJECT_0) { hDesktop = DeskCreateInfo.hDesktop; break; } } CloseHandle(hThread); } CloseHandle(hEvent); } return hDesktop; }