What’s up with the registry key HKEY_CLASSES_ROOTCLSIDCLSID?


While I was looking for spelling errors in the registry, I ran across the strange registry key HKEY_CLASSES_ROOT\CLSID\CLSID, which has as its default value the stringified GUID {0000031A-0000-0000-C000-000000000046}. I asked the COM folks what the deal was with that.

They explained, "It's the progid for the class moniker."

That was enough to push me in the right direction, and it made my brain explode from the meta-ness of it all. Sort of like when you study Category Theory in math class.

If you want to connect a COM class ID with a programmatic ID, you cross-link them like this:

[HKEY_CLASSES_ROOT\CLSID\{clsid}\ProgId]
@="progid"

[HKEY_CLASSES_ROOT\progid\CLSID]
@="{clsid}"

The class ID is a child of HKEY_CLASSES_ROOT\CLSID, and it in turn has a ProgId subkey whose value is the programmatic ID. Meanwhile, the programmatic ID is a child of HKEY_CLASSES_ROOT, and it in turn has a CLSID subkey whose value is the class ID.

Here's where things get weird: The programmatic ID for the class moniker is CLSID.

Plug that into the above formula, and you get

[HKEY_CLASSES_ROOT\CLSID\{0000031A-0000-0000-C000-000000000046}\ProgId]
@="CLSID"

[HKEY_CLASSES_ROOT\CLSID\CLSID]
@="{0000031A-0000-0000-C000-000000000046}"

So it's all legit. It just looks weird.

It's like that trick on the 80386 where you set a page directory entry to point back to the page directory itself, thereby allowing you to access page tables through the page table.

Bonus chatter: It frustrates me when I answer a question by merely giving a push in the right direction, and the person doesn't realize that it was a helpful push and just comes back looking for more hand-holding. I try not to be that person.

Comments (18)
  1. Joshua says:

    What kind of GUID is that? Looks like type 0 but I thought the only type 0 was the empty GUID.

  2. Jason says:

    But… But I just wanted to hold your hand.

    http://youtu.be/OMNPPwq8I2Y

  3. John says:

    So there is a class whose progid is "clsid"?  This bothers me more than it should.

  4. Rick C says:

    @Joshua, all the basic COM guids are like that.  They're not regular guids, they're magic numbers.  Sun did the same thing with Java in a couple of places; each patch level of Java creates HKCRCLSID{CAFEEFAC-00jn-00pp—bb-ABCDEFFEDCBA} where jnppbb maps to a version of the Java plug-in as follows:  j.n.pp_bb.

  5. Paul Z says:

    When I was writing an 80386 operating system in college, we tried the mentioned page directory trick, but it did not actually work. I seem to remember that the format of page directory entries and page table entries are ALMOST identical, except for one bit which is "must always be 0" in PTEs and "reserved for system use" in PDEs (or maybe vice versa). Since it turned out that the system in fact set this bit to 1 pretty often (we never did figure out why), we couldn't use the same page for both. Which was too bad, because it would have been pretty convenient.

    [We used the trick in Windows 95, and it was documented by Intel, so I can't explain why it didn't work for you. -Raymond]
  6. > I answer a question by … giving a push

    > the person … comes back looking for more hand-holding

    TIL Raymond does not understand the difference between pushing and holding hands.

    [I love a good mixed metaphor. -Raymond]
  7. Mal DeMer says:

    >> TIL Raymond does not understand the difference between pushing and holding hands.

    > I love a good mixed metaphor. -Raymond

    We could extend that to Tai Chi's pushing hands…

  8. "So it's all legit. It just looks weird."

    In legal studies, such a thing is called "gaming the system", an attempt to adhere to the word of the law, rule or guideline but to defy its spirit. But in computing, it is called a "hack", until someone pops up and says "Hi, I am a program that is being uninstalled; I want to remove my ProgID from the Registry. My ProgID is 'CLSID'." and Windows says "Sure. There goes the entire CLSID key." Then, it becomes a security vulnerability.

    That was just an example that never happens but I do know of hacks that have turned into security vulnerability.

  9. Joshua says:

    [We used the trick in Windows 95, and it was documented by Intel, so I can't explain why it didn't work for you. -Raymond]

    Windows 95 probably set the reserved bit to 0.

    [I dusted off my old 80386 manual, and it worked on the 80386 because the PDE and PTE formats were identical. It wasn't until later that they diverged due to new processor features. -Raymond]
  10. James Forshaw says:

    @Ian, a Moniker is a fairly simple concept, it is a representation of a COM object or resource, either through a string (which needs to be passed to MkParseDisplayName) or an IMoniker interface but it isn't actually the object itself. It is just a way of naming that object, hence a moniker, a name to refer to the object. When you bind the moniker (through IMoniker::BindToObject or IMoniker::BindToStorage) what you get back is the object the moniker referred to. For example the Class moniker returns a new COM object loaded through CoCreateInstance, the OBJREF moniker returns an unmarshalled COM object, the URL or FILE monikers returns either an IStream of the resource or it applies the usual filename extension CLSID binding rules and returns you an instance of that object initialized through IPersist*. Actually I take it all back, it isn't a simple concept at all, don't get me started on moniker composition.

    You can still see the Class Moniker in the 'classid' attribute of the IE OBJECT element, in the historical past (i.e. pre-XP SP2 IE) you could specify any moniker you liked in that attribute, but that was rightly considered a security problem :) I doubt very much the moniker system is actually directly used for the classid attribute in modern versions.

  11. RobLeit says:

    @Fleet Command

    Have you heard the story about the airtight hatchway?  blogs.msdn.com/…/592350.aspx

    You need to be administrator to be able to remove any system-wide CLSIDs.

  12. Ian Boyd says:

    In the mid-90s i was trying to read about COM. But all i remember the endless amounts of the work "moniker". i never understood what a moniker was, what it was doing, and why it exists.

    A decade ago i read Don Box's *excellent* book on COM, that explains the rationale behind COM. COM is now obvious and intuitiave to me. ClassIDs, ProgIDs, the four exports of every COM dll, CanUnloadNow, regsvr32, all of it.

    Except "moniker", i have no idea what that means. Nor do i know what functionality clsid class might provide, or to whom. A COM object is created by calling CoCreateInstance, i don't know what else there is.

  13. foo says:

    @James Forshaw. I highlighted your comment and right-clicked "Translate with Bing" but for some reason what you wrote confuses the translator because it auto-detects it as "English" :(

    Anyways, too bad they didn't use something like {00000050-0052-004F-0047-004900440000} as the CLSID.

  14. Antonio 'Grijan' says:

    Am I the only one that thinks of http://xkcd.com/917/ after reading this article?

  15. NoP says:

    @RobLeit: by whom is the uninstallation of a program – the situation FleetCommand was talking about – performed by?

  16. Scarlet Manuka says:

    @NoP: I think that is RobLeit's point. There's no point sounding the "security vulnerability" alarm for the case of a malicious uninstaller removing the entire CLSID key, because we expect that a malicious uninstaller will be running with administrative credentials and able to do anything it wants.

  17. @RobLeit says:

    Actually you need to be TrustedInstaller.

  18. Matt says:

    "We did this in Windows 95" is somewhat of an understatement.

    Windows does this is *EVERY* x86-64 system from 32-bit Windows 95 through to 64-bit Windows 8.1. The tables look different on x64, but the trick of mapping directories to tables is used ubiquitously everywhere.

Comments are closed.

Skip to main content