shell32/tests: Fix remaining failures on WinMe.
[wine] / dlls / shdocvw / shdocvw_main.c
index 2886945..9090b7d 100644 (file)
@@ -2,6 +2,8 @@
  * SHDOCVW - Internet Explorer Web Control
  *
  * Copyright 2001 John R. Sheets (for CodeWeavers)
+ * Copyright 2004 Mike McCormack (for CodeWeavers)
+ * Copyright 2008 Detlef Riekenberg
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #include "config.h"
 
-#define COM_NO_WINDOWS_H
 #include <stdarg.h>
 #include <stdio.h>
-#include <string.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "ole2.h"
-#include "shlwapi.h"
-
-#include "shdocvw.h"
-#include "uuids.h"
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
 
-#include "initguid.h"
+#include "shdocvw.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
+#include "winreg.h"
+#include "shlwapi.h"
+#include "wininet.h"
 
+#include "initguid.h"
 
-DEFINE_GUID( CLSID_MozillaBrowser, 0x1339B54C,0x3453,0x11D2,0x93,0xB9,0x00,0x00,0x00,0x00,0x00,0x00);
+WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
 
-typedef HRESULT (WINAPI *fnGetClassObject)(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
+LONG SHDOCVW_refCount = 0;
 
 HINSTANCE shdocvw_hinstance = 0;
 static HMODULE SHDOCVW_hshell32 = 0;
-static HMODULE hMozCtl = (HMODULE)~0UL;
+static ITypeInfo *wb_typeinfo = NULL;
 
-
-/* convert a guid to a wide character string */
-static void SHDOCVW_guid2wstr( const GUID *guid, LPWSTR wstr )
+HRESULT get_typeinfo(ITypeInfo **typeinfo)
 {
-    char str[40];
+    ITypeLib *typelib;
+    HRESULT hres;
 
-    sprintf(str, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
-           guid->Data1, guid->Data2, guid->Data3,
-           guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
-           guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
-    MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 );
-}
+    if(wb_typeinfo) {
+        *typeinfo = wb_typeinfo;
+        return S_OK;
+    }
 
-static BOOL SHDOCVW_GetMozctlPath( LPWSTR szPath, DWORD sz )
-{
-    DWORD r, type;
-    BOOL ret = FALSE;
-    HKEY hkey;
-    const WCHAR szPre[] = {
-        'S','o','f','t','w','a','r','e','\\',
-        'C','l','a','s','s','e','s','\\',
-        'C','L','S','I','D','\\',0 };
-    const WCHAR szPost[] = {
-        '\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2',0 };
-    WCHAR szRegPath[(sizeof(szPre)+sizeof(szPost))/sizeof(WCHAR)+40];
-
-    strcpyW( szRegPath, szPre );
-    SHDOCVW_guid2wstr( &CLSID_MozillaBrowser, &szRegPath[strlenW(szRegPath)] );
-    strcatW( szRegPath, szPost );
-
-    TRACE("key = %s\n", debugstr_w( szRegPath ) );
-
-    r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szRegPath, &hkey );
-    if( r != ERROR_SUCCESS )
-        return FALSE;
+    hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, &typelib);
+    if(FAILED(hres)) {
+        ERR("LoadRegTypeLib failed: %08x\n", hres);
+        return hres;
+    }
 
-    r = RegQueryValueExW( hkey, NULL, NULL, &type, (LPBYTE)szPath, &sz );
-    ret = ( r == ERROR_SUCCESS ) && ( type == REG_SZ );
-    RegCloseKey( hkey );
+    hres = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IWebBrowser2, &wb_typeinfo);
+    ITypeLib_Release(typelib);
 
-    return ret;
+    *typeinfo = wb_typeinfo;
+    return hres;
 }
 
 /*************************************************************************
@@ -99,105 +72,51 @@ static BOOL SHDOCVW_GetMozctlPath( LPWSTR szPath, DWORD sz )
  */
 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
 {
-       TRACE("%p 0x%lx %p\n", hinst, fdwReason, fImpLoad);
-       switch (fdwReason)
-       {
-         case DLL_PROCESS_ATTACH:
-           shdocvw_hinstance = hinst;
-           break;
-         case DLL_PROCESS_DETACH:
-           if (SHDOCVW_hshell32) FreeLibrary(SHDOCVW_hshell32);
-           if (hMozCtl && hMozCtl != (HMODULE)~0UL) FreeLibrary(hMozCtl);
-           break;
-       }
-       return TRUE;
-}
-
-/*************************************************************************
- *              DllCanUnloadNow (SHDOCVW.@)
- */
-HRESULT WINAPI SHDOCVW_DllCanUnloadNow(void)
-{
-    FIXME("(void): stub\n");
-
-    return S_FALSE;
-}
-
-
-static BOOL SHDOCVW_TryLoadMozillaControl()
-{
-    WCHAR szPath[MAX_PATH];
-
-    if( hMozCtl != (HMODULE)~0UL )
-        return hMozCtl ? TRUE : FALSE;
-
-    if( !SHDOCVW_GetMozctlPath( szPath, sizeof szPath ) )
-    {
-        MESSAGE("You need to install the Mozilla ActiveX control to\n");
-        MESSAGE("use Wine's builtin CLSID_WebBrowser from SHDOCVW.DLL\n");
-        return FALSE;
-    }
-    hMozCtl = LoadLibraryExW(szPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
-    if( !hMozCtl )
+    TRACE("%p 0x%x %p\n", hinst, fdwReason, fImpLoad);
+    switch (fdwReason)
     {
-        ERR("Can't load the Mozilla ActiveX control\n");
-        return FALSE;
+        case DLL_PROCESS_ATTACH:
+        shdocvw_hinstance = hinst;
+        register_iewindow_class();
+        break;
+    case DLL_PROCESS_DETACH:
+        if (SHDOCVW_hshell32) FreeLibrary(SHDOCVW_hshell32);
+        unregister_iewindow_class();
+        if(wb_typeinfo)
+            ITypeInfo_Release(wb_typeinfo);
+        break;
     }
     return TRUE;
 }
 
 /*************************************************************************
- *              DllGetClassObject (SHDOCVW.@)
+ *              DllCanUnloadNow (SHDOCVW.@)
  */
-HRESULT WINAPI SHDOCVW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+HRESULT WINAPI DllCanUnloadNow(void)
 {
-    TRACE("\n");
-
-    if( IsEqualGUID( &CLSID_WebBrowser, rclsid ) &&
-        SHDOCVW_TryLoadMozillaControl() )
-    {
-        HRESULT r;
-        fnGetClassObject pGetClassObject;
-
-        TRACE("WebBrowser class %s\n", debugstr_guid(rclsid) );
-
-        pGetClassObject = (fnGetClassObject)
-            GetProcAddress( hMozCtl, "DllGetClassObject" );
-
-        if( !pGetClassObject )
-            return CLASS_E_CLASSNOTAVAILABLE;
-        r = pGetClassObject( &CLSID_MozillaBrowser, riid, ppv );
-
-        TRACE("r = %08lx  *ppv = %p\n", r, *ppv );
-
-        return r;
-    }
-
-    if (IsEqualGUID(&IID_IClassFactory, riid))
-    {
-        /* Pass back our shdocvw class factory */
-        *ppv = (LPVOID)&SHDOCVW_ClassFactory;
-        IClassFactory_AddRef((IClassFactory*)&SHDOCVW_ClassFactory);
-
-        return S_OK;
-    }
-
-    return CLASS_E_CLASSNOTAVAILABLE;
+    return SHDOCVW_refCount ? S_FALSE : S_OK;
 }
 
 /***********************************************************************
  *              DllGetVersion (SHDOCVW.@)
  */
-HRESULT WINAPI SHDOCVW_DllGetVersion (DLLVERSIONINFO *pdvi)
+HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *info)
 {
-    FIXME("(void): stub\n");
-    return S_FALSE;
+    if (info->cbSize != sizeof(DLLVERSIONINFO)) FIXME("support DLLVERSIONINFO2\n");
+
+    /* this is what IE6 on Windows 98 reports */
+    info->dwMajorVersion = 6;
+    info->dwMinorVersion = 0;
+    info->dwBuildNumber = 2600;
+    info->dwPlatformID = DLLVER_PLATFORM_WINDOWS;
+
+    return NOERROR;
 }
 
 /*************************************************************************
  *              DllInstall (SHDOCVW.@)
  */
-HRESULT WINAPI SHDOCVW_DllInstall(BOOL bInstall, LPCWSTR cmdline)
+HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
 {
    FIXME("(%s, %s): stub!\n", bInstall ? "TRUE":"FALSE", debugstr_w(cmdline));
 
@@ -209,7 +128,7 @@ HRESULT WINAPI SHDOCVW_DllInstall(BOOL bInstall, LPCWSTR cmdline)
  *
  * makes sure the handle to shell32 is valid
  */
- BOOL SHDOCVW_LoadShell32(void)
+static BOOL SHDOCVW_LoadShell32(void)
 {
      if (SHDOCVW_hshell32)
        return TRUE;
@@ -244,7 +163,7 @@ BOOL WINAPI ShellDDEInit(BOOL start)
     {
       if (!SHDOCVW_LoadShell32())
         return FALSE;
-      pShellDDEInit = GetProcAddress(SHDOCVW_hshell32, (LPCSTR)188);
+      pShellDDEInit = (void *)GetProcAddress(SHDOCVW_hshell32, (LPCSTR)188);
     }
 
     if (pShellDDEInit)
@@ -264,3 +183,235 @@ DWORD WINAPI RunInstallUninstallStubs(void)
     FIXME("(), stub!\n");
     return 0x0deadbee;
 }
+
+/***********************************************************************
+ *              SetQueryNetSessionCount (SHDOCVW.@)
+ */
+DWORD WINAPI SetQueryNetSessionCount(DWORD arg)
+{
+    FIXME("(%u), stub!\n", arg);
+    return 0;
+}
+
+/**********************************************************************
+ * OpenURL  (SHDOCVW.@)
+ */
+void WINAPI OpenURL(HWND hWnd, HINSTANCE hInst, LPCSTR lpcstrUrl, int nShowCmd)
+{
+    FIXME("%p %p %s %d\n", hWnd, hInst, debugstr_a(lpcstrUrl), nShowCmd);
+}
+
+/**********************************************************************
+ * Some forwards (by ordinal) to SHLWAPI
+ */
+
+static void* fetch_shlwapi_ordinal(UINT_PTR ord)
+{
+    static const WCHAR shlwapiW[] = {'s','h','l','w','a','p','i','.','d','l','l','\0'};
+    static HANDLE h;
+
+    if (!h && !(h = GetModuleHandleW(shlwapiW))) return NULL;
+    return (void*)GetProcAddress(h, (const char*)ord);
+}
+
+/******************************************************************
+ *             WhichPlatformFORWARD            (SHDOCVW.@)
+ */
+DWORD WINAPI WhichPlatformFORWARD(void)
+{
+    static DWORD (WINAPI *p)(void);
+
+    if (p || (p = fetch_shlwapi_ordinal(276))) return p();
+    return 1; /* not integrated, see shlwapi.WhichPlatform */
+}
+
+/******************************************************************
+ *             StopWatchModeFORWARD            (SHDOCVW.@)
+ */
+void WINAPI StopWatchModeFORWARD(void)
+{
+    static void (WINAPI *p)(void);
+
+    if (p || (p = fetch_shlwapi_ordinal(241))) p();
+}
+
+/******************************************************************
+ *             StopWatchFlushFORWARD            (SHDOCVW.@)
+ */
+void WINAPI StopWatchFlushFORWARD(void)
+{
+    static void (WINAPI *p)(void);
+
+    if (p || (p = fetch_shlwapi_ordinal(242))) p();
+}
+
+/******************************************************************
+ *             StopWatchWFORWARD            (SHDOCVW.@)
+ */
+DWORD WINAPI StopWatchWFORWARD(DWORD dwClass, LPCWSTR lpszStr, DWORD dwUnknown,
+                               DWORD dwMode, DWORD dwTimeStamp)
+{
+    static DWORD (WINAPI *p)(DWORD, LPCWSTR, DWORD, DWORD, DWORD);
+
+    if (p || (p = fetch_shlwapi_ordinal(243)))
+        return p(dwClass, lpszStr, dwUnknown, dwMode, dwTimeStamp);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/******************************************************************
+ *             StopWatchAFORWARD            (SHDOCVW.@)
+ */
+DWORD WINAPI StopWatchAFORWARD(DWORD dwClass, LPCSTR lpszStr, DWORD dwUnknown,
+                               DWORD dwMode, DWORD dwTimeStamp)
+{
+    static DWORD (WINAPI *p)(DWORD, LPCSTR, DWORD, DWORD, DWORD);
+
+    if (p || (p = fetch_shlwapi_ordinal(244)))
+        return p(dwClass, lpszStr, dwUnknown, dwMode, dwTimeStamp);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/******************************************************************
+ *  URLSubRegQueryA (SHDOCVW.151)
+ */
+HRESULT WINAPI URLSubRegQueryA(LPCSTR regpath, LPCSTR name, DWORD type,
+                               LPSTR out, DWORD outlen, DWORD unknown)
+{
+    CHAR buffer[INTERNET_MAX_URL_LENGTH];
+    DWORD len;
+    LONG res;
+
+    TRACE("(%s, %s, %d, %p, %d, %d)\n", debugstr_a(regpath), debugstr_a(name),
+            type, out, outlen, unknown);
+
+    if (!out) return S_OK;
+
+    len = sizeof(buffer);
+    res = SHRegGetUSValueA(regpath, name, NULL, buffer,  &len, FALSE, NULL, 0);
+    if (!res) {
+        lstrcpynA(out, buffer, outlen);
+        return S_OK;
+    }
+
+    return E_FAIL;
+}
+
+/******************************************************************
+ *  ParseURLFromOutsideSourceW (SHDOCVW.170)
+ */
+DWORD WINAPI ParseURLFromOutsideSourceW(LPCWSTR url, LPWSTR out, LPDWORD plen, LPDWORD unknown)
+{
+    WCHAR buffer_in[INTERNET_MAX_URL_LENGTH];
+    WCHAR buffer_out[INTERNET_MAX_URL_LENGTH];
+    LPCWSTR ptr = url;
+    HRESULT hr;
+    DWORD needed;
+    DWORD len;
+    DWORD res = 0;
+
+
+    TRACE("(%s, %p, %p, %p) len: %d, unknown: 0x%x\n", debugstr_w(url), out, plen, unknown,
+            plen ? *plen : 0, unknown ? *unknown : 0);
+
+    if (!PathIsURLW(ptr)) {
+        len = sizeof(buffer_in) / sizeof(buffer_in[0]);
+        buffer_in[0] = 0;
+        hr = UrlApplySchemeW(ptr, buffer_in, &len, URL_APPLY_GUESSSCHEME);
+        TRACE("got 0x%x with %s\n", hr, debugstr_w(buffer_in));
+        if (hr != S_OK) {
+            /* when we can't guess the scheme, use the default scheme */
+            len = sizeof(buffer_in) / sizeof(buffer_in[0]);
+            hr = UrlApplySchemeW(ptr, buffer_in, &len, URL_APPLY_DEFAULT);
+        }
+
+        if (hr == S_OK) {
+            /* we parsed the url to buffer_in */
+            ptr = buffer_in;
+        }
+        else
+        {
+            FIXME("call search hook for %s\n", debugstr_w(ptr));
+        }
+    }
+
+    len = sizeof(buffer_out) / sizeof(buffer_out[0]);
+    buffer_out[0] = '\0';
+    hr = UrlCanonicalizeW(ptr, buffer_out, &len, URL_ESCAPE_SPACES_ONLY);
+    needed = lstrlenW(buffer_out)+1;
+    TRACE("got 0x%x with %s (need %d)\n", hr, debugstr_w(buffer_out), needed);
+
+    if (*plen >= needed) {
+        if (out != NULL) {
+            lstrcpyW(out, buffer_out);
+            res++;
+        }
+        needed--;
+    }
+
+    *plen = needed;
+
+    TRACE("=> %d\n", res);
+    return res;
+}
+
+/******************************************************************
+ *  ParseURLFromOutsideSourceA (SHDOCVW.169)
+ *
+ * See ParseURLFromOutsideSourceW
+ */
+DWORD WINAPI ParseURLFromOutsideSourceA(LPCSTR url, LPSTR out, LPDWORD plen, LPDWORD unknown)
+{
+    WCHAR buffer[INTERNET_MAX_URL_LENGTH];
+    LPWSTR urlW = NULL;
+    DWORD needed;
+    DWORD res;
+    DWORD len;
+
+    TRACE("(%s, %p, %p, %p) len: %d, unknown: 0x%x\n", debugstr_a(url), out, plen, unknown,
+            plen ? *plen : 0, unknown ? *unknown : 0);
+
+    if (url) {
+        len = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0);
+        urlW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, url, -1, urlW, len);
+    }
+
+    len = sizeof(buffer) / sizeof(buffer[0]);
+    res = ParseURLFromOutsideSourceW(urlW, buffer, &len, unknown);
+    HeapFree(GetProcessHeap(), 0, urlW);
+
+    needed = WideCharToMultiByte(CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL);
+
+    res = 0;
+    if (*plen >= needed) {
+        if (out != NULL) {
+            WideCharToMultiByte(CP_ACP, 0, buffer, -1, out, *plen, NULL, NULL);
+            res = needed;
+        }
+        needed--;
+    }
+
+    *plen = needed;
+
+    TRACE("=> %d\n", res);
+    return res;
+}
+
+/******************************************************************
+ *  IEParseDisplayNameWithBCW (SHDOCVW.218)
+ */
+HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl)
+{
+    /* Guessing at parameter 3 based on IShellFolder's  ParseDisplayName */
+    FIXME("stub: 0x%x %s %p %p\n",codepage,debugstr_w(lpszDisplayName),pbc,ppidl);
+    return E_FAIL;
+}
+
+/******************************************************************
+ *  SHRestricted2W (SHDOCVW.159)
+ */
+DWORD WINAPI SHRestricted2W(DWORD res, LPCWSTR url, DWORD reserved)
+{
+    FIXME("(%d %s %d) stub\n", res, debugstr_w(url), reserved);
+    return 0;
+}