#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\");
После удаления двойной обратной косой черты в начале строки код выполняется, как и ожидалось.