bool IsBrowserPluginInstalled() { ScopedMem<WCHAR> buf(ReadRegStr(HKEY_LOCAL_MACHINE, REG_PATH_PLUGIN, PLUGIN_PATH)); if (!buf) buf.Set(ReadRegStr(HKEY_CURRENT_USER, REG_PATH_PLUGIN, PLUGIN_PATH)); return file::Exists(buf); }
/* Caller needs to free() the result. */ static WCHAR *GetDefaultPdfViewer() { ScopedMem<WCHAR> buf(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", PROG_ID)); if (buf) return buf.StealData(); return ReadRegStr(HKEY_CLASSES_ROOT, L".pdf", NULL); }
static void GetGraphicsDriverInfo(str::Str<char>& s) { // the info is in registry in: // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0000\ // Device Description REG_SZ (same as DriverDesc, so we don't read it) // DriverDesc REG_SZ // DriverVersion REG_SZ // UserModeDriverName REG_MULTI_SZ // // There can be more than one driver, they are in 0000, 0001 etc. for (int i=0; ; i++) { ScopedMem<WCHAR> key(str::Format(GFX_DRIVER_KEY_FMT, i)); ScopedMem<WCHAR> v1(ReadRegStr(HKEY_LOCAL_MACHINE, key, L"DriverDesc")); // I assume that if I can't read the value, there are no more drivers if (!v1) break; ScopedMem<char> v1a(str::conv::ToUtf8(v1)); s.AppendFmt("Graphics driver %d\r\n", i); s.AppendFmt(" DriverDesc: %s\r\n", v1.Get()); v1.Set(ReadRegStr(HKEY_LOCAL_MACHINE, key, L"DriverVersion")); if (v1) { v1a.Set(str::conv::ToUtf8(v1)); s.AppendFmt(" DriverVersion: %s\r\n", v1a.Get()); } v1.Set(ReadRegStr(HKEY_LOCAL_MACHINE, key, L"UserModeDriverName")); if (v1) { v1a.Set(str::conv::ToUtf8(v1)); s.AppendFmt(" UserModeDriverName: %s\r\n", v1a.Get()); } } }
/* Undo what DoAssociateExeWithPdfExtension() in AppTools.cpp did */ static void UnregisterFromBeingDefaultViewer(HKEY hkey) { ScopedMem<WCHAR> curr(ReadRegStr(hkey, REG_CLASSES_PDF, nullptr)); ScopedMem<WCHAR> prev(ReadRegStr(hkey, REG_CLASSES_APP, L"previous.pdf")); if (!curr || !str::Eq(curr, APP_NAME_STR)) { // not the default, do nothing } else if (prev) { WriteRegStr(hkey, REG_CLASSES_PDF, nullptr, prev); } else { #pragma warning(push) #pragma warning(disable : 6387) // silence /analyze: '_Param_(3)' could be '0': this does not adhere to the specification for the function 'SHDeleteValueW' SHDeleteValue(hkey, REG_CLASSES_PDF, nullptr); #pragma warning(pop) } // the following settings overrule HKEY_CLASSES_ROOT\.pdf ScopedMem<WCHAR> buf(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, PROG_ID)); if (str::Eq(buf, APP_NAME_STR)) { LONG res = SHDeleteValue(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, PROG_ID); if (res != ERROR_SUCCESS) LogLastError(res); } buf.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, APPLICATION)); if (str::EqI(buf, EXENAME)) { LONG res = SHDeleteValue(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, APPLICATION); if (res != ERROR_SUCCESS) LogLastError(res); } buf.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", PROG_ID)); if (str::Eq(buf, APP_NAME_STR)) DeleteRegKey(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", true); }
static WCHAR *GetAcrobatPath() { // Try Adobe Acrobat as a fall-back, if the Reader isn't installed ScopedMem<WCHAR> path(ReadRegStr(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\AcroRd32.exe", NULL)); if (!path) path.Set(ReadRegStr(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Acrobat.exe", NULL)); if (path && file::Exists(path)) return path.StealData(); return NULL; }
static WCHAR *GetFoxitPath() { ScopedMem<WCHAR> path(ReadRegStr(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Foxit Reader", L"DisplayIcon")); if (path && file::Exists(path)) return path.StealData(); // Registry value for Foxit 5 (and maybe later) path.Set(ReadRegStr(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Foxit Reader_is1", L"DisplayIcon")); if (path && file::Exists(path)) return path.StealData(); return NULL; }
static void GetProcessorName(str::Str<char>& s) { WCHAR *name = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", L"ProcessorNameString"); if (!name) // if more than one processor name = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", L"ProcessorNameString"); if (!name) return; ScopedMem<char> tmp(str::conv::ToUtf8(name)); s.AppendFmt("Processor: %s\r\n", tmp); free(name); }
static WCHAR *GetPDFXChangePath() { ScopedMem<WCHAR> path(ReadRegStr(HKEY_LOCAL_MACHINE, L"Software\\Tracker Software\\PDFViewer", L"InstallPath")); if (!path) path.Set(ReadRegStr(HKEY_CURRENT_USER, L"Software\\Tracker Software\\PDFViewer", L"InstallPath")); if (!path) return NULL; ScopedMem<WCHAR> exePath(path::Join(path, L"PDFXCview.exe")); if (file::Exists(exePath)) return exePath.StealData(); return NULL; }
bool IsPdfFilterInstalled() { ScopedMem<WCHAR> handler_iid(ReadRegStr(HKEY_CLASSES_ROOT, L".pdf\\PersistentHandler", nullptr)); if (!handler_iid) return false; return str::EqI(handler_iid, SZ_PDF_FILTER_HANDLER); }
bool IsPdfPreviewerInstalled() { ScopedMem<WCHAR> handler_iid(ReadRegStr(HKEY_CLASSES_ROOT, L".pdf\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}", nullptr)); if (!handler_iid) return false; return str::EqI(handler_iid, SZ_PDF_PREVIEW_CLSID); }
/* Returns true, if a Registry entry indicates that this executable has been created by an installer (and should be updated through an installer) */ bool HasBeenInstalled() { ScopedMem<WCHAR> installedPath; // cf. GetInstallationDir() in installer\Installer.cpp installedPath.Set(ReadRegStr(HKEY_CURRENT_USER, REG_PATH_UNINST, L"InstallLocation")); if (!installedPath) installedPath.Set(ReadRegStr(HKEY_LOCAL_MACHINE, REG_PATH_UNINST, L"InstallLocation")); if (!installedPath) return false; ScopedMem<WCHAR> exePath(GetExePath()); if (!exePath) return false; if (!str::EndsWithI(installedPath, L".exe")) installedPath.Set(path::Join(installedPath, path::GetBaseName(exePath))); return path::IsSame(installedPath, exePath); }
/* Return false if this program has been started from "Program Files" directory (which is an indicator that it has been installed) or from the last known location of a SumatraPDF installation (HKLM\Software\SumatraPDF\Install_Dir) */ bool IsRunningInPortableMode() { // cache the result so that it will be consistent during the lifetime of the process static int sCacheIsPortable = -1; // -1 == uninitialized, 0 == installed, 1 == portable if (sCacheIsPortable != -1) return sCacheIsPortable != 0; sCacheIsPortable = 1; ScopedMem<WCHAR> exePath(GetExePath()); if (!exePath) return true; // if we can't get a path, assume we're not running from "Program Files" ScopedMem<WCHAR> installedPath(NULL); installedPath.Set(ReadRegStr(HKEY_LOCAL_MACHINE, L"Software\\" APP_NAME_STR, L"Install_Dir")); if (!installedPath) installedPath.Set(ReadRegStr(HKEY_CURRENT_USER, L"Software\\" APP_NAME_STR, L"Install_Dir")); if (installedPath) { if (!str::EndsWithI(installedPath.Get(), L".exe")) installedPath.Set(path::Join(installedPath.Get(), path::GetBaseName(exePath))); if (path::IsSame(installedPath, exePath)) { sCacheIsPortable = 0; return false; } } WCHAR programFilesDir[MAX_PATH] = { 0 }; BOOL ok = SHGetSpecialFolderPath(NULL, programFilesDir, CSIDL_PROGRAM_FILES, FALSE); if (!ok) return true; // check if one of the exePath's parent directories is "Program Files" // (or a junction to it) WCHAR *baseName; while ((baseName = (WCHAR*)path::GetBaseName(exePath)) > exePath) { baseName[-1] = '\0'; if (path::IsSame(programFilesDir, exePath)) { sCacheIsPortable = 0; return false; } } return true; }
bool IsRunningInPortableMode() { // cache the result so that it will be consistent during the lifetime of the process static int sCacheIsPortable = -1; // -1 == uninitialized, 0 == installed, 1 == portable if (sCacheIsPortable != -1) return sCacheIsPortable != 0; sCacheIsPortable = 1; ScopedMem<WCHAR> exePath(GetExePath()); if (!exePath) return true; // if we can't get a path, assume we're not running from "Program Files" ScopedMem<WCHAR> installedPath; // cf. GetInstallationDir() in installer\Installer.cpp installedPath.Set(ReadRegStr(HKEY_CURRENT_USER, REG_PATH_UNINST, L"InstallLocation")); if (!installedPath) installedPath.Set(ReadRegStr(HKEY_LOCAL_MACHINE, REG_PATH_UNINST, L"InstallLocation")); if (installedPath) { if (!str::EndsWithI(installedPath.Get(), L".exe")) installedPath.Set(path::Join(installedPath.Get(), path::GetBaseName(exePath))); if (path::IsSame(installedPath, exePath)) { sCacheIsPortable = 0; return false; } } ScopedMem<WCHAR> programFilesDir(GetSpecialFolder(CSIDL_PROGRAM_FILES)); if (!programFilesDir) return true; // check if one of the exePath's parent directories is "Program Files" // (or a junction to it) WCHAR *baseName; while ((baseName = (WCHAR*)path::GetBaseName(exePath)) > exePath) { baseName[-1] = '\0'; if (path::IsSame(programFilesDir, exePath)) { sCacheIsPortable = 0; return false; } } return true; }
static void GetMachineName(str::Str<char>& s) { WCHAR *s1 = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", L"SystemFamily"); WCHAR *s2 = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", L"SystemVersion"); ScopedMem<char> s1u(s1 ? str::conv::ToUtf8(s1) : NULL); ScopedMem<char> s2u(s2 ? str::conv::ToUtf8(s2) : NULL); if (!s1u && !s2u) ; // pass else if (!s1u) s.AppendFmt("Machine: %s\r\n", s2u.Get()); else if (!s2u || str::EqI(s1u, s2u)) s.AppendFmt("Machine: %s\r\n", s1u.Get()); else s.AppendFmt("Machine: %s %s\r\n", s1u.Get(), s2u.Get()); free(s1); free(s2); }
// Detect TeX editors installed on the system and construct the // corresponding inverse search commands. // // Parameters: // hwndCombo -- (optional) handle to a combo list that will be filled with the list of possible inverse search commands. // Returns: // the inverse search command of the first detected editor (the caller needs to free() the result). WCHAR *AutoDetectInverseSearchCommands(HWND hwndCombo) { WCHAR *firstEditor = NULL; ScopedMem<WCHAR> path(NULL); const WCHAR *editorToSkip = NULL; for (int i = 0; i < dimof(editor_rules); i++) { if (editorToSkip && str::Eq(editorToSkip, editor_rules[i].Name)) continue; editorToSkip = NULL; path.Set(ReadRegStr(editor_rules[i].RegRoot, editor_rules[i].RegKey, editor_rules[i].RegValue)); if (!path) continue; WCHAR *exePath; if (editor_rules[i].Type == SiblingPath) { // remove file part ScopedMem<WCHAR> dir(path::GetDir(path)); exePath = path::Join(dir, editor_rules[i].BinaryFilename); } else if (editor_rules[i].Type == BinaryDir) exePath = path::Join(path, editor_rules[i].BinaryFilename); else // if (editor_rules[i].Type == BinaryPath) exePath = str::Dup(path); WCHAR *editorCmd = str::Format(L"\"%s\" %s", exePath, editor_rules[i].InverseSearchArgs); free(exePath); if (!hwndCombo) { // no need to fill a combo box: return immeditately after finding an editor. return editorCmd; } if (!firstEditor) firstEditor = str::Dup(editorCmd); ComboBox_AddString(hwndCombo, editorCmd); free(editorCmd); // skip the remaining rules for this editor editorToSkip = editor_rules[i].Name; } // Fall back to notepad as a default handler if (!firstEditor) { firstEditor = str::Dup(L"notepad %f"); if (hwndCombo) ComboBox_AddString(hwndCombo, firstEditor); } return firstEditor; }
// Detect TeX editors installed on the system and construct the // corresponding inverse search commands. // // Parameters: // hwndCombo -- (optional) handle to a combo list that will be filled with the list of possible inverse search commands. // Returns: // the inverse search command of the first detected editor (the caller needs to free() the result). WCHAR *AutoDetectInverseSearchCommands(HWND hwndCombo) { WCHAR *firstEditor = NULL; WStrList foundExes; for (int i = 0; i < dimof(editor_rules); i++) { ScopedMem<WCHAR> path(ReadRegStr(editor_rules[i].RegRoot, editor_rules[i].RegKey, editor_rules[i].RegValue)); if (!path) continue; ScopedMem<WCHAR> exePath; if (editor_rules[i].Type == SiblingPath) { // remove file part ScopedMem<WCHAR> dir(path::GetDir(path)); exePath.Set(path::Join(dir, editor_rules[i].BinaryFilename)); } else if (editor_rules[i].Type == BinaryDir) exePath.Set(path::Join(path, editor_rules[i].BinaryFilename)); else // if (editor_rules[i].Type == BinaryPath) exePath.Set(path.StealData()); // don't show duplicate entries if (foundExes.FindI(exePath) != -1) continue; // don't show inexistent paths (and don't try again for them) if (!file::Exists(exePath)) { foundExes.Append(exePath.StealData()); continue; } ScopedMem<WCHAR> editorCmd(str::Format(L"\"%s\" %s", exePath, editor_rules[i].InverseSearchArgs)); if (!hwndCombo) { // no need to fill a combo box: return immeditately after finding an editor. return editorCmd.StealData(); } ComboBox_AddString(hwndCombo, editorCmd); if (!firstEditor) firstEditor = editorCmd.StealData(); foundExes.Append(exePath.StealData()); } // Fall back to notepad as a default handler if (!firstEditor) { firstEditor = str::Dup(L"notepad %f"); if (hwndCombo) ComboBox_AddString(hwndCombo, firstEditor); } return firstEditor; }
DLLEXPORT STDAPI DllUnregisterServer(VOID) { ScopedMem<WCHAR> mozPluginPath(ReadRegStr(HKEY_CURRENT_USER, L"Environment", L"MOZ_PLUGIN_PATH")); if (mozPluginPath) { WCHAR szModulePath[MAX_PATH]; GetModuleFileName(g_hInstance, szModulePath, MAX_PATH); if (str::StartsWithI(szModulePath, mozPluginPath)) SHDeleteValue(HKEY_CURRENT_USER, L"Environment", L"MOZ_PLUGIN_PATH"); } DeleteRegKey(HKEY_LOCAL_MACHINE, g_lpRegKey); if (!DeleteRegKey(HKEY_CURRENT_USER, g_lpRegKey)) return E_UNEXPECTED; return S_OK; }
void DoAssociateExeWithPdfExtension(HKEY hkey) { ScopedMem<WCHAR> exePath(GetExePath()); if (!exePath) return; ScopedMem<WCHAR> prevHandler(nullptr); // Remember the previous default app for the Uninstaller prevHandler.Set(ReadRegStr(hkey, REG_CLASSES_PDF, nullptr)); if (prevHandler && !str::Eq(prevHandler, APP_NAME_STR)) WriteRegStr(hkey, REG_CLASSES_APP, L"previous.pdf", prevHandler); WriteRegStr(hkey, REG_CLASSES_APP, nullptr, _TR("PDF Document")); WCHAR *icon_path = str::Join(exePath, L",1"); WriteRegStr(hkey, REG_CLASSES_APP L"\\DefaultIcon", nullptr, icon_path); free(icon_path); WriteRegStr(hkey, REG_CLASSES_APP L"\\shell", nullptr, L"open"); ScopedMem<WCHAR> cmdPath(str::Format(L"\"%s\" \"%%1\" %%*", exePath.Get())); // "${exePath}" "%1" %* bool ok = WriteRegStr(hkey, REG_CLASSES_APP L"\\shell\\open\\command", nullptr, cmdPath); // also register for printing cmdPath.Set(str::Format(L"\"%s\" -print-to-default \"%%1\"", exePath.Get())); // "${exePath}" -print-to-default "%1" WriteRegStr(hkey, REG_CLASSES_APP L"\\shell\\print\\command", nullptr, cmdPath); // also register for printing to specific printer cmdPath.Set(str::Format(L"\"%s\" -print-to \"%%2\" \"%%1\"", exePath.Get())); // "${exePath}" -print-to "%2" "%1" WriteRegStr(hkey, REG_CLASSES_APP L"\\shell\\printto\\command", nullptr, cmdPath); // Only change the association if we're confident, that we've registered ourselves well enough if (!ok) return; WriteRegStr(hkey, REG_CLASSES_PDF, nullptr, APP_NAME_STR); // TODO: also add SumatraPDF to the Open With lists for the other supported extensions? WriteRegStr(hkey, REG_CLASSES_PDF L"\\OpenWithProgids", APP_NAME_STR, L""); if (hkey == HKEY_CURRENT_USER) { WriteRegStr(hkey, REG_EXPLORER_PDF_EXT, L"Progid", APP_NAME_STR); CrashIf(hkey == 0); // to appease prefast SHDeleteValue(hkey, REG_EXPLORER_PDF_EXT, L"Application"); DeleteRegKey(hkey, REG_EXPLORER_PDF_EXT L"\\UserChoice", true); } }
bool GetExePath(WCHAR *lpPath, size_t len) { // Search the plugin's directory first GetModuleFileName(g_hInstance, lpPath, len - 2); str::BufSet((WCHAR *)path::GetBaseName(lpPath), len - 2 - (path::GetBaseName(lpPath) - lpPath), L"SumatraPDF.exe"); if (file::Exists(lpPath)) return true; *lpPath = '\0'; // Try to get the path from the registry (set e.g. when making the default PDF viewer) ScopedMem<WCHAR> path(ReadRegStr(HKEY_CURRENT_USER, L"Software\\Classes\\SumatraPDF\\Shell\\Open\\Command", NULL)); if (!path) return false; WStrVec args; ParseCmdLine(path, args, 2); if (!file::Exists(args.At(0))) return false; str::BufSet(lpPath, len, args.At(0)); return true; }
// verify that all registry entries that need to be set in order to associate // Sumatra with .pdf files exist and have the right values bool IsExeAssociatedWithPdfExtension() { // this one doesn't have to exist but if it does, it must be APP_NAME_STR ScopedMem<WCHAR> tmp(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, L"Progid")); if (tmp && !str::Eq(tmp, APP_NAME_STR)) return false; // this one doesn't have to exist but if it does, it must be APP_NAME_STR.exe tmp.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, L"Application")); if (tmp && !str::EqI(tmp, APP_NAME_STR L".exe")) return false; // this one doesn't have to exist but if it does, it must be APP_NAME_STR tmp.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", L"Progid")); if (tmp && !str::Eq(tmp, APP_NAME_STR)) return false; // HKEY_CLASSES_ROOT\.pdf default key must exist and be equal to APP_NAME_STR tmp.Set(ReadRegStr(HKEY_CLASSES_ROOT, L".pdf", NULL)); if (!str::Eq(tmp, APP_NAME_STR)) return false; // HKEY_CLASSES_ROOT\SumatraPDF\shell\open default key must be: open tmp.Set(ReadRegStr(HKEY_CLASSES_ROOT, APP_NAME_STR L"\\shell", NULL)); if (!str::EqI(tmp, L"open")) return false; // HKEY_CLASSES_ROOT\SumatraPDF\shell\open\command default key must be: "${exe_path}" "%1" tmp.Set(ReadRegStr(HKEY_CLASSES_ROOT, APP_NAME_STR L"\\shell\\open\\command", NULL)); if (!tmp) return false; WStrVec argList; ParseCmdLine(tmp, argList); ScopedMem<WCHAR> exePath(GetExePath()); if (!exePath || !argList.Contains(L"%1") || !str::Find(tmp, L"\"%1\"")) return false; return path::IsSame(exePath, argList.At(0)); }
static WCHAR *GetGhostscriptPath() { WCHAR *gsProducts[] = { L"AFPL Ghostscript", L"Aladdin Ghostscript", L"GPL Ghostscript", L"GNU Ghostscript", }; // find all installed Ghostscript versions WStrVec versions; REGSAM access = KEY_READ | KEY_WOW64_32KEY; TryAgain64Bit: for (int i = 0; i < dimof(gsProducts); i++) { HKEY hkey; ScopedMem<WCHAR> keyName(str::Join(L"Software\\", gsProducts[i])); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, access, &hkey) != ERROR_SUCCESS) continue; WCHAR subkey[32]; for (DWORD ix = 0; RegEnumKey(hkey, ix, subkey, dimof(subkey)) == ERROR_SUCCESS; ix++) versions.Append(str::Dup(subkey)); RegCloseKey(hkey); } if ((access & KEY_WOW64_32KEY)) { // also look for 64-bit Ghostscript versions under 64-bit Windows access = KEY_READ | KEY_WOW64_64KEY; #ifndef _WIN64 // (unless this is 32-bit Windows) if (IsRunningInWow64()) #endif goto TryAgain64Bit; } versions.SortNatural(); // return the path to the newest installation for (size_t ix = versions.Count(); ix > 0; ix--) { for (int i = 0; i < dimof(gsProducts); i++) { ScopedMem<WCHAR> keyName(str::Format(L"Software\\%s\\%s", gsProducts[i], versions.At(ix - 1))); ScopedMem<WCHAR> GS_DLL(ReadRegStr(HKEY_LOCAL_MACHINE, keyName, L"GS_DLL")); if (!GS_DLL) continue; ScopedMem<WCHAR> dir(path::GetDir(GS_DLL)); ScopedMem<WCHAR> exe(path::Join(dir, L"gswin32c.exe")); if (file::Exists(exe)) return exe.StealData(); exe.Set(path::Join(dir, L"gswin64c.exe")); if (file::Exists(exe)) return exe.StealData(); } } // if Ghostscript isn't found in the Registry, try finding it in the %PATH% DWORD size = GetEnvironmentVariable(L"PATH", NULL, 0); ScopedMem<WCHAR> envpath(AllocArray<WCHAR>(size)); if (size > 0 && envpath) { GetEnvironmentVariable(L"PATH", envpath, size); WStrVec paths; paths.Split(envpath, L";", true); for (size_t ix = 0; ix < paths.Count(); ix++) { ScopedMem<WCHAR> exe(path::Join(paths.At(ix), L"gswin32c.exe")); if (file::Exists(exe)) return exe.StealData(); exe.Set(path::Join(paths.At(ix), L"gswin64c.exe")); if (file::Exists(exe)) return exe.StealData(); } } return NULL; }
static bool checkForOverride( LPCSTR libFileName, OVRTargetAPI& targetApi ) { for (int i=0; ; i++) { CHAR keyString[256] = {0}; sprintf_s( keyString, 256, GFX_DRIVER_KEY_FMT, i ); CHAR* providerName = ReadRegStr( HKEY_LOCAL_MACHINE, keyString, "ProviderName" ); // No provider name means we're out of display enumerations if( providerName == NULL ) break; free( providerName ); // Check 64-bit driver names followed by 32-bit driver names const char* driverKeys[] = {"UserModeDriverName", "UserModeDriverNameWoW", "OpenGLDriverName", "OpenGLDriverNameWoW", "InstalledDisplayDrivers" }; for( int j = 0; j < 6; ++j ) { CHAR userModeList[4096] = {0}; switch(j) { case 5: strcpy_s( userModeList, 4095, OptimusDrivers ); break; default: { CHAR* regString = ReadRegStr( HKEY_LOCAL_MACHINE, keyString, driverKeys[j] ); if( regString ) { strcpy_s( userModeList, 4095, regString ); free( regString ); } } break; } char *nextToken = NULL; if( userModeList ) { char* first = strtok_s( userModeList, " ", &nextToken ); while( first ) { if( strstr( libFileName, first ) != 0 ) { if( j < 2 ) targetApi = DirectX; else targetApi = OpenGL; return true; } first = strtok_s( NULL, " ", &nextToken ); } } } } return false; }