1
0
Fork 0

DBG: move InitDLLDebugW out of TitanEngine

This commit is contained in:
Duncan Ogilvie 2020-04-25 22:12:57 +02:00
parent 434ef31a05
commit e0b92786f0
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
8 changed files with 286 additions and 13 deletions

View File

@ -237,7 +237,7 @@ bool cbDebugAttach(int argc, char* argv[])
#endif // _WIN64 #endif // _WIN64
return false; return false;
} }
if(!GetFileNameFromProcessHandle(hProcess, szFileName)) if(!GetFileNameFromProcessHandle(hProcess, szDebuggeePath))
{ {
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not get module filename %X!\n"), DWORD(pid)); dprintf(QT_TRANSLATE_NOOP("DBG", "Could not get module filename %X!\n"), DWORD(pid));
return false; return false;

View File

@ -70,10 +70,11 @@ static WString gInitExe, gInitCmd, gInitDir, gDllLoader;
static CookieQuery cookie; static CookieQuery cookie;
static duint exceptionDispatchAddr = 0; static duint exceptionDispatchAddr = 0;
static bool bPausedOnException = false; static bool bPausedOnException = false;
static HANDLE DebugDLLFileMapping = 0;
char szProgramDir[MAX_PATH] = ""; char szProgramDir[MAX_PATH] = "";
char szFileName[MAX_PATH] = ""; char szDebuggeePath[MAX_PATH] = "";
char szDllLoaderPath[MAX_PATH] = "";
char szSymbolCachePath[MAX_PATH] = ""; char szSymbolCachePath[MAX_PATH] = "";
char sqlitedb[deflen] = "";
std::vector<std::pair<duint, duint>> RunToUserCodeBreakpoints; std::vector<std::pair<duint, duint>> RunToUserCodeBreakpoints;
PROCESS_INFORMATION* fdProcessInfo = &g_pi; PROCESS_INFORMATION* fdProcessInfo = &g_pi;
HANDLE hActiveThread; HANDLE hActiveThread;
@ -1672,8 +1673,10 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
char command[MAX_PATH * 2] = ""; char command[MAX_PATH * 2] = "";
bool bIsDebuggingThis = false; bool bIsDebuggingThis = false;
if(bFileIsDll && !_stricmp(DLLDebugFileName, szFileName) && !bIsAttached) //Set entry breakpoint if(bFileIsDll && !_stricmp(DLLDebugFileName, szDebuggeePath) && !bIsAttached) //Set entry breakpoint
{ {
CloseHandle(DebugDLLFileMapping);
DebugDLLFileMapping = 0;
bIsDebuggingThis = true; bIsDebuggingThis = true;
pDebuggedBase = (duint)base; pDebuggedBase = (duint)base;
DbCheckHash(ModContentHashFromAddr(pDebuggedBase)); //Check hash mismatch DbCheckHash(ModContentHashFromAddr(pDebuggedBase)); //Check hash mismatch
@ -2553,6 +2556,45 @@ void dbgstartscriptthread(CBPLUGINSCRIPT cbScript)
CloseHandle(CreateThread(0, 0, scriptThread, (LPVOID)cbScript, 0, 0)); CloseHandle(CreateThread(0, 0, scriptThread, (LPVOID)cbScript, 0, 0));
} }
static void* InitDLLDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder)
{
WString loaderFilename = StringUtils::sprintf(L"\\DLLLoader" ArchValue(L"32", L"64") L"_%04X.exe", GetTickCount() & 0xFFFF);
WString debuggeeLoaderPath = szFileName;
{
auto backslashIdx = debuggeeLoaderPath.rfind('\\');
if(backslashIdx != WString::npos)
debuggeeLoaderPath.resize(backslashIdx);
}
debuggeeLoaderPath += loaderFilename;
WString loaderPath = StringUtils::Utf8ToUtf16(szDllLoaderPath);
if(!CopyFileW(loaderPath.c_str(), debuggeeLoaderPath.c_str(), FALSE))
{
debuggeeLoaderPath = StringUtils::Utf8ToUtf16(szProgramDir);
debuggeeLoaderPath += loaderFilename;
if(!CopyFileW(loaderPath.c_str(), debuggeeLoaderPath.c_str(), FALSE))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Error debugging DLL (failed to copy loader)\n"));
return nullptr;
}
}
PPROCESS_INFORMATION ReturnValue = (PPROCESS_INFORMATION)InitDebugW(debuggeeLoaderPath.c_str(), szCommandLine, szCurrentFolder);
WString mappingName = StringUtils::sprintf(L"Local\\szLibraryName%X", ReturnValue->dwProcessId);
const auto mappingSize = 512;
DebugDLLFileMapping = CreateFileMappingW(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, mappingSize * sizeof(wchar_t), mappingName.c_str());
if(DebugDLLFileMapping)
{
wchar_t* szLibraryPathMapping = (wchar_t*)MapViewOfFile(DebugDLLFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, mappingSize * sizeof(wchar_t));
if(szLibraryPathMapping)
{
wcscpy_s(szLibraryPathMapping, mappingSize, szFileName);
UnmapViewOfFile(szLibraryPathMapping);
}
}
return ReturnValue;
}
static void debugLoopFunction(void* lpParameter, bool attach) static void debugLoopFunction(void* lpParameter, bool attach)
{ {
//initialize variables //initialize variables
@ -2565,7 +2607,7 @@ static void debugLoopFunction(void* lpParameter, bool attach)
INIT_STRUCT* init; INIT_STRUCT* init;
if(attach) if(attach)
{ {
gInitExe = StringUtils::Utf8ToUtf16(szFileName); gInitExe = StringUtils::Utf8ToUtf16(szDebuggeePath);
pid = DWORD(lpParameter); pid = DWORD(lpParameter);
static PROCESS_INFORMATION pi_attached; static PROCESS_INFORMATION pi_attached;
memset(&pi_attached, 0, sizeof(pi_attached)); memset(&pi_attached, 0, sizeof(pi_attached));
@ -2575,14 +2617,19 @@ static void debugLoopFunction(void* lpParameter, bool attach)
{ {
init = (INIT_STRUCT*)lpParameter; init = (INIT_STRUCT*)lpParameter;
gInitExe = StringUtils::Utf8ToUtf16(init->exe); gInitExe = StringUtils::Utf8ToUtf16(init->exe);
strcpy_s(szFileName, init->exe); strcpy_s(szDebuggeePath, init->exe);
} }
pDebuggedEntry = GetPE32DataW(gInitExe.c_str(), 0, UE_OEP); pDebuggedEntry = GetPE32DataW(gInitExe.c_str(), 0, UE_OEP);
bEntryIsInMzHeader = pDebuggedEntry == 0 || pDebuggedEntry == 1; bEntryIsInMzHeader = pDebuggedEntry == 0 || pDebuggedEntry == 1;
bFileIsDll = IsFileDLLW(StringUtils::Utf8ToUtf16(szFileName).c_str(), 0); bFileIsDll = IsFileDLLW(StringUtils::Utf8ToUtf16(szDebuggeePath).c_str(), 0);
DbSetPath(nullptr, szFileName); if(bFileIsDll && !FileExists(szDllLoaderPath))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Error debugging DLL (loaddll.exe not found)\n"));
return;
}
DbSetPath(nullptr, szDebuggeePath);
if(!attach) if(!attach)
{ {
@ -2602,7 +2649,7 @@ static void debugLoopFunction(void* lpParameter, bool attach)
//start the process //start the process
if(bFileIsDll) if(bFileIsDll)
fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(gInitExe.c_str(), false, gInitCmd.c_str(), gInitDir.c_str(), 0); fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(gInitExe.c_str(), gInitCmd.c_str(), gInitDir.c_str());
else else
fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(gInitExe.c_str(), gInitCmd.c_str(), gInitDir.c_str()); fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(gInitExe.c_str(), gInitCmd.c_str(), gInitDir.c_str());
if(!fdProcessInfo) if(!fdProcessInfo)
@ -2680,10 +2727,10 @@ static void debugLoopFunction(void* lpParameter, bool attach)
//inform GUI we started without problems //inform GUI we started without problems
GuiSetDebugState(initialized); GuiSetDebugState(initialized);
GuiFocusView(GUI_DISASSEMBLY); GuiFocusView(GUI_DISASSEMBLY);
GuiAddRecentFile(szFileName); GuiAddRecentFile(szDebuggeePath);
//set GUI title //set GUI title
strcpy_s(szBaseFileName, szFileName); strcpy_s(szBaseFileName, szDebuggeePath);
int len = (int)strlen(szBaseFileName); int len = (int)strlen(szBaseFileName);
while(szBaseFileName[len] != '\\' && len) while(szBaseFileName[len] != '\\' && len)
len--; len--;
@ -2693,7 +2740,7 @@ static void debugLoopFunction(void* lpParameter, bool attach)
//call plugin callback //call plugin callback
PLUG_CB_INITDEBUG initInfo; PLUG_CB_INITDEBUG initInfo;
initInfo.szFileName = szFileName; initInfo.szFileName = szDebuggeePath;
plugincbcall(CB_INITDEBUG, &initInfo); plugincbcall(CB_INITDEBUG, &initInfo);
//call plugin callback (attach) //call plugin callback (attach)
@ -2760,6 +2807,12 @@ static void debugLoopFunction(void* lpParameter, bool attach)
hProcessToken = 0; hProcessToken = 0;
} }
if(DebugDLLFileMapping)
{
CloseHandle(DebugDLLFileMapping);
DebugDLLFileMapping = 0;
}
pDebuggedEntry = 0; pDebuggedEntry = 0;
pDebuggedBase = 0; pDebuggedBase = 0;
pCreateProcessBase = 0; pCreateProcessBase = 0;

View File

@ -114,7 +114,8 @@ extern PROCESS_INFORMATION* fdProcessInfo;
extern HANDLE hActiveThread; extern HANDLE hActiveThread;
extern HANDLE hProcessToken; extern HANDLE hProcessToken;
extern char szProgramDir[MAX_PATH]; extern char szProgramDir[MAX_PATH];
extern char szFileName[MAX_PATH]; extern char szDebuggeePath[MAX_PATH];
extern char szDllLoaderPath[MAX_PATH];
extern char szSymbolCachePath[MAX_PATH]; extern char szSymbolCachePath[MAX_PATH];
extern bool bUndecorateSymbolNames; extern bool bUndecorateSymbolNames;
extern bool bEnableSourceDebugging; extern bool bEnableSourceDebugging;

View File

@ -630,6 +630,10 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
while(szProgramDir[len] != '\\') while(szProgramDir[len] != '\\')
len--; len--;
szProgramDir[len] = 0; szProgramDir[len] = 0;
strcpy_s(szDllLoaderPath, szProgramDir);
strcat_s(szDllLoaderPath, "\\loaddll.exe");
#ifdef ENABLE_MEM_TRACE #ifdef ENABLE_MEM_TRACE
strcpy_s(alloctrace, szProgramDir); strcpy_s(alloctrace, szProgramDir);
strcat_s(alloctrace, "\\alloctrace.txt"); strcat_s(alloctrace, "\\alloctrace.txt");

23
src/loaddll/loaddll.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <windows.h>
wchar_t szLibraryPath[512];
int main()
{
wchar_t szName[256];
wsprintfW(szName, L"Local\\szLibraryName%X", (unsigned int)GetCurrentProcessId());
HANDLE hMapFile = OpenFileMappingW(FILE_MAP_READ, false, szName);
if(hMapFile)
{
const wchar_t* szLibraryPathMapping = (const wchar_t*)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, sizeof(szLibraryPath));
if(szLibraryPathMapping)
{
lstrcpyW(szLibraryPath, szLibraryPathMapping);
UnmapViewOfFile(szLibraryPathMapping);
}
CloseHandle(hMapFile);
}
if(szLibraryPath[0])
return (LoadLibraryW(szLibraryPath) != NULL);
return 0;
}

157
src/loaddll/loaddll.vcxproj Normal file
View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="loaddll.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{21AD9735-967B-41F7-8329-DB88D03743ED}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\x32\</OutDir>
<GenerateManifest>false</GenerateManifest>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\x32d\</OutDir>
<GenerateManifest>false</GenerateManifest>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\x64\</OutDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\x64d\</OutDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalManifestDependencies>
</AdditionalManifestDependencies>
<LargeAddressAware>true</LargeAddressAware>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalManifestDependencies>
</AdditionalManifestDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalManifestDependencies>
</AdditionalManifestDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalManifestDependencies>
</AdditionalManifestDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="loaddll.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -20,6 +20,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x64dbg_launcher", "src\laun
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zydis_wrapper", "src\zydis_wrapper\zydis_wrapper.vcxproj", "{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zydis_wrapper", "src\zydis_wrapper\zydis_wrapper.vcxproj", "{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loaddll", "src\loaddll\loaddll.vcxproj", "{21AD9735-967B-41F7-8329-DB88D03743ED}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -68,8 +70,19 @@ Global
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|Win32.Build.0 = Release|Win32 {3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|Win32.Build.0 = Release|Win32
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|x64.ActiveCfg = Release|x64 {3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|x64.ActiveCfg = Release|x64
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|x64.Build.0 = Release|x64 {3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|x64.Build.0 = Release|x64
{21AD9735-967B-41F7-8329-DB88D03743ED}.Debug|Win32.ActiveCfg = Debug|Win32
{21AD9735-967B-41F7-8329-DB88D03743ED}.Debug|Win32.Build.0 = Debug|Win32
{21AD9735-967B-41F7-8329-DB88D03743ED}.Debug|x64.ActiveCfg = Debug|x64
{21AD9735-967B-41F7-8329-DB88D03743ED}.Debug|x64.Build.0 = Debug|x64
{21AD9735-967B-41F7-8329-DB88D03743ED}.Release|Win32.ActiveCfg = Release|Win32
{21AD9735-967B-41F7-8329-DB88D03743ED}.Release|Win32.Build.0 = Release|Win32
{21AD9735-967B-41F7-8329-DB88D03743ED}.Release|x64.ActiveCfg = Release|x64
{21AD9735-967B-41F7-8329-DB88D03743ED}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CC6FA67F-9244-45AD-AC13-69C29283D226}
EndGlobalSection
EndGlobal EndGlobal