2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "WebKitDLL.h"
29 #include "autoversion.h"
30 #include "ForEachCoClass.h"
31 #include "ProgIDMacros.h"
34 #include "WebKitClassFactory.h"
35 #include "WebScriptDebugServer.h"
36 #pragma warning( push, 0 )
37 #include <WebCore/COMPtr.h>
38 #include <WebCore/IconDatabase.h>
39 #include <WebCore/Page.h>
40 #include <WebCore/PageGroup.h>
41 #include <WebCore/SharedBuffer.h>
42 #include <WebCore/Widget.h>
43 #include <wtf/Vector.h>
52 #define CLSID_FOR_CLASS(cls) CLSID_##cls,
53 static CLSID gRegCLSIDs[] = {
54 FOR_EACH_COCLASS(CLSID_FOR_CLASS)
56 #undef CLSID_FOR_CLASS
60 WebCore::iconDatabase()->close();
61 WebCore::PageGroup::closeLocalStorage();
64 STDAPI_(BOOL) DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
66 switch (ul_reason_for_call) {
67 case DLL_PROCESS_ATTACH:
68 gLockCount = gClassCount = 0;
70 WebCore::Page::setInstanceHandle(hModule);
73 case DLL_PROCESS_DETACH:
77 case DLL_THREAD_ATTACH:
78 case DLL_THREAD_DETACH:
84 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
87 for (int i = 0; i < ARRAYSIZE(gRegCLSIDs); i++) {
88 if (IsEqualGUID(rclsid, gRegCLSIDs[i])) {
96 if (!IsEqualGUID(riid, IID_IUnknown) && !IsEqualGUID(riid, IID_IClassFactory))
99 WebKitClassFactory* factory = new WebKitClassFactory(rclsid);
100 *ppv = reinterpret_cast<LPVOID>(factory);
102 return E_OUTOFMEMORY;
108 STDAPI DllCanUnloadNow(void)
110 if (!gClassCount && !gLockCount)
117 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_PRODUCTION_PROGID(className)
119 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_OPENSOURCE_PROGID(className)
121 #define CURRENT_VERSIONED_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), CURRENT_PROGID_VERSION)
122 #define VERSIONED_303_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), 3)
124 // FIXME: The last line of this macro only here for the benefit of Safari 3.0.3. Once a newer version
125 // is released, the last line should be removed and gSlotsPerEntry should be decremented by 1.
126 //key value name value }
127 #define KEYS_FOR_CLASS(cls) \
128 { TEXT("CLSID\\{########-####-####-####-############}"), 0, TEXT(#cls) }, \
129 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), 0, (LPCTSTR)-1 }, \
130 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), TEXT("ThreadingModel"), TEXT("Apartment") }, \
131 { TEXT("CLSID\\{########-####-####-####-############}\\ProgID"), 0, CURRENT_VERSIONED_PROGID(cls) }, \
132 { CURRENT_VERSIONED_PROGID(cls), 0, TEXT(#cls) }, \
133 { CURRENT_VERSIONED_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
134 { TEXT("CLSID\\{########-####-####-####-############}\\VersionIndependentProgID"), 0, VERSION_INDEPENDENT_PROGID(cls) }, \
135 { VERSION_INDEPENDENT_PROGID(cls), 0, TEXT(#cls) }, \
136 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
137 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CurVer"), 0, STRINGIFIED_VERSION(CURRENT_PROGID_VERSION) }, \
138 { VERSIONED_303_PROGID(cls), 0, TEXT(#cls) }, \
139 { VERSIONED_303_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
142 static const int gSlotsPerEntry = 12;
143 static LPCTSTR gRegTable[][3] = {
144 FOR_EACH_COCLASS(KEYS_FOR_CLASS)
146 #undef KEYS_FOR_CLASS
148 static void substituteGUID(LPTSTR str, const UUID* guid)
153 TCHAR uuidString[40];
154 _stprintf_s(uuidString, ARRAYSIZE(uuidString), TEXT("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"), guid->Data1, guid->Data2, guid->Data3,
155 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
157 LPCTSTR guidPattern = TEXT("########-####-####-####-############");
158 size_t patternLength = _tcslen(guidPattern);
159 size_t strLength = _tcslen(str);
160 LPTSTR guidSubStr = str;
162 guidSubStr = _tcsstr(guidSubStr, guidPattern);
165 _tcsncpy(guidSubStr, uuidString, patternLength);
166 guidSubStr += patternLength;
167 strLength -= (guidSubStr - str);
171 STDAPI DllUnregisterServer(void)
177 const GUID libID = LIBID_WebKit;
179 const GUID libID = LIBID_OpenSourceWebKit;
182 typedef HRESULT (WINAPI *UnRegisterTypeLibForUserPtr)(REFGUID, unsigned short, unsigned short, LCID, SYSKIND);
183 if (UnRegisterTypeLibForUserPtr unRegisterTypeLibForUser = reinterpret_cast<UnRegisterTypeLibForUserPtr>(GetProcAddress(GetModuleHandle(TEXT("oleaut32.dll")), "UnRegisterTypeLibForUser")))
184 unRegisterTypeLibForUser(libID, __BUILD_NUMBER_MAJOR__, __BUILD_NUMBER_MINOR__, 0, SYS_WIN32);
186 UnRegisterTypeLib(libID, __BUILD_NUMBER_MAJOR__, __BUILD_NUMBER_MINOR__, 0, SYS_WIN32);
188 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS)
191 int nEntries = ARRAYSIZE(gRegTable);
192 for (int i = nEntries - 1; i >= 0; i--) {
193 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]);
195 substituteGUID(pszKeyName, &gRegCLSIDs[i/gSlotsPerEntry]);
196 RegDeleteKey(HKEY_CLASSES_ROOT, pszKeyName);
198 RegDeleteKey(userClasses, pszKeyName);
205 RegCloseKey(userClasses);
209 STDAPI DllRegisterServer(void)
213 // look up server's file name
214 TCHAR szFileName[MAX_PATH];
215 GetModuleFileName(gInstance, szFileName, MAX_PATH);
217 typedef HRESULT (WINAPI *RegisterTypeLibForUserPtr)(ITypeLib*, OLECHAR*, OLECHAR*);
218 COMPtr<ITypeLib> typeLib;
219 LoadTypeLibEx(szFileName, REGKIND_NONE, &typeLib);
220 if (RegisterTypeLibForUserPtr registerTypeLibForUser = reinterpret_cast<RegisterTypeLibForUserPtr>(GetProcAddress(GetModuleHandle(TEXT("oleaut32.dll")), "RegisterTypeLibForUser")))
221 registerTypeLibForUser(typeLib.get(), szFileName, 0);
223 RegisterTypeLib(typeLib.get(), szFileName, 0);
226 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS)
229 // register entries from table
230 int nEntries = ARRAYSIZE(gRegTable);
231 for (int i = 0; SUCCEEDED(hr) && i < nEntries; i++) {
232 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]);
233 LPTSTR pszValueName = gRegTable[i][1] ? _tcsdup(gRegTable[i][1]) : 0;
234 LPTSTR allocatedValue = (gRegTable[i][2] != (LPTSTR)-1) ? _tcsdup(gRegTable[i][2]) : (LPTSTR)-1;
235 LPTSTR pszValue = allocatedValue;
237 if (pszKeyName && pszValue) {
239 int clsidIndex = i/gSlotsPerEntry;
240 substituteGUID(pszKeyName, &gRegCLSIDs[clsidIndex]);
241 substituteGUID(pszValueName, &gRegCLSIDs[clsidIndex]);
243 // map rogue value to module file name
244 if (pszValue == (LPTSTR)-1)
245 pszValue = szFileName;
247 substituteGUID(pszValue, &gRegCLSIDs[clsidIndex]);
251 LONG err = RegCreateKey(HKEY_CLASSES_ROOT, pszKeyName, &hkey);
252 if (err != ERROR_SUCCESS && userClasses)
253 err = RegCreateKey(userClasses, pszKeyName, &hkey);
254 if (err == ERROR_SUCCESS) {
256 err = RegSetValueEx(hkey, pszValueName, 0, REG_SZ, (const BYTE*)pszValue, (DWORD) sizeof(pszValue[0])*(_tcslen(pszValue) + 1));
264 if (allocatedValue && allocatedValue != (LPTSTR)-1)
265 free(allocatedValue);
269 RegCloseKey(userClasses);
274 STDAPI RunAsLocalServer()
277 COMPtr<IUnknown> classFactory;
278 DllGetClassObject(CLSID_WebScriptDebugServer, IID_IUnknown, (void**)&classFactory);
279 CoRegisterClassObject(CLSID_WebScriptDebugServer, classFactory.get(), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, ®);
283 STDAPI LocalServerDidDie()
285 WebScriptDebugServer::sharedWebScriptDebugServer()->serverDidDie();
289 //FIXME: We should consider moving this to a new file for cross-project functionality
290 PassRefPtr<WebCore::SharedBuffer> loadResourceIntoBuffer(const char* name)
293 // temporary hack to get resource id
294 if (!strcmp(name, "textAreaResizeCorner"))
295 idr = IDR_RESIZE_CORNER;
296 else if (!strcmp(name, "missingImage"))
297 idr = IDR_MISSING_IMAGE;
298 else if (!strcmp(name, "urlIcon"))
300 else if (!strcmp(name, "nullPlugin"))
301 idr = IDR_NULL_PLUGIN;
302 else if (!strcmp(name, "zoomInCursor"))
303 idr = IDR_ZOOM_IN_CURSOR;
304 else if (!strcmp(name, "zoomOutCursor"))
305 idr = IDR_ZOOM_OUT_CURSOR;
306 else if (!strcmp(name, "verticalTextCursor"))
307 idr = IDR_VERTICAL_TEXT_CURSOR;
311 HRSRC resInfo = FindResource(gInstance, MAKEINTRESOURCE(idr), L"PNG");
314 HANDLE res = LoadResource(gInstance, resInfo);
317 void* resource = LockResource(res);
320 int size = SizeofResource(gInstance, resInfo);
322 return WebCore::SharedBuffer::create(reinterpret_cast<const char*>(resource), size);