webengine/osswebengine/WebKit/win/WebKitDLL.cpp
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     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, &reg);
       
   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 }