I have been receiving comments that Filter Graph Spy tool does not work with Microsoft Vista operating system. I never had a moment to check until recently, and this time I realized that it really does not work. I am definitely aware of dramatic changes introduced with this operating system, and in particular UAC feature, virtualization and changes in security. No wonder this was the first guess that security was the cause, however the investigation showed there was a trail of issues underneath…
Investigation details deserve a separate post, while this one briefly outlines the issues and also accompany the repository update with a version compatible with Vista OS.
First of all, COM registration of the DLL (which definitely requires privilege elevation) succeeded on Vista. This means the registration procedure did not encounter any errors on the way, or poorly written code ignored the problem. It appeared that the source of the problem was CoTreatAsClass API, which failed to do the requested action, however returned status code indicating successful operation. This definitely looks like a bug and further comments on this particular behavior are expected to appear on Windows Applications Security MSDN forum, where I opened a topic on the matter.
With a COM TreatAs feature activated, the class’s behavior to instantiate instead of DirectShow’s CLSID_FilterGraph is restored, and in particular the DLL generates FilterGraphSpy.log log file on filter graph activity. Note that log file location is OS dependent (due to Vista’s permissions and file system virtualization):
- pre-Vista OS: root of syste drive, typically C:\
- starting Vista, administrator with elevated privileges: CSIDL_COMMON_APPDATA, typically C:\ProgramData (note this directory is hidden by deafult)
- starting Vista, without elevated administrator privileges: CSIDL_LOCAL_APPDATA, typically C:\Users\$(UserName)\AppData\Local (note that AppData directory is hidden by deafult)
Still even with the log file generated and indicating activation of the spy, it was unable to connect to remote graph through the running object table (ROT). It appeared that the ROT entires are there where expected, it was OK to get an object from ROT and the problem came from QueryInterface code:
CComPtr<IUnknown> pFilterGraphUnknown; ATLENSURE_SUCCEEDED(pRunningObjectTable->GetObject(pMoniker, &pFilterGraphUnknown)); CComQIPtr<IMyFilterGraph> pFilterGraph = pFilterGraphUnknown; // E_NOINTERFACE
The call reached the original object but COM subsystem was unable to marshal the interface through apartments to enable interprocess communication on it. The reason for this is absence of PSFactoryBuffer class (CLSID {92A3A302-DA7C-4A1F-BA7E-1802BB5D2D02}), which provides proxy/stub pairs for marshaling well known DirectShow interfaces in the Vista’s version of quartz.dll. As mentioned by Microsoft’s Mike Wasson, this class was moved from quartz.dll into Vista SDK’s proppage.dll, so in order to obtain connectivity to remote DirectShow graphs starting Vista, one needs to install this DLL with Windows SDK, or otherwise have it registered with the operating system.
Also note that DirectShow-enabled applications that have their filter graphs published on ROT will need an utility application such as GraphEdit started with the same permissions (elevated or not) in order to be able to access ROT entires.
- get the latest FilterGraphSpy.dll
- regsvr32 FilterGraphSpy.dll on target system from administrative command prompt, with elevated privileges (note you should have a log file FilterGraphSpy.log generated in CSIDL_COMMON_APPDATA directory, with a few lines indicating registration success)
- get Windows SDK and make $(WindowsSDK)\Bin\proppage.dll file registered on target system (also administrative regsvr32), note that it is necessary to restart DirectShow-enabled applications and GraphEdit after DLL registration to get graphs visible through ROT
- mind the log file directories with FilterGraphSpy.log file
A partial Visual C++ .NET 2008 source code is available from SVN, release binary included.