Re: Доступ к ключу реестра (с НЕПОЛНЫМИ правами)
От: _Nitro  
Дата: 16.06.06 11:52
Оценка:
Здравствуй, Я!

Проблема решилась так:

bool CRegEdit::Open(const std::string & sSubKey, HKEY hKey)
{    
    Close();
    m_sSubKey = sSubKey;
    m_hKey = ((hKey == 0) ? s_hDefaultHKEY : hKey);

    LONG nRegOpenRez = RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &m_hRegKey);

    if (nRegOpenRez != ERROR_SUCCESS)
    {
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp;

        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))    return false;

        if (LookupPrivilegeValue(NULL, SE_TAKE_OWNERSHIP_NAME , &tkp.Privileges[0].Luid))
        {        
            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

            AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
            RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, WRITE_OWNER, &m_hRegKey);

            PSID pSid;
            PSECURITY_DESCRIPTOR pSD;

            std::string sName = "MACHINE\\SYSTEM\\ControlSet001\\Enum"; // ...например
        
            GetNamedSecurityInfo((LPTSTR) sName.c_str(), SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, &pSid, 0, 0, 0, &pSD);

            SetSecurityInfo(m_hRegKey, SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, pSid, NULL, NULL, NULL);

            RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, WRITE_DAC, &m_hRegKey);

            //LocalFree(pSD); //? по идее нужно освобождать, но тогда всё вроде выполняется, но в доступе к ключу - отказ

            PACL pDacl;

            GetNamedSecurityInfo((LPTSTR) sName.c_str(), SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0, 0, &pDacl, 0, &pSD);

            ACL_SIZE_INFORMATION asi;
            GetAclInformation(pDacl, &asi, sizeof(asi), AclSizeInformation);

            ACL_REVISION_INFORMATION ari;
            GetAclInformation(pDacl, &ari, sizeof(ari), AclRevisionInformation);

            BYTE NewDaclBuf[64000];
            PACL pNewDacl = (PACL)NewDaclBuf;

            InitializeAcl(pNewDacl, 64000, ari.AclRevision);

            AddAccessAllowedAceEx(pNewDacl, ACL_REVISION_DS, CONTAINER_INHERIT_ACE, GENERIC_ALL, pSid);

            for (DWORD i = 0; i < asi.AceCount; i++)
            {
                void* pAce;
                GetAce(pDacl, i, &pAce);

                ACE_HEADER* pAceHeader = (ACE_HEADER*)pAce;
                AddAce(pNewDacl, ari.AclRevision, MAXDWORD, pAce, pAceHeader->AceSize);
            }

            SetSecurityInfo(m_hRegKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);

            RegCloseKey(m_hRegKey);
            nRegOpenRez = RegOpenKeyEx(m_hKey, m_sSubKey.c_str(), 0, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &m_hRegKey);

            LocalFree(pSD);
        }
    }
    return (nRegOpenRez == ERROR_SUCCESS);
}

Всё работает!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.