Прочитайте значение реестра правильно с типом reg_binary c ++ - PullRequest
0 голосов
/ 11 апреля 2020

Моя проблема в том, что я не могу правильно извлечь значение реестра в шестнадцатеричном формате, преобразовав его в строку, чтобы оно отображалось в моем ListBox (изображение 1), я знаю, как это сделать правильно в C#, но я новичок в C ++.

String ks;
DWORD reg2()
{


        char value[255];

        DWORD BufferSize = BUFFER;

        RegGetValue(HKEY_CURRENT_USER, namebuf, "415846243", RRF_RT_ANY, NULL, (PVOID)&value, &BufferSize);

        std::wstringstream box_messages;
        box_messages << value;
        ks = box_messages.str().c_str();

}

void __fastcall TAAP_Test::Button1Click(TObject *Sender)
{
     ListBox1->Items->Add(ks);
}

Это изображение показывает результат моей программы:

image

Это изображение показывает, какое значение реестра я пытаюсь получить:

image

1 Ответ

1 голос
/ 11 апреля 2020

Значение реестра, которое вы читаете, находится в необработанном двоичном формате (REG_BINARY). В редакторе реестра вы видите не сами необработанные данные, а читабельное шестнадцатеричное представление данных. RegGetValueA() не вернет вам это шестнадцатеричное представление, вместо этого он вернет необработанные двоичные данные.

Вы прекрасно читаете необработанные данные (за исключением отсутствия проверки ошибок), но пытаетесь записать их как есть к вашему std::wstringstream, поэтому вы получаете странный результат, который видите в своем ListBox. Вместо этого вам нужно l oop через отдельные байты данных, кодируя каждый байт в шестнадцатеричное представление, которое затем вставляется в ваш std::wstringstream, например:

#include <iostream>
#include <iomanip>

void reg2()
{
    char value[255];
    DWORD BufferSize = sizeof(value);

    if (RegGetValueA(HKEY_CURRENT_USER, namebuf, "415846243", RRF_RT_ANY, NULL, value, &BufferSize) == ERROR_SUCCESS)
    {
        std::wstringstream box_messages;
        for(DWORD i = 0; i < BufferSize; ++i) {
            box_messages << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(value[i]) << L" ";
        }
        ks = box_messages.str().c_str();
    }
    else
        ks = _D("error");
}

В качестве альтернативы, RTL имеет доступна функция IntToHex():

#include <System.SysUtils.hpp>

void reg2()
{
    char value[255];
    DWORD BufferSize = sizeof(value);

    if (RegGetValueA(HKEY_CURRENT_USER, namebuf, "415846243", RRF_RT_ANY, NULL, value, &BufferSize) == ERROR_SUCCESS)
    {
        std::wstringstream box_messages;
        for(DWORD i = 0; i < BufferSize; ++i) {
            box_messages << IntToHex(static_cast<int>(value[i]), 2).c_str() << _D(" ");
        }
        ks = box_messages.str().c_str();

        /* or simpler:
        ks = _D("");
        for(DWORD i = 0; i < BufferSize; ++i) {
            ks += (IntToHex(static_cast<int>(value[i]), 2) + _D(" "));
        }
        */
    }
    else
        ks = _D("error");
}

В качестве альтернативы UnicodeString имеет метод cat_sprintf():

void reg2()
{
    char value[255];
    DWORD BufferSize = sizeof(value);

    if (RegGetValueA(HKEY_CURRENT_USER, namebuf, "415846243", RRF_RT_ANY, NULL, value, &BufferSize) == ERROR_SUCCESS)
    {
        ks = _D("");
        for(DWORD i = 0; i < BufferSize; ++i) {
            ks.cat_sprintf(_D("%02X "), static_cast<int>(value[i]));
        }
    }
    else
        ks = _D("error");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...