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 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * 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 #include <stdarg.h> 24 #include <stdio.h> 25 26 #include "wine/debug.h" 27 28 #include "shdocvw.h" 29 30 #include "winreg.h" 31 #ifdef __REACTOS__ 32 #include "winnls.h" 33 #include <shlguid_undoc.h> 34 #include <rpcproxy.h> /* for __wine_register_resources / __wine_unregister_resources */ 35 #endif 36 #include "shlwapi.h" 37 #include "wininet.h" 38 #include "isguids.h" 39 40 #include "initguid.h" 41 42 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); 43 44 LONG SHDOCVW_refCount = 0; 45 46 static HMODULE SHDOCVW_hshell32 = 0; 47 static HINSTANCE ieframe_instance; 48 #ifdef __REACTOS__ 49 static HINSTANCE instance; 50 #endif 51 52 static HINSTANCE get_ieframe_instance(void) 53 { 54 static const WCHAR ieframe_dllW[] = {'i','e','f','r','a','m','e','.','d','l','l',0}; 55 56 if(!ieframe_instance) 57 ieframe_instance = LoadLibraryW(ieframe_dllW); 58 59 return ieframe_instance; 60 } 61 62 static HRESULT get_ieframe_object(REFCLSID rclsid, REFIID riid, void **ppv) 63 { 64 HINSTANCE ieframe_instance; 65 66 static HRESULT (WINAPI *ieframe_DllGetClassObject)(REFCLSID,REFIID,void**); 67 68 if(!ieframe_DllGetClassObject) { 69 ieframe_instance = get_ieframe_instance(); 70 if(!ieframe_instance) 71 return CLASS_E_CLASSNOTAVAILABLE; 72 73 ieframe_DllGetClassObject = (void*)GetProcAddress(ieframe_instance, "DllGetClassObject"); 74 if(!ieframe_DllGetClassObject) 75 return CLASS_E_CLASSNOTAVAILABLE; 76 } 77 78 return ieframe_DllGetClassObject(rclsid, riid, ppv); 79 } 80 81 /************************************************************************* 82 * DllGetClassObject (SHDOCVW.@) 83 */ 84 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) 85 { 86 TRACE("(%s %s %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 87 88 if(IsEqualGUID(&CLSID_WebBrowser, rclsid) 89 || IsEqualGUID(&CLSID_WebBrowser_V1, rclsid) 90 || IsEqualGUID(&CLSID_InternetShortcut, rclsid) 91 || IsEqualGUID(&CLSID_CUrlHistory, rclsid) 92 || IsEqualGUID(&CLSID_TaskbarList, rclsid)) 93 return get_ieframe_object(rclsid, riid, ppv); 94 95 #ifdef __REACTOS__ 96 if (IsEqualGUID(riid, &IID_IClassFactory) || IsEqualGUID(riid, &IID_IUnknown)) 97 { 98 if (IsEqualGUID(rclsid, &CLSID_MruLongList) || 99 IsEqualGUID(rclsid, &CLSID_MruPidlList)) 100 { 101 return CMruClassFactory_CreateInstance(riid, ppv); 102 } 103 } 104 else if (IsEqualGUID(riid, &IID_IMruDataList)) 105 { 106 return CMruLongList_CreateInstance(0, ppv, 0); 107 } 108 else if (IsEqualGUID(riid, &IID_IMruPidlList)) 109 { 110 return CMruPidlList_CreateInstance(0, ppv, 0); 111 } 112 #endif 113 114 /* As a last resort, figure if the CLSID belongs to a 'Shell Instance Object' */ 115 return SHDOCVW_GetShellInstanceObjectClassObject(rclsid, riid, ppv); 116 } 117 118 /*********************************************************************** 119 * DllRegisterServer (shdocvw.@) 120 */ 121 HRESULT WINAPI DllRegisterServer(void) 122 { 123 TRACE("\n"); 124 #ifdef __REACTOS__ 125 return __wine_register_resources(instance); 126 #else 127 return S_OK; 128 #endif 129 } 130 131 /*********************************************************************** 132 * DllUnregisterServer (shdocvw.@) 133 */ 134 HRESULT WINAPI DllUnregisterServer(void) 135 { 136 TRACE("\n"); 137 #ifdef __REACTOS__ 138 return __wine_unregister_resources(instance); 139 #else 140 return S_OK; 141 #endif 142 } 143 144 /****************************************************************** 145 * IEWinMain (SHDOCVW.101) 146 * 147 * Only returns on error. 148 */ 149 DWORD WINAPI IEWinMain(LPSTR szCommandLine, int nShowWindow) 150 { 151 DWORD (WINAPI *pIEWinMain)(const WCHAR*,int); 152 WCHAR *cmdline; 153 DWORD ret, len; 154 155 TRACE("%s %d\n", debugstr_a(szCommandLine), nShowWindow); 156 157 pIEWinMain = (void*)GetProcAddress(get_ieframe_instance(), MAKEINTRESOURCEA(101)); 158 if(!pIEWinMain) 159 ExitProcess(1); 160 161 len = MultiByteToWideChar(CP_ACP, 0, szCommandLine, -1, NULL, 0); 162 cmdline = heap_alloc(len*sizeof(WCHAR)); 163 if(!cmdline) 164 ExitProcess(1); 165 MultiByteToWideChar(CP_ACP, 0, szCommandLine, -1, cmdline, len); 166 167 ret = pIEWinMain(cmdline, nShowWindow); 168 169 heap_free(cmdline); 170 return ret; 171 } 172 173 /************************************************************************* 174 * SHDOCVW DllMain 175 */ 176 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad) 177 { 178 TRACE("%p 0x%x %p\n", hinst, fdwReason, fImpLoad); 179 switch (fdwReason) 180 { 181 case DLL_PROCESS_ATTACH: 182 #ifdef __REACTOS__ 183 instance = hinst; 184 #endif 185 DisableThreadLibraryCalls(hinst); 186 break; 187 case DLL_PROCESS_DETACH: 188 if (fImpLoad) break; 189 if (SHDOCVW_hshell32) FreeLibrary(SHDOCVW_hshell32); 190 if (ieframe_instance) FreeLibrary(ieframe_instance); 191 break; 192 } 193 return TRUE; 194 } 195 196 /************************************************************************* 197 * DllCanUnloadNow (SHDOCVW.@) 198 */ 199 HRESULT WINAPI DllCanUnloadNow(void) 200 { 201 return SHDOCVW_refCount ? S_FALSE : S_OK; 202 } 203 204 /*********************************************************************** 205 * DllGetVersion (SHDOCVW.@) 206 */ 207 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *info) 208 { 209 if (info->cbSize != sizeof(DLLVERSIONINFO)) FIXME("support DLLVERSIONINFO2\n"); 210 211 /* this is what IE6 on Windows 98 reports */ 212 info->dwMajorVersion = 6; 213 info->dwMinorVersion = 0; 214 info->dwBuildNumber = 2600; 215 info->dwPlatformID = DLLVER_PLATFORM_WINDOWS; 216 217 return NOERROR; 218 } 219 220 /************************************************************************* 221 * DllInstall (SHDOCVW.@) 222 */ 223 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline) 224 { 225 FIXME("(%s, %s): stub!\n", bInstall ? "TRUE":"FALSE", debugstr_w(cmdline)); 226 227 return S_OK; 228 } 229 230 /************************************************************************* 231 * SHDOCVW_LoadShell32 232 * 233 * makes sure the handle to shell32 is valid 234 */ 235 static BOOL SHDOCVW_LoadShell32(void) 236 { 237 if (SHDOCVW_hshell32) 238 return TRUE; 239 return ((SHDOCVW_hshell32 = LoadLibraryA("shell32.dll")) != NULL); 240 } 241 242 /*********************************************************************** 243 * @ (SHDOCVW.110) 244 * 245 * Called by Win98 explorer.exe main binary, definitely has 0 246 * parameters. 247 */ 248 DWORD WINAPI WinList_Init(void) 249 { 250 FIXME("(), stub!\n"); 251 return 0x0deadfeed; 252 } 253 254 /*********************************************************************** 255 * @ (SHDOCVW.118) 256 * 257 * Called by Win98 explorer.exe main binary, definitely has only one 258 * parameter. 259 */ 260 static BOOL (WINAPI *pShellDDEInit)(BOOL start) = NULL; 261 262 BOOL WINAPI ShellDDEInit(BOOL start) 263 { 264 TRACE("(%d)\n", start); 265 266 if (!pShellDDEInit) 267 { 268 if (!SHDOCVW_LoadShell32()) 269 return FALSE; 270 pShellDDEInit = (void *)GetProcAddress(SHDOCVW_hshell32, (LPCSTR)188); 271 } 272 273 if (pShellDDEInit) 274 return pShellDDEInit(start); 275 else 276 return FALSE; 277 } 278 279 /*********************************************************************** 280 * @ (SHDOCVW.125) 281 * 282 * Called by Win98 explorer.exe main binary, definitely has 0 283 * parameters. 284 */ 285 DWORD WINAPI RunInstallUninstallStubs(void) 286 { 287 FIXME("(), stub!\n"); 288 return 0x0deadbee; 289 } 290 291 /*********************************************************************** 292 * @ (SHDOCVW.130) 293 * 294 * Called by Emerge Desktop (alternative Windows Shell). 295 */ 296 DWORD WINAPI RunInstallUninstallStubs2(int arg) 297 { 298 FIXME("(%d), stub!\n", arg); 299 return 0x0deadbee; 300 } 301 302 /*********************************************************************** 303 * SetQueryNetSessionCount (SHDOCVW.@) 304 */ 305 DWORD WINAPI SetQueryNetSessionCount(DWORD arg) 306 { 307 FIXME("(%u), stub!\n", arg); 308 return 0; 309 } 310 311 /********************************************************************** 312 * Some forwards (by ordinal) to SHLWAPI 313 */ 314 315 static void* fetch_shlwapi_ordinal(UINT_PTR ord) 316 { 317 static const WCHAR shlwapiW[] = {'s','h','l','w','a','p','i','.','d','l','l','\0'}; 318 static HANDLE h; 319 320 if (!h && !(h = GetModuleHandleW(shlwapiW))) return NULL; 321 return (void*)GetProcAddress(h, (const char*)ord); 322 } 323 324 /****************************************************************** 325 * WhichPlatformFORWARD (SHDOCVW.@) 326 */ 327 DWORD WINAPI WhichPlatformFORWARD(void) 328 { 329 static DWORD (WINAPI *p)(void); 330 331 if (p || (p = fetch_shlwapi_ordinal(276))) return p(); 332 return 1; /* not integrated, see shlwapi.WhichPlatform */ 333 } 334 335 /****************************************************************** 336 * StopWatchModeFORWARD (SHDOCVW.@) 337 */ 338 void WINAPI StopWatchModeFORWARD(void) 339 { 340 static void (WINAPI *p)(void); 341 342 if (p || (p = fetch_shlwapi_ordinal(241))) p(); 343 } 344 345 /****************************************************************** 346 * StopWatchFlushFORWARD (SHDOCVW.@) 347 */ 348 void WINAPI StopWatchFlushFORWARD(void) 349 { 350 static void (WINAPI *p)(void); 351 352 if (p || (p = fetch_shlwapi_ordinal(242))) p(); 353 } 354 355 /****************************************************************** 356 * StopWatchAFORWARD (SHDOCVW.@) 357 */ 358 DWORD WINAPI StopWatchAFORWARD(DWORD dwClass, LPCSTR lpszStr, DWORD dwUnknown, 359 DWORD dwMode, DWORD dwTimeStamp) 360 { 361 static DWORD (WINAPI *p)(DWORD, LPCSTR, DWORD, DWORD, DWORD); 362 363 if (p || (p = fetch_shlwapi_ordinal(243))) 364 return p(dwClass, lpszStr, dwUnknown, dwMode, dwTimeStamp); 365 return ERROR_CALL_NOT_IMPLEMENTED; 366 } 367 368 /****************************************************************** 369 * StopWatchWFORWARD (SHDOCVW.@) 370 */ 371 DWORD WINAPI StopWatchWFORWARD(DWORD dwClass, LPCWSTR lpszStr, DWORD dwUnknown, 372 DWORD dwMode, DWORD dwTimeStamp) 373 { 374 static DWORD (WINAPI *p)(DWORD, LPCWSTR, DWORD, DWORD, DWORD); 375 376 if (p || (p = fetch_shlwapi_ordinal(244))) 377 return p(dwClass, lpszStr, dwUnknown, dwMode, dwTimeStamp); 378 return ERROR_CALL_NOT_IMPLEMENTED; 379 } 380 381 /****************************************************************** 382 * URLSubRegQueryA (SHDOCVW.151) 383 */ 384 HRESULT WINAPI URLSubRegQueryA(LPCSTR regpath, LPCSTR name, DWORD type, 385 LPSTR out, DWORD outlen, DWORD unknown) 386 { 387 CHAR buffer[INTERNET_MAX_URL_LENGTH]; 388 DWORD len; 389 LONG res; 390 391 TRACE("(%s, %s, %d, %p, %d, %d)\n", debugstr_a(regpath), debugstr_a(name), 392 type, out, outlen, unknown); 393 394 if (!out) return S_OK; 395 396 len = sizeof(buffer); 397 res = SHRegGetUSValueA(regpath, name, NULL, buffer, &len, FALSE, NULL, 0); 398 if (!res) { 399 lstrcpynA(out, buffer, outlen); 400 return S_OK; 401 } 402 403 return E_FAIL; 404 } 405 406 /****************************************************************** 407 * ParseURLFromOutsideSourceW (SHDOCVW.170) 408 */ 409 DWORD WINAPI ParseURLFromOutsideSourceW(LPCWSTR url, LPWSTR out, LPDWORD plen, LPDWORD unknown) 410 { 411 WCHAR buffer_in[INTERNET_MAX_URL_LENGTH]; 412 WCHAR buffer_out[INTERNET_MAX_URL_LENGTH]; 413 LPCWSTR ptr = url; 414 HRESULT hr; 415 DWORD needed; 416 DWORD len; 417 DWORD res; 418 419 TRACE("(%s, %p, %p, %p) len: %d, unknown: 0x%x\n", debugstr_w(url), out, plen, unknown, 420 plen ? *plen : 0, unknown ? *unknown : 0); 421 422 if (!PathIsURLW(ptr)) { 423 len = ARRAY_SIZE(buffer_in); 424 buffer_in[0] = 0; 425 hr = UrlApplySchemeW(ptr, buffer_in, &len, URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT); 426 TRACE("got 0x%x with %s\n", hr, debugstr_w(buffer_in)); 427 if (hr == S_OK) { 428 /* we parsed the url to buffer_in */ 429 ptr = buffer_in; 430 } 431 else 432 { 433 FIXME("call search hook for %s\n", debugstr_w(ptr)); 434 } 435 } 436 437 len = ARRAY_SIZE(buffer_out); 438 buffer_out[0] = '\0'; 439 hr = UrlCanonicalizeW(ptr, buffer_out, &len, URL_ESCAPE_SPACES_ONLY); 440 needed = lstrlenW(buffer_out)+1; 441 TRACE("got 0x%x with %s (need %d)\n", hr, debugstr_w(buffer_out), needed); 442 443 res = 0; 444 if (*plen >= needed) { 445 if (out != NULL) { 446 lstrcpyW(out, buffer_out); 447 /* On success, 1 is returned for unicode version */ 448 res = 1; 449 } 450 needed--; 451 } 452 453 *plen = needed; 454 455 TRACE("=> %d\n", res); 456 return res; 457 } 458 459 /****************************************************************** 460 * ParseURLFromOutsideSourceA (SHDOCVW.169) 461 * 462 * See ParseURLFromOutsideSourceW 463 */ 464 DWORD WINAPI ParseURLFromOutsideSourceA(LPCSTR url, LPSTR out, LPDWORD plen, LPDWORD unknown) 465 { 466 WCHAR buffer[INTERNET_MAX_URL_LENGTH]; 467 LPWSTR urlW = NULL; 468 DWORD needed; 469 DWORD res; 470 DWORD len; 471 472 TRACE("(%s, %p, %p, %p) len: %d, unknown: 0x%x\n", debugstr_a(url), out, plen, unknown, 473 plen ? *plen : 0, unknown ? *unknown : 0); 474 475 if (url) { 476 len = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0); 477 urlW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 478 MultiByteToWideChar(CP_ACP, 0, url, -1, urlW, len); 479 } 480 481 len = ARRAY_SIZE(buffer); 482 ParseURLFromOutsideSourceW(urlW, buffer, &len, unknown); 483 HeapFree(GetProcessHeap(), 0, urlW); 484 485 needed = WideCharToMultiByte(CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL); 486 487 res = 0; 488 if (*plen >= needed) { 489 if (out != NULL) { 490 WideCharToMultiByte(CP_ACP, 0, buffer, -1, out, *plen, NULL, NULL); 491 /* On success, string size including terminating 0 is returned for ansi version */ 492 res = needed; 493 } 494 needed--; 495 } 496 497 *plen = needed; 498 499 TRACE("=> %d\n", res); 500 return res; 501 } 502 503 /****************************************************************** 504 * IEParseDisplayNameWithBCW (SHDOCVW.218) 505 */ 506 HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl) 507 { 508 /* Guessing at parameter 3 based on IShellFolder's ParseDisplayName */ 509 FIXME("stub: 0x%x %s %p %p\n",codepage,debugstr_w(lpszDisplayName),pbc,ppidl); 510 return E_FAIL; 511 } 512 513 /****************************************************************** 514 * SHRestricted2W (SHDOCVW.159) 515 */ 516 DWORD WINAPI SHRestricted2W(DWORD res, LPCWSTR url, DWORD reserved) 517 { 518 FIXME("(%d %s %d) stub\n", res, debugstr_w(url), reserved); 519 return 0; 520 } 521 522 /****************************************************************** 523 * SHRestricted2A (SHDOCVW.158) 524 * 525 * See SHRestricted2W 526 */ 527 DWORD WINAPI SHRestricted2A(DWORD restriction, LPCSTR url, DWORD reserved) 528 { 529 LPWSTR urlW = NULL; 530 DWORD res; 531 532 TRACE("(%d, %s, %d)\n", restriction, debugstr_a(url), reserved); 533 if (url) { 534 DWORD len = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0); 535 urlW = heap_alloc(len * sizeof(WCHAR)); 536 MultiByteToWideChar(CP_ACP, 0, url, -1, urlW, len); 537 } 538 res = SHRestricted2W(restriction, urlW, reserved); 539 heap_free(urlW); 540 return res; 541 } 542 543 /****************************************************************** 544 * ImportPrivacySettings (SHDOCVW.@) 545 * 546 * Import global and/or per site privacy preferences from an xml file 547 * 548 * PARAMS 549 * filename [I] XML file to use 550 * pGlobalPrefs [IO] PTR to a usage flag for the global privacy preferences 551 * pPerSitePrefs [IO] PTR to a usage flag for the per site privacy preferences 552 * 553 * RETURNS 554 * Success: TRUE (the privacy preferences where updated) 555 * Failure: FALSE (the privacy preferences are unchanged) 556 * 557 * NOTES 558 * Set the flag to TRUE, when the related privacy preferences in the xml file 559 * should be used (parsed and overwrite the current settings). 560 * On return, the flag is TRUE, when the related privacy settings where used 561 * 562 */ 563 BOOL WINAPI ImportPrivacySettings(LPCWSTR filename, BOOL *pGlobalPrefs, BOOL * pPerSitePrefs) 564 { 565 FIXME("(%s, %p->%d, %p->%d): stub\n", debugstr_w(filename), 566 pGlobalPrefs, pGlobalPrefs ? *pGlobalPrefs : 0, 567 pPerSitePrefs, pPerSitePrefs ? *pPerSitePrefs : 0); 568 569 if (pGlobalPrefs) *pGlobalPrefs = FALSE; 570 if (pPerSitePrefs) *pPerSitePrefs = FALSE; 571 572 return TRUE; 573 } 574 575 /****************************************************************** 576 * ResetProfileSharing (SHDOCVW.164) 577 */ 578 HRESULT WINAPI ResetProfileSharing(HWND hwnd) 579 { 580 FIXME("(%p) stub\n", hwnd); 581 return E_NOTIMPL; 582 } 583 584 /****************************************************************** 585 * InstallReg_RunDLL (SHDOCVW.@) 586 */ 587 void WINAPI InstallReg_RunDLL(HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show) 588 { 589 FIXME("(%p %p %s %x)\n", hwnd, handle, debugstr_a(cmdline), show); 590 } 591 592 /****************************************************************** 593 * DoFileDownload (SHDOCVW.@) 594 */ 595 BOOL WINAPI DoFileDownload(LPWSTR filename) 596 { 597 FIXME("(%s) stub\n", debugstr_w(filename)); 598 return FALSE; 599 } 600 601 /****************************************************************** 602 * DoOrganizeFavDlgW (SHDOCVW.@) 603 */ 604 BOOL WINAPI DoOrganizeFavDlgW(HWND hwnd, LPCWSTR initDir) 605 { 606 FIXME("(%p %s) stub\n", hwnd, debugstr_w(initDir)); 607 return FALSE; 608 } 609 610 /****************************************************************** 611 * DoOrganizeFavDlg (SHDOCVW.@) 612 */ 613 BOOL WINAPI DoOrganizeFavDlg(HWND hwnd, LPCSTR initDir) 614 { 615 LPWSTR initDirW = NULL; 616 BOOL res; 617 618 TRACE("(%p %s)\n", hwnd, debugstr_a(initDir)); 619 620 if (initDir) { 621 DWORD len = MultiByteToWideChar(CP_ACP, 0, initDir, -1, NULL, 0); 622 initDirW = heap_alloc(len * sizeof(WCHAR)); 623 MultiByteToWideChar(CP_ACP, 0, initDir, -1, initDirW, len); 624 } 625 res = DoOrganizeFavDlgW(hwnd, initDirW); 626 heap_free(initDirW); 627 return res; 628 } 629