mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-28 18:31:40 +00:00
Add feature to globally hook processes to inject indirectly.
* This allows you to hook into processes that are difficult to launch directly with the existing functionality in RenderDoc. * This is rather risky, as it modifies the AppInit_DLLs registry key to inject a small shim dll that checks for the desired process and injects the full renderdoc.dll. If that registry key got left, or if there was some incompatibility with the shim dll, you could have problems. It should only ever be used as a last resort if there's no other way to capture.
This commit is contained in:
@@ -45,9 +45,9 @@ rm -f dist/Release{32,64}/*.{exp,lib,metagen,xml} dist/Release{32,64}/*.vshost.*
|
||||
# In the 64bit release folder, make an x86 subfolder and copy in renderdoc 32bit
|
||||
mkdir -p dist/Release64/x86
|
||||
rm -rf dist/Release32/pdblocate/x64 dist/ReleasePDBs32/pdblocate/x64
|
||||
cp -R dist/Release32/{renderdoc.dll,renderdoccmd.exe,pdblocate} dist/Release64/x86/
|
||||
cp -R dist/Release32/{renderdoc.dll,renderdocshim32.dll,renderdoccmd.exe,pdblocate} dist/Release64/x86/
|
||||
mkdir -p dist/ReleasePDBs64/x86
|
||||
cp -R dist/ReleasePDBs32/{renderdoc.dll,renderdoc.pdb,renderdoccmd.exe,renderdoccmd.pdb,pdblocate} dist/ReleasePDBs64/x86/
|
||||
cp -R dist/ReleasePDBs32/{renderdoc.dll,renderdoc.pdb,renderdocshim32.dll,renderdocshim32.pdb,renderdoccmd.exe,renderdoccmd.pdb,pdblocate} dist/ReleasePDBs64/x86/
|
||||
|
||||
if [[ $AUTOBUILD -eq 0 ]]; then
|
||||
echo "Ready to make installer MSIs - make sure to bump version numbers on package."
|
||||
|
||||
@@ -289,5 +289,21 @@
|
||||
|
||||
</content>
|
||||
</section>
|
||||
<section address="FAQ13">
|
||||
<title>I can't launch my program for capture directly. Can I capture it anyway?</title>
|
||||
<content>
|
||||
<para>
|
||||
There is an option for capturing programs using RenderDoc where you can't easily set
|
||||
up a direct launch of the process.
|
||||
</para>
|
||||
<para>
|
||||
More details can be found in the
|
||||
<link xlink:href="D1612D25-C8BA-4349-9CE2-1E57D60F98C5">capture options</link> page which
|
||||
details how to use it, however you should take care to read the warnings! This option
|
||||
isn't without its risks, so you need to be sure you know what you're doing before
|
||||
using it. It should always be used as a last resort when there is no other option.
|
||||
</para>
|
||||
</content>
|
||||
</section>
|
||||
</developerConceptualDocument>
|
||||
</topic>
|
||||
|
||||
@@ -126,6 +126,8 @@
|
||||
<HelpKeywords>
|
||||
<HelpKeyword index="K" term="Window, Capture Window" />
|
||||
<HelpKeyword index="K" term="Window, Attach to Process" />
|
||||
<HelpKeyword index="K" term="Capture All Processes" />
|
||||
<HelpKeyword index="K" term="Global Hook" />
|
||||
</HelpKeywords>
|
||||
</Topic>
|
||||
<Topic id="16D2B42E-65B0-40D1-AB91-AD2B156F5DA0" visible="True" title="Event Browser">
|
||||
|
||||
@@ -201,6 +201,42 @@
|
||||
|
||||
</content>
|
||||
</section>
|
||||
<section address="globalhook">
|
||||
<title>Global Process Hook</title>
|
||||
<content>
|
||||
<alert class="caution">
|
||||
<para>This option is risky and should not be used lightly. Know what you're doing and
|
||||
use it as a last resort.</para>
|
||||
</alert>
|
||||
<para>To expose this option you have to enable it in
|
||||
<link xlink:href="B1826EEE-2ED1-44E4-8202-37CD8B3FEEB5">the settings</link>,
|
||||
to prevent it being used accidentally.</para>
|
||||
<para>When you've entered a path, or filename, in the executable text at the top
|
||||
of the window, this option will then insert a global hook that causes <legacyBold>every</legacyBold> new
|
||||
process created to load a very small shim dll.</para>
|
||||
<para>The shim dll will load, create a thread that checks to see if the process
|
||||
matches the path or filename specified, and then unload. If the process matches
|
||||
it will also inject RenderDoc and capturing will continue as normal. At this
|
||||
point you should <legacyItalic>first disable the global hook</legacyItalic>, then
|
||||
you can use the 'Attach to running instance' menu option to continue as normal.</para>
|
||||
<para>RenderDoc implements this behaviour by modifying the
|
||||
<externalLink>
|
||||
<linkText>AppInit_DLLs</linkText>
|
||||
<linkAlternateText>AppInit_DLLs on MSDN</linkAlternateText>
|
||||
<linkUri>http://support2.microsoft.com/kb/197571</linkUri>
|
||||
</externalLink> registry key to reference RenderDoc's dlls. This is not a particularly safe
|
||||
method but it's the only reliable method to do what we want. The shim dll is
|
||||
deliberately made as small and thin as possible, referencing only kernel32.dll, to
|
||||
minimise any risks.
|
||||
</para>
|
||||
<para>If RenderDoc crashes or something otherwise goes wrong while these registry
|
||||
keys are modified, the shim dll will continue to be injected into every process which
|
||||
is certainly not desireable. Should anything go wrong, RenderDoc writes a .reg
|
||||
file that restores the registry to its previous state in %TEMP%.</para>
|
||||
<para>Again, <legacyBold>this method should be a last resort</legacyBold>. Given
|
||||
the risks you should always try to capture directly in some way before trying this.</para>
|
||||
</content>
|
||||
</section>
|
||||
<relatedTopics>
|
||||
<link xlink:href="f2f4fbfa-6127-4831-84e7-07309bd85908" />
|
||||
<link xlink:href="14048aef-0053-4e38-98cd-541f4d15d12e" />
|
||||
|
||||
@@ -96,6 +96,15 @@
|
||||
recommended that you manually check for updates as new versions will be made available regularly with bugfixes.</para></entry>
|
||||
<entry><para>Enabled</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Allow global process hooking</para></entry>
|
||||
<entry><para>This option enables the functionality allowing capturing of programs that aren't
|
||||
launched directly from RenderDoc, but are launched from somewhere else.</para>
|
||||
<para>This option <legacyBold>can be dangerous</legacyBold> which is why you have to deliberately enable it
|
||||
here. Be careful when using this and only do so when necessary - more details can be found in the
|
||||
<link xlink:href="D1612D25-C8BA-4349-9CE2-1E57D60F98C5">capture options</link> page.</para></entry>
|
||||
<entry><para>Disabled</para></entry>
|
||||
</row>
|
||||
</table>
|
||||
|
||||
</content>
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
<Component Id='RenderDocCPP' Guid='2E6F718F-8BCC-4D41-9688-E99CF2F6B303'>
|
||||
<File Id='RenderDocCPP' Name='renderdoc.dll' DiskId='1' Source='dist/Release32/renderdoc.dll' KeyPath='yes' />
|
||||
<File Id='D3DCompiler47' Name='d3dcompiler_47.dll' DiskId='1' Source='dist/Release32/d3dcompiler_47.dll' />
|
||||
<File Id='RenderDocSHIM' Name='renderdocshim32.dll' DiskId='1' Source='dist/Release32/renderdocshim32.dll' />
|
||||
|
||||
<RegistryValue Root="HKLM" Id="RDCCLSID" Action="write"
|
||||
Key="Software\Classes\CLSID\{5D6BF029-A6BA-417A-8523-120492B1DCE3}"
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
<Component Id='RenderDocCPP' Win64="yes" Guid='9D5949F9-0447-47B6-829D-77465E1FDAD9'>
|
||||
<File Id='RenderDocCPP' Name='renderdoc.dll' DiskId='1' Source='dist/Release64/renderdoc.dll' KeyPath='yes' />
|
||||
<File Id='D3DCompiler47' Name='d3dcompiler_47.dll' DiskId='1' Source='dist/Release64/d3dcompiler_47.dll' />
|
||||
<File Id='RenderDocSHIM' Name='renderdocshim64.dll' DiskId='1' Source='dist/Release64/renderdocshim64.dll' />
|
||||
|
||||
<RegistryValue Root="HKLM" Id="RDCCLSID" Action="write"
|
||||
Key="Software\Classes\CLSID\{5D6BF029-A6BA-417A-8523-120492B1DCE3}"
|
||||
@@ -130,6 +131,7 @@
|
||||
<Directory Id='renderdocX86' Name='x86'>
|
||||
<Component Id='renderdocX86Bins' Win64="yes" Guid='EB58A048-899A-4239-B229-DA9781C431F8'>
|
||||
<File Id='renderdocX86DLL' Name='renderdoc.dll' DiskId='1' Source='dist/Release64/x86/renderdoc.dll' KeyPath='yes' />
|
||||
<File Id='renderdocshimX86DLL' Name='renderdocshim32.dll' DiskId='1' Source='dist/Release64/x86/renderdocshim32.dll' />
|
||||
<File Id='renderdocX86CMD' Name='renderdoccmd.exe' DiskId='1' Source='dist/Release64/x86/renderdoccmd.exe' />
|
||||
|
||||
<RegistryValue Root="HKLM" Id="RDCCLSID32" Action="write"
|
||||
|
||||
@@ -45,6 +45,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crash_generation_server", "
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exception_handler", "renderdoc\3rdparty\breakpad\client\windows\handler\exception_handler.vcxproj", "{B7399F39-300F-450E-F471-9490F959D2A7}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderdocshim", "renderdocshim\renderdocshim.vcxproj", "{6DEE3F12-F2F8-42CA-865A-578D0FD11387}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Profile|Win32 = Profile|Win32
|
||||
@@ -117,6 +119,14 @@ Global
|
||||
{B7399F39-300F-450E-F471-9490F959D2A7}.Release|Win32.Build.0 = Release|Win32
|
||||
{B7399F39-300F-450E-F471-9490F959D2A7}.Release|x64.ActiveCfg = Release|x64
|
||||
{B7399F39-300F-450E-F471-9490F959D2A7}.Release|x64.Build.0 = Release|x64
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Profile|Win32.ActiveCfg = Profile|Win32
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Profile|Win32.Build.0 = Profile|Win32
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Profile|x64.ActiveCfg = Profile|x64
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Profile|x64.Build.0 = Profile|x64
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Release|Win32.Build.0 = Release|Win32
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Release|x64.ActiveCfg = Release|x64
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -128,6 +138,7 @@ Global
|
||||
{5504BAC8-287E-4083-A57F-5EE172EDDAEB} = {89059266-9C4E-4637-AB1D-BFF1DC15096B}
|
||||
{D03DF2F9-513C-4084-BBDD-1DEE8D9250D7} = {B5A783D9-AEB9-420D-8E77-D4D930F8D88C}
|
||||
{6CCB39BA-AB6B-4589-B7C4-9DA879571713} = {B5A783D9-AEB9-420D-8E77-D4D930F8D88C}
|
||||
{6DEE3F12-F2F8-42CA-865A-578D0FD11387} = {B5A783D9-AEB9-420D-8E77-D4D930F8D88C}
|
||||
{EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7} = {9B86ABCF-0A48-41CE-B109-FFA08D80F345}
|
||||
{EC847717-119A-2391-0477-212E1140082C} = {9B86ABCF-0A48-41CE-B109-FFA08D80F345}
|
||||
{7893E300-3ED0-7F4C-158F-67EA63934C57} = {9B86ABCF-0A48-41CE-B109-FFA08D80F345}
|
||||
|
||||
@@ -268,15 +268,3 @@ typedef void (RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(KeyButton *keys, int num)
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_InitRemoteAccess(uint32_t *ident);
|
||||
typedef void (RENDERDOC_CC *pRENDERDOC_InitRemoteAccess)(uint32_t *ident);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Injection/execution capture functions.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_ExecuteAndInject(const wchar_t *app, const wchar_t *workingDir, const wchar_t *cmdLine,
|
||||
const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
typedef uint32_t (RENDERDOC_CC *pRENDERDOC_ExecuteAndInject)(const wchar_t *app, const wchar_t *workingDir, const wchar_t *cmdLine,
|
||||
const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
typedef uint32_t (RENDERDOC_CC *pRENDERDOC_InjectIntoProcess)(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
|
||||
@@ -240,6 +240,23 @@ typedef ReplayCreateStatus (RENDERDOC_CC *pRENDERDOC_CreateRemoteReplayConnectio
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SpawnReplayHost(volatile bool32 *killReplay);
|
||||
typedef void (RENDERDOC_CC *pRENDERDOC_SpawnReplayHost)(volatile bool32 *killReplay);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Injection/execution capture functions.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct CaptureOptions;
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartGlobalHook(const wchar_t *pathmatch, const wchar_t *logfile, const CaptureOptions *opts);
|
||||
typedef void (RENDERDOC_CC *pRENDERDOC_StartGlobalHook)(const wchar_t *pathmatch, const wchar_t *logfile, const CaptureOptions *opts);
|
||||
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_ExecuteAndInject(const wchar_t *app, const wchar_t *workingDir, const wchar_t *cmdLine,
|
||||
const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
typedef uint32_t (RENDERDOC_CC *pRENDERDOC_ExecuteAndInject)(const wchar_t *app, const wchar_t *workingDir, const wchar_t *cmdLine,
|
||||
const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
typedef uint32_t (RENDERDOC_CC *pRENDERDOC_InjectIntoProcess)(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Miscellaneous!
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -40,6 +40,12 @@ uint32_t Process::CreateAndInjectIntoProcess(const wchar_t *app, const wchar_t *
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Process::StartGlobalHook(const wchar_t *pathmatch, const wchar_t *logfile, const CaptureOptions *opts)
|
||||
{
|
||||
RDCUNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *Process::GetFunctionAddress(const char *module, const char *function)
|
||||
{
|
||||
RDCUNIMPLEMENTED();
|
||||
@@ -49,4 +55,4 @@ void *Process::GetFunctionAddress(const char *module, const char *function)
|
||||
uint32_t Process::GetCurrentPID()
|
||||
{
|
||||
return (uint32_t)getpid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ struct CaptureOptions;
|
||||
|
||||
namespace Process
|
||||
{
|
||||
void StartGlobalHook(const wchar_t *pathmatch, const wchar_t *logfile, const CaptureOptions *opts);
|
||||
uint32_t InjectIntoProcess(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, bool waitForExit);
|
||||
uint32_t CreateAndInjectIntoProcess(const wchar_t *app, const wchar_t *workingDir, const wchar_t *cmdLine,
|
||||
const wchar_t *logfile, const CaptureOptions *opts, bool waitForExit);
|
||||
|
||||
@@ -411,6 +411,62 @@ uint32_t Process::CreateAndInjectIntoProcess(const wchar_t *app, const wchar_t *
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Process::StartGlobalHook(const wchar_t *pathmatch, const wchar_t *logfile, const CaptureOptions *opts)
|
||||
{
|
||||
if(pathmatch == NULL) return;
|
||||
|
||||
wchar_t renderdocPath[MAX_PATH] = {0};
|
||||
GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), &renderdocPath[0], MAX_PATH-1);
|
||||
|
||||
wchar_t *slash = wcsrchr(renderdocPath, L'\\');
|
||||
|
||||
if(slash) *slash = 0;
|
||||
else slash = renderdocPath + wcslen(renderdocPath);
|
||||
|
||||
wcscat_s(renderdocPath, L"\\renderdoccmd.exe");
|
||||
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
STARTUPINFO si = {0};
|
||||
SECURITY_ATTRIBUTES pSec = {0};
|
||||
SECURITY_ATTRIBUTES tSec = {0};
|
||||
pSec.nLength = sizeof(pSec);
|
||||
tSec.nLength = sizeof(tSec);
|
||||
|
||||
wchar_t *paramsAlloc = new wchar_t[2048];
|
||||
|
||||
string optstr = opts->ToString();
|
||||
|
||||
_snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --globalhook \"%ls\" \"%ls\" \"%hs\"",
|
||||
renderdocPath, pathmatch, logfile == NULL ? L"" : logfile, optstr.c_str());
|
||||
|
||||
paramsAlloc[2047] = 0;
|
||||
|
||||
BOOL retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, 0, NULL, NULL, &si, &pi);
|
||||
|
||||
if(retValue == FALSE) return;
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
#if defined(WIN64)
|
||||
*slash = 0;
|
||||
|
||||
wcscat_s(renderdocPath, L"\\x86\\renderdoccmd.exe");
|
||||
|
||||
_snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --globalhook \"%ls\" \"%ls\" \"%hs\"",
|
||||
renderdocPath, pathmatch, logfile == NULL ? L"" : logfile, optstr.c_str());
|
||||
|
||||
paramsAlloc[2047] = 0;
|
||||
|
||||
retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, 0, NULL, NULL, &si, &pi);
|
||||
|
||||
if(retValue == FALSE) return;
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *Process::GetFunctionAddress(const char *module, const char *function)
|
||||
{
|
||||
HMODULE mod = GetModuleHandleA(module);
|
||||
|
||||
@@ -219,6 +219,12 @@ uint32_t RENDERDOC_CC RENDERDOC_ExecuteAndInject(const wchar_t *app, const wchar
|
||||
return Process::CreateAndInjectIntoProcess(app, workingDir, cmdLine, logfile, opts, waitForExit != 0);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API
|
||||
void RENDERDOC_CC RENDERDOC_StartGlobalHook(const wchar_t *pathmatch, const wchar_t *logfile, const CaptureOptions *opts)
|
||||
{
|
||||
Process::StartGlobalHook(pathmatch, logfile, opts);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API
|
||||
uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, bool32 waitForExit)
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;RENDERDOC_PLATFORM=win32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
@@ -109,8 +109,8 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;RENDERDOC_PLATFORM=win32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;WIN64;RENDERDOC_PLATFORM=win32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
@@ -129,7 +129,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;RENDERDOC_PLATFORM=win32;NDEBUG;RELEASE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -148,8 +148,8 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;RENDERDOC_PLATFORM=win32;NDEBUG;RELEASE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;WIN64;RENDERDOC_PLATFORM=win32;NDEBUG;RELEASE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <replay/renderdoc_replay.h>
|
||||
#include <app/renderdoc_app.h>
|
||||
|
||||
#include <renderdocshim.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#include "miniz/miniz.h"
|
||||
@@ -293,6 +295,7 @@ void DisplayRendererPreview(ReplayRenderer *renderer)
|
||||
}
|
||||
|
||||
int renderdoccmd(int argc, wchar_t **argv);
|
||||
bool argequal(const wchar_t *a, const wchar_t *b);
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd )
|
||||
{
|
||||
@@ -499,5 +502,105 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPWSTR lpCmdLine,
|
||||
}
|
||||
#endif
|
||||
|
||||
// this installs a global windows hook pointing at renderdocshim*.dll that filters all running processes and
|
||||
// loads renderdoc.dll in the target one. In any other process it unloads as soon as possible
|
||||
if(argc == 5 && argequal(argv[1], L"--globalhook"))
|
||||
{
|
||||
wchar_t *pathmatch = argv[2];
|
||||
|
||||
wchar_t *log = argv[3];
|
||||
|
||||
CaptureOptions cmdopts;
|
||||
string optstring(&argv[4][0], &argv[4][0] + wcslen(argv[4]));
|
||||
cmdopts.FromString(optstring);
|
||||
|
||||
// make sure the user doesn't accidentally run this with 'a' as a parameter or something.
|
||||
// "a.exe" is over 4 characters so this limit should not be a problem.
|
||||
if(wcslen(pathmatch) < 4)
|
||||
{
|
||||
fprintf(stderr, "--globalhook path match is too short/general. Danger of matching too many processes!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wchar_t rdocpath[1024];
|
||||
|
||||
// fetch path to our matching renderdoc.dll
|
||||
HMODULE rdoc = GetModuleHandleA("renderdoc.dll");
|
||||
|
||||
if(rdoc == NULL)
|
||||
{
|
||||
fprintf(stderr, "--globalhook couldn't find renderdoc.dll!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
GetModuleFileNameW(rdoc, rdocpath, _countof(rdocpath)-1);
|
||||
FreeLibrary(rdoc);
|
||||
|
||||
// Create pipe from control program, to stay open until requested to close
|
||||
HANDLE pipe = CreateFileW(L"\\\\.\\pipe\\"
|
||||
#ifdef WIN64
|
||||
L"RenderDoc.GlobalHookControl64"
|
||||
#else
|
||||
L"RenderDoc.GlobalHookControl32"
|
||||
#endif
|
||||
, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if(pipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "--globalhook couldn't open control pipe.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME);
|
||||
|
||||
if(datahandle != NULL)
|
||||
{
|
||||
CloseHandle(pipe);
|
||||
CloseHandle(datahandle);
|
||||
fprintf(stderr, "--globalhook found pre-existing global data, not creating second global hook.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
datahandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(ShimData), GLOBAL_HOOK_DATA_NAME);
|
||||
|
||||
if(datahandle)
|
||||
{
|
||||
ShimData *shimdata = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_WRITE|FILE_MAP_READ, 0, 0, sizeof(ShimData));
|
||||
|
||||
if(shimdata)
|
||||
{
|
||||
memset(shimdata, 0, sizeof(ShimData));
|
||||
|
||||
wcsncpy_s(shimdata->pathmatchstring, pathmatch, _TRUNCATE);
|
||||
wcsncpy_s(shimdata->rdocpath, rdocpath, _TRUNCATE);
|
||||
wcsncpy_s(shimdata->log, log, _TRUNCATE);
|
||||
memcpy (shimdata->opts, &cmdopts, sizeof(CaptureOptions));
|
||||
|
||||
static_assert(sizeof(CaptureOptions) <= sizeof(shimdata->opts), "ShimData options is too small");
|
||||
|
||||
// wait until a write comes in over the pipe
|
||||
char buf[16];
|
||||
DWORD read = 0;
|
||||
ReadFile(pipe, buf, 16, &read, NULL);
|
||||
|
||||
UnmapViewOfFile(shimdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "--globalhook couldn't map global data store.\n");
|
||||
}
|
||||
|
||||
CloseHandle(datahandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "--globalhook couldn't create global data store.\n");
|
||||
}
|
||||
|
||||
CloseHandle(pipe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return renderdoccmd(argc, argv);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
// This project deliberately references only kernel32.dll (ie. not even the CRT)
|
||||
// so that when inserted into an application it has as small an overhead/impact
|
||||
// as possible. Ideally it would be present only to be a pass-through hook and
|
||||
// the first time only to allocate a little, check if this process should be hooked
|
||||
// and load the renderdoc dll.
|
||||
//
|
||||
// The no-CRT restriction causes some awkward bits and pieces but the dll is simple
|
||||
// enough that it's not a big issue.
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "renderdocshim.h"
|
||||
|
||||
struct CaptureOptions;
|
||||
typedef void (__cdecl *pRENDERDOC_SetCaptureOptions)(const CaptureOptions *opts);
|
||||
typedef void (__cdecl *pRENDERDOC_SetLogFile)(const wchar_t *logfile);
|
||||
|
||||
#if defined(RELEASE)
|
||||
#define LOGPRINT(txt) do { } while (0)
|
||||
#else
|
||||
// define this to something to get logging
|
||||
//#define LOGPRINT(txt) OutputDebugStringW(txt)
|
||||
#define LOGPRINT(txt) do { } while (0)
|
||||
#endif
|
||||
|
||||
void CheckHook()
|
||||
{
|
||||
ShimData *data = NULL;
|
||||
|
||||
HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME);
|
||||
|
||||
if(datahandle == NULL)
|
||||
{
|
||||
LOGPRINT(L"renderdocshim: can't open global data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
data = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_READ, 0, 0, sizeof(ShimData));
|
||||
|
||||
if(data == NULL)
|
||||
{
|
||||
CloseHandle(datahandle);
|
||||
LOGPRINT(L"renderdocshim: can't map global data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(data->pathmatchstring[0] == 0 ||
|
||||
data->pathmatchstring[1] == 0 ||
|
||||
data->pathmatchstring[2] == 0 ||
|
||||
data->pathmatchstring[3] == 0)
|
||||
{
|
||||
LOGPRINT(L"renderdocshim: invalid pathmatchstring: '");
|
||||
LOGPRINT(data->pathmatchstring);
|
||||
LOGPRINT(L"'\n");
|
||||
|
||||
UnmapViewOfFile(data);
|
||||
CloseHandle(datahandle);
|
||||
return;
|
||||
}
|
||||
|
||||
// no new[], need to use VirtualAlloc
|
||||
const int exepathLen = 1024;
|
||||
wchar_t *exepath = (wchar_t *)VirtualAlloc(NULL, exepathLen*sizeof(wchar_t), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
if(exepath)
|
||||
{
|
||||
// no memset :).
|
||||
for(int i=0; i < exepathLen; i++) exepath[i] = 0;
|
||||
|
||||
GetModuleFileNameW(NULL, exepath, exepathLen - 1);
|
||||
|
||||
// no str*cmp functions
|
||||
int find = FindStringOrdinal(FIND_FROMSTART, exepath, -1, data->pathmatchstring, -1, TRUE);
|
||||
|
||||
if(find >= 0)
|
||||
{
|
||||
LOGPRINT(L"renderdocshim: Hooking into '");
|
||||
LOGPRINT(exepath);
|
||||
LOGPRINT(L"', based on '");
|
||||
LOGPRINT(data->pathmatchstring);
|
||||
LOGPRINT(L"'\n");
|
||||
|
||||
HMODULE mod = LoadLibraryW(data->rdocpath);
|
||||
|
||||
if(mod)
|
||||
{
|
||||
pRENDERDOC_SetCaptureOptions setopts = (pRENDERDOC_SetCaptureOptions)GetProcAddress(mod, "RENDERDOC_SetCaptureOptions");
|
||||
pRENDERDOC_SetLogFile setlog = (pRENDERDOC_SetLogFile)GetProcAddress(mod, "RENDERDOC_SetLogFile");
|
||||
|
||||
if(setopts)
|
||||
setopts( (const CaptureOptions *)data->opts );
|
||||
|
||||
if(setlog && data->log[0])
|
||||
setlog( data->log );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGPRINT(L"renderdocshim: NOT Hooking into '");
|
||||
LOGPRINT(data->exepath);
|
||||
LOGPRINT(L"', based on '");
|
||||
LOGPRINT(data->pathmatchstring);
|
||||
LOGPRINT(L"'\n");
|
||||
}
|
||||
|
||||
VirtualFree(exepath, 0, MEM_RELEASE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGPRINT(L"renderdocshim: Failed to allocate exepath\n");
|
||||
}
|
||||
|
||||
UnmapViewOfFile(data);
|
||||
CloseHandle(datahandle);
|
||||
}
|
||||
|
||||
DWORD CheckHookThread(LPVOID param)
|
||||
{
|
||||
CheckHook();
|
||||
|
||||
// this makes sure that we remove the reference to the shim dll and unload from
|
||||
// the target process. That minimises the impact of having the dll inserted into
|
||||
// every process
|
||||
FreeLibraryAndExitThread((HMODULE)param, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL APIENTRY dll_entry(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
|
||||
// create a thread so that we can perform more complex actions (DllMain must be minimal
|
||||
// in size, even this is a bit dodgy).
|
||||
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&CheckHookThread, (LPVOID)hModule, 0, NULL);
|
||||
|
||||
// Sleep on this thread a bit, as we want to call CheckHook() before any real work is done.
|
||||
// Note it is important we don't try to *synchronise* on CheckHookThread, as that can easily
|
||||
// cause deadlocks, crashes, etc.
|
||||
Sleep(500);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
struct ShimData
|
||||
{
|
||||
wchar_t pathmatchstring[2048];
|
||||
wchar_t rdocpath[2048];
|
||||
wchar_t log[2048];
|
||||
|
||||
unsigned char opts[512];
|
||||
};
|
||||
|
||||
#ifdef WIN64
|
||||
#define GLOBAL_HOOK_DATA_NAME "RenderDocGlobalHookData64"
|
||||
#define SHIM_DLL_NAME "renderdocshim64.dll"
|
||||
#else
|
||||
#define GLOBAL_HOOK_DATA_NAME "RenderDocGlobalHookData32"
|
||||
#define SHIM_DLL_NAME "renderdocshim32.dll"
|
||||
#endif
|
||||
@@ -0,0 +1,205 @@
|
||||
<?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="Profile|Win32">
|
||||
<Configuration>Profile</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Profile|x64">
|
||||
<Configuration>Profile</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>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{6DEE3F12-F2F8-42CA-865A-578D0FD11387}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>renderdocshim</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</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)'=='Release|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)'=='Profile|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<TargetName>$(ProjectName)32</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<TargetName>$(ProjectName)32</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
<EntryPointSymbol>dll_entry</EntryPointSymbol>
|
||||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
<EntryPointSymbol>dll_entry</EntryPointSymbol>
|
||||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;RELEASE;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
<EntryPointSymbol>dll_entry</EntryPointSymbol>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;WIN64;RELEASE;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
<EntryPointSymbol>dll_entry</EntryPointSymbol>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="renderdocshim.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="renderdocshim.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="renderdocshim.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="renderdocshim.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -94,6 +94,8 @@ namespace renderdocui.Code
|
||||
public bool CheckUpdate_UpdateAvailable = false;
|
||||
public DateTime CheckUpdate_LastUpdate = new DateTime(2012, 06, 27);
|
||||
|
||||
public bool AllowGlobalHook = false;
|
||||
|
||||
public void SetupFormatter()
|
||||
{
|
||||
Formatter.MinFigures = Formatter_MinFigures;
|
||||
@@ -124,8 +126,12 @@ namespace renderdocui.Code
|
||||
RecentCaptureSettings.Clear();
|
||||
}
|
||||
|
||||
public bool ReadOnly = false;
|
||||
|
||||
public void Serialize(string file)
|
||||
{
|
||||
if (ReadOnly) return;
|
||||
|
||||
try
|
||||
{
|
||||
ReplayHostKeyValues.Clear();
|
||||
|
||||
@@ -91,5 +91,17 @@ namespace renderdocui.Code
|
||||
|
||||
[DllImport("shell32.dll")]
|
||||
public static extern void SHChangeNotify(HChangeNotifyEventID wEventId, HChangeNotifyFlags uFlags, IntPtr dwItem1, IntPtr dwItem2);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern uint GetShortPathName(string lpszLongPath, char[] lpszShortPath, int cchBuffer);
|
||||
|
||||
public static string ShortPath(string longpath)
|
||||
{
|
||||
char[] buffer = new char[256];
|
||||
|
||||
GetShortPathName(longpath, buffer, buffer.Length);
|
||||
|
||||
return new string(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ namespace renderdoc
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ReplayCreateStatus RENDERDOC_CreateReplayRenderer(string logfile, ref float progress, ref IntPtr rendPtr);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RENDERDOC_StartGlobalHook(string pathmatch, string logfile, CaptureOptions opts);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern UInt32 RENDERDOC_ExecuteAndInject(string app, string workingDir, string cmdLine,
|
||||
string logfile, CaptureOptions opts, bool waitForExit);
|
||||
@@ -94,6 +97,11 @@ namespace renderdoc
|
||||
return new ReplayRenderer(rendPtr);
|
||||
}
|
||||
|
||||
public static void StartGlobalHook(string pathmatch, string logfile, CaptureOptions opts)
|
||||
{
|
||||
RENDERDOC_StartGlobalHook(pathmatch, logfile, opts);
|
||||
}
|
||||
|
||||
public static UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, string logfile, CaptureOptions opts)
|
||||
{
|
||||
return RENDERDOC_ExecuteAndInject(app, workingDir, cmdLine, logfile, opts, false);
|
||||
|
||||
+137
-60
@@ -34,10 +34,14 @@
|
||||
System.Windows.Forms.ColumnHeader pid;
|
||||
System.Windows.Forms.ColumnHeader name;
|
||||
System.Windows.Forms.Label label5;
|
||||
System.Windows.Forms.GroupBox groupBox1;
|
||||
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.globalLabel = new System.Windows.Forms.Label();
|
||||
this.actionsGroup = new System.Windows.Forms.GroupBox();
|
||||
this.actionsFlow = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.queueFrameCap = new System.Windows.Forms.CheckBox();
|
||||
this.queuedCapFrame = new System.Windows.Forms.NumericUpDown();
|
||||
this.globalGroup = new System.Windows.Forms.GroupBox();
|
||||
this.globalFlow = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.toggleGlobalHook = new System.Windows.Forms.CheckBox();
|
||||
this.capOptsGroup = new System.Windows.Forms.GroupBox();
|
||||
this.capOptsFlow = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.AllowFullscreen = new System.Windows.Forms.CheckBox();
|
||||
@@ -79,10 +83,11 @@
|
||||
pid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
name = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
label5 = new System.Windows.Forms.Label();
|
||||
groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
groupBox1.SuspendLayout();
|
||||
this.flowLayoutPanel2.SuspendLayout();
|
||||
this.actionsGroup.SuspendLayout();
|
||||
this.actionsFlow.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.queuedCapFrame)).BeginInit();
|
||||
this.globalGroup.SuspendLayout();
|
||||
this.globalFlow.SuspendLayout();
|
||||
this.capOptsGroup.SuspendLayout();
|
||||
this.capOptsFlow.SuspendLayout();
|
||||
this.panel3.SuspendLayout();
|
||||
@@ -128,32 +133,48 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
label5.Location = new System.Drawing.Point(9, 16);
|
||||
label5.Name = "label5";
|
||||
label5.Size = new System.Drawing.Size(581, 23);
|
||||
label5.Size = new System.Drawing.Size(473, 23);
|
||||
label5.TabIndex = 3;
|
||||
label5.Text = "NOTE: Injecting only works when the process has not used the target API";
|
||||
//
|
||||
// groupBox1
|
||||
// globalLabel
|
||||
//
|
||||
groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
this.globalLabel.AutoSize = true;
|
||||
this.globalLabel.ForeColor = System.Drawing.Color.Red;
|
||||
this.globalLabel.Location = new System.Drawing.Point(3, 3);
|
||||
this.globalLabel.Margin = new System.Windows.Forms.Padding(3);
|
||||
this.globalLabel.Name = "globalLabel";
|
||||
this.globalLabel.Size = new System.Drawing.Size(188, 39);
|
||||
this.globalLabel.TabIndex = 2;
|
||||
this.globalLabel.Text = "Text is set by code Text is set by code\r\nText is set by codeText is set by code\r\n" +
|
||||
"Text is set by codeText is set by code";
|
||||
//
|
||||
// actionsGroup
|
||||
//
|
||||
this.actionsGroup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
groupBox1.Controls.Add(this.flowLayoutPanel2);
|
||||
groupBox1.Location = new System.Drawing.Point(10, 500);
|
||||
groupBox1.Margin = new System.Windows.Forms.Padding(10);
|
||||
groupBox1.Name = "groupBox1";
|
||||
groupBox1.Size = new System.Drawing.Size(603, 49);
|
||||
groupBox1.TabIndex = 11;
|
||||
groupBox1.TabStop = false;
|
||||
groupBox1.Text = "Actions";
|
||||
this.actionsGroup.AutoSize = true;
|
||||
this.actionsGroup.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.actionsGroup.Controls.Add(this.actionsFlow);
|
||||
this.actionsGroup.Location = new System.Drawing.Point(10, 500);
|
||||
this.actionsGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.actionsGroup.Name = "actionsGroup";
|
||||
this.actionsGroup.Size = new System.Drawing.Size(195, 65);
|
||||
this.actionsGroup.TabIndex = 11;
|
||||
this.actionsGroup.TabStop = false;
|
||||
this.actionsGroup.Text = "Actions";
|
||||
this.actionsGroup.Layout += new System.Windows.Forms.LayoutEventHandler(this.actionsGroup_Layout);
|
||||
//
|
||||
// flowLayoutPanel2
|
||||
// actionsFlow
|
||||
//
|
||||
this.flowLayoutPanel2.Controls.Add(this.queueFrameCap);
|
||||
this.flowLayoutPanel2.Controls.Add(this.queuedCapFrame);
|
||||
this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.flowLayoutPanel2.Location = new System.Drawing.Point(3, 16);
|
||||
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
|
||||
this.flowLayoutPanel2.Size = new System.Drawing.Size(597, 30);
|
||||
this.flowLayoutPanel2.TabIndex = 1;
|
||||
this.actionsFlow.AutoSize = true;
|
||||
this.actionsFlow.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.actionsFlow.Controls.Add(this.queueFrameCap);
|
||||
this.actionsFlow.Controls.Add(this.queuedCapFrame);
|
||||
this.actionsFlow.Location = new System.Drawing.Point(3, 16);
|
||||
this.actionsFlow.Name = "actionsFlow";
|
||||
this.actionsFlow.Size = new System.Drawing.Size(283, 30);
|
||||
this.actionsFlow.TabIndex = 1;
|
||||
//
|
||||
// queueFrameCap
|
||||
//
|
||||
@@ -188,6 +209,45 @@
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// globalGroup
|
||||
//
|
||||
this.globalGroup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.globalGroup.AutoSize = true;
|
||||
this.globalGroup.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.globalGroup.Controls.Add(this.globalFlow);
|
||||
this.globalGroup.Location = new System.Drawing.Point(10, 585);
|
||||
this.globalGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.globalGroup.Name = "globalGroup";
|
||||
this.globalGroup.Size = new System.Drawing.Size(195, 80);
|
||||
this.globalGroup.TabIndex = 12;
|
||||
this.globalGroup.TabStop = false;
|
||||
this.globalGroup.Text = "Global Process Hook";
|
||||
this.globalGroup.Layout += new System.Windows.Forms.LayoutEventHandler(this.globalGroup_Layout);
|
||||
//
|
||||
// globalFlow
|
||||
//
|
||||
this.globalFlow.AutoSize = true;
|
||||
this.globalFlow.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.globalFlow.Controls.Add(this.globalLabel);
|
||||
this.globalFlow.Controls.Add(this.toggleGlobalHook);
|
||||
this.globalFlow.Location = new System.Drawing.Point(3, 16);
|
||||
this.globalFlow.Name = "globalFlow";
|
||||
this.globalFlow.Size = new System.Drawing.Size(312, 45);
|
||||
this.globalFlow.TabIndex = 0;
|
||||
//
|
||||
// toggleGlobalHook
|
||||
//
|
||||
this.toggleGlobalHook.Appearance = System.Windows.Forms.Appearance.Button;
|
||||
this.toggleGlobalHook.AutoSize = true;
|
||||
this.toggleGlobalHook.Location = new System.Drawing.Point(197, 3);
|
||||
this.toggleGlobalHook.Name = "toggleGlobalHook";
|
||||
this.toggleGlobalHook.Size = new System.Drawing.Size(112, 23);
|
||||
this.toggleGlobalHook.TabIndex = 3;
|
||||
this.toggleGlobalHook.Text = "Enable Global Hook";
|
||||
this.toggleGlobalHook.UseVisualStyleBackColor = true;
|
||||
this.toggleGlobalHook.CheckedChanged += new System.EventHandler(this.toggleGlobalHook_CheckedChanged);
|
||||
//
|
||||
// capOptsGroup
|
||||
//
|
||||
this.capOptsGroup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
@@ -198,7 +258,7 @@
|
||||
this.capOptsGroup.Location = new System.Drawing.Point(10, 367);
|
||||
this.capOptsGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.capOptsGroup.Name = "capOptsGroup";
|
||||
this.capOptsGroup.Size = new System.Drawing.Size(603, 113);
|
||||
this.capOptsGroup.Size = new System.Drawing.Size(195, 113);
|
||||
this.capOptsGroup.TabIndex = 4;
|
||||
this.capOptsGroup.TabStop = false;
|
||||
this.capOptsGroup.Text = "Capture Options";
|
||||
@@ -312,7 +372,7 @@
|
||||
//
|
||||
// HookIntoChildren
|
||||
//
|
||||
this.HookIntoChildren.Location = new System.Drawing.Point(411, 29);
|
||||
this.HookIntoChildren.Location = new System.Drawing.Point(275, 29);
|
||||
this.HookIntoChildren.Name = "HookIntoChildren";
|
||||
this.HookIntoChildren.Size = new System.Drawing.Size(130, 20);
|
||||
this.HookIntoChildren.TabIndex = 14;
|
||||
@@ -323,7 +383,7 @@
|
||||
//
|
||||
// SaveAllInitials
|
||||
//
|
||||
this.SaveAllInitials.Location = new System.Drawing.Point(3, 55);
|
||||
this.SaveAllInitials.Location = new System.Drawing.Point(411, 29);
|
||||
this.SaveAllInitials.Name = "SaveAllInitials";
|
||||
this.SaveAllInitials.Size = new System.Drawing.Size(130, 20);
|
||||
this.SaveAllInitials.TabIndex = 15;
|
||||
@@ -333,7 +393,7 @@
|
||||
//
|
||||
// RefAllResources
|
||||
//
|
||||
this.RefAllResources.Location = new System.Drawing.Point(139, 55);
|
||||
this.RefAllResources.Location = new System.Drawing.Point(3, 55);
|
||||
this.RefAllResources.Name = "RefAllResources";
|
||||
this.RefAllResources.Size = new System.Drawing.Size(130, 20);
|
||||
this.RefAllResources.TabIndex = 16;
|
||||
@@ -343,7 +403,7 @@
|
||||
//
|
||||
// CaptureAllCmdLists
|
||||
//
|
||||
this.CaptureAllCmdLists.Location = new System.Drawing.Point(275, 55);
|
||||
this.CaptureAllCmdLists.Location = new System.Drawing.Point(139, 55);
|
||||
this.CaptureAllCmdLists.Name = "CaptureAllCmdLists";
|
||||
this.CaptureAllCmdLists.Size = new System.Drawing.Size(130, 20);
|
||||
this.CaptureAllCmdLists.TabIndex = 17;
|
||||
@@ -354,7 +414,7 @@
|
||||
//
|
||||
// AutoStart
|
||||
//
|
||||
this.AutoStart.Location = new System.Drawing.Point(411, 55);
|
||||
this.AutoStart.Location = new System.Drawing.Point(275, 55);
|
||||
this.AutoStart.Name = "AutoStart";
|
||||
this.AutoStart.Size = new System.Drawing.Size(130, 20);
|
||||
this.AutoStart.TabIndex = 18;
|
||||
@@ -371,19 +431,19 @@
|
||||
this.panel2.Controls.Add(this.save);
|
||||
this.panel2.Controls.Add(this.close);
|
||||
this.panel2.Controls.Add(this.capture);
|
||||
this.panel2.Location = new System.Drawing.Point(3, 562);
|
||||
this.panel2.Location = new System.Drawing.Point(3, 678);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(617, 26);
|
||||
this.panel2.Size = new System.Drawing.Size(209, 26);
|
||||
this.panel2.TabIndex = 8;
|
||||
//
|
||||
// load
|
||||
//
|
||||
this.load.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.load.Location = new System.Drawing.Point(104, 3);
|
||||
this.load.Location = new System.Drawing.Point(50, 3);
|
||||
this.load.Name = "load";
|
||||
this.load.Size = new System.Drawing.Size(86, 23);
|
||||
this.load.Size = new System.Drawing.Size(39, 23);
|
||||
this.load.TabIndex = 24;
|
||||
this.load.Text = "Load Settings";
|
||||
this.load.Text = "Load";
|
||||
this.toolTip.SetToolTip(this.load, "Load a saved set of capture settings");
|
||||
this.load.UseVisualStyleBackColor = true;
|
||||
this.load.Click += new System.EventHandler(this.load_Click);
|
||||
@@ -393,9 +453,9 @@
|
||||
this.save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.save.Location = new System.Drawing.Point(4, 3);
|
||||
this.save.Name = "save";
|
||||
this.save.Size = new System.Drawing.Size(94, 23);
|
||||
this.save.Size = new System.Drawing.Size(40, 23);
|
||||
this.save.TabIndex = 23;
|
||||
this.save.Text = "Save Settings";
|
||||
this.save.Text = "Save";
|
||||
this.toolTip.SetToolTip(this.save, "Save these capture settings to file to load later");
|
||||
this.save.UseVisualStyleBackColor = true;
|
||||
this.save.Click += new System.EventHandler(this.save_Click);
|
||||
@@ -403,10 +463,10 @@
|
||||
// close
|
||||
//
|
||||
this.close.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.close.Location = new System.Drawing.Point(540, 3);
|
||||
this.close.Location = new System.Drawing.Point(162, 3);
|
||||
this.close.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.close.Name = "close";
|
||||
this.close.Size = new System.Drawing.Size(70, 23);
|
||||
this.close.Size = new System.Drawing.Size(41, 23);
|
||||
this.close.TabIndex = 22;
|
||||
this.close.Text = "Close";
|
||||
this.close.UseVisualStyleBackColor = true;
|
||||
@@ -415,10 +475,10 @@
|
||||
// capture
|
||||
//
|
||||
this.capture.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.capture.Location = new System.Drawing.Point(464, 3);
|
||||
this.capture.Location = new System.Drawing.Point(105, 3);
|
||||
this.capture.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.capture.Name = "capture";
|
||||
this.capture.Size = new System.Drawing.Size(70, 23);
|
||||
this.capture.Size = new System.Drawing.Size(52, 23);
|
||||
this.capture.TabIndex = 21;
|
||||
this.capture.Text = "Capture";
|
||||
this.toolTip.SetToolTip(this.capture, "Trigger a capture of the selected program");
|
||||
@@ -466,14 +526,14 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdline.Location = new System.Drawing.Point(137, 71);
|
||||
this.cmdline.Name = "cmdline";
|
||||
this.cmdline.Size = new System.Drawing.Size(460, 20);
|
||||
this.cmdline.Size = new System.Drawing.Size(52, 20);
|
||||
this.cmdline.TabIndex = 4;
|
||||
this.toolTip.SetToolTip(this.cmdline, "The command-line that will be passed to the executable on launch");
|
||||
//
|
||||
// workDirBrowse
|
||||
//
|
||||
this.workDirBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.workDirBrowse.Location = new System.Drawing.Point(573, 45);
|
||||
this.workDirBrowse.Location = new System.Drawing.Point(165, 45);
|
||||
this.workDirBrowse.Name = "workDirBrowse";
|
||||
this.workDirBrowse.Size = new System.Drawing.Size(24, 20);
|
||||
this.workDirBrowse.TabIndex = 3;
|
||||
@@ -488,7 +548,7 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.workDirPath.Location = new System.Drawing.Point(137, 45);
|
||||
this.workDirPath.Name = "workDirPath";
|
||||
this.workDirPath.Size = new System.Drawing.Size(430, 20);
|
||||
this.workDirPath.Size = new System.Drawing.Size(22, 20);
|
||||
this.workDirPath.TabIndex = 2;
|
||||
this.toolTip.SetToolTip(this.workDirPath, "The working directory the executable will be launched in");
|
||||
this.workDirPath.TextChanged += new System.EventHandler(this.workDirPath_TextChanged);
|
||||
@@ -498,7 +558,7 @@
|
||||
// exeBrowse
|
||||
//
|
||||
this.exeBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.exeBrowse.Location = new System.Drawing.Point(573, 19);
|
||||
this.exeBrowse.Location = new System.Drawing.Point(165, 18);
|
||||
this.exeBrowse.Name = "exeBrowse";
|
||||
this.exeBrowse.Size = new System.Drawing.Size(24, 20);
|
||||
this.exeBrowse.TabIndex = 1;
|
||||
@@ -514,7 +574,7 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.exePath.Location = new System.Drawing.Point(137, 19);
|
||||
this.exePath.Name = "exePath";
|
||||
this.exePath.Size = new System.Drawing.Size(430, 20);
|
||||
this.exePath.Size = new System.Drawing.Size(22, 20);
|
||||
this.exePath.TabIndex = 0;
|
||||
this.toolTip.SetToolTip(this.exePath, "The executable file to launch");
|
||||
this.exePath.TextChanged += new System.EventHandler(this.exePath_TextChanged);
|
||||
@@ -524,7 +584,7 @@
|
||||
// pidRefresh
|
||||
//
|
||||
this.pidRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.pidRefresh.Location = new System.Drawing.Point(518, 180);
|
||||
this.pidRefresh.Location = new System.Drawing.Point(410, 180);
|
||||
this.pidRefresh.Name = "pidRefresh";
|
||||
this.pidRefresh.Size = new System.Drawing.Size(75, 23);
|
||||
this.pidRefresh.TabIndex = 6;
|
||||
@@ -547,7 +607,7 @@
|
||||
this.pidList.Location = new System.Drawing.Point(6, 42);
|
||||
this.pidList.MultiSelect = false;
|
||||
this.pidList.Name = "pidList";
|
||||
this.pidList.Size = new System.Drawing.Size(584, 129);
|
||||
this.pidList.Size = new System.Drawing.Size(183, 129);
|
||||
this.pidList.TabIndex = 5;
|
||||
this.toolTip.SetToolTip(this.pidList, "Select the process to inject into - must not yet have utilised the target API");
|
||||
this.pidList.UseCompatibleStateImageBehavior = false;
|
||||
@@ -555,23 +615,28 @@
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tableLayoutPanel2.AutoSize = true;
|
||||
this.tableLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.tableLayoutPanel2.ColumnCount = 1;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.programGroup, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.panel2, 0, 4);
|
||||
this.tableLayoutPanel2.Controls.Add(this.panel2, 0, 5);
|
||||
this.tableLayoutPanel2.Controls.Add(this.capOptsGroup, 0, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.processGroup, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(groupBox1, 0, 3);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel2.Controls.Add(this.actionsGroup, 0, 3);
|
||||
this.tableLayoutPanel2.Controls.Add(this.globalGroup, 0, 4);
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 5;
|
||||
this.tableLayoutPanel2.RowCount = 6;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(623, 761);
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(215, 707);
|
||||
this.tableLayoutPanel2.TabIndex = 8;
|
||||
//
|
||||
// programGroup
|
||||
@@ -589,7 +654,7 @@
|
||||
this.programGroup.Location = new System.Drawing.Point(10, 10);
|
||||
this.programGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.programGroup.Name = "programGroup";
|
||||
this.programGroup.Size = new System.Drawing.Size(603, 108);
|
||||
this.programGroup.Size = new System.Drawing.Size(195, 108);
|
||||
this.programGroup.TabIndex = 10;
|
||||
this.programGroup.TabStop = false;
|
||||
this.programGroup.Text = "Program";
|
||||
@@ -604,7 +669,7 @@
|
||||
this.processGroup.Location = new System.Drawing.Point(10, 138);
|
||||
this.processGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.processGroup.Name = "processGroup";
|
||||
this.processGroup.Size = new System.Drawing.Size(603, 209);
|
||||
this.processGroup.Size = new System.Drawing.Size(195, 209);
|
||||
this.processGroup.TabIndex = 9;
|
||||
this.processGroup.TabStop = false;
|
||||
this.processGroup.Text = "Process";
|
||||
@@ -614,16 +679,22 @@
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoScroll = true;
|
||||
this.AutoScrollMinSize = new System.Drawing.Size(360, 0);
|
||||
this.ClientSize = new System.Drawing.Size(623, 761);
|
||||
this.AutoScrollMinSize = new System.Drawing.Size(215, 0);
|
||||
this.ClientSize = new System.Drawing.Size(215, 736);
|
||||
this.Controls.Add(this.tableLayoutPanel2);
|
||||
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.Name = "CaptureDialog";
|
||||
this.ShowHint = WeifenLuo.WinFormsUI.Docking.DockState.Document;
|
||||
this.Text = "CaptureDialog";
|
||||
groupBox1.ResumeLayout(false);
|
||||
this.flowLayoutPanel2.ResumeLayout(false);
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CaptureDialog_FormClosing);
|
||||
this.actionsGroup.ResumeLayout(false);
|
||||
this.actionsGroup.PerformLayout();
|
||||
this.actionsFlow.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.queuedCapFrame)).EndInit();
|
||||
this.globalGroup.ResumeLayout(false);
|
||||
this.globalGroup.PerformLayout();
|
||||
this.globalFlow.ResumeLayout(false);
|
||||
this.globalFlow.PerformLayout();
|
||||
this.capOptsGroup.ResumeLayout(false);
|
||||
this.capOptsGroup.PerformLayout();
|
||||
this.capOptsFlow.ResumeLayout(false);
|
||||
@@ -636,6 +707,7 @@
|
||||
this.programGroup.PerformLayout();
|
||||
this.processGroup.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@@ -676,10 +748,15 @@
|
||||
private System.Windows.Forms.ListView pidList;
|
||||
private System.Windows.Forms.Button pidRefresh;
|
||||
private System.Windows.Forms.CheckBox CaptureAllCmdLists;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
|
||||
private System.Windows.Forms.FlowLayoutPanel actionsFlow;
|
||||
private System.Windows.Forms.NumericUpDown queuedCapFrame;
|
||||
private System.Windows.Forms.CheckBox queueFrameCap;
|
||||
private System.Windows.Forms.GroupBox capOptsGroup;
|
||||
private System.Windows.Forms.FlowLayoutPanel globalFlow;
|
||||
private System.Windows.Forms.CheckBox toggleGlobalHook;
|
||||
private System.Windows.Forms.GroupBox actionsGroup;
|
||||
private System.Windows.Forms.GroupBox globalGroup;
|
||||
private System.Windows.Forms.Label globalLabel;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -28,14 +28,18 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using Microsoft.Win32;
|
||||
using renderdocui.Code;
|
||||
using renderdoc;
|
||||
|
||||
using Process = System.Diagnostics.Process;
|
||||
using System.IO.Pipes;
|
||||
|
||||
namespace renderdocui.Windows.Dialogs
|
||||
{
|
||||
public partial class CaptureDialog : DockContent
|
||||
@@ -134,6 +138,8 @@ namespace renderdocui.Windows.Dialogs
|
||||
processGroup.Visible = true;
|
||||
programGroup.Visible = false;
|
||||
|
||||
globalGroup.Visible = false;
|
||||
|
||||
capture.Text = "Inject";
|
||||
|
||||
FillProcessList();
|
||||
@@ -145,6 +151,8 @@ namespace renderdocui.Windows.Dialogs
|
||||
processGroup.Visible = false;
|
||||
programGroup.Visible = true;
|
||||
|
||||
globalGroup.Visible = m_Core.Config.AllowGlobalHook;
|
||||
|
||||
capture.Text = "Capture";
|
||||
|
||||
Text = "Capture Executable";
|
||||
@@ -170,6 +178,8 @@ namespace renderdocui.Windows.Dialogs
|
||||
workDirPath.ForeColor = SystemColors.GrayText;
|
||||
|
||||
SetSettings(defaults);
|
||||
|
||||
UpdateGlobalHook();
|
||||
}
|
||||
|
||||
#region Callbacks
|
||||
@@ -445,6 +455,16 @@ namespace renderdocui.Windows.Dialogs
|
||||
capOptsFlow.MaximumSize = new Size(capOptsGroup.ClientRectangle.Width - 8, 0);
|
||||
}
|
||||
|
||||
private void actionsGroup_Layout(object sender, LayoutEventArgs e)
|
||||
{
|
||||
actionsFlow.MaximumSize = new Size(actionsGroup.ClientRectangle.Width - 8, 0);
|
||||
}
|
||||
|
||||
private void globalGroup_Layout(object sender, LayoutEventArgs e)
|
||||
{
|
||||
globalFlow.MaximumSize = new Size(globalGroup.ClientRectangle.Width - 8, 0);
|
||||
}
|
||||
|
||||
private void workDirPath_Enter(object sender, EventArgs e)
|
||||
{
|
||||
if (workDirHint)
|
||||
@@ -470,13 +490,14 @@ namespace renderdocui.Windows.Dialogs
|
||||
private void exePath_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateWorkDirHint();
|
||||
UpdateGlobalHook();
|
||||
}
|
||||
|
||||
private void UpdateWorkDirHint()
|
||||
{
|
||||
if (workDirHint == false) return;
|
||||
|
||||
if(exePath.Text == "")
|
||||
if (exePath.Text == "")
|
||||
{
|
||||
workDirPath.Text = "";
|
||||
return;
|
||||
@@ -491,5 +512,335 @@ namespace renderdocui.Windows.Dialogs
|
||||
// invalid path or similar
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateGlobalHook()
|
||||
{
|
||||
globalGroup.Visible = !InjectMode && m_Core.Config.AllowGlobalHook;
|
||||
|
||||
if (exePath.Text.Length >= 4)
|
||||
{
|
||||
toggleGlobalHook.Enabled = true;
|
||||
globalLabel.Text = "Global hooking is risky!" + Environment.NewLine + Environment.NewLine +
|
||||
"Be sure you know what you're doing.";
|
||||
|
||||
if (toggleGlobalHook.Checked)
|
||||
globalLabel.Text += Environment.NewLine + "Emergency restore @ %TEMP%\\RenderDoc_RestoreGlobalHook.reg";
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleGlobalHook.Enabled = false;
|
||||
globalLabel.Text = "Global hooking requires an executable path, or filename";
|
||||
}
|
||||
}
|
||||
|
||||
private string prevAppInit = "";
|
||||
private string prevAppInitWoW64 = "";
|
||||
private int prevAppInitEnabled = 0;
|
||||
private int prevAppInitWoW64Enabled = 0;
|
||||
|
||||
private AutoResetEvent wakeupEvent = new AutoResetEvent(false);
|
||||
private bool pipeExit = false;
|
||||
private Thread pipeThread = null;
|
||||
private NamedPipeServerStream pipe32 = null;
|
||||
private NamedPipeServerStream pipe64 = null;
|
||||
|
||||
private void EnableAppInit(RegistryKey parent, string path, string dllname, out int prevEnabled, out string prevStr)
|
||||
{
|
||||
RegistryKey key = parent.OpenSubKey("Microsoft", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
key = key.OpenSubKey("Windows NT", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
key = key.OpenSubKey("CurrentVersion", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
key = key.OpenSubKey("Windows", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
object o = key.GetValue("LoadAppInit_DLLs");
|
||||
if (o == null || !(o is int)) { prevEnabled = 0; prevStr = ""; return; }
|
||||
prevEnabled = (int)o;
|
||||
|
||||
o = key.GetValue("AppInit_DLLs");
|
||||
if (o == null || !(o is string)) { prevEnabled = 0; prevStr = ""; return; }
|
||||
prevStr = (string)o;
|
||||
|
||||
key.SetValue("AppInit_DLLs", Win32PInvoke.ShortPath(Path.Combine(path, dllname)));
|
||||
key.SetValue("LoadAppInit_DLLs", (int)1);
|
||||
}
|
||||
|
||||
private void RestoreAppInit(RegistryKey parent, int prevEnabled, string prevStr)
|
||||
{
|
||||
RegistryKey key = parent.OpenSubKey("Microsoft", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
key = key.OpenSubKey("Windows NT", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
key = key.OpenSubKey("CurrentVersion", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
key = key.OpenSubKey("Windows", true);
|
||||
if (key == null) { prevEnabled = 0; prevStr = ""; return; }
|
||||
|
||||
key.SetValue("AppInit_DLLs", prevStr);
|
||||
key.SetValue("LoadAppInit_DLLs", prevEnabled);
|
||||
}
|
||||
|
||||
private void PipeTick()
|
||||
{
|
||||
while (!pipeExit)
|
||||
{
|
||||
wakeupEvent.WaitOne(250);
|
||||
}
|
||||
|
||||
if (pipe32 != null)
|
||||
{
|
||||
if (pipe32.IsConnected)
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(pipe32))
|
||||
{
|
||||
writer.Write("exit");
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
pipe32.Dispose();
|
||||
pipe32 = null;
|
||||
}
|
||||
|
||||
if (pipe64 != null)
|
||||
{
|
||||
if (pipe64.IsConnected)
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(pipe64))
|
||||
{
|
||||
writer.Write("exit");
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
pipe64.Dispose();
|
||||
pipe64 = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ExitPipeThread()
|
||||
{
|
||||
pipeExit = true;
|
||||
wakeupEvent.Set();
|
||||
|
||||
if (pipeThread != null)
|
||||
{
|
||||
if (pipeThread.ThreadState != ThreadState.Aborted &&
|
||||
pipeThread.ThreadState != ThreadState.Stopped)
|
||||
{
|
||||
// try to shut down gracefully
|
||||
pipeThread.Join(1000);
|
||||
|
||||
if (pipeThread.ThreadState != ThreadState.Aborted &&
|
||||
pipeThread.ThreadState != ThreadState.Stopped)
|
||||
{
|
||||
pipeThread.Abort();
|
||||
pipeThread.Join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pipeThread = null;
|
||||
|
||||
if (pipe32 != null)
|
||||
{
|
||||
pipe32.Dispose();
|
||||
pipe32 = null;
|
||||
}
|
||||
|
||||
if (pipe64 != null)
|
||||
{
|
||||
pipe64.Dispose();
|
||||
pipe64 = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleGlobalHook_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!toggleGlobalHook.Enabled)
|
||||
return;
|
||||
|
||||
toggleGlobalHook.Enabled = false;
|
||||
|
||||
if (toggleGlobalHook.Checked)
|
||||
{
|
||||
if(!Helpers.IsElevated)
|
||||
{
|
||||
DialogResult res = MessageBox.Show("RenderDoc needs to restart with admin privileges. Restart?", "Restart as admin", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
|
||||
|
||||
if (res == DialogResult.Yes)
|
||||
{
|
||||
string capfile = Path.GetTempFileName() + ".cap";
|
||||
|
||||
AutoStart.Checked = false;
|
||||
|
||||
SaveSettings(capfile);
|
||||
|
||||
var process = new Process();
|
||||
process.StartInfo = new System.Diagnostics.ProcessStartInfo(Application.ExecutablePath, capfile);
|
||||
process.StartInfo.Verb = "runas";
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// don't restart if it failed for some reason (e.g. user clicked no to UAC)
|
||||
toggleGlobalHook.Checked = false;
|
||||
toggleGlobalHook.Enabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
m_Core.Config.Serialize(Core.ConfigFilename);
|
||||
m_Core.Config.ReadOnly = true;
|
||||
m_Core.AppWindow.Close();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleGlobalHook.Checked = false;
|
||||
toggleGlobalHook.Enabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
exePath.Enabled = exeBrowse.Enabled =
|
||||
workDirPath.Enabled = workDirBrowse.Enabled =
|
||||
cmdline.Enabled =
|
||||
capture.Enabled = save.Enabled = load.Enabled = false;
|
||||
|
||||
foreach (Control c in capOptsFlow.Controls)
|
||||
c.Enabled = false;
|
||||
|
||||
foreach (Control c in actionsFlow.Controls)
|
||||
c.Enabled = false;
|
||||
|
||||
toggleGlobalHook.Text = "Disable Global Hook";
|
||||
|
||||
var path = Path.GetDirectoryName(Path.GetFullPath(Application.ExecutablePath));
|
||||
|
||||
var regfile = Path.Combine(Path.GetTempPath(), "RenderDoc_RestoreGlobalHook.reg");
|
||||
|
||||
if (Environment.Is64BitProcess)
|
||||
{
|
||||
EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"),
|
||||
path, "x86\\renderdocshim32.dll",
|
||||
out prevAppInitWoW64Enabled, out prevAppInitWoW64);
|
||||
|
||||
EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"),
|
||||
path, "renderdocshim64.dll",
|
||||
out prevAppInitEnabled, out prevAppInit);
|
||||
|
||||
using (FileStream s = File.OpenWrite(regfile))
|
||||
{
|
||||
using(StreamWriter sw = new StreamWriter(s))
|
||||
{
|
||||
sw.WriteLine("Windows Registry Editor Version 5.00");
|
||||
sw.WriteLine("");
|
||||
sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Windows]");
|
||||
sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitWoW64Enabled));
|
||||
sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInitWoW64));
|
||||
sw.WriteLine("");
|
||||
sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows]");
|
||||
sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitEnabled));
|
||||
sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInit));
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we
|
||||
// don't need to handle that manually
|
||||
EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), path, "renderdocshim32.dll",
|
||||
out prevAppInitEnabled, out prevAppInit);
|
||||
|
||||
using (FileStream s = File.OpenWrite(regfile))
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(s))
|
||||
{
|
||||
sw.WriteLine("Windows Registry Editor Version 5.00");
|
||||
sw.WriteLine("");
|
||||
sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows]");
|
||||
sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitEnabled));
|
||||
sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInit));
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExitPipeThread();
|
||||
|
||||
pipeExit = false;
|
||||
|
||||
pipe32 = new NamedPipeServerStream("RenderDoc.GlobalHookControl32");
|
||||
pipe64 = new NamedPipeServerStream("RenderDoc.GlobalHookControl64");
|
||||
|
||||
pipeThread = Helpers.NewThread(new ThreadStart(PipeTick));
|
||||
|
||||
pipeThread.Start();
|
||||
|
||||
string exe = exePath.Text;
|
||||
|
||||
string logfile = exe;
|
||||
if (logfile.Contains("/")) logfile = logfile.Substring(logfile.LastIndexOf('/') + 1);
|
||||
if (logfile.Contains("\\")) logfile = logfile.Substring(logfile.LastIndexOf('\\') + 1);
|
||||
if (logfile.Contains(".")) logfile = logfile.Substring(0, logfile.IndexOf('.'));
|
||||
logfile = m_Core.TempLogFilename(logfile);
|
||||
|
||||
StaticExports.StartGlobalHook(exe, logfile, GetSettings().Options);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitPipeThread();
|
||||
|
||||
exePath.Enabled = exeBrowse.Enabled =
|
||||
workDirPath.Enabled = workDirBrowse.Enabled =
|
||||
cmdline.Enabled =
|
||||
capture.Enabled = save.Enabled = load.Enabled = true;
|
||||
|
||||
foreach (Control c in capOptsFlow.Controls)
|
||||
c.Enabled = true;
|
||||
|
||||
foreach (Control c in actionsFlow.Controls)
|
||||
c.Enabled = true;
|
||||
|
||||
toggleGlobalHook.Text = "Enable Global Hook";
|
||||
|
||||
if (Environment.Is64BitProcess)
|
||||
{
|
||||
RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"), prevAppInitWoW64Enabled, prevAppInitWoW64);
|
||||
RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we
|
||||
// don't need to handle that manually
|
||||
RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit);
|
||||
}
|
||||
|
||||
var regfile = Path.Combine(Path.GetTempPath(), "RenderDoc_RestoreGlobalHook.reg");
|
||||
|
||||
if (File.Exists(regfile)) File.Delete(regfile);
|
||||
}
|
||||
|
||||
toggleGlobalHook.Enabled = true;
|
||||
|
||||
UpdateGlobalHook();
|
||||
}
|
||||
|
||||
private void CaptureDialog_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (toggleGlobalHook.Checked)
|
||||
toggleGlobalHook.Checked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,9 +135,6 @@
|
||||
<metadata name="label5.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="groupBox1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="exeBrowser.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
@@ -150,4 +147,7 @@
|
||||
<metadata name="loadDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>382, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>485, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
+60
-24
@@ -32,6 +32,7 @@
|
||||
System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
System.Windows.Forms.GroupBox groupBox1;
|
||||
System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
System.Windows.Forms.Label label13;
|
||||
System.Windows.Forms.Label label6;
|
||||
System.Windows.Forms.Label label4;
|
||||
System.Windows.Forms.Label label1;
|
||||
@@ -47,9 +48,13 @@
|
||||
System.Windows.Forms.GroupBox groupBox4;
|
||||
System.Windows.Forms.Label label8;
|
||||
System.Windows.Forms.Label label9;
|
||||
TreelistView.TreeListColumn treeListColumn1 = new TreelistView.TreeListColumn("Section", "Section");
|
||||
TreelistView.TreeListColumn treeListColumn1 = ((TreelistView.TreeListColumn)(new TreelistView.TreeListColumn("Section", "Section")));
|
||||
this.ok = new System.Windows.Forms.Button();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.browserCaptureDialog = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.settingsTabs = new renderdocui.Controls.TablessControl();
|
||||
this.generalTab = new System.Windows.Forms.TabPage();
|
||||
this.AllowGlobalHook = new System.Windows.Forms.CheckBox();
|
||||
this.Formatter_PosExp = new System.Windows.Forms.NumericUpDown();
|
||||
this.Formatter_NegExp = new System.Windows.Forms.NumericUpDown();
|
||||
this.rdcAssoc = new System.Windows.Forms.Button();
|
||||
@@ -69,12 +74,10 @@
|
||||
this.EventBrowser_TimeUnit = new System.Windows.Forms.ComboBox();
|
||||
this.EventBrowser_HideEmpty = new System.Windows.Forms.CheckBox();
|
||||
this.pagesTree = new TreelistView.TreeListView();
|
||||
this.ok = new System.Windows.Forms.Button();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.browserCaptureDialog = new System.Windows.Forms.FolderBrowserDialog();
|
||||
tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
label13 = new System.Windows.Forms.Label();
|
||||
label6 = new System.Windows.Forms.Label();
|
||||
label4 = new System.Windows.Forms.Label();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
@@ -128,6 +131,21 @@
|
||||
tableLayoutPanel1.Size = new System.Drawing.Size(580, 353);
|
||||
tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// ok
|
||||
//
|
||||
this.ok.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.ok.Location = new System.Drawing.Point(502, 327);
|
||||
this.ok.Name = "ok";
|
||||
this.ok.Size = new System.Drawing.Size(75, 23);
|
||||
this.ok.TabIndex = 100;
|
||||
this.ok.Text = "OK";
|
||||
this.ok.UseVisualStyleBackColor = true;
|
||||
this.ok.Click += new System.EventHandler(this.ok_Click);
|
||||
//
|
||||
// browserCaptureDialog
|
||||
//
|
||||
this.browserCaptureDialog.RootFolder = System.Environment.SpecialFolder.MyComputer;
|
||||
//
|
||||
// settingsTabs
|
||||
//
|
||||
this.settingsTabs.Alignment = System.Windows.Forms.TabAlignment.Left;
|
||||
@@ -170,6 +188,8 @@
|
||||
tableLayoutPanel2.ColumnCount = 2;
|
||||
tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
tableLayoutPanel2.Controls.Add(this.AllowGlobalHook, 1, 7);
|
||||
tableLayoutPanel2.Controls.Add(label13, 0, 7);
|
||||
tableLayoutPanel2.Controls.Add(this.Formatter_PosExp, 1, 5);
|
||||
tableLayoutPanel2.Controls.Add(this.Formatter_NegExp, 1, 4);
|
||||
tableLayoutPanel2.Controls.Add(label6, 0, 3);
|
||||
@@ -182,14 +202,15 @@
|
||||
tableLayoutPanel2.Controls.Add(label7, 0, 5);
|
||||
tableLayoutPanel2.Controls.Add(this.Formatter_MaxFigures, 1, 3);
|
||||
tableLayoutPanel2.Controls.Add(this.Formatter_MinFigures, 1, 2);
|
||||
tableLayoutPanel2.Controls.Add(label3, 0, 7);
|
||||
tableLayoutPanel2.Controls.Add(this.CheckUpdate_AllowChecks, 1, 7);
|
||||
tableLayoutPanel2.Controls.Add(label3, 0, 8);
|
||||
tableLayoutPanel2.Controls.Add(this.CheckUpdate_AllowChecks, 1, 8);
|
||||
tableLayoutPanel2.Controls.Add(label11, 0, 6);
|
||||
tableLayoutPanel2.Controls.Add(this.browseCaptureDirectory, 1, 6);
|
||||
tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
tableLayoutPanel2.Location = new System.Drawing.Point(3, 16);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 9;
|
||||
tableLayoutPanel2.RowCount = 10;
|
||||
tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
@@ -201,6 +222,35 @@
|
||||
tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
tableLayoutPanel2.Size = new System.Drawing.Size(361, 285);
|
||||
tableLayoutPanel2.TabIndex = 0;
|
||||
//
|
||||
// AllowGlobalHook
|
||||
//
|
||||
this.AllowGlobalHook.AutoSize = true;
|
||||
this.AllowGlobalHook.Checked = true;
|
||||
this.AllowGlobalHook.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.AllowGlobalHook.Location = new System.Drawing.Point(268, 194);
|
||||
this.AllowGlobalHook.Name = "AllowGlobalHook";
|
||||
this.AllowGlobalHook.Size = new System.Drawing.Size(15, 14);
|
||||
this.AllowGlobalHook.TabIndex = 16;
|
||||
this.toolTip.SetToolTip(this.AllowGlobalHook, "Allow RenderDoc to insert a global hook into all processes to catch the execution" +
|
||||
" of the desired process, without directly launching it.");
|
||||
this.AllowGlobalHook.UseVisualStyleBackColor = true;
|
||||
this.AllowGlobalHook.CheckedChanged += new System.EventHandler(this.AllowGlobalHook_CheckedChanged);
|
||||
//
|
||||
// label13
|
||||
//
|
||||
label13.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
label13.AutoSize = true;
|
||||
label13.Location = new System.Drawing.Point(3, 191);
|
||||
label13.Name = "label13";
|
||||
label13.Size = new System.Drawing.Size(259, 20);
|
||||
label13.TabIndex = 15;
|
||||
label13.Text = "Allow global process hooking - be careful!";
|
||||
label13.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.toolTip.SetToolTip(label13, "Allows RenderDoc to phone home to http://renderdoc.org to anonymously check for n" +
|
||||
"ew versions.");
|
||||
//
|
||||
// Formatter_PosExp
|
||||
//
|
||||
@@ -408,7 +458,7 @@
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new System.Drawing.Point(3, 191);
|
||||
label3.Location = new System.Drawing.Point(3, 211);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new System.Drawing.Size(259, 20);
|
||||
label3.TabIndex = 12;
|
||||
@@ -422,7 +472,7 @@
|
||||
this.CheckUpdate_AllowChecks.AutoSize = true;
|
||||
this.CheckUpdate_AllowChecks.Checked = true;
|
||||
this.CheckUpdate_AllowChecks.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.CheckUpdate_AllowChecks.Location = new System.Drawing.Point(268, 194);
|
||||
this.CheckUpdate_AllowChecks.Location = new System.Drawing.Point(268, 214);
|
||||
this.CheckUpdate_AllowChecks.Name = "CheckUpdate_AllowChecks";
|
||||
this.CheckUpdate_AllowChecks.Size = new System.Drawing.Size(15, 14);
|
||||
this.CheckUpdate_AllowChecks.TabIndex = 8;
|
||||
@@ -701,21 +751,6 @@
|
||||
this.pagesTree.ViewOptions.ShowPlusMinus = false;
|
||||
this.pagesTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.pagesTree_AfterSelect);
|
||||
//
|
||||
// ok
|
||||
//
|
||||
this.ok.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.ok.Location = new System.Drawing.Point(502, 327);
|
||||
this.ok.Name = "ok";
|
||||
this.ok.Size = new System.Drawing.Size(75, 23);
|
||||
this.ok.TabIndex = 100;
|
||||
this.ok.Text = "OK";
|
||||
this.ok.UseVisualStyleBackColor = true;
|
||||
this.ok.Click += new System.EventHandler(this.ok_Click);
|
||||
//
|
||||
// browserCaptureDialog
|
||||
//
|
||||
this.browserCaptureDialog.RootFolder = System.Environment.SpecialFolder.MyComputer;
|
||||
//
|
||||
// SettingsDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@@ -779,5 +814,6 @@
|
||||
private System.Windows.Forms.CheckBox EventBrowser_HideEmpty;
|
||||
private System.Windows.Forms.Button browseCaptureDirectory;
|
||||
private System.Windows.Forms.FolderBrowserDialog browserCaptureDialog;
|
||||
private System.Windows.Forms.CheckBox AllowGlobalHook;
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,8 @@ namespace renderdocui.Windows.Dialogs
|
||||
TextureViewer_ResetRange.Checked = m_Core.Config.TextureViewer_ResetRange;
|
||||
ShaderViewer_FriendlyNaming.Checked = m_Core.Config.ShaderViewer_FriendlyNaming;
|
||||
CheckUpdate_AllowChecks.Checked = m_Core.Config.CheckUpdate_AllowChecks;
|
||||
|
||||
AllowGlobalHook.Checked = m_Core.Config.AllowGlobalHook;
|
||||
|
||||
{
|
||||
Type type = m_Core.Config.EventBrowser_TimeUnit.GetType();
|
||||
@@ -142,6 +144,16 @@ namespace renderdocui.Windows.Dialogs
|
||||
m_Core.Config.Serialize(Core.ConfigFilename);
|
||||
}
|
||||
|
||||
private void AllowGlobalHook_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
m_Core.Config.AllowGlobalHook = AllowGlobalHook.Checked;
|
||||
|
||||
m_Core.Config.Serialize(Core.ConfigFilename);
|
||||
|
||||
if (m_Core.CaptureDialog != null)
|
||||
m_Core.CaptureDialog.UpdateGlobalHook();
|
||||
}
|
||||
|
||||
private void EventBrowser_TimeUnit_SelectionChangeCommitted(object sender, EventArgs e)
|
||||
{
|
||||
m_Core.Config.EventBrowser_TimeUnit = (PersistantConfig.TimeUnit)EventBrowser_TimeUnit.SelectedIndex;
|
||||
|
||||
@@ -129,6 +129,9 @@
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="label13.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label6.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
|
||||
Reference in New Issue
Block a user