2013-07-28 23 views
1

我無法理解爲什麼我的源只返回註冊表DWORD的LOWORD部分。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 

這個執行以下操作:它從一個data和​​然後將其延伸到DWORD

相反,你要採取DWORD從存儲位置:

* ((DWORD*) data) 
+0

嗨,你能解釋'(DWORD)* data'和'*((DWORD *)data)'?第二個是指向存儲在該內存位置的值的指針。但是(DWORD *)如何影響數據呢? –

+0

'(DWORD *)data'將指針從「指針指向8位值」轉換爲「指向32位值的指針」。然後你使用這個指針來獲取它引用的32位值。 –

+0

另請注意其他答案 - 這是您將要面對的下一個問題。 –

2

你需要在每次調用前設置dataSizedata大小RegEnumValue(),如:

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

看到的說明爲lpcbDataMSDN documentation

+0

嗨,愛德華 - 好。在'for'循環的每次迭代過程中需要設置'datasize',對嗎? –

+0

是的,因爲每次調用都會更新'dataSize',並將實際數據的大小放入'data'中 –