我查找了MSDN,其中有一个示例代码,但是,无法达到我要的效果,不知原因何在?
我想达到的目的:设定某个注册表键及其子键的everyone或者system用户访问权限,使其拥有完全控制的权限或者只有读取的权限,应该如何实现呢?MSDN中的示例代码我看得也不是很懂,不知哪位能详细解释一下,以及如何利用示例代码传递变量?示例代码我贴在下面:
//*************************************************************
// 设定某个对象的访问权限
//*************************************************************
DWORD CUSBCleanerApp::AddAceToObjectsSecurityDescriptor (
    LPTSTR pszObjName,          // 对象名 // hkey
    SE_OBJECT_TYPE ObjectType,  // 对象类型 // SE_REGISTRY_KEY,若用预定义键必须用如下"CLASSES_ROOT", "CURRENT_USER", "MACHINE", and "USERS".
    LPTSTR pszTrustee,          // trustee for new ACE // TRUSTEE_IS_NAME or TRUSTEE_IS_SID
    TRUSTEE_FORM TrusteeForm,   // format of trustee structure // TRUSTEE_IS_SID or TRUSTEE_IS_NAME
    DWORD dwAccessRights,       // access mask for new ACE // GENERIC_ALL,访问的权限设置
    ACCESS_MODE AccessMode,     // type of ACE // SET_ACCESS
    DWORD dwInheritance         // inheritance flags for new ACE // CONTAINER_INHERIT_ACE

{
DWORD dwRes = 0;
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;if (NULL == pszObjName) 
    return ERROR_INVALID_PARAMETER;// Get a pointer to the existing DACL.
// 获取已存在的DACL
dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, 
      DACL_SECURITY_INFORMATION,
      NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes) {
    printf( "GetNamedSecurityInfo Error %u\n", dwRes );
    goto Cleanup; 
}  // Initialize an EXPLICIT_ACCESS structure for the new ACE. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = dwAccessRights;
ea.grfAccessMode = AccessMode;
ea.grfInheritance= dwInheritance;
ea.Trustee.TrusteeForm = TrusteeForm;
ea.Trustee.ptstrName = pszTrustee;// Create a new ACL that merges the new ACE
// into the existing DACL.dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes)  {
    printf( "SetEntriesInAcl Error %u\n", dwRes );
    goto Cleanup; 
}  // Attach the new ACL as the object's DACL.dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, 
      DACL_SECURITY_INFORMATION,
      NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwRes)  {
    printf( "SetNamedSecurityInfo Error %u\n", dwRes );
    goto Cleanup; 
}  Cleanup:    if(pSD != NULL) 
        LocalFree((HLOCAL) pSD); 
    if(pNewDACL != NULL) 
        LocalFree((HLOCAL) pNewDACL);     return dwRes;
}

解决方案 »

  1.   

    “以程序的方式操纵NTFS文件的权限”一文实现的方法复杂了一点,我想我上面的MSDN示例函数应该可以实现同样的功能,但在具体传递变量上还有好多不理解的地方,比如:什么是trustee?怎么样来构造它?等等
      

  2.   

    我自己解决了,贴出解决方案,以供同我一样的初学者参考,以下示例代码原见MSDN,我修改了一下,使之可以更改注册表键的权限。// 文件说明:修改注册表中键的everyone和administrators用户组的权限,使之均拥有完全权限。当然,
    // 你也可以根据自己的需要设定相应的权限,此处不赘述,具体见代码。
    #include "stdafx.h"
    #include <windows.h>
    #include <stdio.h>
    #include <aclapi.h>void main()
    {    DWORD dwRes;
        PSID pEveryoneSID = NULL, pAdminSID = NULL;
        PACL pACL = NULL;
        PSECURITY_DESCRIPTOR pSD = NULL;
        EXPLICIT_ACCESS ea[2];
        SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
        SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
        LONG lRes;
        HKEY hkSub = NULL;    // 为everyone用户组创建一个常规的SID
        if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
                         SECURITY_WORLD_RID,
                         0, 0, 0, 0, 0, 0, 0,
                         &pEveryoneSID))
        {
            printf("AllocateAndInitializeSid Error %u\n", GetLastError());
            goto Cleanup;
        }    // 初始化一个ACE的EXPLICIT_ACCESS结构体,使everyone用户组拥有此键的完全权限
        ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
        ea[0].grfAccessPermissions = KEY_ALL_ACCESS;
        ea[0].grfAccessMode = SET_ACCESS;
        ea[0].grfInheritance= NO_INHERITANCE;
        ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
        ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
        ea[0].Trustee.ptstrName  = (LPTSTR) pEveryoneSID;    // 为BUILTIN\Administrators用户组创建一个SID.
        if(! AllocateAndInitializeSid(&SIDAuthNT, 2,
                         SECURITY_BUILTIN_DOMAIN_RID,
                         DOMAIN_ALIAS_RID_ADMINS,
                         0, 0, 0, 0, 0, 0,
                         &pAdminSID)) 
        {
            printf("AllocateAndInitializeSid Error %u\n", GetLastError());
            goto Cleanup; 
        }    // 初始化一个ACE的EXPLICIT_ACCESS结构体,使Administrators用户组拥有此键的完全权限
        ea[1].grfAccessPermissions = KEY_ALL_ACCESS;
        ea[1].grfAccessMode = SET_ACCESS;
        ea[1].grfInheritance= NO_INHERITANCE;
        ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
        ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
        ea[1].Trustee.ptstrName  = (LPTSTR) pAdminSID;    // 创建一个ACL以容纳新生成的ACE
        dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
        if (ERROR_SUCCESS != dwRes) 
        {
            printf("SetEntriesInAcl Error %u\n", GetLastError());
            goto Cleanup;
        }    // 初始化安全描述符(security descriptor)  
        pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, 
                                 SECURITY_DESCRIPTOR_MIN_LENGTH); 
        if (NULL == pSD) 
        { 
            printf("LocalAlloc Error %u\n", GetLastError());
            goto Cleanup; 
        } 
     
        if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) 
        {  
            printf("InitializeSecurityDescriptor Error %u\n",
                                    GetLastError());
            goto Cleanup; 
        } 
     
        // 添加ACL到安全描述符(security descriptor)
        if (!SetSecurityDescriptorDacl(pSD, 
                TRUE,     // bDaclPresent flag   
                pACL, 
                FALSE))   // not a default DACL 
        {  
            printf("SetSecurityDescriptorDacl Error %u\n", GetLastError());
            goto Cleanup; 
        } 
        
        // 最后一步,设置所打开的键的权限
        HKEY hkey;
        RegOpenKeyEx( HKEY_CURRENT_USER, _T("mykey"), 0, KEY_ALL_ACCESS, &hkey );
        lRes = RegSetKeySecurity( hkey, DACL_SECURITY_INFORMATION, pSD );
        printf("RegCreateKeyEx result %u\n", lRes );Cleanup:    if (pEveryoneSID) 
            FreeSid(pEveryoneSID);
        if (pAdminSID) 
            FreeSid(pAdminSID);
        if (pACL) 
            LocalFree(pACL);
        if (pSD) 
            LocalFree(pSD);
        if (hkSub) 
            RegCloseKey(hkSub);    return;}
      

  3.   

    你设置的是HKEY_CURRENT_USER
    如果换成HKEY_LOCAL_MACHINE,能行么?