scan secondary library folders on windows

This commit is contained in:
Ricardo Luís Vaz Silva 2023-07-05 21:31:52 -03:00 committed by Rachael Alexanderson
parent 7e8bb6ea30
commit 7235058f09

View file

@ -80,6 +80,112 @@
#include "cmdlib.h"
#include "i_interface.h"
//TODO maybe move this code to a separate cpp file, so that there isn't code duplication between the win32 and posix backends
static void PSR_FindEndBlock(FScanner &sc)
{
int depth = 1;
do
{
if(sc.CheckToken('}'))
--depth;
else if(sc.CheckToken('{'))
++depth;
else
sc.MustGetAnyToken();
}
while(depth);
}
static void PSR_SkipBlock(FScanner &sc)
{
sc.MustGetToken('{');
PSR_FindEndBlock(sc);
}
static bool PSR_FindAndEnterBlock(FScanner &sc, const char* keyword)
{
// Finds a block with a given keyword and then enter it (opening brace)
// Should be closed with PSR_FindEndBlock
while(sc.GetToken())
{
if(sc.TokenType == '}')
{
sc.UnGet();
return false;
}
sc.TokenMustBe(TK_StringConst);
if(!sc.Compare(keyword))
{
if(!sc.CheckToken(TK_StringConst))
PSR_SkipBlock(sc);
}
else
{
sc.MustGetToken('{');
return true;
}
}
return false;
}
static TArray<FString> PSR_ReadBaseInstalls(FScanner &sc)
{
TArray<FString> result;
// Get a list of possible install directories.
while(sc.GetToken())
{
if(sc.TokenType == '}')
break;
sc.TokenMustBe(TK_StringConst);
FString key(sc.String);
if(key.Left(18).CompareNoCase("BaseInstallFolder_") == 0)
{
sc.MustGetToken(TK_StringConst);
result.Push(FString(sc.String) + "/steamapps/common");
}
else
{
if(sc.CheckToken('{'))
PSR_FindEndBlock(sc);
else
sc.MustGetToken(TK_StringConst);
}
}
return result;
}
static TArray<FString> ParseSteamRegistry(const char* path)
{
TArray<FString> dirs;
// Read registry data
FScanner sc;
if (sc.OpenFile(path))
{
sc.SetCMode(true);
// Find the SteamApps listing
if (PSR_FindAndEnterBlock(sc, "InstallConfigStore"))
{
if (PSR_FindAndEnterBlock(sc, "Software"))
{
if (PSR_FindAndEnterBlock(sc, "Valve"))
{
if (PSR_FindAndEnterBlock(sc, "Steam"))
{
dirs = PSR_ReadBaseInstalls(sc);
}
PSR_FindEndBlock(sc);
}
PSR_FindEndBlock(sc);
}
PSR_FindEndBlock(sc);
}
}
return dirs;
}
//==========================================================================
//
// QueryPathKey
@ -240,18 +346,30 @@ TArray<FString> I_GetSteamPath()
"Doom 2/finaldoombase"
};
FString path;
FString steamPath;
if (!QueryPathKey(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", L"SteamPath", path))
if (!QueryPathKey(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", L"SteamPath", steamPath))
{
if (!QueryPathKey(HKEY_LOCAL_MACHINE, L"Software\\Valve\\Steam", L"InstallPath", path))
if (!QueryPathKey(HKEY_LOCAL_MACHINE, L"Software\\Valve\\Steam", L"InstallPath", steamPath))
return result;
}
path += "/SteamApps/common/";
TArray<FString> paths = ParseSteamRegistry(steamPath + "/config/config.vdf");
for(FString &path : paths)
{
path.ReplaceChars('\\','/');
path+="/";
}
paths.Push(steamPath + "/steamapps/common/");
for(unsigned int i = 0; i < countof(steam_dirs); ++i)
{
result.Push(path + steam_dirs[i]);
for(const FString &path : paths)
{
result.Push(path + steam_dirs[i]);
}
}
return result;