diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/win/WebKitDLL.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/win/WebKitDLL.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebKitDLL.h" + +#include "IWebURLResponse.h" +#include "ProgIDMacros.h" +#include "WebKit.h" +#include "WebKitClassFactory.h" +#include "resource.h" +#pragma warning( push, 0 ) +#include +#include +#include +#include +#include +#include +#pragma warning(pop) +#include +#include + +ULONG gLockCount; +ULONG gClassCount; +HINSTANCE gInstance; + +#define FOR_EACH_CLASS(macro) \ + macro(CFDictionaryPropertyBag) \ + macro(WebCache) \ + macro(WebDebugProgram) \ + macro(WebDownload) \ + macro(WebError) \ + macro(WebHistory) \ + macro(WebHistoryItem) \ + macro(WebIconDatabase) \ + macro(WebJavaScriptCollector) \ + macro(WebKitStatistics) \ + macro(WebMutableURLRequest) \ + macro(WebNotificationCenter) \ + macro(WebPreferences) \ + macro(WebScrollBar) \ + macro(WebURLCredential) \ + macro(WebURLProtectionSpace) \ + macro(WebURLRequest) \ + macro(WebURLResponse) \ + macro(WebView) + +#define CLSID_FOR_CLASS(cls) CLSID_##cls, + +static CLSID gRegCLSIDs[] = { + FOR_EACH_CLASS(CLSID_FOR_CLASS) +}; + +void shutDownWebKit() +{ + WebCore::iconDatabase()->close(); +} + +STDAPI_(BOOL) DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) +{ + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + gLockCount = gClassCount = 0; + gInstance = hModule; + WebCore::Page::setInstanceHandle(hModule); + return TRUE; + + case DLL_PROCESS_DETACH: + shutDownWebKit(); + break; + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + } + return FALSE; +} + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + bool found = false; + for (int i = 0; i < ARRAYSIZE(gRegCLSIDs); i++) { + if (IsEqualGUID(rclsid, gRegCLSIDs[i])) { + found = true; + break; + } + } + if (!found) + return E_FAIL; + + if (!IsEqualGUID(riid, IID_IUnknown) && !IsEqualGUID(riid, IID_IClassFactory)) + return E_NOINTERFACE; + + WebKitClassFactory* factory = new WebKitClassFactory(rclsid); + *ppv = reinterpret_cast(factory); + if (!factory) + return E_OUTOFMEMORY; + + factory->AddRef(); + return S_OK; +} + +STDAPI DllCanUnloadNow(void) +{ + if (!gClassCount && !gLockCount) + return S_OK; + + return S_FALSE; +} + +#if __BUILDBOT__ +#define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_PRODUCTION_PROGID(className) +#else +#define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_OPENSOURCE_PROGID(className) +#endif +#define CURRENT_VERSIONED_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), CURRENT_PROGID_VERSION) +#define VERSIONED_303_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), 3) + +// FIXME: The last line of this macro only here for the benefit of Safari 3.0.3. Once a newer version +// is released, the last line should be removed and gSlotsPerEntry should be decremented by 1. +//key value name value } +#define KEYS_FOR_CLASS(cls) \ +{ TEXT("CLSID\\{########-####-####-####-############}"), 0, TEXT(#cls) }, \ +{ TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), 0, (LPCTSTR)-1 }, \ +{ TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), TEXT("ThreadingModel"), TEXT("Apartment") }, \ +{ TEXT("CLSID\\{########-####-####-####-############}\\ProgID"), 0, CURRENT_VERSIONED_PROGID(cls) }, \ +{ CURRENT_VERSIONED_PROGID(cls), 0, TEXT(#cls) }, \ +{ CURRENT_VERSIONED_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \ +{ TEXT("CLSID\\{########-####-####-####-############}\\VersionIndependentProgID"), 0, VERSION_INDEPENDENT_PROGID(cls) }, \ +{ VERSION_INDEPENDENT_PROGID(cls), 0, TEXT(#cls) }, \ +{ VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \ +{ VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CurVer"), 0, STRINGIFIED_VERSION(CURRENT_PROGID_VERSION) }, \ +{ VERSIONED_303_PROGID(cls), 0, TEXT(#cls) }, \ +{ VERSIONED_303_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \ +// end of macro + +static const int gSlotsPerEntry = 12; +static LPCTSTR gRegTable[][3] = { + FOR_EACH_CLASS(KEYS_FOR_CLASS) +}; + +static void substituteGUID(LPTSTR str, const UUID* guid) +{ + if (!guid || !str) + return; + + TCHAR uuidString[40]; + _stprintf_s(uuidString, ARRAYSIZE(uuidString), TEXT("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"), guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); + + LPCTSTR guidPattern = TEXT("########-####-####-####-############"); + size_t patternLength = _tcslen(guidPattern); + size_t strLength = _tcslen(str); + LPTSTR guidSubStr = str; + while (strLength) { + guidSubStr = _tcsstr(guidSubStr, guidPattern); + if (!guidSubStr) + break; + _tcsncpy(guidSubStr, uuidString, patternLength); + guidSubStr += patternLength; + strLength -= (guidSubStr - str); + } +} + +STDAPI DllUnregisterServer(void) +{ + HRESULT hr = S_OK; + HKEY userClasses; + +#if __BUILDBOT__ + UnRegisterTypeLib(LIBID_WebKit, 3, 0, 0, SYS_WIN32); +#else + UnRegisterTypeLib(LIBID_OpenSourceWebKit, 3, 0, 0, SYS_WIN32); +#endif + + if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS) + userClasses = 0; + + int nEntries = ARRAYSIZE(gRegTable); + for (int i = nEntries - 1; i >= 0; i--) { + LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]); + if (pszKeyName) { + substituteGUID(pszKeyName, &gRegCLSIDs[i/gSlotsPerEntry]); + RegDeleteKey(HKEY_CLASSES_ROOT, pszKeyName); + if (userClasses) + RegDeleteKey(userClasses, pszKeyName); + free(pszKeyName); + } else + hr = E_OUTOFMEMORY; + } + + if (userClasses) + RegCloseKey(userClasses); + return hr; +} + +STDAPI DllRegisterServer(void) +{ + HRESULT hr = S_OK; + + // look up server's file name + TCHAR szFileName[MAX_PATH]; + GetModuleFileName(gInstance, szFileName, MAX_PATH); + + COMPtr typeLib; + LoadTypeLibEx(szFileName, REGKIND_REGISTER, &typeLib); + + HKEY userClasses; + if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS) + userClasses = 0; + + // register entries from table + int nEntries = ARRAYSIZE(gRegTable); + for (int i = 0; SUCCEEDED(hr) && i < nEntries; i++) { + LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]); + LPTSTR pszValueName = gRegTable[i][1] ? _tcsdup(gRegTable[i][1]) : 0; + LPTSTR allocatedValue = (gRegTable[i][2] != (LPTSTR)-1) ? _tcsdup(gRegTable[i][2]) : (LPTSTR)-1; + LPTSTR pszValue = allocatedValue; + + if (pszKeyName && pszValue) { + + int clsidIndex = i/gSlotsPerEntry; + substituteGUID(pszKeyName, &gRegCLSIDs[clsidIndex]); + substituteGUID(pszValueName, &gRegCLSIDs[clsidIndex]); + + // map rogue value to module file name + if (pszValue == (LPTSTR)-1) + pszValue = szFileName; + else + substituteGUID(pszValue, &gRegCLSIDs[clsidIndex]); + + // create the key + HKEY hkey; + LONG err = RegCreateKey(HKEY_CLASSES_ROOT, pszKeyName, &hkey); + if (err != ERROR_SUCCESS && userClasses) + err = RegCreateKey(userClasses, pszKeyName, &hkey); + if (err == ERROR_SUCCESS) { + // set the value + err = RegSetValueEx(hkey, pszValueName, 0, REG_SZ, (const BYTE*)pszValue, (DWORD) sizeof(pszValue[0])*(_tcslen(pszValue) + 1)); + RegCloseKey(hkey); + } + } + if (pszKeyName) + free(pszKeyName); + if (pszValueName) + free(pszValueName); + if (allocatedValue && allocatedValue != (LPTSTR)-1) + free(allocatedValue); + } + + if (userClasses) + RegCloseKey(userClasses); + + return hr; +} + +STDAPI RunAsLocalServer(void) +{ + DWORD reg; + COMPtr classFactory; + DllGetClassObject(CLSID_WebDebugProgram, IID_IUnknown, (void**)&classFactory); + CoRegisterClassObject(CLSID_WebDebugProgram, classFactory.get(), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, ®); + return 0; +} + +//FIXME: We should consider moving this to a new file for cross-project functionality +PassRefPtr loadResourceIntoBuffer(const char* name) +{ + int idr; + // temporary hack to get resource id + if (!strcmp(name, "textAreaResizeCorner")) + idr = IDR_RESIZE_CORNER; + else if (!strcmp(name, "missingImage")) + idr = IDR_MISSING_IMAGE; + else if (!strcmp(name, "urlIcon")) + idr = IDR_URL_ICON; + else if (!strcmp(name, "nullPlugin")) + idr = IDR_NULL_PLUGIN; + else if (!strcmp(name, "zoomInCursor")) + idr = IDR_ZOOM_IN_CURSOR; + else if (!strcmp(name, "zoomOutCursor")) + idr = IDR_ZOOM_OUT_CURSOR; + else if (!strcmp(name, "verticalTextCursor")) + idr = IDR_VERTICAL_TEXT_CURSOR; + else + return 0; + + HRSRC resInfo = FindResource(gInstance, MAKEINTRESOURCE(idr), L"PNG"); + if (!resInfo) + return 0; + HANDLE res = LoadResource(gInstance, resInfo); + if (!res) + return 0; + void* resource = LockResource(res); + if (!resource) + return 0; + int size = SizeofResource(gInstance, resInfo); + + return new WebCore::SharedBuffer(reinterpret_cast(resource), size); +}