shdocvw_main.c 11.3 KB
Newer Older
1
/*
2
 * SHDOCVW - Internet Explorer Web Control
3
 *
4
 * Copyright 2001 John R. Sheets (for CodeWeavers)
5
 * Copyright 2004 Mike McCormack (for CodeWeavers)
6
 * Copyright 2008 Detlef Riekenberg
7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 22
 */

23 24
#include "config.h"

25
#include <stdarg.h>
26
#include <stdio.h>
27

28 29
#include "wine/unicode.h"
#include "wine/debug.h"
30 31

#include "shdocvw.h"
32

33 34
#include "winreg.h"
#include "shlwapi.h"
35
#include "wininet.h"
36

37 38
#include "initguid.h"

39
WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
40

41 42
LONG SHDOCVW_refCount = 0;

43
HINSTANCE shdocvw_hinstance = 0;
44
static HMODULE SHDOCVW_hshell32 = 0;
45 46 47 48 49 50 51 52 53 54 55 56 57 58
static ITypeInfo *wb_typeinfo = NULL;

HRESULT get_typeinfo(ITypeInfo **typeinfo)
{
    ITypeLib *typelib;
    HRESULT hres;

    if(wb_typeinfo) {
        *typeinfo = wb_typeinfo;
        return S_OK;
    }

    hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, &typelib);
    if(FAILED(hres)) {
59
        ERR("LoadRegTypeLib failed: %08x\n", hres);
60 61 62 63 64 65 66 67 68
        return hres;
    }

    hres = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IWebBrowser2, &wb_typeinfo);
    ITypeLib_Release(typelib);

    *typeinfo = wb_typeinfo;
    return hres;
}
69 70 71 72 73 74

/*************************************************************************
 * SHDOCVW DllMain
 */
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
{
75
    TRACE("%p 0x%x %p\n", hinst, fdwReason, fImpLoad);
76 77 78 79 80 81 82 83 84
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        shdocvw_hinstance = hinst;
        register_iewindow_class();
        break;
    case DLL_PROCESS_DETACH:
        if (SHDOCVW_hshell32) FreeLibrary(SHDOCVW_hshell32);
        unregister_iewindow_class();
85 86
        if(wb_typeinfo)
            ITypeInfo_Release(wb_typeinfo);
87 88 89
        break;
    }
    return TRUE;
90 91 92
}

/*************************************************************************
93 94
 *              DllCanUnloadNow (SHDOCVW.@)
 */
95
HRESULT WINAPI DllCanUnloadNow(void)
96
{
97
    return SHDOCVW_refCount ? S_FALSE : S_OK;
98 99 100
}

/***********************************************************************
101
 *              DllGetVersion (SHDOCVW.@)
102
 */
103
HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *info)
104
{
105 106 107 108 109 110 111 112 113
    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;
114 115 116
}

/*************************************************************************
117
 *              DllInstall (SHDOCVW.@)
118
 */
119
HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
120
{
121
   FIXME("(%s, %s): stub!\n", bInstall ? "TRUE":"FALSE", debugstr_w(cmdline));
122

123
   return S_OK;
124 125
}

126 127 128 129 130
/*************************************************************************
 * SHDOCVW_LoadShell32
 *
 * makes sure the handle to shell32 is valid
 */
131
static BOOL SHDOCVW_LoadShell32(void)
132 133 134 135 136 137
{
     if (SHDOCVW_hshell32)
       return TRUE;
     return ((SHDOCVW_hshell32 = LoadLibraryA("shell32.dll")) != NULL);
}

138
/***********************************************************************
139
 *		@ (SHDOCVW.110)
140 141 142 143
 *
 * Called by Win98 explorer.exe main binary, definitely has 0
 * parameters.
 */
144
DWORD WINAPI WinList_Init(void)
145 146 147 148 149 150
{
    FIXME("(), stub!\n");
    return 0x0deadfeed;
}

/***********************************************************************
151
 *		@ (SHDOCVW.118)
152 153 154 155
 *
 * Called by Win98 explorer.exe main binary, definitely has only one
 * parameter.
 */
156 157 158
static BOOL (WINAPI *pShellDDEInit)(BOOL start) = NULL;

BOOL WINAPI ShellDDEInit(BOOL start)
159
{
160 161 162 163 164 165
    TRACE("(%d)\n", start);

    if (!pShellDDEInit)
    {
      if (!SHDOCVW_LoadShell32())
        return FALSE;
166
      pShellDDEInit = (void *)GetProcAddress(SHDOCVW_hshell32, (LPCSTR)188);
167 168 169 170 171 172
    }

    if (pShellDDEInit)
      return pShellDDEInit(start);
    else
      return FALSE;
173 174 175
}

/***********************************************************************
176
 *		@ (SHDOCVW.125)
177 178 179 180
 *
 * Called by Win98 explorer.exe main binary, definitely has 0
 * parameters.
 */
181
DWORD WINAPI RunInstallUninstallStubs(void)
182 183 184 185
{
    FIXME("(), stub!\n");
    return 0x0deadbee;
}
186 187 188 189 190 191

/***********************************************************************
 *              SetQueryNetSessionCount (SHDOCVW.@)
 */
DWORD WINAPI SetQueryNetSessionCount(DWORD arg)
{
192
    FIXME("(%u), stub!\n", arg);
193 194
    return 0;
}
195 196 197 198 199 200 201 202

/**********************************************************************
 * 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);
}
203 204 205 206 207

/**********************************************************************
 * Some forwards (by ordinal) to SHLWAPI
 */

208
static void* fetch_shlwapi_ordinal(UINT_PTR ord)
209 210 211 212 213 214 215 216 217 218 219 220 221
{
    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)
{
222
    static DWORD (WINAPI *p)(void);
223 224 225 226 227 228 229 230 231 232

    if (p || (p = fetch_shlwapi_ordinal(276))) return p();
    return 1; /* not integrated, see shlwapi.WhichPlatform */
}

/******************************************************************
 *		StopWatchModeFORWARD            (SHDOCVW.@)
 */
void WINAPI StopWatchModeFORWARD(void)
{
233
    static void (WINAPI *p)(void);
234 235 236 237 238 239 240 241 242

    if (p || (p = fetch_shlwapi_ordinal(241))) p();
}

/******************************************************************
 *		StopWatchFlushFORWARD            (SHDOCVW.@)
 */
void WINAPI StopWatchFlushFORWARD(void)
{
243
    static void (WINAPI *p)(void);
244 245 246 247 248 249 250 251 252 253

    if (p || (p = fetch_shlwapi_ordinal(242))) p();
}

/******************************************************************
 *		StopWatchWFORWARD            (SHDOCVW.@)
 */
DWORD WINAPI StopWatchWFORWARD(DWORD dwClass, LPCWSTR lpszStr, DWORD dwUnknown,
                               DWORD dwMode, DWORD dwTimeStamp)
{
254
    static DWORD (WINAPI *p)(DWORD, LPCWSTR, DWORD, DWORD, DWORD);
255 256 257 258 259 260 261 262 263 264 265 266

    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)
{
267
    static DWORD (WINAPI *p)(DWORD, LPCSTR, DWORD, DWORD, DWORD);
268 269 270 271 272

    if (p || (p = fetch_shlwapi_ordinal(244)))
        return p(dwClass, lpszStr, dwUnknown, dwMode, dwTimeStamp);
    return ERROR_CALL_NOT_IMPLEMENTED;
}
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297

/******************************************************************
 *  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;
}
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398

/******************************************************************
 *  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;
}
399 400 401 402 403 404 405 406 407 408

/******************************************************************
 *  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;
}