// // TryAllowSetForegroundWindow // Calls AllowSetForegroundWindow on platforms that support it // HRESULT TryAllowSetForegroundWindow(HWND hWnd) { ASSERT(hWnd != NULL); HRESULT hr = E_FAIL; typedef BOOL (WINAPI* ASFWPROC)(DWORD); ASFWPROC pAllowSetForegroundWindow = (ASFWPROC)GetProcAddress( GetModuleHandle(_T("user32.dll")), "AllowSetForegroundWindow"); if (pAllowSetForegroundWindow) { DWORD dwProcessId = 0; GetWindowThreadProcessId(hWnd, &dwProcessId); if (pAllowSetForegroundWindow(dwProcessId)) { hr = S_OK; } else { hr = HrGetLastError(); } } else { // this platform doesn't have ASFW (Win95, NT4), so the // target process is allowed to set the foreground window anyway hr = S_FALSE; } return hr; }
// // CLSIDToString // Mostly for debugging purposes (TRACE et al) // HRESULT CLSIDToString(REFCLSID rclsid, LPTSTR ptzBuffer, size_t cchBuffer) { ASSERT(NULL != ptzBuffer); ASSERT(0 != cchBuffer); LPOLESTR pOleString = NULL; HRESULT hr = ProgIDFromCLSID(rclsid, &pOleString); if (FAILED(hr)) { hr = StringFromCLSID(rclsid, &pOleString); } if (SUCCEEDED(hr) && pOleString) { #if defined(UNICODE) hr = StringCchCopy(ptzBuffer, cchBuffer, pOleString); #else // UNICODE int nReturn = WideCharToMultiByte(CP_ACP, 0, pOleString, (int)wcslen(pOleString), ptzBuffer, (int)cchBuffer, NULL, NULL); if (nReturn == 0) { hr = HrGetLastError(); } #endif } CoTaskMemFree(pOleString); return hr; }
// // Start // HRESULT TaskbarListHandler::Start(HWND hWndTray) { HRESULT hr = E_FAIL; m_hLiteStep = GetLitestepWnd(); GetWindowThreadProcessId(m_hLiteStep, &m_dwLiteStepProc); m_hInstance = GetModuleHandle(NULL); WNDCLASSEX wndClass; ZeroMemory(&wndClass, sizeof(WNDCLASSEX)); wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.cbWndExtra = sizeof(TaskbarListHandler*); wndClass.lpszClassName = _T("taskbandHWNDClass"); wndClass.lpfnWndProc = &TaskbarListHandler::WindowProcedureInit; wndClass.hInstance = m_hInstance; wndClass.style = CS_NOCLOSE; m_aWndClass = RegisterClassEx(&wndClass); if (m_aWndClass == 0) { hr = HrGetLastError(); } else { m_hWndTaskband = CreateWindowEx(WS_EX_TOOLWINDOW, (LPCTSTR)m_aWndClass, _T("taskbandHWND"), WS_CHILD, 0, 0, 100, 100, hWndTray, nullptr, m_hInstance, this); if (m_hWndTaskband == nullptr) { hr = HrGetLastError(); } else { WM_ShellHook = RegisterWindowMessage(_T("SHELLHOOK")); SetProp(hWndTray, _T("TaskbandHWND"), m_hWndTaskband); hr = S_OK; } } return hr; }
bool Module::_LoadDll() { bool bReturn = false; if (!m_hInstance) { // Modules like popup2 like to call SetErrorMode. While that may not be // good style, there is little we can do about it. However, LoadLibrary // usually produces helpful error messages such as // "msvcp70.dll not found" which are not displayed if a module has // disabled them via SetErrorMode. We force their display here. // First, make Windows display all errors UINT uOldMode = SetErrorMode(0); if ((m_hInstance = LoadLibraryW(m_wzLocation.c_str())) != nullptr) { AssignToFunction(m_pInit, (initModuleProc) GetProcAddress( m_hInstance, "initModuleW")); if (!m_pInit) // Might be a legacy module, check for initModuleEx { initModuleProcA pInit = (initModuleProcA)GetProcAddress( m_hInstance, "initModuleEx"); if (!pInit) // Might be a BC module, check for underscore { pInit = (initModuleProcA)GetProcAddress( m_hInstance, "_initModuleEx"); } if (pInit) { m_pInit = [pInit] (HWND hWnd, HINSTANCE hInst, LPCWSTR pwzPath) -> int { char szPath[MAX_PATH]; WideCharToMultiByte(CP_ACP, 0, pwzPath, -1, szPath, sizeof(szPath), "", nullptr); return pInit(hWnd, hInst, szPath); }; } } m_pQuit = (quitModuleProc)GetProcAddress( m_hInstance, "quitModule"); if (!m_pQuit) // Might be a BC module, check for underscore { m_pQuit = (quitModuleProc)GetProcAddress( m_hInstance, "_quitModule"); } if (m_pInit == nullptr) { RESOURCE_STR(nullptr, IDS_INITMODULEEXNOTFOUND_ERROR, L"Error: Could not find initModule().\n" L"\n" L"Please confirm that the dll is a LiteStep module,\n" L"and check with the author for updates."); } else if (m_pQuit == nullptr) { RESOURCE_STR(nullptr, IDS_QUITMODULENOTFOUND_ERROR, L"Error: Could not find quitModule().\n" L"\n" L"Please confirm that the dll is a LiteStep module."); } else { bReturn = true; } } else { HRESULT hrError = HrGetLastError(); #if defined(_WIN64) if (GetModuleArchitecture(m_wzLocation.c_str()) == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { RESOURCE_STR(nullptr, IDS_MODULEWRONGARCH64_ERROR, L"Error: Could not load module.\n" L"\n" L"The module seems to compiled for 32-bit LiteStep. This is a 64-bit version of LiteStep, which can only load 64-bit modules."); } #else if (GetModuleArchitecture(m_wzLocation.c_str()) == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { RESOURCE_STR(nullptr, IDS_MODULEWRONGARCH32_ERROR, L"Error: Could not load module.\n" L"\n" L"The module seems to compiled for 64-bit LiteStep. This is a 32-bit version of LiteStep, which can only load 32-bit modules."); } #endif else if (PathFileExistsW(m_wzLocation.c_str())) { RESOURCE_STR(nullptr, IDS_MODULEDEPENDENCY_ERROR, L"Error: Could not load module.\n" L"\n" L"This is likely a case of a missing C Run-Time Library" L"or other dependency." L"\n" L"Error Information:" L"\n"); size_t nLen = 0; StringCchLengthW(resourceTextBuffer, _countof(resourceTextBuffer), &nLen); DescriptionFromHR(hrError, resourceTextBuffer + nLen, _countof(resourceTextBuffer) - nLen); } else { RESOURCE_STR(nullptr, IDS_MODULENOTFOUND_ERROR, L"Error: Could not locate module.\n" L"\n" L"Please check your configuration."); } } // Second, restore the old state SetErrorMode(uOldMode); if (!bReturn) { LPCWSTR pwzFileName = PathFindFileNameW(m_wzLocation.c_str()); RESOURCE_MSGBOX_F(pwzFileName, MB_ICONERROR); if (m_hInstance) { FreeLibrary(m_hInstance); m_hInstance = nullptr; } } } return bReturn; }
void StartupRunner::_SpawnProcess(LPTSTR ptzCommandLine, DWORD dwFlags) { ASSERT(!(dwFlags & ERK_WAITFOR_QUIT && dwFlags & ERK_WAITFOR_IDLE)); // // The following cases need to be supported: // // 1. "C:\Program Files\App\App.exe" -params // 2. C:\Program Files\App\App.exe -params // 3. App.exe -params (App.exe is in %path% or HKLM->REGSTR_PATH_APPPATHS) // and all the above cases without arguments. // // Note that 'App.exe' may contain spaces too // // CreateProcess handles 1 and 2, ShellExecuteEx handles 1 and 3. // // ShellExecuteEx works with UAC. CreateProcess does not. // Therefore, we have to attempt to emulate CreateProcess's path parsing // when we detect case 2. // TCHAR tzToken[MAX_LINE_LENGTH] = { 0 }; LPTSTR ptzArgs = nullptr; GetTokenW(ptzCommandLine, tzToken, const_cast<LPCTSTR*>(&ptzArgs), FALSE); HANDLE hProcess = nullptr; // If the first character is a quote, assume that the first token is the complete path. // If the first token does not contain a \ or the first token does not contain a :, assume it's a relative path. if (*_tcsspnp(ptzCommandLine, _T(" \t")) == _T('"') || !_tcschr(tzToken, _T('\\')) || !_tcschr(tzToken, _T(':'))) { hProcess = _ShellExecuteEx(tzToken, ptzArgs); } else { // This is an approximation of how CreateProcess determines which file to launch. ptzArgs = ptzCommandLine; do { ptzArgs = _tcschr(ptzArgs, _T(' ')); if (ptzArgs != nullptr) { *ptzArgs++ = _T('\0'); } if (PathFileExists(ptzCommandLine) && PathIsDirectory(ptzCommandLine) == FALSE) { hProcess = _ShellExecuteEx(ptzCommandLine, ptzArgs); break; } if (ptzArgs != nullptr) { *(ptzArgs-1) = _T(' '); } } while (ptzArgs != nullptr); } if (hProcess != nullptr) { if (dwFlags & ERK_WAITFOR_QUIT) { WaitForSingleObject(hProcess, INFINITE); } else if (dwFlags & ERK_WAITFOR_IDLE) { WaitForInputIdle(hProcess, INFINITE); } CloseHandle(hProcess); } #ifdef _DEBUG else { TCHAR tzError[4096]; DescriptionFromHR(HrGetLastError(), tzError, _countof(tzError)); TRACE("StartupRunner failed to launch '%ls', %ls", ptzCommandLine, tzError); } #endif }