以编程方式设置ACCESS\u ALLOWED\u ACE,得到与RegEdit不同的结果

以编程方式设置ACCESS\u ALLOWED\u ACE,得到与RegEdit不同的结果,c,windows,permissions,registrykey,C,Windows,Permissions,Registrykey,我有一个有趣的问题,我希望有人能解释一下。我们正在做以下工作: 创建一个注册表项 使用SetSecurityDescriptorDacl向DACL添加允许的访问权限 查看注册表中的注册表项(权限看起来很好) 在Regedit中,添加新的子项 查看子密钥的权限 Regedit报告权限顺序不正确(并且似乎添加了一些意外的权限) 不过 如果在Regedit中创建第一个键而不是以编程方式创建,然后重复步骤3-5,则子键创建正确 使用一些额外的代码(下面不包括),我比较了来自Regedit创建的键和通过编

我有一个有趣的问题,我希望有人能解释一下。我们正在做以下工作:

  • 创建一个注册表项
  • 使用SetSecurityDescriptorDacl向DACL添加允许的访问权限
  • 查看注册表中的注册表项(权限看起来很好)
  • 在Regedit中,添加新的子项
  • 查看子密钥的权限
  • Regedit报告权限顺序不正确(并且似乎添加了一些意外的权限)

    不过

    如果在Regedit中创建第一个键而不是以编程方式创建,然后重复步骤3-5,则子键创建正确

    使用一些额外的代码(下面不包括),我比较了来自Regedit创建的键和通过编程创建的键的DACL,它们是相同的。但是,如果您通过代码创建密钥,那么似乎有问题

    下面是一些创建密钥和修改访问权限的示例代码。这基本上是一个MSDN示例,只是为了修改注册表项而进行了调整。同样,它正确地创建了关键点,但子关键点不正确

    任何线索都将不胜感激

    #include "stdafx.h"
    #include <Windows.h>
    #include <Sddl.h>
    
    BOOL AddAceToKey(HKEY hKey, PSID psid)
    {
       ACCESS_ALLOWED_ACE   *pace = NULL;
       ACL_SIZE_INFORMATION aclSizeInfo;
       BOOL                 bDaclExist;
       BOOL                 bDaclPresent;
       BOOL                 bSuccess = FALSE;
       DWORD                dwNewAclSize;
       DWORD                dwSidSize = 0;
       DWORD                dwSdSizeNeeded = 0;
       PACL                 pacl;
       PACL                 pNewAcl = NULL;
       PSECURITY_DESCRIPTOR psd = NULL;
       PSECURITY_DESCRIPTOR psdNew = NULL;
       PVOID                pTempAce;
       SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
       unsigned int         i;
    
       __try
       {
          // Obtain the DACL for the key.
    
           LONG lResult = RegGetKeySecurity
            ( hKey
            , si
            , 0
            , &dwSdSizeNeeded
            );
    
          if ( lResult != ERROR_SUCCESS )
          if ( lResult == ERROR_INSUFFICIENT_BUFFER)
          {
             psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                   GetProcessHeap(),
                   HEAP_ZERO_MEMORY,
                   dwSdSizeNeeded);
    
             if (psd == NULL)
                __leave;
    
             psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
                   GetProcessHeap(),
                   HEAP_ZERO_MEMORY,
                   dwSdSizeNeeded);
    
             if (psdNew == NULL)
                __leave;
    
             dwSidSize = dwSdSizeNeeded;
    
             if (RegGetKeySecurity(
                   hKey,
                   si,
                   psd,
                   &dwSdSizeNeeded) != ERROR_SUCCESS
             )
                __leave;
          }
          else
             __leave;
    
          // Create a new DACL.
    
          if (!InitializeSecurityDescriptor(
                psdNew,
                SECURITY_DESCRIPTOR_REVISION)
          )
             __leave;
    
          // Get the DACL from the security descriptor.
    
          if (!GetSecurityDescriptorDacl(
                psd,
                &bDaclPresent,
                &pacl,
                &bDaclExist)
          )
             __leave;
    
          // Initialize the ACL.
    
          ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
          aclSizeInfo.AclBytesInUse = sizeof(ACL);
    
          // Call only if the DACL is not NULL.
    
          if (pacl != NULL)
          {
             // get the file ACL size info
             if (!GetAclInformation(
                   pacl,
                   (LPVOID)&aclSizeInfo,
                   sizeof(ACL_SIZE_INFORMATION),
                   AclSizeInformation)
             )
                __leave;
          }
    
          // Compute the size of the new ACL.
    
          dwNewAclSize = aclSizeInfo.AclBytesInUse +
                sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD);
    
          // Allocate memory for the new ACL.
    
          pNewAcl = (PACL)HeapAlloc(
                GetProcessHeap(),
                HEAP_ZERO_MEMORY,
                dwNewAclSize);
    
          if (pNewAcl == NULL)
             __leave;
    
          // Initialize the new DACL.
    
          if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
             __leave;
    
          // Add the ACE to the key
    
          pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
                GetProcessHeap(),
                HEAP_ZERO_MEMORY,
                sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
                      sizeof(DWORD));
    
          if (pace == NULL)
             __leave;
    
          pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
          pace->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
          pace->Header.AceSize  = LOWORD(sizeof(ACCESS_ALLOWED_ACE) +
                       GetLengthSid(psid) - sizeof(DWORD));
          pace->Mask            = KEY_ALL_ACCESS;
    
          if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
             __leave;
    
          if (!AddAce(
                pNewAcl,
                ACL_REVISION,
                MAXDWORD,
                (LPVOID)pace,
                pace->Header.AceSize)
          )
             __leave;
    
          // If DACL is present, copy it to a new DACL.
    
          if (bDaclPresent)
          {
             // Copy the ACEs to the new ACL.
             if (aclSizeInfo.AceCount)
             {
                for (i=0; i < aclSizeInfo.AceCount; i++)
                {
                   // Get an ACE.
                   if (!GetAce(pacl, i, &pTempAce))
                      __leave;
    
                   // Add the ACE to the new ACL.
                   if (!AddAce(
                         pNewAcl,
                         ACL_REVISION,
                         MAXDWORD,
                         pTempAce,
                        ((PACE_HEADER)pTempAce)->AceSize)
                   )
                      __leave;
                }
             }
          }
    
          // Set a new DACL for the security descriptor.
    
          if (!SetSecurityDescriptorDacl(
                psdNew,
                TRUE,
                pNewAcl,
                FALSE)
          )
             __leave;
    
          // Set the new security descriptor for the window station.
    
          if (RegSetKeySecurity( hKey, si, psdNew ) != ERROR_SUCCESS)
             __leave;
    
          // Indicate success.
    
          bSuccess = TRUE;
       }
       __finally
       {
          // Free the allocated buffers.
    
          if (pace != NULL)
             HeapFree(GetProcessHeap(), 0, (LPVOID)pace);
    
          if (pNewAcl != NULL)
             HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
    
          if (psd != NULL)
             HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
    
          if (psdNew != NULL)
             HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
       }
    
       return bSuccess;
    
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        HKEY hKey;
        DWORD dwDisposition;
    
        LONG lResult = RegCreateKeyEx
            ( HKEY_LOCAL_MACHINE
            , L"SOFTWARE\\MyCompany"
            , 0
            , NULL
            , REG_OPTION_NON_VOLATILE
            , KEY_ALL_ACCESS | KEY_WOW64_64KEY
            , NULL
            , &hKey
            , &dwDisposition
            );
    
        if ( lResult != ERROR_SUCCESS )
        {
            return 1;
        }
    
        PSID pSid;
    
        // The 'Users' SID.
        ConvertStringSidToSid( L"S-1-5-32-545", &pSid );
    
        AddAceToKey( hKey, pSid );
    
        LocalFree( pSid );
    
        RegCloseKey( hKey );
    
        return 0;
    }
    
    #包括“stdafx.h”
    #包括
    #包括
    BOOL AddAceToKey(HKEY HKEY,PSID PSID)
    {
    允许访问\u ACE*pace=NULL;
    ACL_SIZE_信息aclSizeInfo;
    布尔·比塔克西斯特;
    BOOL-bdacl-present;
    BOOL bsucces=假;
    DWORD dwNewAclSize;
    DWORD dwSidSize=0;
    DWORD DWSDSIZENEDED=0;
    PACL-PACL;
    PACL pNewAcl=NULL;
    PSECURITY_描述符psd=NULL;
    PSECURITY_描述符psdNew=NULL;
    PVOID;
    安全信息si=DACL安全信息;
    无符号整数i;
    __试一试
    {
    //获取密钥的DACL。
    LONG lResult=RegGetKeySecurity
    (hKey)
    ,si
    , 0
    ,&dwsdsizeneed
    );
    如果(lResult!=错误\u成功)
    如果(lResult==错误\u缓冲区不足)
    {
    psd=(PSECURITY\u描述符)HeapAlloc(
    GetProcessHeap(),
    堆零内存,
    dwsdsizeneed);
    如果(psd==NULL)
    __离开;
    psdNew=(PSECURITY_描述符)HeapAlloc(
    GetProcessHeap(),
    堆零内存,
    dwsdsizeneed);
    if(psdNew==NULL)
    __离开;
    dwSidSize=DWSDSIZENEED;
    if(RegGetKeySecurity(
    香港大学,
    硅,
    psd,
    &dwSdSizeNeeded)!=错误\u成功
    )
    __离开;
    }
    其他的
    __离开;
    //创建一个新的DACL。
    如果(!InitializeSecurityDescriptor(
    psdNew,
    安全性(描述符(修订版)
    )
    __离开;
    //从安全描述符获取DACL。
    如果(!GetSecurityDescriptorDacl(
    psd,
    &现在,
    &pacl,
    &b(马克思主义)
    )
    __离开;
    //初始化ACL。
    零内存(&aclSizeInfo,sizeof(ACL_SIZE_信息));
    aclSizeInfo.AclBytesInUse=sizeof(ACL);
    //仅当DACL不为空时调用。
    如果(pacl!=NULL)
    {
    //获取文件ACL大小信息
    如果(!GetAclInformation(
    pacl,
    (LPVOID)和aclSizeInfo,
    sizeof(ACL大小信息),
    ACLSIZE信息)
    )
    __离开;
    }
    //计算新ACL的大小。
    dwNewAclSize=aclSizeInfo.AclBytesInUse+
    sizeof(允许访问)+GetLengthSid(psid)-sizeof(DWORD);
    //为新ACL分配内存。
    pNewAcl=(PACL)HeapAlloc(
    GetProcessHeap(),
    堆零内存,
    dw(新尺寸);
    如果(pNewAcl==NULL)
    __离开;
    //初始化新的DACL。
    如果(!InitializeCal(pNewAcl、dwNewAclSize、ACL_修订版))
    __离开;
    //将ACE添加到密钥中
    速度=(允许访问速度*)HeapAlloc(
    GetProcessHeap(),
    堆零内存,
    sizeof(允许访问)+GetLengthSid(psid)-
    西泽夫(德沃德));
    如果(速度==NULL)
    __离开;
    pace->Header.AceType=ACCESS\u ALLOWED\u ACE\u TYPE;
    pace->Header.AceFlags=容器_继承|对象_继承_ACE;
    pace->Header.AceSize=LOWORD(sizeof(允许访问)+
    GetLengthSid(psid)-sizeof(DWORD));
    速度->掩码=键所有访问;
    if(!CopySid(GetLengthSid(psid),&pace->SidStart,psid))
    __离开;
    如果(!AddAce(
    pNewAcl,
    ACL_修订版,
    马克斯沃德,
    (LPVOID)速度,
    速度->页眉.AceSize)
    )
    __离开;
    //如果存在DACL,请将其复制到新的DACL。
    如果(bDaclPresent)
    {
    //将ACE复制到新ACL。
    if(aclSizeInfo.acecont)
    {
    对于(i=0;iAceSize)
    )
    __离开;
    }
    }
    }
    //为安全描述符设置新的DACL。
    如果(!SetSecurityDescriptorDacl(
    psdNew,
    是的,
    pNewAcl,
    (错误)
    )
    __离开;
    //为窗口站设置新的安全描述符。
    if(RegSetKeySecurity(hKey、si、psdNew)!=错误\成功)
    __离开;
    //表示成功。
    B