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/SharedBuffer.h>
41 #include <WebCore/Widget.h>
42 #include <wtf/Vector.h>
51 #define CLSID_FOR_CLASS(cls) CLSID_##cls,
52 static CLSID gRegCLSIDs[] = {
53 FOR_EACH_COCLASS(CLSID_FOR_CLASS)
55 #undef CLSID_FOR_CLASS
59 WebCore::iconDatabase()->close();
62 STDAPI_(BOOL) DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
64 switch (ul_reason_for_call) {
65 case DLL_PROCESS_ATTACH:
66 gLockCount = gClassCount = 0;
68 WebCore::Page::setInstanceHandle(hModule);
71 case DLL_PROCESS_DETACH:
75 case DLL_THREAD_ATTACH:
76 case DLL_THREAD_DETACH:
82 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
85 for (int i = 0; i < ARRAYSIZE(gRegCLSIDs); i++) {
86 if (IsEqualGUID(rclsid, gRegCLSIDs[i])) {
94 if (!IsEqualGUID(riid, IID_IUnknown) && !IsEqualGUID(riid, IID_IClassFactory))
97 WebKitClassFactory* factory = new WebKitClassFactory(rclsid);
98 *ppv = reinterpret_cast<LPVOID>(factory);
100 return E_OUTOFMEMORY;
106 STDAPI DllCanUnloadNow(void)
108 if (!gClassCount && !gLockCount)
115 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_PRODUCTION_PROGID(className)
117 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_OPENSOURCE_PROGID(className)
119 #define CURRENT_VERSIONED_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), CURRENT_PROGID_VERSION)
120 #define VERSIONED_303_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), 3)
122 // FIXME: The last line of this macro only here for the benefit of Safari 3.0.3. Once a newer version
123 // is released, the last line should be removed and gSlotsPerEntry should be decremented by 1.
124 //key value name value }
125 #define KEYS_FOR_CLASS(cls) \
126 { TEXT("CLSID\\{########-####-####-####-############}"), 0, TEXT(#cls) }, \
127 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), 0, (LPCTSTR)-1 }, \
128 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), TEXT("ThreadingModel"), TEXT("Apartment") }, \
129 { TEXT("CLSID\\{########-####-####-####-############}\\ProgID"), 0, CURRENT_VERSIONED_PROGID(cls) }, \
130 { CURRENT_VERSIONED_PROGID(cls), 0, TEXT(#cls) }, \
131 { CURRENT_VERSIONED_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
132 { TEXT("CLSID\\{########-####-####-####-############}\\VersionIndependentProgID"), 0, VERSION_INDEPENDENT_PROGID(cls) }, \
133 { VERSION_INDEPENDENT_PROGID(cls), 0, TEXT(#cls) }, \
134 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
135 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CurVer"), 0, STRINGIFIED_VERSION(CURRENT_PROGID_VERSION) }, \
136 { VERSIONED_303_PROGID(cls), 0, TEXT(#cls) }, \
137 { VERSIONED_303_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
140 static const int gSlotsPerEntry = 12;
141 static LPCTSTR gRegTable[][3] = {
142 FOR_EACH_COCLASS(KEYS_FOR_CLASS)
144 #undef KEYS_FOR_CLASS
146 static void substituteGUID(LPTSTR str, const UUID* guid)
151 TCHAR uuidString[40];
152 _stprintf_s(uuidString, ARRAYSIZE(uuidString), TEXT("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"), guid->Data1, guid->Data2, guid->Data3,
153 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
155 LPCTSTR guidPattern = TEXT("########-####-####-####-############");
156 size_t patternLength = _tcslen(guidPattern);
157 size_t strLength = _tcslen(str);
158 LPTSTR guidSubStr = str;
160 guidSubStr = _tcsstr(guidSubStr, guidPattern);
163 _tcsncpy(guidSubStr, uuidString, patternLength);
164 guidSubStr += patternLength;
165 strLength -= (guidSubStr - str);
169 STDAPI DllUnregisterServer(void)
175 const GUID libID = LIBID_WebKit;
177 const GUID libID = LIBID_OpenSourceWebKit;
180 typedef HRESULT (WINAPI *UnRegisterTypeLibForUserPtr)(REFGUID, unsigned short, unsigned short, LCID, SYSKIND);
181 if (UnRegisterTypeLibForUserPtr unRegisterTypeLibForUser = reinterpret_cast<UnRegisterTypeLibForUserPtr>(GetProcAddress(GetModuleHandle(TEXT("oleaut32.dll")), "UnRegisterTypeLibForUser")))
182 unRegisterTypeLibForUser(libID, __BUILD_NUMBER_MAJOR__, __BUILD_NUMBER_MINOR__, 0, SYS_WIN32);
184 UnRegisterTypeLib(libID, __BUILD_NUMBER_MAJOR__, __BUILD_NUMBER_MINOR__, 0, SYS_WIN32);
186 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS)
189 int nEntries = ARRAYSIZE(gRegTable);
190 for (int i = nEntries - 1; i >= 0; i--) {
191 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]);
193 substituteGUID(pszKeyName, &gRegCLSIDs[i/gSlotsPerEntry]);
194 RegDeleteKey(HKEY_CLASSES_ROOT, pszKeyName);
196 RegDeleteKey(userClasses, pszKeyName);
203 RegCloseKey(userClasses);
207 STDAPI DllRegisterServer(void)
211 // look up server's file name
212 TCHAR szFileName[MAX_PATH];
213 GetModuleFileName(gInstance, szFileName, MAX_PATH);
215 typedef HRESULT (WINAPI *RegisterTypeLibForUserPtr)(ITypeLib*, OLECHAR*, OLECHAR*);
216 COMPtr<ITypeLib> typeLib;
217 LoadTypeLibEx(szFileName, REGKIND_NONE, &typeLib);
218 if (RegisterTypeLibForUserPtr registerTypeLibForUser = reinterpret_cast<RegisterTypeLibForUserPtr>(GetProcAddress(GetModuleHandle(TEXT("oleaut32.dll")), "RegisterTypeLibForUser")))
219 registerTypeLibForUser(typeLib.get(), szFileName, 0);
221 RegisterTypeLib(typeLib.get(), szFileName, 0);
224 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS)
227 // register entries from table
228 int nEntries = ARRAYSIZE(gRegTable);
229 for (int i = 0; SUCCEEDED(hr) && i < nEntries; i++) {
230 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]);
231 LPTSTR pszValueName = gRegTable[i][1] ? _tcsdup(gRegTable[i][1]) : 0;
232 LPTSTR allocatedValue = (gRegTable[i][2] != (LPTSTR)-1) ? _tcsdup(gRegTable[i][2]) : (LPTSTR)-1;
233 LPTSTR pszValue = allocatedValue;
235 if (pszKeyName && pszValue) {
237 int clsidIndex = i/gSlotsPerEntry;
238 substituteGUID(pszKeyName, &gRegCLSIDs[clsidIndex]);
239 substituteGUID(pszValueName, &gRegCLSIDs[clsidIndex]);
241 // map rogue value to module file name
242 if (pszValue == (LPTSTR)-1)
243 pszValue = szFileName;
245 substituteGUID(pszValue, &gRegCLSIDs[clsidIndex]);
249 LONG err = RegCreateKey(HKEY_CLASSES_ROOT, pszKeyName, &hkey);
250 if (err != ERROR_SUCCESS && userClasses)
251 err = RegCreateKey(userClasses, pszKeyName, &hkey);
252 if (err == ERROR_SUCCESS) {
254 err = RegSetValueEx(hkey, pszValueName, 0, REG_SZ, (const BYTE*)pszValue, (DWORD) sizeof(pszValue[0])*(_tcslen(pszValue) + 1));
262 if (allocatedValue && allocatedValue != (LPTSTR)-1)
263 free(allocatedValue);
267 RegCloseKey(userClasses);
272 STDAPI RunAsLocalServer()
275 COMPtr<IUnknown> classFactory;
276 DllGetClassObject(CLSID_WebScriptDebugServer, IID_IUnknown, (void**)&classFactory);
277 CoRegisterClassObject(CLSID_WebScriptDebugServer, classFactory.get(), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, ®);
281 STDAPI LocalServerDidDie()
283 WebScriptDebugServer::sharedWebScriptDebugServer()->serverDidDie();
287 //FIXME: We should consider moving this to a new file for cross-project functionality
288 PassRefPtr<WebCore::SharedBuffer> loadResourceIntoBuffer(const char* name)
291 // temporary hack to get resource id
292 if (!strcmp(name, "textAreaResizeCorner"))
293 idr = IDR_RESIZE_CORNER;
294 else if (!strcmp(name, "missingImage"))
295 idr = IDR_MISSING_IMAGE;
296 else if (!strcmp(name, "urlIcon"))
298 else if (!strcmp(name, "nullPlugin"))
299 idr = IDR_NULL_PLUGIN;
300 else if (!strcmp(name, "zoomInCursor"))
301 idr = IDR_ZOOM_IN_CURSOR;
302 else if (!strcmp(name, "zoomOutCursor"))
303 idr = IDR_ZOOM_OUT_CURSOR;
304 else if (!strcmp(name, "verticalTextCursor"))
305 idr = IDR_VERTICAL_TEXT_CURSOR;
309 HRSRC resInfo = FindResource(gInstance, MAKEINTRESOURCE(idr), L"PNG");
312 HANDLE res = LoadResource(gInstance, resInfo);
315 void* resource = LockResource(res);
318 int size = SizeofResource(gInstance, resInfo);
320 return WebCore::SharedBuffer::create(reinterpret_cast<const char*>(resource), size);