我正在对注册表进行一些编辑,以创建从一个区域到另一个区域的符号链接。我使用了以下代码:
HKEY hkFS;
HKEY hkSOFTWARE;
DWORD dwDisposition;
LSTATUS result;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE"), 0,
KEY_CREATE_SUB_KEY , &hkSOFTWARE);
if (result == 0) {
result = RegOpenKeyEx(hkSOFTWARE, _T("MyKey"), REG_OPTION_OPEN_LINK,
KEY_WRITE | KEY_CREATE_LINK | KEY_WOW64_64KEY, &hkFS);
if (result != ERROR_SUCCESS) {
_tprintf(_T("%d\n"), result);
result = RegCreateKeyEx(hkSOFTWARE, _T("MyKey"), 0, NULL,
REG_OPTION_CREATE_LINK,
KEY_WRITE | KEY_CREATE_LINK | KEY_WOW64_64KEY,
NULL, &hkFS, &dwDisposition);
_tprintf(_T("%d\n"), result);
}
if (result == ERROR_SUCCESS) {
//result = ZwDeleteKey(hkFS);
TCHAR target[] = _T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MyKey");
result = RegSetValueEx(hkFS, _T("SymbolicLinkValue"), 0, REG_SZ,
(const BYTE const *)target, sizeof(target));
if (result != ERROR_SUCCESS) {
TCHAR msg[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, result, 0, msg,
sizeof(msg) / sizeof(TCHAR), NULL);
_tprintf(_T("Failed to write SymbolicLinkValue: %s"), msg);
}
RegCloseKey(hkFS);
}
else {
TCHAR msg[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, result, 0, msg,
sizeof(msg) / sizeof(TCHAR), NULL);
_putts(msg);
}
}
else {
TCHAR msg[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, result, 0, msg,
sizeof(msg) / sizeof(TCHAR), NULL);
_tprintf(_T("Error opening SOFTWARE: %s"), msg);
}
RegCloseKey(hkSOFTWARE);
现在我有两个问题。
我需要帮助清理我的注册表并使此代码工作。
我在http://www.codeproject.com/Articles/11973/Registry-Symbolic-Links找到了解决我所有问题的代码。
这是用于删除表示符号链接的注册表项的代码:
typedef LONG NTSTATUS;
#if !defined(_NTSYSTEM_)
#define NTSYSAPI DECLSPEC_IMPORT
#else
#define NTSYSAPI
#endif
NTSYSAPI
NTSTATUS
NTAPI
ZwDeleteKey(
IN HANDLE KeyHandle
);
typedef NTSYSAPI NTSTATUS (NTAPI *ZW_DELETE_KEY_PROTO)(HANDLE);
static LONG DynZwDeleteKey(HKEY hKey)
{
LONG lStatus = ERROR_SUCCESS;
HMODULE hNTDll = LoadLibraryW( L"ntdll.dll" );
if (hNTDll)
{
ZW_DELETE_KEY_PROTO lpfnZwDeleteKey = (ZW_DELETE_KEY_PROTO)GetProcAddress(hNTDll, "ZwDeleteKey");
if (lpfnZwDeleteKey)
lStatus = lpfnZwDeleteKey(hKey);
else
lStatus = GetLastError();
VERIFY(FreeLibrary(hNTDll));
}
else
lStatus = GetLastError();
return lStatus;
}
我上面的代码在创建链接时遇到了一些问题。这些修正的线条使其工作:
result = RegCreateKeyEx(hkSOFTWARE, _T("MyKey"), 0, NULL,
REG_OPTION_CREATE_LINK,
KEY_ALL_ACCESS | KEY_CREATE_LINK | KEY_WOW64_64KEY,
NULL, &hkFS, &dwDisposition);
...
result = RegSetValueExW(hkFS, L"SymbolicLinkValue", 0, REG_LINK,
(const BYTE const *)target, lstrlen(target) * sizeof(WCHAR));
上面的链接创建代码将完美适用于HKEY_LOCAL_MACHINE,如果您的路径有不同的密钥,请使用以下代码
//HKEY_USERS
TCHAR target[] = _T("\\Registry\\USER\\SOFTWARE\\MyKey");
//HKEY_LOCAL_MACHINE
TCHAR target[] = _T("\\Registry\\MACHINE\\SOFTWARE\\MyKey");
//HKEY_CURRENT_USER
TCHAR target[] = _T("\\Registry\\USER\\CurrentUser\\SOFTWARE\\MyKey");
我没有足够的业力来提交......但是AFAIK你不能在符号链接上使用普通的RegKeyDelete。使用符号链接标志创建密钥时,Windows会将容器标记为符号链接,并且所有进一步的操作都将在目标上完成。我不认为用户模式具有足够的粒度来指定您希望在符号链接的实际容器上而不是目标上完成操作。
您可以调用ZwOpenKey并为其提供一个OBJECT_ATTRIBUTES结构,该结构具有OBJ_OPENLINK标志
如果设置了此标志的对象句柄被传递给打开对象的例程,并且如果该对象是符号链接对象,则例程应该打开符号链接对象本身,而不是符号链接引用的对象(是默认行为)。
然后,您可以使用该句柄执行任何操作。