Initialisation String

When a ProgID element is initialised through its SetString
method, the registry key that is used as the query source is:

Key:

HKEY_CLASSES_ROOT\MappedProgID

where MappedProgID is generated from the initialisation
string and from potentially many consultations of the registry. The first step is
to obtain the basic ProgID. The algorithm for this has two distinct cases to it.
In each, a list of candidate ProgIDs is found from various places in the registry
and one more registry setting chooses from the list. SHELL32 presently provides
for as many as 16 candidates.

File Associations

If the initialisation string is a file extension (meaning simply that it begins
with a period), then the candidate ProgIDs are drawn from three sources. A ProgID
may be specified as the default value of the given extension’s own subkey of
HKEY_CLASSES_ROOT:

Key:

HKEY_CLASSES_ROOT\.ext

Value:

default

Type:

REG_SZ or REG_EXPAND_SZ

where .ext is the initialisation string. More
ProgIDs may be listed in a subkey:

Key:

HKEY_CLASSES_ROOT\.ext\OpenWithProgIds

Each value in this key names a candidate ProgID. Data for the value is immaterial.
All that matters is the name of the value. Yet more ProgIDs may be specified in
the key:

If this value has no string data, then the first candidate is chosen by
default. If there are no candidates, the ultimate default is
Unknown.

Note that the string data for this value is ordinarily chosen as the ProgID even
if it is not among the candidate ProgIDs. The way this happens in the code is that
the UserChoice ProgID is added to the list and therefore
is among the candidates (given that the list does not overflow). But if it is always
to be in the list, then why build the list? This code is new for Windows Vista and
is plainly not complete: its analysis may need to be revisited to see how the code
settles in later versions.

URL Associations

If the initialisation string does not begin with a period, then the initialisation
string is itself the first candidate ProgID. More may be named as values in the
key:

If this value has no string data, then the first candidate is chosen by default.
If there are no candidates, the ultimate default is Unknown.
(As for file associations, the string data for this value is ordinarily chosen
as the ProgID even if it is not among the candidate ProgIDs.)

ProgID Key

The chosen ProgID must yet be mapped to a subkey of HKEY_CLASSES_ROOT.
The ProgID key, which serves as the query source for the ProgID element, is

Key:

HKEY_CLASSES_ROOT\MappedProgID

in which MappedProgID is in general the string
data from the following registry value:

Key:

HKEY_CLASSES_ROOT\ChosenProgID\CurVer

Value:

default

Type:

REG_SZ or REG_EXPAND_SZ

If this value cannot be read or is empty, then the mapped ProgID is just the
chosen ProgID. This trivial mapping is also applied, regardless of any
CurVer subkey, if the ProgID is Excel.Sheet.8. (This
special case appears first in the SHELL32 version 6.00 from Windows XP SP1.) A more
general case of trivial mapping expresses a preference that the ProgID key should
have a shell subkey that can be opened for reading.
If this preference is not met when using the mapped ProgID but would be without
the mapping, then the mapping is abandoned and the ProgID key uses the chosen ProgID
instead.

Queries

For most queries, a ProgID element is just a basic shell element with a different
query source. However, two queries are defined just for ProgID elements and three
others behave differently.

When the initialisation string for a ProgID element is a file extension, the
element has a secondary query source which is used for any query whose
ASSOCQUERY value has the 0x80000000
bit set, if put to the QueryString or
QueryGuid methods. At present, just two queries are
defined for this handling:

where extra is provided as the second argument
to the query method. Query 0x80070002 is valid only for ProgID elements and can
be answered only from the extension key. For query 0x81470002, the special handling
is a fall-back. If the query cannot be answered from the ProgID key it is answered
instead from the extension key.

Query 0x00020014 is defined for ProgID elements such that
QueryExists succeeds if a ProgID element has a file-extension
key as a secondary source.

Two other queries have fall-backs when put to a ProgID element through
QueryString. If query 0x00170000 cannot be answered
from the FriendlyTypeName value in the ProgID key,
as usual for other association elements, it is answered instead from the default
value in the ProgID key. If query 0x00070004 cannot be answered from the
Progid subkey of the ProgID key, it is answered instead
with the (unmapped) ProgID as determined above from the initialisation string.

This page was created on 7th July 2009 and was last modified
on 24th July 2009.