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 "ForEachCoClass.h"
30 #include "IWebURLResponse.h"
31 #include "ProgIDMacros.h"
33 #include "WebKitClassFactory.h"
35 #pragma warning( push, 0 )
36 #include <WebCore/COMPtr.h>
37 #include <WebCore/IconDatabase.h>
38 #include <WebCore/Page.h>
39 #include <WebCore/SharedBuffer.h>
40 #include <WebCore/Widget.h>
41 #include <wtf/Vector.h>
50 #define CLSID_FOR_CLASS(cls) CLSID_##cls,
51 static CLSID gRegCLSIDs[] = {
52 FOR_EACH_COCLASS(CLSID_FOR_CLASS)
54 #undef CLSID_FOR_CLASS
58 WebCore::iconDatabase()->close();
61 STDAPI_(BOOL) DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
63 switch (ul_reason_for_call) {
64 case DLL_PROCESS_ATTACH:
65 gLockCount = gClassCount = 0;
67 WebCore::Page::setInstanceHandle(hModule);
70 case DLL_PROCESS_DETACH:
74 case DLL_THREAD_ATTACH:
75 case DLL_THREAD_DETACH:
81 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
84 for (int i = 0; i < ARRAYSIZE(gRegCLSIDs); i++) {
85 if (IsEqualGUID(rclsid, gRegCLSIDs[i])) {
93 if (!IsEqualGUID(riid, IID_IUnknown) && !IsEqualGUID(riid, IID_IClassFactory))
96 WebKitClassFactory* factory = new WebKitClassFactory(rclsid);
97 *ppv = reinterpret_cast<LPVOID>(factory);
105 STDAPI DllCanUnloadNow(void)
107 if (!gClassCount && !gLockCount)
114 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_PRODUCTION_PROGID(className)
116 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_OPENSOURCE_PROGID(className)
118 #define CURRENT_VERSIONED_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), CURRENT_PROGID_VERSION)
119 #define VERSIONED_303_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), 3)
121 // FIXME: The last line of this macro only here for the benefit of Safari 3.0.3. Once a newer version
122 // is released, the last line should be removed and gSlotsPerEntry should be decremented by 1.
123 //key value name value }
124 #define KEYS_FOR_CLASS(cls) \
125 { TEXT("CLSID\\{########-####-####-####-############}"), 0, TEXT(#cls) }, \
126 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), 0, (LPCTSTR)-1 }, \
127 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), TEXT("ThreadingModel"), TEXT("Apartment") }, \
128 { TEXT("CLSID\\{########-####-####-####-############}\\ProgID"), 0, CURRENT_VERSIONED_PROGID(cls) }, \
129 { CURRENT_VERSIONED_PROGID(cls), 0, TEXT(#cls) }, \
130 { CURRENT_VERSIONED_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
131 { TEXT("CLSID\\{########-####-####-####-############}\\VersionIndependentProgID"), 0, VERSION_INDEPENDENT_PROGID(cls) }, \
132 { VERSION_INDEPENDENT_PROGID(cls), 0, TEXT(#cls) }, \
133 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
134 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CurVer"), 0, STRINGIFIED_VERSION(CURRENT_PROGID_VERSION) }, \
135 { VERSIONED_303_PROGID(cls), 0, TEXT(#cls) }, \
136 { VERSIONED_303_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \
139 static const int gSlotsPerEntry = 12;
140 static LPCTSTR gRegTable[][3] = {
141 FOR_EACH_COCLASS(KEYS_FOR_CLASS)
143 #undef KEYS_FOR_CLASS
145 static void substituteGUID(LPTSTR str, const UUID* guid)
150 TCHAR uuidString[40];
151 _stprintf_s(uuidString, ARRAYSIZE(uuidString), TEXT("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"), guid->Data1, guid->Data2, guid->Data3,
152 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
154 LPCTSTR guidPattern = TEXT("########-####-####-####-############");
155 size_t patternLength = _tcslen(guidPattern);
156 size_t strLength = _tcslen(str);
157 LPTSTR guidSubStr = str;
159 guidSubStr = _tcsstr(guidSubStr, guidPattern);
162 _tcsncpy(guidSubStr, uuidString, patternLength);
163 guidSubStr += patternLength;
164 strLength -= (guidSubStr - str);
168 STDAPI DllUnregisterServer(void)
174 UnRegisterTypeLib(LIBID_WebKit, 3, 0, 0, SYS_WIN32);
176 UnRegisterTypeLib(LIBID_OpenSourceWebKit, 3, 0, 0, SYS_WIN32);
179 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS)
182 int nEntries = ARRAYSIZE(gRegTable);
183 for (int i = nEntries - 1; i >= 0; i--) {
184 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]);
186 substituteGUID(pszKeyName, &gRegCLSIDs[i/gSlotsPerEntry]);
187 RegDeleteKey(HKEY_CLASSES_ROOT, pszKeyName);
189 RegDeleteKey(userClasses, pszKeyName);
196 RegCloseKey(userClasses);
200 STDAPI DllRegisterServer(void)
204 // look up server's file name
205 TCHAR szFileName[MAX_PATH];
206 GetModuleFileName(gInstance, szFileName, MAX_PATH);
208 COMPtr<ITypeLib> typeLib;
209 LoadTypeLibEx(szFileName, REGKIND_REGISTER, &typeLib);
212 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS)
215 // register entries from table
216 int nEntries = ARRAYSIZE(gRegTable);
217 for (int i = 0; SUCCEEDED(hr) && i < nEntries; i++) {
218 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]);
219 LPTSTR pszValueName = gRegTable[i][1] ? _tcsdup(gRegTable[i][1]) : 0;
220 LPTSTR allocatedValue = (gRegTable[i][2] != (LPTSTR)-1) ? _tcsdup(gRegTable[i][2]) : (LPTSTR)-1;
221 LPTSTR pszValue = allocatedValue;
223 if (pszKeyName && pszValue) {
225 int clsidIndex = i/gSlotsPerEntry;
226 substituteGUID(pszKeyName, &gRegCLSIDs[clsidIndex]);
227 substituteGUID(pszValueName, &gRegCLSIDs[clsidIndex]);
229 // map rogue value to module file name
230 if (pszValue == (LPTSTR)-1)
231 pszValue = szFileName;
233 substituteGUID(pszValue, &gRegCLSIDs[clsidIndex]);
237 LONG err = RegCreateKey(HKEY_CLASSES_ROOT, pszKeyName, &hkey);
238 if (err != ERROR_SUCCESS && userClasses)
239 err = RegCreateKey(userClasses, pszKeyName, &hkey);
240 if (err == ERROR_SUCCESS) {
242 err = RegSetValueEx(hkey, pszValueName, 0, REG_SZ, (const BYTE*)pszValue, (DWORD) sizeof(pszValue[0])*(_tcslen(pszValue) + 1));
250 if (allocatedValue && allocatedValue != (LPTSTR)-1)
251 free(allocatedValue);
255 RegCloseKey(userClasses);
260 STDAPI RunAsLocalServer(void)
263 COMPtr<IUnknown> classFactory;
264 DllGetClassObject(CLSID_WebDebugProgram, IID_IUnknown, (void**)&classFactory);
265 CoRegisterClassObject(CLSID_WebDebugProgram, classFactory.get(), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, ®);
269 //FIXME: We should consider moving this to a new file for cross-project functionality
270 PassRefPtr<WebCore::SharedBuffer> loadResourceIntoBuffer(const char* name)
273 // temporary hack to get resource id
274 if (!strcmp(name, "textAreaResizeCorner"))
275 idr = IDR_RESIZE_CORNER;
276 else if (!strcmp(name, "missingImage"))
277 idr = IDR_MISSING_IMAGE;
278 else if (!strcmp(name, "urlIcon"))
280 else if (!strcmp(name, "nullPlugin"))
281 idr = IDR_NULL_PLUGIN;
282 else if (!strcmp(name, "zoomInCursor"))
283 idr = IDR_ZOOM_IN_CURSOR;
284 else if (!strcmp(name, "zoomOutCursor"))
285 idr = IDR_ZOOM_OUT_CURSOR;
286 else if (!strcmp(name, "verticalTextCursor"))
287 idr = IDR_VERTICAL_TEXT_CURSOR;
291 HRSRC resInfo = FindResource(gInstance, MAKEINTRESOURCE(idr), L"PNG");
294 HANDLE res = LoadResource(gInstance, resInfo);
297 void* resource = LockResource(res);
300 int size = SizeofResource(gInstance, resInfo);
302 return new WebCore::SharedBuffer(reinterpret_cast<const char*>(resource), size);