This is a quick example of using the the ATL Security classes. The original source code for the project is displayed on the MSDN web site: Creating a Security Descriptor for a New Object in C++. The example presented in the MSDN topic creates a registry key in hive HKEY_CURRENT_USER. This allows the code to function if the user is not an administrator on the Windows XP machine. If you want to create a key in HKEY_LOCAL_MACHINE, you will need to make sure you are a member of the Admins group.
Here's the example, rewritten to utilize the ATL Security classes. The reduction in source code is startling.
//
// CreateSecurityDescriptior.cpp
//
#define WINVER 0x0502
#define _WIN32_WINNT 0x0502
#define _WIN32_IE 0x0700
#include <stdio.h>
#include <tchar.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#include <atlbase.h>
#include <atlstr.h>
#include <atlsecurity.h>
using namespace Sids;
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwRes;
// Create instances of the security classes
CDacl Acl;
CSecurityDesc SD;
CSecurityAttributes sa;
Acl.SetEmpty();
// Add two allowed ACEs
// World() is a predefined SID in the namespace Sids
if (!Acl.AddAllowedAce(World(), KEY_READ, NO_INHERITANCE))
{
_tprintf(_T("AddAllowedAce Error %u\n"), GetLastError());
return 1;
}
// Admins() is a predefined SID in the namespace Sids
if (!Acl.AddAllowedAce(Admins(), KEY_ALL_ACCESS, NO_INHERITANCE))
{
_tprintf(_T("Acl.AddAllowedAce Error %u\n"), GetLastError());
return 1;
}
// Check that the ACEs were added to the DAcl
dwRes = Acl.GetAceCount();
if (2 != dwRes)
{
_tprintf(_T("Acl.GetAceCount returned %u, should be 2\n"), dwRes);
return 1;
}
// Add the ACL to the security descriptor.
try
{
SD.SetDacl(Acl);
sa.Set(SD);
}
catch (...)
{
_tprintf(_T("An error occured setting the Dacl."));
return 1;
}
// Use the security attributes to set the security descriptor
// when you create a key.
CRegKey hkSub;
DWORD dwDisposition = 0;
long lRes = hkSub.Create( HKEY_CURRENT_USER,
_T("mykey"),
0,
0,
KEY_READ | KEY_WRITE,
&sa,
&dwDisposition);
_tprintf(_T("RegCreateKeyEx result %u\n"), lRes );
return 0;
};