2013-03-31 2 views
1

Мой вопрос: Можно ли изменить значение ключа реестра, когда оно было создано с использованием настраиваемого дескриптора безопасности? Нужно ли мне звонить RegSetKeyValueEx с структурой SECURITY_ATTRIBUTES? Если нет, тогда мне нужно будет удалить ключ, а затем воссоздать его.Редактировать/Удалить защищенный реестр Значение ключа

Я пытаюсь изменить (или удалить затем переписать) значение ключа реестра, но не работает. Некоторая важная информация заключается в том, что я создал раздел реестра с помощью специального дескриптора безопасности. Пользовательский дескриптор безопасности имеет только набор KEY_READ Registry Key Security and Access Rights.

Но я не могу даже удалить ключ из-за его дескриптора безопасности ACL. Это проблема, потому что, когда я удалю, я даже не смогу удалить раздел реестра. Причина, по которой я создаю раздел реестра с настраиваемым дескриптором безопасности, заключается в том, что пользователь не может изменить его случайно или по назначению. Ключ говорит мне, было ли мое приложение раньше.

Кто-нибудь знает, как я могу отредактировать/удалить раздел реестра этого типа?

Мой код (который пытается изменить свой ключ и показывает, как я создал ключ в первую очередь):

// Code to change key value 
LONG lResult = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software/MyApplication"), 0, KEY_READ, &hKey); 
LONG setValueRes = RegSetValueEx(hKey, _T("FirstRunSignafier"), 0, REG_DWORD, (LPBYTE) &firstRunSignafierValue, 
           (DWORD) sizeof(firstRunSignafierValue)); 
// Error Value of setValueRes is 5. lResult succeeds 


// Code that creates the registry key 
int recordFirstApplicationRun() 
{ 
    tstring REG_FIRST_RUN_SIGNIFIER = _T("Software\\MyApplication"); 
    HKEY hKey; 
    LONG lResult; 
    int res      = 1; 
    DWORD dwValue, dwType, dwSize = sizeof(dwValue); 
    DWORD firstRunSignafierValue = 1; 
    DWORD keyAlreadyExists; // Two potential values: REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY 
    PSID pEveryoneSID    = NULL; 
    PACL pACL      = NULL; 
    PSECURITY_DESCRIPTOR pSD  = NULL; 
    SECURITY_ATTRIBUTES secAttr; 

    createSecurityAttributes(&secAttr, pEveryoneSID, pACL, pSD); 
    LONG createRes = RegCreateKeyEx(HKEY_CURRENT_USER, &REG_FIRST_RUN_SIGNIFIER[0], 0, NULL, REG_OPTION_NON_VOLATILE, 
            KEY_WRITE|KEY_WRITE, &secAttr, &hKey, &keyAlreadyExists); 
    if (createRes != ERROR_SUCCESS) { 
     //_tprintf(_T("Failed to create key: Last Error: %x, Return Val: %x\n"), GetLastError(), createRes); 
     CPP_Utilities::outputLastError("Failed to create key"); 
     res = -1; 
     goto Cleanup; 
    } 

    //CPP_Utilities::outputLastErrorEx((keyAlreadyExists == REG_CREATED_NEW_KEY) ? _T("Created new registry key"):_T("Registry key already exists")); 
    _tprintf((keyAlreadyExists == REG_CREATED_NEW_KEY) ? _T("Created new registry key\n"):_T("Registry key already exists\n")); 

    // To Write a DWORD to the registry 
    LONG setValueRes = RegSetValueEx(hKey, _T("FirstRunSignafier"), 0, REG_DWORD, (LPBYTE) &firstRunSignafierValue, 
            (DWORD) sizeof(firstRunSignafierValue)); 
    if (setValueRes != ERROR_SUCCESS) { 
     _tprintf(_T("B: %X\n"), setValueRes); 
     CPP_Utilities::outputLastError("Failed to set registry value"); 
     res = -2; 
     goto Cleanup; 
    } 

    Cleanup: 
     if (pEveryoneSID) 
      FreeSid(pEveryoneSID); 
     if (pACL) 
      LocalFree(pACL); 
     if (pSD) 
      LocalFree(pSD); 
     if (hKey) 
      RegCloseKey(hKey); 

    return res; 
} 

int createSecurityAttributes(SECURITY_ATTRIBUTES* secAttr, PSID pEveryoneSID, PACL pACL, PSECURITY_DESCRIPTOR pSD) 
{ 
    // Pre: Memory release for parameters MUST be handled by caller 

    EXPLICIT_ACCESS ea; 
    DWORD dwRes; 
    /*PSID*/ pEveryoneSID     = NULL; 
    /*PACL*/ pACL       = NULL; 
    /*PSECURITY_DESCRIPTOR*/ pSD   = NULL; 
    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; 

    // Create a well-known SID for the Everyone group. 
    if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) { 
     _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError()); 
     CPP_Utilities::outputLastError("AllocateAndInitializeSid Error"); 
     return -1; 
    } 

    // Initialize an EXPLICIT_ACCESS structure for an ACE. The ACE will allow Everyone read access to the key. 
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); 
    ea.grfAccessPermissions = KEY_READ; 
    ea.grfAccessMode  = SET_ACCESS; 
    ea.grfInheritance  = NO_INHERITANCE; 
    ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; 
    ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 
    ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID; 

    // Create a new ACL that contains the new ACEs. 
    dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL); 
    if (ERROR_SUCCESS != dwRes) { 
     _tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError()); 
     CPP_Utilities::outputLastError("SetEntriesInAcl Error"); 
     return -2; 
    } 

    // Initialize a security descriptor. 
    pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 
    if (NULL == pSD) { 
     _tprintf(_T("LocalAlloc Error %u\n"), GetLastError()); 
     CPP_Utilities::outputLastError("LocalAlloc Error"); 
     return -3; 
    } 

    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { 
     _tprintf(_T("InitializeSecurityDescriptor Error %u\n"), GetLastError()); 
     CPP_Utilities::outputLastError("InitializeSecurityDescriptor Error"); 
     return -4; 
    } 

    // Add the ACL to the security descriptor. 
    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { 
     _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"), GetLastError()); 
     CPP_Utilities::outputLastError("SetSecurityDescriptorDacl Error"); 
     return -5; 
    } 

    // Initialize a security attributes structure. 
    secAttr->nLength    = sizeof (SECURITY_ATTRIBUTES); 
    secAttr->lpSecurityDescriptor = pSD; 
    secAttr->bInheritHandle   = FALSE; 

    return 1; 
} 

ответ

0

Вам нужно изменить права доступа таким образом, что пользователь имеет KEY_SET_VALUE права доступа. Самый простой способ сделать это будет для вашей программы удаления, чтобы удалить ACL, добавленный установщиком.

Вам просто нужен ваш деинсталлятор, чтобы отменить шаги, выполненные установщиком. Ваш установщик отправился:

  1. Создать ключ.
  2. Добавить ACL на ключ.

Так что ваш деинсталлятор должен:

  1. Удалите ACL из ключа.
  2. Удалить ключ.
+0

благодарит за ответ. Вы знаете, как удалить ACL из раздела реестра? –

+0

С RegSetKeySecurity, я думаю –