If I simply want to create a registry key but don’t intend to do anything else with it, what security access mask should I ask for?

A customer wanted to create a registry key if it didn't already exist, but they weren't interested in writing anything to the key yet. They just wanted to ensure that it existed. Now, we know that the Reg­Create­Key­Ex function will either open a key (if it exists) or create a key (if it doesn't already exist). That seems to fit the bill perfectly, so we have this so far:

HKEY subKey;
LONG result = RegCreateKeyEx(
    parentKey, subkeyName, 0, nullptr,
    0, ????, nullptr, &subKey, nullptr);
if (result == ERROR_SUCCESS) {

Now, we know that the parentKey must have been opened with KEY_CREATE_SUB_KEY access in order for us to be able to create a subkey. But what goes into the question marks, which specify the access mask for the subkey? Should we say KEY_WRITE because we are creating the key? Or do we say 0 because we aren't intending to do anything at all with the new key?

In this case, saying 0 is just fine. The program doesn't do anything with the subkey aside from close the handle, and closing a handle doesn't require any special permissions. If you planned to use the subKey to perform any operations on the subkey, then you need to request an access mask that is compatible with the operations you intend to perform.

But if you don't intend to perform any operations, then you don't need to request any access. Passing 0 is just fine.

Comments (10)
  1. DWalker07 says:

    I hope they plan to do something with the key eventually — otherwise, they don’t need to create it.

    Why can’t they create the key when they want to write to it or add subkeys? I don’t understand…

    1. Probably because they are interacting with a component that triggers on key existence, where the value is not relevant.

      1. DWalker07 says:

        Ah, thanks.

  2. Joshua says:

    Before the UAC days, passing MAXIMUM_ALLOWED in contexts like this was sane. But then again, 0 is sane either way.

    1. Dave says:

      Is passing 0 guaranteed to be future-proof? What if a future version of the API, performing more rigorous checking, decides that passing 0 doesn’t make sense since you won’t be able to use the key you’ve just created, and returns an error?

      1. anai says:

        As I understand it, the access is for the handle returned, not for the operation of the function call. So if this (key creation unrelated to returned handle use) remains in the future, and you still don’t want to use the handle returned (apart from close which requires no special permissions) passing 0 will always be valid.

        That is, the function is designed for a use case whereby the handle returned is not used (except to close). That case is the creation of a key. If this use case is valid in the future then passing 0 will be valid.


        From the documentation (and the name of the function) it does not appear that this ‘just create a key’ is a side effect, that could be ‘dropped’.

        In the future, maybe you will have to have non-zero access permissions on handles (why?), which would break this use, however best practice is to use the minimum permissions required. Therefore if the above use case is required, best practice would dictate that should be supported.

        1. anai says:

          … that {nothing} should be supported … (angle brackets not good)

      2. Darran Rowe says:

        Well, there is a use for opening a file or key with no access to it already. So while there is a reason for it then it isn’t going away.
        Checking for the existence is one very valid reason, and you don’t need the access mask to have anything other than 0 for that. Pre-emptively creating a file or a key is also another very valid reason, and again a 0 for the access mask will do just fine.
        Another thing that is called out in the documentation is that some actions don’t actually check the access mask, they check the key’s ACL instead. So an example of this is if you create a key, specifying that the key has a 0 access mask, you can still use the handle obtained from that to use as a parent key for another call to RegCreateKeyEx. This is mentioned in the remarks section for RegOpenKeyEx. (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724897(v=vs.85).aspx).
        So no, the access mask being 0 is not going away because it is quite future proof and also quite useful.

      3. rbmm says:

        “Is passing 0 guaranteed to be future-proof?” – interesting situation here with Createfile/NtOpenFile/NtCreateFile – in windows XP we can pass 0 as ACCESS_MASK and open file. but begin from win2003 and all latest windows – we got STATUS_ACCESS_DENIED when try open/create file with 0 as DesiredAccess. so that in principle this possible and for Keys too. and for file really exist sence request 0 as access – if we will be use CTL_CODE(*, FILE_ANY_ACCESS). say FSCTL_GET_RETRIEVAL_POINTERS and FSCTL_MOVE_FILE very useful for defragmentators – open file (in XP) with 0 access – we cannot read or write to this file, even can not query it attributes – but we can move (defragment) file in disk. hard to say why begin from 2003 this broken (let open fles with 0 access)

    2. Kirill says:

      Passing MAXIMUM_ALLOWED has never been sane. It worked, sure, but it wasn’t sane.

Comments are closed.

Skip to main content