2013-07-28 4 views
1

У меня возникли проблемы с пониманием того, почему мой источник возвращает только часть LOWORD реестра DWORD.RegEnumValue возвращает только LOWORD

Следующий исходный код в основном основан на this MSDN example. Я добавил в раздел для вывода значения (данных) раздела реестра.

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

#define MAX_KEY_LENGTH 255 
#define MAX_VALUE_NAME 16383 

void QueryKey(HKEY hKey) 
{ 
    TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name 
    DWORD cchClassName = MAX_PATH; // size of class string 
    DWORD cSubKeys=0;    // number of subkeys 
    DWORD cbMaxSubKey;    // longest subkey size 
    DWORD cchMaxClass;    // longest class string 
    DWORD cValues;    // number of values for key 
    DWORD cchMaxValue;   // longest value name 
    DWORD cbMaxValueData;  // longest value data 
    DWORD cbSecurityDescriptor; // size of security descriptor 
    FILETIME ftLastWriteTime;  // last write time 

    DWORD i, retCode; 

    TCHAR achValue[MAX_VALUE_NAME]; 
    DWORD cchValue = MAX_VALUE_NAME; 
    DWORD dataType = 0, dataSize; 
    LPBYTE data = (LPBYTE)malloc(512); 

    // Get the class name and the value count. 
    retCode = RegQueryInfoKey(
     hKey,     // key handle 
     achClass,    // buffer for class name 
     &cchClassName,   // size of class string 
     NULL,     // reserved 
     &cSubKeys,    // number of subkeys 
     &cbMaxSubKey,   // longest subkey size 
     &cchMaxClass,   // longest class string 
     &cValues,    // number of values for this key 
     &cchMaxValue,   // longest value name 
     &cbMaxValueData,   // longest value data 
     &cbSecurityDescriptor, // security descriptor 
     &ftLastWriteTime);  // last write time 

    // Enumerate the key values. 

    if (cValues) 
    { 
     printf("\nNumber of values: %d\n", cValues); 

     for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) 
     { 
      cchValue = MAX_VALUE_NAME; 
      achValue[0] = '\0'; 
      retCode = RegEnumValue(hKey, i, achValue, &cchValue, 
          NULL, &dataType, data, &dataSize); 

      if (retCode == ERROR_SUCCESS && dataType == REG_DWORD) 
      { 
       _tprintf(TEXT("(%d) %s: 0x%08X\n"), i+1, achValue, (DWORD)*data); 
      } 
     } 
    } 
} 

void __cdecl _tmain(void) 
{ 
    HKEY hTestKey; 

    if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Console"), 0, KEY_READ, &hTestKey) == ERROR_SUCCESS) 
    { 
     QueryKey(hTestKey); 
    } 

    RegCloseKey(hTestKey); 
} 

Источник выдает пару ключ-значение, как и ожидалось, но для определенных клавиш (например. ScreenBufferSize и WindowSize) только LOWORD часть печатается.

Но когда тестовый код запускается, все идеально.

#include <windows.h> 
#include <stdio.h> 

int main(void) 
{ 
    DWORD d = 0x00190050; 

    printf("DWORD: %08x\n", d); 
    printf("HIWORD: %04x, LOWORD: %04x\n", HIWORD(d), LOWORD(d)); 

    return 0; 
} 

Как распечатать полное значение DWORD?

ответ

3
LPBYTE data; 
... 
(DWORD)*data 

это делает следующее: он принимает BYTE от data, а затем распространяет его на DWORD.

Вместо этого вы хотите принять DWORD из ячейки памяти:

* ((DWORD*) data) 
+0

Привет, не могли бы вы объяснить разницу между '(DWORD) * data' и' * ((DWORD *)))? Второй - указатель на значение, хранящееся в этой ячейке памяти. Но как '' (DWORD *) 'влияет на' данные'? –

+0

'(DWORD *) data' преобразует указатель из« указателя в 8-битные значения »в« указатель на 32-битные значения ». Затем вы используете этот указатель, чтобы получить 32-битное значение, на которое оно ссылается. –

+0

Также обратите внимание на другой ответ - это следующая проблема, с которой вам придется столкнуться. –

2

Вы должны установить dataSize до размера data перед каждым вызовом RegEnumValue(), как:

dataSize = 512; // size of data 
retCode = RegEnumValue(hKey, i, achValue, &cchValue, NULL, &dataType, data, &dataSize); 

Смотрите описание для lpcbData в MSDN documentation

+0

Привет Эдвард - хороший улов. Установка 'datasize' должна произойти во время каждой итерации цикла' for', правильно? –

+0

Да, поскольку каждый вызов обновляет 'dataSize' с размером фактических данных, помещенных в' data' –

Смежные вопросы