|
1 /* |
|
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
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. |
|
12 * |
|
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. |
|
24 */ |
|
25 |
|
26 #include "config.h" |
|
27 #include "WebKitDLL.h" |
|
28 |
|
29 #include "IWebURLResponse.h" |
|
30 #include "ProgIDMacros.h" |
|
31 #include "WebKit.h" |
|
32 #include "WebKitClassFactory.h" |
|
33 #include "resource.h" |
|
34 #pragma warning( push, 0 ) |
|
35 #include <WebCore/COMPtr.h> |
|
36 #include <WebCore/IconDatabase.h> |
|
37 #include <WebCore/Page.h> |
|
38 #include <WebCore/SharedBuffer.h> |
|
39 #include <WebCore/Widget.h> |
|
40 #include <wtf/Vector.h> |
|
41 #pragma warning(pop) |
|
42 #include <tchar.h> |
|
43 #include <olectl.h> |
|
44 |
|
45 ULONG gLockCount; |
|
46 ULONG gClassCount; |
|
47 HINSTANCE gInstance; |
|
48 |
|
49 #define FOR_EACH_CLASS(macro) \ |
|
50 macro(CFDictionaryPropertyBag) \ |
|
51 macro(WebCache) \ |
|
52 macro(WebDebugProgram) \ |
|
53 macro(WebDownload) \ |
|
54 macro(WebError) \ |
|
55 macro(WebHistory) \ |
|
56 macro(WebHistoryItem) \ |
|
57 macro(WebIconDatabase) \ |
|
58 macro(WebJavaScriptCollector) \ |
|
59 macro(WebKitStatistics) \ |
|
60 macro(WebMutableURLRequest) \ |
|
61 macro(WebNotificationCenter) \ |
|
62 macro(WebPreferences) \ |
|
63 macro(WebScrollBar) \ |
|
64 macro(WebURLCredential) \ |
|
65 macro(WebURLProtectionSpace) \ |
|
66 macro(WebURLRequest) \ |
|
67 macro(WebURLResponse) \ |
|
68 macro(WebView) |
|
69 |
|
70 #define CLSID_FOR_CLASS(cls) CLSID_##cls, |
|
71 |
|
72 static CLSID gRegCLSIDs[] = { |
|
73 FOR_EACH_CLASS(CLSID_FOR_CLASS) |
|
74 }; |
|
75 |
|
76 void shutDownWebKit() |
|
77 { |
|
78 WebCore::iconDatabase()->close(); |
|
79 } |
|
80 |
|
81 STDAPI_(BOOL) DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) |
|
82 { |
|
83 switch (ul_reason_for_call) { |
|
84 case DLL_PROCESS_ATTACH: |
|
85 gLockCount = gClassCount = 0; |
|
86 gInstance = hModule; |
|
87 WebCore::Page::setInstanceHandle(hModule); |
|
88 return TRUE; |
|
89 |
|
90 case DLL_PROCESS_DETACH: |
|
91 shutDownWebKit(); |
|
92 break; |
|
93 |
|
94 case DLL_THREAD_ATTACH: |
|
95 case DLL_THREAD_DETACH: |
|
96 break; |
|
97 } |
|
98 return FALSE; |
|
99 } |
|
100 |
|
101 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) |
|
102 { |
|
103 bool found = false; |
|
104 for (int i = 0; i < ARRAYSIZE(gRegCLSIDs); i++) { |
|
105 if (IsEqualGUID(rclsid, gRegCLSIDs[i])) { |
|
106 found = true; |
|
107 break; |
|
108 } |
|
109 } |
|
110 if (!found) |
|
111 return E_FAIL; |
|
112 |
|
113 if (!IsEqualGUID(riid, IID_IUnknown) && !IsEqualGUID(riid, IID_IClassFactory)) |
|
114 return E_NOINTERFACE; |
|
115 |
|
116 WebKitClassFactory* factory = new WebKitClassFactory(rclsid); |
|
117 *ppv = reinterpret_cast<LPVOID>(factory); |
|
118 if (!factory) |
|
119 return E_OUTOFMEMORY; |
|
120 |
|
121 factory->AddRef(); |
|
122 return S_OK; |
|
123 } |
|
124 |
|
125 STDAPI DllCanUnloadNow(void) |
|
126 { |
|
127 if (!gClassCount && !gLockCount) |
|
128 return S_OK; |
|
129 |
|
130 return S_FALSE; |
|
131 } |
|
132 |
|
133 #if __BUILDBOT__ |
|
134 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_PRODUCTION_PROGID(className) |
|
135 #else |
|
136 #define VERSION_INDEPENDENT_PROGID(className) VERSION_INDEPENDENT_OPENSOURCE_PROGID(className) |
|
137 #endif |
|
138 #define CURRENT_VERSIONED_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), CURRENT_PROGID_VERSION) |
|
139 #define VERSIONED_303_PROGID(className) VERSIONED_PROGID(VERSION_INDEPENDENT_PROGID(className), 3) |
|
140 |
|
141 // FIXME: The last line of this macro only here for the benefit of Safari 3.0.3. Once a newer version |
|
142 // is released, the last line should be removed and gSlotsPerEntry should be decremented by 1. |
|
143 //key value name value } |
|
144 #define KEYS_FOR_CLASS(cls) \ |
|
145 { TEXT("CLSID\\{########-####-####-####-############}"), 0, TEXT(#cls) }, \ |
|
146 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), 0, (LPCTSTR)-1 }, \ |
|
147 { TEXT("CLSID\\{########-####-####-####-############}\\InprocServer32"), TEXT("ThreadingModel"), TEXT("Apartment") }, \ |
|
148 { TEXT("CLSID\\{########-####-####-####-############}\\ProgID"), 0, CURRENT_VERSIONED_PROGID(cls) }, \ |
|
149 { CURRENT_VERSIONED_PROGID(cls), 0, TEXT(#cls) }, \ |
|
150 { CURRENT_VERSIONED_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \ |
|
151 { TEXT("CLSID\\{########-####-####-####-############}\\VersionIndependentProgID"), 0, VERSION_INDEPENDENT_PROGID(cls) }, \ |
|
152 { VERSION_INDEPENDENT_PROGID(cls), 0, TEXT(#cls) }, \ |
|
153 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \ |
|
154 { VERSION_INDEPENDENT_PROGID(cls) TEXT("\\CurVer"), 0, STRINGIFIED_VERSION(CURRENT_PROGID_VERSION) }, \ |
|
155 { VERSIONED_303_PROGID(cls), 0, TEXT(#cls) }, \ |
|
156 { VERSIONED_303_PROGID(cls) TEXT("\\CLSID"), 0, TEXT("{########-####-####-####-############}") }, \ |
|
157 // end of macro |
|
158 |
|
159 static const int gSlotsPerEntry = 12; |
|
160 static LPCTSTR gRegTable[][3] = { |
|
161 FOR_EACH_CLASS(KEYS_FOR_CLASS) |
|
162 }; |
|
163 |
|
164 static void substituteGUID(LPTSTR str, const UUID* guid) |
|
165 { |
|
166 if (!guid || !str) |
|
167 return; |
|
168 |
|
169 TCHAR uuidString[40]; |
|
170 _stprintf_s(uuidString, ARRAYSIZE(uuidString), TEXT("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"), guid->Data1, guid->Data2, guid->Data3, |
|
171 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); |
|
172 |
|
173 LPCTSTR guidPattern = TEXT("########-####-####-####-############"); |
|
174 size_t patternLength = _tcslen(guidPattern); |
|
175 size_t strLength = _tcslen(str); |
|
176 LPTSTR guidSubStr = str; |
|
177 while (strLength) { |
|
178 guidSubStr = _tcsstr(guidSubStr, guidPattern); |
|
179 if (!guidSubStr) |
|
180 break; |
|
181 _tcsncpy(guidSubStr, uuidString, patternLength); |
|
182 guidSubStr += patternLength; |
|
183 strLength -= (guidSubStr - str); |
|
184 } |
|
185 } |
|
186 |
|
187 STDAPI DllUnregisterServer(void) |
|
188 { |
|
189 HRESULT hr = S_OK; |
|
190 HKEY userClasses; |
|
191 |
|
192 #if __BUILDBOT__ |
|
193 UnRegisterTypeLib(LIBID_WebKit, 3, 0, 0, SYS_WIN32); |
|
194 #else |
|
195 UnRegisterTypeLib(LIBID_OpenSourceWebKit, 3, 0, 0, SYS_WIN32); |
|
196 #endif |
|
197 |
|
198 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS) |
|
199 userClasses = 0; |
|
200 |
|
201 int nEntries = ARRAYSIZE(gRegTable); |
|
202 for (int i = nEntries - 1; i >= 0; i--) { |
|
203 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]); |
|
204 if (pszKeyName) { |
|
205 substituteGUID(pszKeyName, &gRegCLSIDs[i/gSlotsPerEntry]); |
|
206 RegDeleteKey(HKEY_CLASSES_ROOT, pszKeyName); |
|
207 if (userClasses) |
|
208 RegDeleteKey(userClasses, pszKeyName); |
|
209 free(pszKeyName); |
|
210 } else |
|
211 hr = E_OUTOFMEMORY; |
|
212 } |
|
213 |
|
214 if (userClasses) |
|
215 RegCloseKey(userClasses); |
|
216 return hr; |
|
217 } |
|
218 |
|
219 STDAPI DllRegisterServer(void) |
|
220 { |
|
221 HRESULT hr = S_OK; |
|
222 |
|
223 // look up server's file name |
|
224 TCHAR szFileName[MAX_PATH]; |
|
225 GetModuleFileName(gInstance, szFileName, MAX_PATH); |
|
226 |
|
227 COMPtr<ITypeLib> typeLib; |
|
228 LoadTypeLibEx(szFileName, REGKIND_REGISTER, &typeLib); |
|
229 |
|
230 HKEY userClasses; |
|
231 if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\CLASSES"), 0, KEY_WRITE, &userClasses) != ERROR_SUCCESS) |
|
232 userClasses = 0; |
|
233 |
|
234 // register entries from table |
|
235 int nEntries = ARRAYSIZE(gRegTable); |
|
236 for (int i = 0; SUCCEEDED(hr) && i < nEntries; i++) { |
|
237 LPTSTR pszKeyName = _tcsdup(gRegTable[i][0]); |
|
238 LPTSTR pszValueName = gRegTable[i][1] ? _tcsdup(gRegTable[i][1]) : 0; |
|
239 LPTSTR allocatedValue = (gRegTable[i][2] != (LPTSTR)-1) ? _tcsdup(gRegTable[i][2]) : (LPTSTR)-1; |
|
240 LPTSTR pszValue = allocatedValue; |
|
241 |
|
242 if (pszKeyName && pszValue) { |
|
243 |
|
244 int clsidIndex = i/gSlotsPerEntry; |
|
245 substituteGUID(pszKeyName, &gRegCLSIDs[clsidIndex]); |
|
246 substituteGUID(pszValueName, &gRegCLSIDs[clsidIndex]); |
|
247 |
|
248 // map rogue value to module file name |
|
249 if (pszValue == (LPTSTR)-1) |
|
250 pszValue = szFileName; |
|
251 else |
|
252 substituteGUID(pszValue, &gRegCLSIDs[clsidIndex]); |
|
253 |
|
254 // create the key |
|
255 HKEY hkey; |
|
256 LONG err = RegCreateKey(HKEY_CLASSES_ROOT, pszKeyName, &hkey); |
|
257 if (err != ERROR_SUCCESS && userClasses) |
|
258 err = RegCreateKey(userClasses, pszKeyName, &hkey); |
|
259 if (err == ERROR_SUCCESS) { |
|
260 // set the value |
|
261 err = RegSetValueEx(hkey, pszValueName, 0, REG_SZ, (const BYTE*)pszValue, (DWORD) sizeof(pszValue[0])*(_tcslen(pszValue) + 1)); |
|
262 RegCloseKey(hkey); |
|
263 } |
|
264 } |
|
265 if (pszKeyName) |
|
266 free(pszKeyName); |
|
267 if (pszValueName) |
|
268 free(pszValueName); |
|
269 if (allocatedValue && allocatedValue != (LPTSTR)-1) |
|
270 free(allocatedValue); |
|
271 } |
|
272 |
|
273 if (userClasses) |
|
274 RegCloseKey(userClasses); |
|
275 |
|
276 return hr; |
|
277 } |
|
278 |
|
279 STDAPI RunAsLocalServer(void) |
|
280 { |
|
281 DWORD reg; |
|
282 COMPtr<IUnknown> classFactory; |
|
283 DllGetClassObject(CLSID_WebDebugProgram, IID_IUnknown, (void**)&classFactory); |
|
284 CoRegisterClassObject(CLSID_WebDebugProgram, classFactory.get(), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, ®); |
|
285 return 0; |
|
286 } |
|
287 |
|
288 //FIXME: We should consider moving this to a new file for cross-project functionality |
|
289 PassRefPtr<WebCore::SharedBuffer> loadResourceIntoBuffer(const char* name) |
|
290 { |
|
291 int idr; |
|
292 // temporary hack to get resource id |
|
293 if (!strcmp(name, "textAreaResizeCorner")) |
|
294 idr = IDR_RESIZE_CORNER; |
|
295 else if (!strcmp(name, "missingImage")) |
|
296 idr = IDR_MISSING_IMAGE; |
|
297 else if (!strcmp(name, "urlIcon")) |
|
298 idr = IDR_URL_ICON; |
|
299 else if (!strcmp(name, "nullPlugin")) |
|
300 idr = IDR_NULL_PLUGIN; |
|
301 else if (!strcmp(name, "zoomInCursor")) |
|
302 idr = IDR_ZOOM_IN_CURSOR; |
|
303 else if (!strcmp(name, "zoomOutCursor")) |
|
304 idr = IDR_ZOOM_OUT_CURSOR; |
|
305 else if (!strcmp(name, "verticalTextCursor")) |
|
306 idr = IDR_VERTICAL_TEXT_CURSOR; |
|
307 else |
|
308 return 0; |
|
309 |
|
310 HRSRC resInfo = FindResource(gInstance, MAKEINTRESOURCE(idr), L"PNG"); |
|
311 if (!resInfo) |
|
312 return 0; |
|
313 HANDLE res = LoadResource(gInstance, resInfo); |
|
314 if (!res) |
|
315 return 0; |
|
316 void* resource = LockResource(res); |
|
317 if (!resource) |
|
318 return 0; |
|
319 int size = SizeofResource(gInstance, resInfo); |
|
320 |
|
321 return new WebCore::SharedBuffer(reinterpret_cast<const char*>(resource), size); |
|
322 } |