Я решил взломать эту проблему, но я должен предупредить вас: это не красиво.Хватит читать сейчас, если вы легко обиделись ...
Поскольку, похоже, нет способа заставить IE9 использовать метод IDocHostUIHandler :: GetOptionKeyPath (), я использовал инструменты SysInternals, чтобы увидеть, какие библиотеки IE9 получили доступ ксоответствующие разделы реестра для загрузки настроек IE9.Это выявило единственных виновников, таких как «mshtml.dll» и «iertutil.dll», оба из которых вызывают RegOpenKeyExW ().
Затем планировалось загрузить эти библиотеки DLL перед инициализацией элемента управления WebBrowser и исправить их такэти вызовы перенаправляются в мой код, где я могу лгать о том, какой раздел реестра я открыл, используя dbghelp.dll.Итак, для начала, прежде чем инициализировать элемент управления WebBrowser:
if (theApp.GetIEVersion() >= 9.0)
{
HMODULE advadi = ::LoadLibrary("advapi32.dll");
HMODULE mshtml = ::LoadLibrary("mshtml.dll");
HookApiFunction(mshtml,advadi,"advapi32.dll","RegOpenKeyExW",(PROC)HookRegOpenKeyExW);
HMODULE iertutil = ::LoadLibrary("iertutil.dll");
HookApiFunction(iertutil,advadi,"advapi32.dll","RegOpenKeyExW",(PROC)HookRegOpenKeyExW);
}
И теперь, код, который выполняет злобную работу по сканированию таблиц адресов импорта DLL и исправлению запрошенной функции (обработка ошибок опущена, чтобы сохранитьразмер кода уменьшен):
void HookApiFunction(HMODULE callingDll, HMODULE calledDll, const char* calledDllName, const char* functionName, PROC newFunction)
{
// Get the pointer to the 'real' function
PROC realFunction = ::GetProcAddress(calledDll,functionName);
// Get the import section of the DLL, using dbghelp.dll's ImageDirectoryEntryToData()
ULONG sz;
PIMAGE_IMPORT_DESCRIPTOR import = (PIMAGE_IMPORT_DESCRIPTOR)
ImageDirectoryEntryToData(callingDll,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&sz);
// Find the import section matching the named DLL
while (import->Name)
{
PSTR dllName = (PSTR)((PBYTE)callingDll + import->Name);
{
if (stricmp(dllName,calledDllName) == 0)
break;
}
import++;
}
if (import->Name == NULL)
return;
// Scan the IAT for this DLL
PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)((PBYTE)callingDll + import->FirstThunk);
while (thunk->u1.Function)
{
PROC* function = (PROC*)&(thunk->u1.Function);
if (*function == realFunction)
{
// Make the function pointer writable and hook the function
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(function,&mbi,sizeof mbi);
if (::VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_READWRITE,&mbi.Protect))
{
*function = newFunction;
DWORD protect;
::VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&protect);
return;
}
}
thunk++;
}
Наконец, функция, которую я пропатчил DLL для вызова в моем коде, вместо RegOpenKeyExW ():
LONG WINAPI HookRegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
{
static const wchar_t* ieKey = L"Software\\Microsoft\\Internet Explorer";
// Never redirect any of the FeatureControl settings
if (wcsstr(lpSubKey,L"FeatureControl") != NULL)
return ::RegOpenKeyExW(hKey,lpSubKey,ulOptions,samDesired,phkResult);
if (wcsnicmp(lpSubKey,ieKey,wcslen(ieKey)) == 0)
{
// Redirect the IE settings to our registry key
CStringW newSubKey(m_registryPath);
newSubKey.Append(lpSubKey+wcslen(ieKey));
return ::RegOpenKeyExW(hKey,newSubKey,ulOptions,samDesired,phkResult);
}
else
return ::RegOpenKeyExW(hKey,lpSubKey,ulOptions,samDesired,phkResult);
}
Удивительно, но этоужасный хак на самом деле работает.Но, пожалуйста, Microsoft, если вы слушаете, пожалуйста, исправьте это правильно в IE10.