Geoff Chappell - Software Analyst
Each member of the SHELLKEY enumeration is an ID that selects a shell key. The ID can then be used as the first argument for the various shell key functions. This enumeration is undocumented. Microsoft’s public symbol files for SHLWAPI name the enumeration as _SHELLKEY. Microsoft’s usual practice would have a typedef define SHELLKEY as the ordinary name.
The precise correspondence between ID and shell key depends on the SHLWAPI build. In the original design, from before Windows Vista, three bit masks specify a root, a key and a subkey, whose concatenation is the registry path to the shell key.
Mask | Role | Masked Constant | Interpretation |
---|---|---|---|
0x0000000F | root | 0x00000001 | HKEY_CURRENT_USER |
0x00000002 | HKEY_LOCAL_MACHINE | ||
0x00000FF0 | key | 0x00000000 | Software\Microsoft\Windows\CurrentVersion\Explorer |
0x00000010 | Software\Microsoft\Windows\Shell | ||
0x00000020 | Software\Microsoft\Windows\ShellNoRoam | ||
0x00000030 | Software\Classes | ||
0x000FF000 | subkey | 0x00000000 | no subkey |
0x00001000 | LocalizedResourceName | ||
0x00002000 | Handlers | ||
0x00003000 | Associations | ||
0x00004000 | Volatile | ||
0x00005000 | MUICache | ||
0x00006000 | FileExts |
Perhaps only as a side-effect of the particular coding, anything other than 2 in the root mask denotes HKEY_CURRENT_USER. When a shell key whose root is HKEY_CURRENT_USER is opened in a thread that has an impersonation token, the target user’s branch of HKEY_USERS becomes the root instead.
If the subkey mask produces zero (or, perhaps again only as a coding side-effect, any value other than listed above), then the shell key is just root\key. Otherwise, the shell key is root\key\subkey.
For Windows Vista, Microsoft seems to have decided that the original scheme is much more than needed. The enumeration is reduced to an assortment of constants for the shell keys that find actual use:
Constant | Key |
---|---|
0x00000001 | HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer |
0x00000002 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer |
0x00000011 | HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell |
0x00000012 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Shell |
0x00000021 0x0001FFFF |
HKEY_CURRENT_USER_LOCAL_SETTINGS\Software\Microsoft\Windows\Shell |
0x00005021 | HKEY_CURRENT_USER_LOCAL_SETTINGS\Software\Microsoft\Windows\Shell\MuiCache |
0x00006001 | HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts |
For this table, HKEY_CURRENT_USER_LOCAL_SETTINGS is invented as a symbolic name for the pre-defined registry key 0x80000007. This predefined key seems to be undocumented. ADVAPI32 maps it to HKEY_CURRENT_USER\Software\Classes\Local Settings. If HKEY_CURRENT_USER_LOCAL_SETTINGS is not a valid handle, all shell keys that have this root have HKEY_CURRENT_USER as the root instead.
As with earlier builds, when a shell key whose root is HKEY_CURRENT_USER (including because HKEY_CURRENT_USER_LOCAL_SETTINGS is inaccessible) is opened in a thread that has an impersonation token, the target user’s branch of HKEY_USERS becomes the root instead.