Why do registry keys have a default value?


In addition to all the named values you can create underneath a registry key with the RegSetValueEx function, there is also the so-called default value which you obtain by passing NULL or a pointer to a null string as the lpValue. This default value is also the value set and retrieved when you call RegSetValue and RegQueryValue. What's the deal with this default value?

The original 16-bit registry didn't have named values. All it had were keys, and associated with each key was a single piece of data: a string. The functions that operated on this data were RegSetValue and RegQueryValue, which explains why those functions (1) don't have a lpValue parameter and (2) set and retrieve only string data. Because back in the 16-bit world, that's all you had.

In the conversion to Win32, the registry gained new capabilities, such as storing data in formats beyond simple strings, and storing multiple pieces of data under a single key, using a name to distinguish them. What used to be called simply "the value of a registry key" (for since there was only one, there was no need to give it a name) now goes by the special name the default value: It's the value whose name is null.

There's nothing particularly special about the default value aside from its unusual name. A named value need not exist, and if it exists, the data type could be anything. Similarly, the default value need not exist, and its type can be anything. At this point, it's just a value with a strange name.

Comments (36)
  1. Anonymous says:

    Oh! I had always wondered why Registry keys aren’t called "nodes" or "folders", values aren’t "keys", and the associated data with one of those isn’t the "value". Now it all makes sense!

  2. anony.muos says:

    I’ve another question for you: Since the introduction of the registry, why doesn’t it still allow per-value (more fine-grained) permissions? It only allows per key permissions.

  3. Anonymous says:

    Someone:  Why would this be necessary?  If you need to split up permissions, put them in different keys.

    Next, you’ll want to allow some users to change part of a value…

  4. Anonymous says:

    I don’t know.  Registry keys and values are analogous to file system folders and files.  If the file system allows you to set permissions on specific files, why not be able to set permissions on specific registry values?  I don’t really see the need for it, but it seems like it could have been done.

    On the other hand, separation of global and user data into HKLM and HKCU probably provide enough functionality for 99.9% of developers.

  5. Anonymous says:

    The whole registry nomenclature is a bit confusing, because a “key” has multiple “values”, and each “value” has an associated name and value. (Except for the default value, which is not named.) So to get a setting out of the registry you have to get the “value value.”

    (Yes, I know, backwards compatibility forces your hand, like in everything.)

    [The correct term for the contents of a value is data, so it’s not “value value” but rather “value data”. Not that it helps much. -Raymond]
  6. Anonymous says:

    Why were values introduced anyway? What advantage did they bring over simply nesting keys?

  7. Anonymous says:

    Presumably multiple values are far more efficient than multiple keys. You can read all values of a key in a single system call and store them with less metadata.

  8. Anonymous says:

    << I don’t know.  Registry keys and values are analogous to file system folders and files.  If the file system allows you to set permissions on specific files, why not be able to set permissions on specific registry values?  I don’t really see the need for it, but it seems like it could have been done. >>

    In my experience, good engineers think "why" while others think "why not?"  If you can’t think of a good need to do something, then don’t do it.

  9. Anonymous says:

    While on the subject, I’ve always wondered about REG_EXPAND_SZ. I know it’s supposed to store strings which have env variables,  but was never clear about who should do the expanding – RegQueryValue[ex] doesn’t do it by itself. So, does it represent any contractual information, or just an additional metadata of "you should expand me"?

  10. Anonymous says:

    As I understand it, RegQueryValueEx is supposed to expand environment strings in REG_EXPAND_SZ data when it returns.

    I assume the environment string names have to be surrounded by percents, as has been the case since DOS.

    IE %WINDIR%, %SystemRoot%, etc.

  11. Anonymous says:

    Why was it called ReqQueryValue and not RegGetValue?

  12. Anonymous says:

    Ahh yes, the default value.  One of the quirks of regedit is that is places the string "(Default)" into the default value for the key when the default value is not set.  This, unfortunately, leads some people to believe that the value actually *is* set, and that its contents are "(Default)".  

    I remember working on one project where the we had used the default values for registry keys for one reason or another, and the software would operate in a specific way if the default value was set or not.  One of the junior developers was working on a registry script and, noticing the large number of "(Default)" when using regedit, decided to put them into the registry script.  Needless to say, it took us a while to figure out why our software wasn’t quite working right.

  13. Anonymous says:

    Note that to actually set the default value you need to use regedt32.exe on Windows NT/2000 and reg.exe on Windows XP, as regedit.exe will only let you set string data.

  14. Anonymous says:

    El Guapo, why do you query a database instead of "get" a database?

  15. Anonymous says:

    El Guapo, why do you query a database instead of "get" a database?

    You assume he "gets" databases ;)

  16. Anonymous says:

    <i>Why was it called ReqQueryValue and not RegGetValue?</i>

    Don’t ask, don’t tell. (I am SO ashamed!)

  17. Anonymous says:

    Tom: it confuses people all the time.

    Open regedit and do a search with “(Default)”.

    You’ll find some amusing entries worthy of screenshots and puzzlement.

    E.g., on my Vista machine, HKLMSYSTEMCurrentControlSetControlNlsLocale has two “(Default)” names. Easily confused since one is the default for the key, while the other is one that is literally named (Default).

    XP has a few more I believe. The only problem is which one you get back isn’t easily distinguished since regedit lists them both as “(Default)”.

    Source of great amusement and puzzlement. Use it to amaze your coworkers!

    [So amusing I wrote about it in 2006. -Raymond]
  18. scorpion007 says:

    Well, Get is opposite to Set, so if you can Set a value, you should be able to Get one, no? Query is perfectly fine though.

    Also, there *is* a RegGetValue function, but it is very new, and only available in Win XP 64+, and Server 2003+.

    It seems to be able to ‘do more’.

  19. Anonymous says:

    > El Guapo, why do you query a database instead of "get" a database?

    There is a difference between query and get, and I find your parallel between databases and the registry to be inappropriate. What this function is doing is a *get*, not a *query*. Hence the question.

  20. Anonymous says:

    Slightly off-topic, but related to amusing/odd labels on empty items:

    If you enumerate the groups of an NT account that isn’t in any groups, you don’t get a zero-length list as you’d expect; you get a list with one item: "None" (or something like that).

    At least, that’s how it worked some years ago (must’ve been NT4 or Win2k and I think the API was NetUserGetGroups). It was confusing I tested my GUI with a groupless user. "I don’t remember adding special code to do that… Oh, wait, it’s coming from the API." :)

  21. Anonymous says:

    I believe (although I haven’t checked) that the real default value comes first in Regedit.

    Another one, which also has a bad CLSID:

    HKEY_LOCAL_MACHINESOFTWAREMicrosoftActive SetupInstalled Components{5A8D6EE0-3E18-11D0-821E-444553540000}

  22. anony.muos says:

    @David Walker who said:"Why would this be necessary?  If you need to split up permissions, put them in different keys."

    For the same reason that permissions basically exist. If you realize, the users/ones who set the permissions are not necessarily the ones who create the registry values/keys. Typically, registry values/keys are created by ones who DEVELOP/DISTRIBUTE software or by the OS, whereas a user can also have the need to set registry permissions. The registry isn’t like files and folders where permissions also serve the purpose of privacy from other users. Permissions exist in the registry to configure app behavior and if some app depends on several values in a key and if you deny it read/write/change permissions for all values rather than some optional value, that app will refuse to function entirely. Per-value permissions would not have been necessary if the registry was divided into keys which contained values which were optional separately from ones which were required for functioning.

    That’s why I need more fine-grained control. Did you think I was merely ranting without a rational need?

    @Jack Mathews: In my experience, good engineers think "why" while others think "why not?"  If you can’t think of a good need to do something, then don’t do it.

    And if it did not strike to that good engineer "why" rather than "why not", though it may be a reason good enough, would he still be a good engineer?

  23. Anonymous says:

    someone:

    Nothing you described shows an actual need.  If you want different permissions for different values, then put them into different keys.  You just described overengineering a system for no real gain at all.

  24. bcthanks says:

    So the original registry had keys, which can contain subkeys, any of which can have a value.

    IMO, it would have made more sense to simply use subkeys to hold data instead of adding the concept of "values" with "data."  The only difference between a value and a key is that values are leaf nodes, unable to hold subkeys.

    Was this done to make the registry resemble a filesystem? Keys == directories, values == files. Except registry keys can contain data (the "default value") as if a directory can also have data attached.

    As far as enumerating the registry, returning all of a key’s values would be the same as returning the key’s immediate subkeys and values.

    Regedit would be less confusing: no "(Default)" values, each key has an optional value and zero or more subkeys.

    As it stands today, it could use a different font/color for the "default value" to make it stand out. Changing the system language just for regedit is a hack.

  25. Anonymous says:

    Is there a way to set (Default) to be expandable with regedit? I had quite hard time trying to do this until it dawned to me to export the key and edit it with text editor.

  26. Dean Harding says:

    someone: "The registry isn’t like files and folders where permissions also serve the purpose of privacy from other users."

    Err, that’s *exactly* the purpose that permissions in the registry serve. How can you "configure app behavour" with registry keys, when all the programs are running under your own account?

    You haven’t given any actual examples of WHY per-value ACLs would have been beneficial. You basically answered Jack Matthew’s "why" question with "because I want it to." That’s the same as "why not?"

    One thing you need to remember is that in order to have an ACL, the value would need to be a kernel object (because only the kernel is able to enforce permissions). At the moment, only the *key* is a kernel object – the values are just a set of name/value pairs hanging off that one kernel object.

    If you wanted to put an ACL on the values as well, then you would be *significantly* increasing the number of objects the kernel would have to keep track of. So make sure your answer to the "why" question takes that into account, and show that the benefit outweights the cost.

  27. Anonymous says:

    Worf – This search behaviour is interesting in itslef.  When you search for ‘(Default)’, regedit (sensibly in my view) does not find any of the real default values.  Unless that is, a key contains a fake "(Default)" value in which case regedit confuses itself and finds both the real default value and the "(Default)" value. You can see this using find next (F3) to step between its search results.  

    Pressing F2 on the value name clearly shows which is the real (unrenameable) and which is the fake (renameable) default value.

  28. Anonymous says:

    So let’s get this straight: first you had keys, then someone decided keys should values, then someone decided values should have reg_multi_sz?

    Any plans for reg_multi_sz.keys?

    To get the whole tree you’d only have to return one multi_sz value.

    If implemented properly, you could store the whole hive in one multi_sz value – which would also rationalise the permission thing.

  29. Mike Dimmick says:

    @someone: that’s what HKEY_CURRENT_USER is for. Even better, data written to HKEY_CURRENT_USER roams with the user, if they have a roaming profile.

    Use the registry properly.

  30. Mike Dimmick says:

    @david: Sounds like you want RegQueryMultipleValues.

  31. Anonymous says:

    Both values and names are data. Using synonym words to distinguish between two similar type of items are doomed to fail.

  32. Anonymous says:

    @bcthanks: Keys are a bit more heavyweight than values, since they are kernel objects with permissions assigned to them. The aim of values, I suspect, was to remove a little of that heavyweight approach where it wasn’t needed.

    @someone: I can see where you’re coming from when poorly thought out application registry usage prevents you from securing a single setting, without forcing you to ACL them all at the key level. IMO, that’s better solved by good registry design than by promoting values to effectively act like keys.

  33. Anonymous says:

    Leo: it’s for POSIX compatibility. Tokens have a "primary group" field to express the "effective group id" POSIX concept, but it’s completely unused by the Windows security model. To preserve the meaning, there’s a special group in every domain ("None") that gets assigned to all users as the primary group

  34. Anonymous says:

    Okay, this is going offtopic and quite late but I want to give an example to explain. Registry keys are comparable to INI files and values are comparable to INI file values. Just like you can comment out INI values with a semicolon or whatever, I need the ability to disable only certain values in a key. Now if I delete that value, it is usually recreated by the app when it starts or the app gives an error and doesn’t run. Here is where permissions help. I can set read-only permissions. But settings the same ACLs on multiple values in a single key almost always prevents the app from running or acting strangely. As for the overengineering problem/more kernel work, I don’t think there are that many values or keys in the registry that set so many permissions that the kernel’s job would increase greatly, except maybe for Vista. And users can always set ACLs on keys whereever possible and on values only when its needed.

  35. Dean Harding says:

    "users can always set ACLs on keys whereever possible and on values only when its needed"

    Doesn’t work like that. You’re either a kernel object and so can have an ACL, or you’re not a kernel object and so cannot have an ACL.

    You can comment out a registry key. Just put a semi-colon in front of it’s name and the app will no longer find it, either. That the app might just re-add the key again is no different to if the app just re-added the value to an .ini file.

  36. Anonymous says:

    reference:http://blogs.msdn.com/oldnewthing/archive/2008/01/18/7145021.aspx 这是因为在16位的操作系统中,每一个注册…

Comments are closed.