bool InitRegistryRoot(CESERVER_CONSOLE_MAPPING_HDR* pInfo) { wchar_t szTitle[64]; msprintf(szTitle, countof(szTitle), L"ConEmuHk, PID=%u", GetCurrentProcessId()); if (!ghAdvapi32) { GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but ghAdvapi32 is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); return false; } if (!RegOpenKeyEx_f) { _ASSERTE(RegOpenKeyEx_f!=NULL); RegOpenKeyEx_f = (RegOpenKeyEx_t)GetProcAddress(ghAdvapi32, "RegOpenKeyExW"); if (!RegOpenKeyEx_f) { GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegOpenKeyExW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); return false; } } if (!RegCreateKeyEx_f) { _ASSERTE(RegCreateKeyEx_f!=NULL); RegCreateKeyEx_f = (RegCreateKeyEx_t)GetProcAddress(ghAdvapi32, "RegCreateKeyExW"); if (!RegCreateKeyEx_f) { GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegCreateKeyExW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); return false; } } if (!RegCloseKey_f) { _ASSERTE(RegCloseKey_f!=NULL); RegCloseKey_f = (RegCloseKey_t)GetProcAddress(ghAdvapi32, "RegCloseKey"); if (!RegCloseKey_f) { GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegCloseKey) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); return false; } } if (ghNewKeyRoot == NULL) { //OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)}; //GetVersionEx(&osv); //if (osv.dwMajorVersion >= 6) if (!*pInfo->sMountKey) { // Vista+ typedef LONG (WINAPI* RegLoadAppKey_t)(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions, DWORD Reserved); RegLoadAppKey_t RegLoadAppKey_f = (RegLoadAppKey_t)GetProcAddress(ghAdvapi32, "RegLoadAppKeyW"); if (RegLoadAppKey_f) { LONG lRc = 0; if ((lRc = RegLoadAppKey_f(pInfo->sHiveFileName, &ghNewKeyRoot, KEY_ALL_ACCESS, 0, 0)) != 0) { if ((lRc = RegLoadAppKey_f(pInfo->sHiveFileName, &ghNewKeyRoot, KEY_READ, 0, 0)) != 0) { wchar_t szDbgMsg[128]; msprintf(szDbgMsg, countof(szDbgMsg), L"ConEmuHk: RegLoadAppKey failed, code=0x%08X!\n", (DWORD)lRc); GuiMessageBox(ghConEmuWnd, szDbgMsg, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); ghNewKeyRoot = NULL; } } } else { GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegLoadAppKeyW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); ghNewKeyRoot = NULL; } } else { // XP Only. т.к. для монтирования хайва требуются права админа HKEY hkRoot = pInfo->hMountRoot; if (hkRoot == HKEY_CURRENT_USER) { // Значит это "HKCU\Software\ConEmu Virtual Registry" if (RegOpenKeyEx_f(HKEY_CURRENT_USER, VIRTUAL_REGISTRY_ROOT, 0, KEY_ALL_ACCESS, &hkRoot)) { GuiMessageBox(ghConEmuWnd, L"ConEmuHk: RegOpenKeyEx(" VIRTUAL_REGISTRY_ROOT L") failed!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); ghNewKeyRoot = NULL; hkRoot = NULL; } } if (hkRoot && RegOpenKeyEx_f(hkRoot, pInfo->sMountKey, 0, KEY_ALL_ACCESS, &ghNewKeyRoot)) { if (RegOpenKeyEx_f(hkRoot, pInfo->sMountKey, 0, KEY_READ, &ghNewKeyRoot)) { wchar_t szErrMsg[512]; msprintf(szErrMsg, countof(szErrMsg), L"ConEmuHk: RegOpenKeyEx(0x%X,'%s') failed!\n", (DWORD)(LONG)(LONG_PTR)hkRoot, pInfo->sMountKey); GuiMessageBox(ghConEmuWnd, szErrMsg, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); ghNewKeyRoot = NULL; } } } if (!ghNewKeyRoot) { ghNewKeyRoot = (HKEY)-1; } else { LONG lRc = 0; LPCWSTR pszKeyName = NULL; if (!lRc) lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKCU", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKCU, 0); if (!lRc) lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKCU\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKCUSoftware, 0); if (!lRc) lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM32, 0); if (!lRc) lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM32Software, 0); if (!lRc && IsWindows64()) { // эта ветка не должна выполняться в 32битных ОС if (!lRc) lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM64", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM64, 0); if (!lRc) lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM64\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM64Software, 0); } if (lRc != 0) { CloseRootKeys(); ghNewKeyRoot = (HKEY)-1; // чтобы не пытаться открыть повторно wchar_t szErrInfo[MAX_PATH]; msprintf(szErrInfo, countof(szErrInfo), L"ConEmuHk: Virtual subkey (%s) creation failed! ErrCode=0x%08X\n", pszKeyName ? pszKeyName : L"<NULL>", (DWORD)lRc); GuiMessageBox(ghConEmuWnd, szErrInfo, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); } // Для консистентности if (!ghNewHKLM64) ghNewHKLM64 = ghNewHKLM32; if (!ghNewHKLM64Software) ghNewHKLM64Software = ghNewHKLM32Software; } } if ((ghNewKeyRoot == NULL) || (ghNewKeyRoot == (HKEY)-1)) { DEBUGSTR(L"ConEmuHk: Registry virtualization failed!\n"); return false; } else { DEBUGSTR(L"ConEmuHk: Registry virtualization succeeded\n"); } return true; }
// 0 - SUCCEEDED, otherwise - error code int WINAPI MountVirtualHive(LPCWSTR asHive, PHKEY phKey, LPCWSTR asXPMountName, wchar_t* pszErrInfo, int cchErrInfoMax, BOOL* pbKeyMounted) { int lRc = -1; if (pszErrInfo && cchErrInfoMax) *pszErrInfo = 0; // если передали буфер для ошибки - сразу его почистить *pbKeyMounted = FALSE; OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)}; GetVersionEx(&osv); HMODULE hAdvapi32 = LoadLibrary(L"advapi32.dll"); //LPCWSTR pszKeyName = NULL; LPCWSTR ppszKeys[] = { L"HKCU", L"HKCU\\Software", L"HKLM", L"HKLM\\Software", L"HKLM64", L"HKLM64\\Software" }; size_t nRootKeys = IsWindows64() ? countof(ppszKeys) : (countof(ppszKeys) - 2); if (!hAdvapi32) { if (pszErrInfo && cchErrInfoMax) msprintf(pszErrInfo, cchErrInfoMax, L"LoadLibrary(advapi32.dll) failed, code=0x%08X!\n", GetLastError()); lRc = -2; goto wrap; } if (osv.dwMajorVersion >= 6) { // Vista+ typedef LONG (WINAPI* RegLoadAppKey_t)(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions, DWORD Reserved); RegLoadAppKey_t RegLoadAppKey_f = (RegLoadAppKey_t)GetProcAddress(hAdvapi32, "RegLoadAppKeyW"); if (!RegLoadAppKey_f) { if (pszErrInfo && cchErrInfoMax) msprintf(pszErrInfo, cchErrInfoMax, L"RegLoadAppKeyW not found, code=0x%08X!\n", GetLastError()); lRc = -3; goto wrap; } else { if ((lRc = RegLoadAppKey_f(asHive, phKey, KEY_ALL_ACCESS, 0, 0)) != 0) { if ((lRc = RegLoadAppKey_f(asHive, phKey, KEY_READ, 0, 0)) != 0) { if (pszErrInfo && cchErrInfoMax) msprintf(pszErrInfo, cchErrInfoMax, L"RegLoadAppKey failed, code=0x%08X!", (DWORD)lRc); lRc = -4; //-V112 goto wrap; } } *pbKeyMounted = TRUE; } } else if (!asXPMountName || !*asXPMountName) { lRc = -7; if (pszErrInfo && cchErrInfoMax) lstrcpyn(pszErrInfo, L"XPMountName is empty!", cchErrInfoMax); goto wrap; } else { CBackupPrivileges se; if (!se.BackupPrivilegesAcuire(TRUE)) { if (pszErrInfo && cchErrInfoMax) msprintf(pszErrInfo, cchErrInfoMax, L"Aquiring SE_BACKUP_NAME/SE_RESTORE_NAME failed, code=0x%08X!\nYou must be Administrator or Backup operator", GetLastError()); lRc = -5; goto wrap; } //_wcscpy_c(rsXPMountName, cchXPMountMax, VIRTUAL_REGISTRY_GUID); //WARNING("###: Докинуть в конец что-нть уникальное, например CRC пути к hive"); // Hive уже мог быть подключен другой копией ConEmu. TODO("При выходе - может возникнуть конфликт? Кто первый сделает RegUnloadKey..."); if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_ALL_ACCESS, phKey)) == 0) { goto wrap; // успешно - hive уже подключен } else if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_READ, phKey)) == 0) { goto wrap; // успешно - hive уже подключен (ReadOnly) } // Hive еще не был подключен if ((lRc = RegLoadKey(HKEY_USERS, asXPMountName, asHive)) != 0) { if (pszErrInfo && cchErrInfoMax) msprintf(pszErrInfo, cchErrInfoMax, L"RegLoadKey failed, code=0x%08X!", (DWORD)lRc); lRc = -6; goto wrap; } // Ключ смонтирован, нужно его будет демонтировать при выходе *pbKeyMounted = TRUE; if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_ALL_ACCESS, phKey)) == 0) { goto wrap; // успешно - hive уже подключен } else if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_READ, phKey)) == 0) { goto wrap; // успешно - hive уже подключен (ReadOnly) } } // Нужно проверить, можно ли создать/открыть необходимые ключи for (UINT i = 0; i < nRootKeys; i++) { HKEY hTest = NULL; LPCWSTR pszKeyName = ppszKeys[i]; lRc = RegCreateKeyEx(*phKey, pszKeyName, 0,0,0, KEY_ALL_ACCESS, 0, &hTest, 0); if (lRc != 0) lRc = RegCreateKeyEx(*phKey, pszKeyName, 0,0,0, KEY_READ, 0, &hTest, 0); if (lRc != 0) { if (pszErrInfo && cchErrInfoMax) msprintf(pszErrInfo, cchErrInfoMax, L"RegCreateKeyEx(%s) failed, code=0x%08X!", pszKeyName, (DWORD)lRc); RegCloseKey(*phKey); *phKey = NULL; if (asXPMountName && *asXPMountName) UnMountVirtualHive(asXPMountName, NULL, 0); lRc = -8; goto wrap; } } wrap: if (hAdvapi32) FreeLibrary(hAdvapi32); // Decrease counter return lRc; }