RegQueryValueExW возвращает исключение местоположения чтения нарушения доступа в C - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть две функции, написанные на C, которые должны считывать некоторую информацию из реестра Windows.Хотя оба используют одну и ту же логику, один из них выдает ошибку.Работающие функции получают некоторую информацию о процессоре.

struct CPUInfo {
    wchar_t model[128];
    DWORD frequency;
};

struct CPUInfo cpuinfo() {
    SYSTEM_INFO siSysInfo;
    HKEY hKey;

    struct CPUInfo cpu = { L"", 0 };

    LONG lRes = RegOpenKeyExW(
        HKEY_LOCAL_MACHINE,
        L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
        0,
        KEY_READ,
        &hKey
    );
    if (lRes == ERROR_SUCCESS) {
        DWORD dwBufferSize = sizeof(cpu.model);

        ULONG nError = RegQueryValueExW(
            hKey,
            L"ProcessorNameString",
            0,
            NULL,
            (LPBYTE)cpu.model,
            &dwBufferSize
        );
        dwBufferSize = sizeof(DWORD);
        nError = RegQueryValueExW(
            hKey,
            L"~MHz",
            0,
            NULL,
            (LPBYTE)(&cpu.frequency),
            &dwBufferSize
        );
        RegCloseKey(hKey);
    }

    return cpu;
}

Эта функция работает, и информация извлекается из реестра.Теперь я делаю то же самое во второй раз с этой функцией

struct GPUInfo {
    DWORD adaptersCount;
};

struct GPUInfo gpuinfo() {
    HKEY hKey;
    struct GPUInfo gpu = { 0 };

    LONG lRes = RegOpenKeyExW(
        HKEY_LOCAL_MACHINE,
        L"HARDWARE\\DEVICEMAP\\VIDEO",
        0,
        KEY_READ,
        &hKey
    );
    if (lRes == ERROR_SUCCESS) {
        DWORD dwBufferSize = sizeof(DWORD);
        ULONG nError = RegQueryValueExW(
            hKey,
            L"MaxObjectNumber",
            0,
            NULL,
            (LPBYTE)(&gpu.adaptersCount),
            dwBufferSize
        );

        RegCloseKey(hKey);
    }

    return gpu;
}

Когда я отлаживаю программу, как я уже сказал, первая функция работает, но вторая вызывает исключение в этой точке:

ULONG nError = RegQueryValueExW( // !!!! Access violation reading location 0x0000000000000004
    hKey,
    L"MaxObjectNumber",
    0,
    NULL,
    (LPBYTE)(&gpu.adaptersCount),
    dwBufferSize
);

Я проверил в реестре, и путь существует.На самом деле не понимаю, почему первый работает, а второй нет.Я вызываю их за другим

1 Ответ

0 голосов
/ 07 февраля 2019

Обратите внимание на предупреждения вашего компилятора.Вы передаете lpcbData (длина буфера) по значению , а не по адресу .

Это должно выглядеть так:

DWORD dwBufferSize = sizeof(gpu.adaptersCount);  // (2)
ULONG nError = RegQueryValueExW(
        hKey,
        L"MaxObjectNumber",
        0,
        NULL,
        (LPBYTE)(&gpu.adaptersCount),
        &dwBufferSize                // (1)
    );

Изменения:

  1. Добавьте амперсанд перед dwBufferSize, как в первом примере
  2. Используйте sizeof ваш фактический член структуры.Это эквивалентно, но безопаснее перед лицом будущих изменений.

Ссылка: - RegQueryValueExW

...