Download demo project - 17 KbDownload source files - 4 Kb
If you have ever tried to do something simple like set a security descriptor for a
Registry key you know what a pain the Win32 Security APIs can be. The process of initializing the
various structures, allocating and deallocating memory and testing for error conditions is tedious
and you end up with at least a page and a half of code which is difficult to read and doesn't lend itself
to being reused next time you want to do the same thing. There had to be a better way, I thought. So I wrote a set of
classes which take care of much of the donkey-work for you.
All of the classes correspond to the structures used by the low-level Security APIs -
ACEs, ACLs, SIDs, TRUSTEEs, Security Descriptors. Their member functions are in most cases the same
as the calls you would use when working with the API. The crucial differences are:
- Often, a single constructor call is all that is needed to allocate and initialize an object
- The classes which need to allocate memory will release it safely when the object goes out of scope.
Other than that, they are just thin wrappers. You can still get at the underlying objects if you need to,
and you can also pass them to any of the API functions expecting a security object.
The best documentation I can give you is some sample code, so here is an example of how to create a secure
Registry key which can be read by any user but only changed by administrators.
To compare this with code which does the same thing using only API calls, see
Setting a Security
Descriptor for a new object in the MSDN library. Notice how much longer
CTrustee trEveryone(TRUSTEE_IS_WELL_KNOWN_GROUP, sidEveryone);
CTrustee trAdmins(TRUSTEE_IS_GROUP, sidAdmins);
ea = CExplicitAccess(KEY_READ, SET_ACCESS, NO_INHERITANCE, trEveryone);
ea = CExplicitAccess(KEY_ALL_ACCESS, SET_ACCESS, NO_INHERITANCE, trAdmins);
Note the constructor for CSid which allows you to create a SID for any of the well-known groups such as
Administrators, ordinary users, etc.
if(acl.SetEntriesInAcl(2, ea) == ERROR_SUCCESS)
CSecurityAttributes sa(sd, FALSE);
RegCreateKeyEx(HKEY_CURRENT_USER, "mykey1", 0, "", 0,
KEY_READ | KEY_WRITE, sa, &hKey, &dwDisposition);
That's it! If you have any suggestions or problems to report, post them here. There are plenty of ways
this idea could be extended if you are of an inclination to do so.