verclsid.exe is preventing me from loading my shell namespace extension. If
I renamed verclsid.exe to ~verclsid.exe (so that explorer.exe can't find it)
my namespace extension will load correctly.
Using RegMon.exe and monitoring just the verclsid.exe process I can see that
my Shell Namespace Extension is getting created and called when explorer.exe
tries to open my namespace extension. However, I can't figure out how to
debug my namespace extension when verclsid.exe calls it and fails. Using a
::DebugBreak(); in my namespace doesn't kick up the debugger when
verclsid.exe calls the namespace extension. And verclsid.exe doesn't exist
as a process long enought to "Attach To Process" from Visual Studio or the
Task Manager.
If I add a a DWORD to:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell
Extensions\Cached
Name:
{A4355C7E-B79B-4708-BAC2-C3875F36C372}
{000214E6-0000-0000-C000-000000000046} 0x401
Value:
1
{A4355C7E-B79B-4708-BAC2-C3875F36C372} is the CLSID of my Shell Namespace
Extension.
Like KB918165 (http://support.microsoft.com/default.aspx/kb/918165) suggest
verclsid.exe does allow my namespace extension to come up with verclsid.exe
enabled in system32. However the Property Sheet Handler that is at the same
CLSID doesn't work. The only way to make the Property Sheet Handler work is
to rename verclsid.exe so that explorer.exe can't find it.
So my question is: How to I make my namespace extension and property sheet
handler work with verclsid.exe? What am I don't wrong in my namespace
extension that causes verclsid.exe to fail? This has only been happening for
a couple of weeks -- well after verclsid.exe was deployed so it has to be
something I added to my code recently. How do I debug what is happening when
verclsid.exe calls my namespace. What checks does verclsid.exe perform and
how can I pass them?
My goal is to be able to distribute my namespace extension end users -- and
I can't have them uninstall security patches or tamper with verclsid.exe to
make it work.
######## SIDE NOTE ############
I created a dummy console application called verclsid.exe and copied it into
c:\windows\system32\, then added a break point to see what the input
arguments from explorer.exe were. It turned out they where:
/S /C {A4355C7E-B79B-4708-BAC2-C3875F36C372} /I
{000214E6-0000-0000-C000-000000000046} /X 0x401
{A4355C7E-B79B-4708-BAC2-C3875F36C372} is the CLSID of my Shell Namespace
Extension.
So I run Visual Studio when the debug parameters of verclsid.exe (The real
one from the OS) and the command line that explorer.exe was sending.
However, verclsid.exe didn't load my Namespace Extension.dll. I also tried
from the command line with FileMon.exe running and verclsid didn't try to
open my namespace extension DLL. And tried again with RegMon.exe running and
it didn't call keys for my CLSID. So it appears that you can't run it from
the command line or via Visual Studio.
There is no help for verclsid.exe, i.e. verclsid.exe /? doesn't work
Thanks,
Wayne
Im sure the same approach would apply to verclsid.exe if you could get the
command line string to pass, so you could directly debug the interaction
between verclsid and your namespace.
I slightly different thing to try would be to place an infinite loop in your
DllMain or class factory methods - this should stall verclsid allowing you
to attach a debugger - allowing you to manually start normal execution.
"Wayne Berry" <way...@nospam.nospam> wrote in message
news:F38172B4-7F9C-46A8...@microsoft.com...
Do you mean that your NSE currently works fine but not the property sheet
handler?
Note the second GUID in registry (which will be passed to verclsid.exe)
should be the interface id that the CLSID (first GUID) will be created and
QueryInterface. {000214E6-0000-0000-C000-000000000046} is IShellFolder. For
your property sheet handler, you certainly cannot use it here.
The KB is somewhat misleading here, actually we don't recommend manually
create those registry keys under
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell
Extensions\Cached". If you leave that out, this should work by default
since verclsid.exe will create it after your shell extension passed the
verification.
Sorry we currently don't have public documentation of verclsid.exe,
documentation team is currently working on it.
Regards,
Walter Wang (waw...@online.microsoft.com, remove 'online.')
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Yes I think this is a good approach -- however I can't get that command
string to pass.
> I slightly different thing to try would be to place an infinite loop in your
> DllMain or class factory methods - this should stall verclsid allowing you
> to attach a debugger - allowing you to manually start normal execution.
>
I tried this and did get some success. I can get the debugger to attached
to verclsid.exe, however it appears that explorer.exe kills it quickly if it
doesn't respond fast. Which means I have to do some fast debugging.
It does look like it calls DllGetClassObject and it might be there that my
issue lies. Still trying to work it out.
-Wayne
Yes
> If you leave that out, this should work by default
> since verclsid.exe will create it after your shell extension passed the
> verification.
My shell extension doesn't pass the verification and I can't figure out why.
Adding those keys or renaming verclsid.exe so it doesn't exist seem to work.
I would really like my shell extension to pass the verification -- however I
don't know what I did wrong.
It is like when a girlfriend gets mad at you and doesn't tell you why -- it
is frustrating and you don't know what you did to cause the problem. All you
can do is guess.
> {000214E6-0000-0000-C000-000000000046} is IShellFolder. For
> your property sheet handler, you certainly cannot use it here.
Ah, good hint. I also added the Key for IShellExInit
{000214E8-0000-0000-C000-000000000046} which is the interface for property
page handlers and now both my Property Page Handler and my Shell Extension
Work in Windows XP and Windows 2003.
Just as a note: renaming verclsid.exe in Vista causes explorer.exe to crash
-- and the adding the keys to the Cache folder doesn't work in Vista -- it
also causes explorer.exe to crash. So I am still looking for a way to make
my namespace extension pass verification.
-Wayne
Make sure that your object responds to QI for the interfaces it is
registered for, fails for ones it doesn't support, and doesn't crash when
loaded outside of explorer.
I have narrowed down the problem to the DllGetClassObject API on my DLL. I
am doing some registry calls and crypto work to figure out if my customer has
a license for my product. I am going to more the licensing stuff into
IShellFolder::Initialize. Hopefully verclsid.exe will not call that API. I
think it is either failing getting a Crypto context or reading the license
from the registry. I.e. verclsid.exe doesn't have the same permissions as
IShellFolder.
I am adding ETW to my Shell Extension right now -- so that I can trace the
calls and the failures. Something I have to do anyways for a fully supported
product. This should help me narrow it down without the debugger.
-Wayne
The odd thing is that it appears the verclsid.exe process just stops dead in
it's tracks. No exiting the function, no exception my try/catch doesn't get
an exception. Just an exit.
Once I had it fixed I figured out that verclsid.exe calls DllGetClassObject
to get a IClassFactory. Then uses that to do a CreateInstance on
IID_IBrowserFrameOptions, then calls QueryInterface on the IUnknown that
CreateInstance returns to get a IBrowserFrameOption interface. After that it
doesn't call any method on the IBrowserFrameOption nor does it try to get an
other interfaces.
Anyways, problem solved.
-Wayne
verclsid kills itself if CoCreateInstance takes too long in order to prevent
explorer hangs. It just calls TerminateProcess that's why you cannot catch it.
I've had some fun with verclsid.exe lately. Looking through the code
it looks like verclsid.exe sets up a thread which simply terminates
the process after a given period of time. The obvious workaround
is to freeze this thread (~ f in WinDBG, context menu in Threads
window in VC debugger).
Also note, that verclsid.exe can't cope with a command line that
includes the executable name. I think both Windbg and VC++
prepend it automatically. I opted to simply adjust the return
value from GetCommandLineW.
And in case you wonder why my DLL failed to pass verification:
It took me a while to realize that things only worked when running
under a debugger and I eventually remembered what I did to prevent
execution on my development machine:
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
if ( !IsDebuggerPresent() )
return REGDB_E_CLASSNOTREG;
// ...
}
Oh well.
-hg