RegCreateKeyExW не создает ключи

#winapi #visual-c #registry

#winapi #visual-c #реестр

Вопрос:

Я пытаюсь создать разделы реестра под HKEY_CURRENT_USER кустом. Я использую эту RegCreateKeyExW функцию. Я прочитал документацию Microsoft для этой функции и считаю, что я правильно ее вызываю. Однако возвращаемое значение не ERROR_SUCCESS соответствует коду в операторе if, обнаруживающем сбои. Выполняется. При вызове GetLastError текст ошибки указывает, что операция была выполнена успешно. При проверке реестра я могу подтвердить, что ключи не создаются. Я запускаю код с правами администратора, поскольку это контекст безопасности, в котором работает VS. Вот код ниже:

Registry.cpp

 int createRegistryKey(HKEY hiveHandle, LPCWSTR registryKeySequence) {

    HKEY keyHandle;

    if (RegCreateKeyExW(HKEY_CURRENT_USER, registryKeySequence, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, amp;keyHandle, NULL)  != ERROR_SUCCESS) {

        wchar_t buf[256];
        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            buf, (sizeof(buf) / sizeof(wchar_t)), NULL);

        /* Display error */
        std::wcout << "Creating key/s failed: " << buf << std::endl;

        //return -1;

    }
    else {

        std::wcout << "Keys added successfuly" << std::endl;

    }

    RegCloseKey(keyHandle);
    RegCloseKey(hiveHandle);

    return 0;
}

 

Ниже приведен код, который вызывает указанную выше функцию:

fodhelperBypass.cpp

 #include <iostream>
#include <Windows.h>
#include "registry.h"

int main() {

    HKEY hiveHandle;

    /* Get handle to HKCU hive*/
    if (RegOpenCurrentUser(KEY_SET_VALUE, amp;hiveHandle) != ERROR_SUCCESS) {

        wchar_t buf[256];
        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            buf, (sizeof(buf) / sizeof(wchar_t)), NULL);

        /* Display error */
        std::wcout << "Opening hive failed: " << buf << std::endl;

        return -1;

    }
    else {

        std::wcout << "HKCU Hive opened successfully" << std::endl;

    }

    createRegistryKey(hiveHandle, L"\SOFTWARE\TestKey\");
}
 

Я полагаю, что использую правильные права доступа ( KEY_CREATE_SUB_KEY ), но изменил на using KEY_ALL_ACCESS , однако это, похоже, не помогло. В документах говорится, что, даже если ключ существует, должен быть возвращен дескриптор, но это не то, что происходит, насколько я вижу.

Я попытался использовать аргумент disposition для дальнейшего понимания того, что именно происходит, однако даже в режиме отладки VS я получал значение 0x00000000 , которое не имеет смысла по сравнению с ожидаемыми значениями, указанными в документации. 0x00000001L для создания и 0x00000002L для открытого ключа. Я даже создал оператор if, else if, else, который сначала перехватил disposition == REG_CREATED_NEW_KEY then disposition == REG_OPENED_EXISTING_KEY , и оператор else, улавливающий случаи, когда disposition не было равно ни одному значению. Это был оператор else, который выполнялся каждый раз, когда я его тестировал.

Кто-нибудь может дать мне представление о том, чего мне здесь не хватает, пожалуйста?

Комментарии:

1. Что происходит при передаче фактического возвращаемого кода ошибки, а не GetLastError() ? (И каков исходный код ошибки, независимо от этого?)

2. В случае (случаях), когда «.. возвращаемое значение не является ERROR_SUCCESS [и] текст ошибки [из GetLastError() указывает, что операция была выполнена успешно.»; в принципе, сначала попробуйте изолировать, если GetLastError() усложняет наблюдения, что можно сделать, сравнив его свозвращает значение и / или полностью удаляет его. (Надеюсь, результатом будет то, что половина вопроса может быть устранена или объяснена.)

3. GetLastError здесь бесполезен. Возвращаемое значение — это код ошибки. Что это?

4. Возвращаемый необработанный код ошибки равен 161, не уверен, где именно я это ищу.

5. «Если функция завершается с ошибкой, возвращаемое значение представляет собой ненулевой код ошибки, определенный в Winerror.h» из документации Microsoft. Итак, я использую FormatMessage функцию, чтобы получить значимую ошибку из этого?

Ответ №1:

Здесь возникали две проблемы; Во-первых, как отметил @David Heffernan, вызов GetLastError() не давал значимой информации о возникшей ошибке. При первоначальном чтении документации Microsoft я неправильно прочитал информацию, относящуюся к кодам ошибок.

Если функция завершается с ошибкой, возвращаемое значение является ненулевым кодом ошибки, определенным в Winerror.h . Вы можете использовать функцию FormatMessage с флагом FORMAT_MESSAGE_FROM_SYSTEM, чтобы получить общее описание ошибки.

Изменение кода обработки ошибок и предоставление возвращаемого значения RegCreateKeyExW to FormatMessage() вместо кода ошибки from GetLastError() привело к более значимой ошибке: ERROR_BAD_PATHNAME (код 161).

 int createRegistryKey(HKEY hiveHandle, LPCWSTR registryKeySequence) {

    HKEY keyHandle;

    LSTATUS resu<
    result = RegCreateKeyExW(hiveHandle, registryKeySequence, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, amp;keyHandle, NULL);
    
    if (result != ERROR_SUCCESS) {

        wchar_t buf[256];
        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, result, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            buf, (sizeof(buf) / sizeof(wchar_t)), NULL);

        /* Display error */
        std::wcout << "Creating key/s failed: " << buf << std::endl;

        return -1;

    }
    else {

        std::wcout << "Keys added successfuly" << std::endl;

    }

    RegCloseKey(keyHandle);

    return 0;

}

 

После небольшого тестирования стало очевидно, что при предоставлении данных в lpSubKey предыдущие обратные косые черты были проблемой:

 createRegistryKey(hiveHandle, L"\SOFTWARE\TestKey\");
 

После удаления двойной обратной косой черты в начале строки код выполняется, как и ожидалось.