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:
baldurk
2014-10-05 13:57:11 +01:00
parent a6d68e5598
commit 9460fbd970
29 changed files with 1292 additions and 110 deletions
+2 -2
View File
@@ -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."
+16
View File
@@ -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>
+2
View File
@@ -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">
+36
View File
@@ -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" />
+9
View File
@@ -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>
+1
View File
@@ -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}"
+2
View File
@@ -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"
+11
View File
@@ -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}
-12
View File
@@ -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);
+17
View File
@@ -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!
//////////////////////////////////////////////////////////////////////////
+7 -1
View File
@@ -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();
}
}
+1
View File
@@ -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);
+56
View File
@@ -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);
+6
View File
@@ -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)
{
+6 -6
View File
@@ -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>
+103
View File
@@ -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);
}
+169
View File
@@ -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;
}
+40
View File
@@ -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
+205
View File
@@ -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>
+6
View File
@@ -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();
+12
View File
@@ -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);
}
}
}
+8
View File
@@ -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
View File
@@ -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;
}
}
+353 -2
View File
@@ -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
View File
@@ -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>