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