(Windows) Added a find rule to search the Windows Registry for the emulator.

This commit is contained in:
Leon Styhre 2021-06-26 12:00:09 +02:00
parent 3d12c440d9
commit 4160732ab0
4 changed files with 90 additions and 3 deletions

View file

@ -1064,6 +1064,9 @@ std::string FileData::findEmulatorPath(std::string& command)
// Method 1, emulator binary is defined using find rules:
#if defined(_WIN64)
std::vector<std::string> emulatorWinRegistryPaths;
#endif
std::vector<std::string> emulatorSystemPaths;
std::vector<std::string> emulatorStaticPaths;
std::string emulatorEntry;
@ -1076,6 +1079,10 @@ std::string FileData::findEmulatorPath(std::string& command)
}
if (emulatorEntry != "") {
#if defined(_WIN64)
emulatorWinRegistryPaths =
SystemData::sFindRules.get()->mEmulators[emulatorEntry].winRegistryPaths;
#endif
emulatorSystemPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].systemPaths;
emulatorStaticPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].staticPaths;
}
@ -1084,6 +1091,66 @@ std::string FileData::findEmulatorPath(std::string& command)
if (emulatorEntry != "" && emulatorSystemPaths.empty() && emulatorStaticPaths.empty())
return "NO EMULATOR RULE: " + emulatorEntry;
#if defined(_WIN64)
for (std::string path : emulatorWinRegistryPaths) {
// Search for the emulator using the App Paths keys in the Windows Registry.
std::string registryKeyPath =
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + path;
HKEY registryKey;
LSTATUS keyStatus = -1;
LSTATUS pathStatus = -1;
char registryPath[1024] {};
DWORD pathSize = 1024;
// First look in HKEY_CURRENT_USER.
keyStatus = RegOpenKeyEx(
HKEY_CURRENT_USER,
registryKeyPath.c_str(),
0,
KEY_QUERY_VALUE,
&registryKey);
// If not found, then try in HKEY_LOCAL_MACHINE.
if (keyStatus != ERROR_SUCCESS) {
keyStatus = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
registryKeyPath.c_str(),
0,
KEY_QUERY_VALUE,
&registryKey);
}
// If the key exists, then try to retrieve the value.
if (keyStatus == ERROR_SUCCESS) {
pathStatus = RegGetValue(
registryKey,
nullptr,
nullptr,
RRF_RT_REG_SZ,
nullptr,
&registryPath,
&pathSize);
}
else {
RegCloseKey(registryKey);
continue;
}
// That a value was found does not guarantee that the emulator binary actually exists,
// so check for that as well.
if (pathStatus == ERROR_SUCCESS) {
if (Utils::FileSystem::isRegularFile(registryPath) ||
Utils::FileSystem::isSymlink(registryPath)) {
command.replace(0, endPos + 1, registryPath);
RegCloseKey(registryKey);
return registryPath;
}
}
RegCloseKey(registryKey);
}
#endif
for (std::string path : emulatorSystemPaths) {
#if defined(_WIN64)
std::wstring pathWide = Utils::String::stringToWideString(path);

View file

@ -115,7 +115,12 @@ void FindRules::loadFindRules()
emulatorName << "\", skipping entry";
continue;
}
#if defined(_WIN64)
if (ruleType != "winregistrypath" && ruleType != "systempath" &&
ruleType != "staticpath") {
#else
if (ruleType != "systempath" && ruleType != "staticpath") {
#endif
LOG(LogWarning) << "Found invalid rule type \"" << ruleType <<
"\" for emulator \"" << emulatorName << "\", skipping entry";
continue;
@ -127,11 +132,18 @@ void FindRules::loadFindRules()
emulatorRules.systemPaths.push_back(entryValue);
else if (ruleType == "staticpath")
emulatorRules.staticPaths.push_back(entryValue);
#if defined(_WIN64)
else if (ruleType == "winregistrypath")
emulatorRules.winRegistryPaths.push_back(entryValue);
#endif
}
}
mEmulators[emulatorName] = emulatorRules;
emulatorRules.systemPaths.clear();
emulatorRules.staticPaths.clear();
#if defined(_WIN64)
emulatorRules.winRegistryPaths.clear();
#endif
}
for (pugi::xml_node core = ruleList.child("core"); core;

View file

@ -41,6 +41,9 @@ public:
private:
struct EmulatorRules {
#if defined(_WIN64)
std::vector<std::string> winRegistryPaths;
#endif
std::vector<std::string> systemPaths;
std::vector<std::string> staticPaths;
};

View file

@ -1,15 +1,20 @@
<?xml version="1.0"?>
<!-- This is the ES-DE find rules configuration file for Windows. -->
<!-- This is the ES-DE find rules configuration file for Windows -->
<ruleList>
<emulator name="RETROARCH">
<rule type="winregistrypath">
<!-- Check for an App Paths entry in the Windows Registry -->
<entry>retroarch.exe</entry>
</rule>
<rule type="systempath">
<!-- This requires that the user has manually updated the Path variable -->
<entry>retroarch.exe</entry>
</rule>
<rule type="staticpath">
<!-- Some reasonable installation locations -->
<!-- Some reasonable installation locations as fallback -->
<entry>C:\RetroArch-Win64\retroarch.exe</entry>
<entry>C:\RetroArch\retroarch.exe</entry>
<entry>~\AppData\Roaming\RetroArch\retroarch.exe</entry>
<entry>C:\Program Files\RetroArch-Win64\retroarch.exe</entry>
<entry>C:\Program Files\RetroArch\retroarch.exe</entry>
<entry>C:\Program Files (x86)\RetroArch-Win64\retroarch.exe</entry>
@ -20,7 +25,7 @@
</rule>
</emulator>
<emulator name="YUZU">
<!-- Nintendo Switch emulator Yuzu. -->
<!-- Nintendo Switch emulator Yuzu -->
<rule type="systempath">
<entry>yuzu.exe</entry>
</rule>