WOW64의 레지스트리 리디렉션 예제
다음 예제 코드는 64비트 Windows의 레지스트리 리디렉터에서 제공하는 레지스트리의 별도 보기를 보여 줍니다. 키의 공유 또는 리디렉션 여부에 따라 키 값이 설정되는 방법도 보여 줍니다. 자세한 내용은 WOW64의 영향을 받는 레지스트리 키를 참조하세요.
32비트 및 64비트 Windows 모두에 대해 다음 코드를 별도로 컴파일합니다. 64비트 Windows에서 결과 실행 파일을 각각 실행하고 출력을 비교합니다. 두 버전의 샘플 출력은 소스 코드 아래에 나열됩니다.
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
// Define application constants.
#if defined(_WIN64)
#define VIEW_DATA L"Hello! 64-bit World"
#define ALT_VIEW_DATA L"Hello! 32-bit World"
#define CROSS_ACCESS KEY_WOW64_32KEY
#else
#define VIEW_DATA L"Hello! 32-bit World"
#define ALT_VIEW_DATA L"Hello! 64-bit World"
#define CROSS_ACCESS KEY_WOW64_64KEY
#endif
// Create a registry key and set its value.
// Return TRUE if the function succeeds, FALSE if it fails.
BOOL
CreateRegistryKeyValue(
HKEY hKeyParent,
PWCHAR KeyName,
REGSAM rsAccessMask,
REGSAM rsSamViewFlag,
PBYTE pValue,
DWORD dwValueSize
)
{
DWORD dwDisposition;
HKEY hKey;
DWORD dwRet;
dwRet =
RegCreateKeyEx(
hKeyParent,
KeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
rsAccessMask | rsSamViewFlag,
NULL,
&hKey,
&dwDisposition);
if (dwRet != ERROR_SUCCESS)
{
printf("Error opening or creating key.\n");
return FALSE;
}
// Attempt to set the value of the key.
// If the call fails, close the key and return.
if (ERROR_SUCCESS !=
RegSetValueEx(
hKey,
NULL,
0,
REG_SZ,
pValue,
dwValueSize))
{
printf("Could not set registry value.\n");
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
return TRUE;
}
// Access a registry key and print its value.
// Return TRUE if the function succeeds, FALSE if it fails.
BOOL
AccessRegistryKeyValue(
HKEY hKeyParent,
PWCHAR KeyName,
REGSAM rsAccessMask,
REGSAM rsSamViewFlag
)
{
HKEY hKey;
WCHAR Buffer[MAX_PATH];
DWORD dwSize = sizeof(Buffer);
DWORD dwType;
DWORD dwRet;
dwRet =
RegOpenKeyEx(
hKeyParent,
KeyName,
0,
rsAccessMask | rsSamViewFlag,
&hKey);
if (dwRet != ERROR_SUCCESS)
{
printf("Error opening key!\n");
return FALSE;
}
if (ERROR_SUCCESS !=
RegQueryValueEx(
hKey,
NULL,
0,
&dwType,
(PBYTE)Buffer,
&dwSize))
{
printf("Could not read registry value.\n");
RegCloseKey(hKey);
return FALSE;
}
if (rsSamViewFlag != 0)
{
printf("Alternate view: %S\n", Buffer);
}
else
{
printf("Default view: %S\n", Buffer);
}
RegCloseKey(hKey);
return TRUE;
}
int
main()
{
BOOL Res;
// Define the list of keys to work with.
typedef struct {
HKEY hkRoot;
LPWSTR szRootName;
LPWSTR szName;
}KEYDATA;
KEYDATA Keys[] =
{
{ HKEY_LOCAL_MACHINE, L"HKLM", L"Software\\Hello World" },
{ HKEY_CLASSES_ROOT, L"HKCR", L"Hello" },
{ HKEY_CLASSES_ROOT, L"HKCR", L"CLSID\\{00000000-0000-0000-0000-ABCD00000000}" },
{ HKEY_CLASSES_ROOT, L"HKCR", L"CLSID\\{00000000-0000-0000-0000-ABCD00000000}\\InprocServer32" },
{ HKEY_CLASSES_ROOT, L"HKCR", L"CLSID\\{00000000-0000-0000-0000-ABCD00000000}\\LocalServer32" }
};
// Now create the keys.
for (int i = 0; i < _countof(Keys); i++)
{
// Create the keys in the alternate view of the registry.
Res =
CreateRegistryKeyValue(
Keys[i].hkRoot,
Keys[i].szName,
KEY_READ | KEY_WRITE,
CROSS_ACCESS,
(PBYTE)ALT_VIEW_DATA,
sizeof(ALT_VIEW_DATA));
if (Res == FALSE)
{
printf("Could not create keys in alternate view of the registry.\n");
return 1;
}
// Create the keys in the default view of the registry.
Res =
CreateRegistryKeyValue(
Keys[i].hkRoot,
Keys[i].szName,
KEY_READ | KEY_WRITE,
0,
(PBYTE)VIEW_DATA,
sizeof(VIEW_DATA));
if (Res == FALSE)
{
printf("Could not create keys in default view of the registry.\n");
return 1;
}
}
// Access the registry and print key values.
printf("Application string: %S\n", VIEW_DATA);
for (int i = 0; i < _countof(Keys); i++)
{
printf("%S\\%S\n", Keys[i].szRootName, Keys[i].szName);
Res =
AccessRegistryKeyValue(
Keys[i].hkRoot,
Keys[i].szName,
KEY_READ,
0);
if (Res == FALSE)
{
printf("Unable to access default view of registry.\n");
return 1;
}
// Calls with CROSS_ACCESS explicitly access the alternate registry view.
Res =
AccessRegistryKeyValue(
Keys[i].hkRoot,
Keys[i].szName,
KEY_READ,
CROSS_ACCESS);
if (Res == FALSE)
{
printf("Unable to access alternate view of registry.\n");
return 1;
}
}
return 0;
}
예제의 64비트 버전을 실행하면 다음 출력이 생성됩니다. 이 키가 공유되기 때문에 HKCR\Hello 의 기본 보기와 대체 보기의 값은 동일합니다. 다른 키의 값은 리디렉션되므로 다릅니다.
Windows Server 2008, Windows Vista, Windows Server 2003 및 Windows XP: 이 예제가 이러한 운영 체제에서 실행되면 LocalServer32 키의 기본 및 대체 보기 값이 동일합니다. 이는 LocalServer32 키가 리디렉션되고 반영되어 키에 대한 핸들이 닫히자마자 레지스트리의 64비트 보기와 32비트 뷰 간에 해당 값이 동기화되기 때문입니다. Windows 7부터 레지스트리 리플렉션이 제거되었습니다. 자세한 내용은 레지스트리 리플렉션을 참조하세요.
Application string: Hello! 64-bit World
HKLM\Software\Hello World
Default view: Hello! 64-bit World
Alternate view: Hello! 32-bit World
HKCR\Hello
Default view: Hello! 64-bit World
Alternate view: Hello! 64-bit World
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}
Default view: Hello! 64-bit World
Alternate view: Hello! 32-bit World
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}\InprocServer32
Default view: Hello! 64-bit World
Alternate view: Hello! 32-bit World
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}\LocalServer32
Default view: Hello! 64-bit World
Alternate view: Hello! 32-bit World
예제의 32비트 버전을 실행하면 다음 출력이 생성됩니다. 32비트 애플리케이션의 경우 레지스트리의 64비트 뷰는 대체 보기이므로 공유 키인 HKCR\Hello를 제외하고 값이 반전됩니다.
Application string: Hello! 32-bit World
HKLM\Software\Hello World
Default view: Hello! 32-bit World
Alternate view: Hello! 64-bit World
HKCR\Hello
Default view: Hello! 32-bit World
Alternate view: Hello! 32-bit World
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}
Default view: Hello! 32-bit World
Alternate view: Hello! 64-bit World
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}\InprocServer32
Default view: Hello! 32-bit World
Alternate view: Hello! 64-bit World
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}\LocalServer32
Default view: Hello! 32-bit World
Alternate view: Hello! 64-bit World
regedit를 사용하여 이 예제를 실행하는 효과를 검사하려면 다음 키의 값을 검사합니다. 애플리케이션은 하드 코딩된 레지스트리 경로에서 Wow6432Node를 사용하지 않아야 합니다.
HKLM\SOFTWARE\헬로 월드
HKLM\SOFTWARE\Wow6432Node\헬로 월드
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}\InprocServer32
HKCR\CLSID\{00000000-0000-0000-0000-ABCD00000000}\LocalServer32
HKCR\Hello HKCR\Wow6432Node\CLSID\{00000000-0000-0000-0000-ABCD00000000}
HKCR\Wow6432Node\CLSID\{000000000-0000-0000-0000-ABCD00000000}\InprocServer32
HKCR\Wow6432Node\CLSID\{000000000-0000-0000-0000-ABCD00000000}\LocalServer32
HKCR\Wow6432Node\Hello
관련 항목