1 /* 2 * UrlMon 3 * 4 * Copyright (c) 2000 Patrik Stridvall 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 23 #define NONAMELESSUNION 24 25 #include "urlmon_main.h" 26 27 #include "winreg.h" 28 29 #define NO_SHLWAPI_REG 30 #include "shlwapi.h" 31 #include "advpub.h" 32 #include "initguid.h" 33 34 #include "wine/debug.h" 35 36 #include "urlmon.h" 37 38 WINE_DEFAULT_DEBUG_CHANNEL(urlmon); 39 40 DEFINE_GUID(CLSID_CUri, 0xDF2FCE13, 0x25EC, 0x45BB, 0x9D,0x4C, 0xCE,0xCD,0x47,0xC2,0x43,0x0C); 41 42 LONG URLMON_refCount = 0; 43 HINSTANCE urlmon_instance; 44 45 static HMODULE hCabinet = NULL; 46 static DWORD urlmon_tls = TLS_OUT_OF_INDEXES; 47 48 static void init_session(void); 49 50 static struct list tls_list = LIST_INIT(tls_list); 51 52 static CRITICAL_SECTION tls_cs; 53 static CRITICAL_SECTION_DEBUG tls_cs_dbg = 54 { 55 0, 0, &tls_cs, 56 { &tls_cs_dbg.ProcessLocksList, &tls_cs_dbg.ProcessLocksList }, 57 0, 0, { (DWORD_PTR)(__FILE__ ": tls") } 58 }; 59 60 static CRITICAL_SECTION tls_cs = { &tls_cs_dbg, -1, 0, 0, 0, 0 }; 61 62 tls_data_t *get_tls_data(void) 63 { 64 tls_data_t *data; 65 66 if(urlmon_tls == TLS_OUT_OF_INDEXES) { 67 DWORD tls = TlsAlloc(); 68 if(tls == TLS_OUT_OF_INDEXES) 69 return NULL; 70 71 tls = InterlockedCompareExchange((LONG*)&urlmon_tls, tls, TLS_OUT_OF_INDEXES); 72 if(tls != urlmon_tls) 73 TlsFree(tls); 74 } 75 76 data = TlsGetValue(urlmon_tls); 77 if(!data) { 78 data = heap_alloc_zero(sizeof(tls_data_t)); 79 if(!data) 80 return NULL; 81 82 EnterCriticalSection(&tls_cs); 83 list_add_tail(&tls_list, &data->entry); 84 LeaveCriticalSection(&tls_cs); 85 86 TlsSetValue(urlmon_tls, data); 87 } 88 89 return data; 90 } 91 92 static void free_tls_list(void) 93 { 94 tls_data_t *data; 95 96 if(urlmon_tls == TLS_OUT_OF_INDEXES) 97 return; 98 99 while(!list_empty(&tls_list)) { 100 data = LIST_ENTRY(list_head(&tls_list), tls_data_t, entry); 101 list_remove(&data->entry); 102 heap_free(data); 103 } 104 105 TlsFree(urlmon_tls); 106 } 107 108 static void detach_thread(void) 109 { 110 tls_data_t *data; 111 112 if(urlmon_tls == TLS_OUT_OF_INDEXES) 113 return; 114 115 data = TlsGetValue(urlmon_tls); 116 if(!data) 117 return; 118 119 EnterCriticalSection(&tls_cs); 120 list_remove(&data->entry); 121 LeaveCriticalSection(&tls_cs); 122 123 if(data->notif_hwnd) { 124 WARN("notif_hwnd not destroyed\n"); 125 DestroyWindow(data->notif_hwnd); 126 } 127 128 heap_free(data); 129 } 130 131 static void process_detach(void) 132 { 133 HINTERNET internet_session; 134 135 internet_session = get_internet_session(NULL); 136 if(internet_session) 137 InternetCloseHandle(internet_session); 138 139 if (hCabinet) 140 FreeLibrary(hCabinet); 141 142 free_session(); 143 free_tls_list(); 144 unregister_notif_wnd_class(); 145 } 146 147 /*********************************************************************** 148 * DllMain (URLMON.init) 149 */ 150 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) 151 { 152 TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad); 153 154 URLMON_DllMain( hinstDLL, fdwReason, fImpLoad ); 155 156 switch(fdwReason) { 157 case DLL_PROCESS_ATTACH: 158 urlmon_instance = hinstDLL; 159 init_session(); 160 break; 161 162 case DLL_PROCESS_DETACH: 163 if (fImpLoad) break; 164 process_detach(); 165 DeleteCriticalSection(&tls_cs); 166 break; 167 168 case DLL_THREAD_DETACH: 169 detach_thread(); 170 break; 171 } 172 return TRUE; 173 } 174 175 const char *debugstr_bindstatus(ULONG status) 176 { 177 switch(status) { 178 #define X(x) case x: return #x 179 X(BINDSTATUS_FINDINGRESOURCE); 180 X(BINDSTATUS_CONNECTING); 181 X(BINDSTATUS_REDIRECTING); 182 X(BINDSTATUS_BEGINDOWNLOADDATA); 183 X(BINDSTATUS_DOWNLOADINGDATA); 184 X(BINDSTATUS_ENDDOWNLOADDATA); 185 X(BINDSTATUS_BEGINDOWNLOADCOMPONENTS); 186 X(BINDSTATUS_INSTALLINGCOMPONENTS); 187 X(BINDSTATUS_ENDDOWNLOADCOMPONENTS); 188 X(BINDSTATUS_USINGCACHEDCOPY); 189 X(BINDSTATUS_SENDINGREQUEST); 190 X(BINDSTATUS_CLASSIDAVAILABLE); 191 X(BINDSTATUS_MIMETYPEAVAILABLE); 192 X(BINDSTATUS_CACHEFILENAMEAVAILABLE); 193 X(BINDSTATUS_BEGINSYNCOPERATION); 194 X(BINDSTATUS_ENDSYNCOPERATION); 195 X(BINDSTATUS_BEGINUPLOADDATA); 196 X(BINDSTATUS_UPLOADINGDATA); 197 X(BINDSTATUS_ENDUPLOADINGDATA); 198 X(BINDSTATUS_PROTOCOLCLASSID); 199 X(BINDSTATUS_ENCODING); 200 X(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE); 201 X(BINDSTATUS_CLASSINSTALLLOCATION); 202 X(BINDSTATUS_DECODING); 203 X(BINDSTATUS_LOADINGMIMEHANDLER); 204 X(BINDSTATUS_CONTENTDISPOSITIONATTACH); 205 X(BINDSTATUS_FILTERREPORTMIMETYPE); 206 X(BINDSTATUS_CLSIDCANINSTANTIATE); 207 X(BINDSTATUS_IUNKNOWNAVAILABLE); 208 X(BINDSTATUS_DIRECTBIND); 209 X(BINDSTATUS_RAWMIMETYPE); 210 X(BINDSTATUS_PROXYDETECTING); 211 X(BINDSTATUS_ACCEPTRANGES); 212 X(BINDSTATUS_COOKIE_SENT); 213 X(BINDSTATUS_COMPACT_POLICY_RECEIVED); 214 X(BINDSTATUS_COOKIE_SUPPRESSED); 215 X(BINDSTATUS_COOKIE_STATE_UNKNOWN); 216 X(BINDSTATUS_COOKIE_STATE_ACCEPT); 217 X(BINDSTATUS_COOKIE_STATE_REJECT); 218 X(BINDSTATUS_COOKIE_STATE_PROMPT); 219 X(BINDSTATUS_COOKIE_STATE_LEASH); 220 X(BINDSTATUS_COOKIE_STATE_DOWNGRADE); 221 X(BINDSTATUS_POLICY_HREF); 222 X(BINDSTATUS_P3P_HEADER); 223 X(BINDSTATUS_SESSION_COOKIE_RECEIVED); 224 X(BINDSTATUS_PERSISTENT_COOKIE_RECEIVED); 225 X(BINDSTATUS_SESSION_COOKIES_ALLOWED); 226 X(BINDSTATUS_CACHECONTROL); 227 X(BINDSTATUS_CONTENTDISPOSITIONFILENAME); 228 X(BINDSTATUS_MIMETEXTPLAINMISMATCH); 229 X(BINDSTATUS_PUBLISHERAVAILABLE); 230 X(BINDSTATUS_DISPLAYNAMEAVAILABLE); 231 #undef X 232 default: 233 return wine_dbg_sprintf("(invalid status %u)", status); 234 } 235 } 236 237 /*********************************************************************** 238 * DllInstall (URLMON.@) 239 */ 240 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline) 241 { 242 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE", 243 debugstr_w(cmdline)); 244 245 return S_OK; 246 } 247 248 /*********************************************************************** 249 * DllCanUnloadNow (URLMON.@) 250 */ 251 HRESULT WINAPI DllCanUnloadNow(void) 252 { 253 return URLMON_refCount != 0 ? S_FALSE : S_OK; 254 } 255 256 257 258 /****************************************************************************** 259 * Urlmon ClassFactory 260 */ 261 typedef struct { 262 IClassFactory IClassFactory_iface; 263 264 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); 265 } ClassFactory; 266 267 static inline ClassFactory *impl_from_IClassFactory(IClassFactory *iface) 268 { 269 return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface); 270 } 271 272 static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv) 273 { 274 *ppv = NULL; 275 276 if(IsEqualGUID(riid, &IID_IUnknown)) { 277 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv); 278 *ppv = iface; 279 }else if(IsEqualGUID(riid, &IID_IClassFactory)) { 280 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv); 281 *ppv = iface; 282 } 283 284 if(*ppv) { 285 IUnknown_AddRef((IUnknown*)*ppv); 286 return S_OK; 287 } 288 289 WARN("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ppv); 290 return E_NOINTERFACE; 291 } 292 293 static ULONG WINAPI CF_AddRef(IClassFactory *iface) 294 { 295 URLMON_LockModule(); 296 return 2; 297 } 298 299 static ULONG WINAPI CF_Release(IClassFactory *iface) 300 { 301 URLMON_UnlockModule(); 302 return 1; 303 } 304 305 306 static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *outer, 307 REFIID riid, void **ppv) 308 { 309 ClassFactory *This = impl_from_IClassFactory(iface); 310 IUnknown *unk; 311 HRESULT hres; 312 313 TRACE("(%p)->(%p %s %p)\n", This, outer, debugstr_guid(riid), ppv); 314 315 if(outer && !IsEqualGUID(riid, &IID_IUnknown)) { 316 *ppv = NULL; 317 return CLASS_E_NOAGGREGATION; 318 } 319 320 hres = This->pfnCreateInstance(outer, (void**)&unk); 321 if(FAILED(hres)) { 322 *ppv = NULL; 323 return hres; 324 } 325 326 if(!IsEqualGUID(riid, &IID_IUnknown)) { 327 hres = IUnknown_QueryInterface(unk, riid, ppv); 328 IUnknown_Release(unk); 329 }else { 330 *ppv = unk; 331 } 332 return hres; 333 } 334 335 static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock) 336 { 337 TRACE("(%d)\n", dolock); 338 339 if (dolock) 340 URLMON_LockModule(); 341 else 342 URLMON_UnlockModule(); 343 344 return S_OK; 345 } 346 347 static const IClassFactoryVtbl ClassFactoryVtbl = 348 { 349 CF_QueryInterface, 350 CF_AddRef, 351 CF_Release, 352 CF_CreateInstance, 353 CF_LockServer 354 }; 355 356 static ClassFactory FileProtocolCF = 357 { { &ClassFactoryVtbl }, FileProtocol_Construct}; 358 static ClassFactory FtpProtocolCF = 359 { { &ClassFactoryVtbl }, FtpProtocol_Construct}; 360 static ClassFactory GopherProtocolCF = 361 { { &ClassFactoryVtbl }, GopherProtocol_Construct}; 362 static ClassFactory HttpProtocolCF = 363 { { &ClassFactoryVtbl }, HttpProtocol_Construct}; 364 static ClassFactory HttpSProtocolCF = 365 { { &ClassFactoryVtbl }, HttpSProtocol_Construct}; 366 static ClassFactory MkProtocolCF = 367 { { &ClassFactoryVtbl }, MkProtocol_Construct}; 368 static ClassFactory SecurityManagerCF = 369 { { &ClassFactoryVtbl }, SecManagerImpl_Construct}; 370 static ClassFactory ZoneManagerCF = 371 { { &ClassFactoryVtbl }, ZoneMgrImpl_Construct}; 372 static ClassFactory StdURLMonikerCF = 373 { { &ClassFactoryVtbl }, StdURLMoniker_Construct}; 374 static ClassFactory MimeFilterCF = 375 { { &ClassFactoryVtbl }, MimeFilter_Construct}; 376 static ClassFactory CUriCF = 377 { { &ClassFactoryVtbl }, Uri_Construct}; 378 379 struct object_creation_info 380 { 381 const CLSID *clsid; 382 IClassFactory *cf; 383 LPCWSTR protocol; 384 }; 385 386 static const WCHAR wszFile[] = {'f','i','l','e',0}; 387 static const WCHAR wszFtp[] = {'f','t','p',0}; 388 static const WCHAR wszGopher[] = {'g','o','p','h','e','r',0}; 389 static const WCHAR wszHttp[] = {'h','t','t','p',0}; 390 static const WCHAR wszHttps[] = {'h','t','t','p','s',0}; 391 static const WCHAR wszMk[] = {'m','k',0}; 392 393 static const struct object_creation_info object_creation[] = 394 { 395 { &CLSID_FileProtocol, &FileProtocolCF.IClassFactory_iface, wszFile }, 396 { &CLSID_FtpProtocol, &FtpProtocolCF.IClassFactory_iface, wszFtp }, 397 { &CLSID_GopherProtocol, &GopherProtocolCF.IClassFactory_iface, wszGopher }, 398 { &CLSID_HttpProtocol, &HttpProtocolCF.IClassFactory_iface, wszHttp }, 399 { &CLSID_HttpSProtocol, &HttpSProtocolCF.IClassFactory_iface, wszHttps }, 400 { &CLSID_MkProtocol, &MkProtocolCF.IClassFactory_iface, wszMk }, 401 { &CLSID_InternetSecurityManager, &SecurityManagerCF.IClassFactory_iface, NULL }, 402 { &CLSID_InternetZoneManager, &ZoneManagerCF.IClassFactory_iface, NULL }, 403 { &CLSID_StdURLMoniker, &StdURLMonikerCF.IClassFactory_iface, NULL }, 404 { &CLSID_DeCompMimeFilter, &MimeFilterCF.IClassFactory_iface, NULL }, 405 { &CLSID_CUri, &CUriCF.IClassFactory_iface, NULL } 406 }; 407 408 static void init_session(void) 409 { 410 unsigned int i; 411 412 for(i = 0; i < ARRAY_SIZE(object_creation); i++) { 413 if(object_creation[i].protocol) 414 register_namespace(object_creation[i].cf, object_creation[i].clsid, 415 object_creation[i].protocol, TRUE); 416 } 417 } 418 419 /******************************************************************************* 420 * DllGetClassObject [URLMON.@] 421 * Retrieves class object from a DLL object 422 * 423 * NOTES 424 * Docs say returns STDAPI 425 * 426 * PARAMS 427 * rclsid [I] CLSID for the class object 428 * riid [I] Reference to identifier of interface for class object 429 * ppv [O] Address of variable to receive interface pointer for riid 430 * 431 * RETURNS 432 * Success: S_OK 433 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, 434 * E_UNEXPECTED 435 */ 436 437 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 438 { 439 unsigned int i; 440 HRESULT hr; 441 442 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 443 444 for (i = 0; i < ARRAY_SIZE(object_creation); i++) 445 { 446 if (IsEqualGUID(object_creation[i].clsid, rclsid)) 447 return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv); 448 } 449 450 hr = URLMON_DllGetClassObject(rclsid, riid, ppv); 451 if(SUCCEEDED(hr)) 452 return hr; 453 454 FIXME("%s: no class found.\n", debugstr_guid(rclsid)); 455 return CLASS_E_CLASSNOTAVAILABLE; 456 } 457 458 static HRESULT register_inf(BOOL doregister) 459 { 460 HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable); 461 HMODULE hAdvpack; 462 463 static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0}; 464 465 hAdvpack = LoadLibraryW(wszAdvpack); 466 pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall"); 467 468 return pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", NULL); 469 } 470 471 /*********************************************************************** 472 * DllRegisterServer (URLMON.@) 473 */ 474 HRESULT WINAPI DllRegisterServer(void) 475 { 476 HRESULT hr; 477 478 TRACE("\n"); 479 480 hr = URLMON_DllRegisterServer(); 481 return SUCCEEDED(hr) ? register_inf(TRUE) : hr; 482 } 483 484 /*********************************************************************** 485 * DllUnregisterServer (URLMON.@) 486 */ 487 HRESULT WINAPI DllUnregisterServer(void) 488 { 489 HRESULT hr; 490 491 TRACE("\n"); 492 493 hr = URLMON_DllUnregisterServer(); 494 return SUCCEEDED(hr) ? register_inf(FALSE) : hr; 495 } 496 497 /*********************************************************************** 498 * DllRegisterServerEx (URLMON.@) 499 */ 500 HRESULT WINAPI DllRegisterServerEx(void) 501 { 502 FIXME("(void): stub\n"); 503 504 return E_FAIL; 505 } 506 507 /************************************************************************** 508 * IsValidURL (URLMON.@) 509 * 510 * Determines if a specified string is a valid URL. 511 * 512 * PARAMS 513 * pBC [I] ignored, should be NULL. 514 * szURL [I] string that represents the URL in question. 515 * dwReserved [I] reserved and must be zero. 516 * 517 * RETURNS 518 * Success: S_OK. 519 * Failure: S_FALSE. 520 * returns E_INVALIDARG if one or more of the args is invalid. 521 * 522 * TODO: 523 * test functionality against windows to see what a valid URL is. 524 */ 525 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved) 526 { 527 FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved); 528 529 if (dwReserved || !szURL) 530 return E_INVALIDARG; 531 532 return S_OK; 533 } 534 535 /************************************************************************** 536 * FaultInIEFeature (URLMON.@) 537 * 538 * Undocumented. Appears to be used by native shdocvw.dll. 539 */ 540 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec, 541 QUERYCONTEXT *pQuery, DWORD flags ) 542 { 543 FIXME("%p %p %p %08x\n", hwnd, pClassSpec, pQuery, flags); 544 return E_NOTIMPL; 545 } 546 547 /************************************************************************** 548 * CoGetClassObjectFromURL (URLMON.@) 549 */ 550 HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS, 551 DWORD dwFileVersionLS, LPCWSTR szContentType, 552 LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved, 553 REFIID riid, LPVOID *ppv ) 554 { 555 FIXME("(%s %s %d %d %s %p %d %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL), 556 dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved, 557 debugstr_guid(riid), ppv); 558 return E_NOINTERFACE; 559 } 560 561 /*********************************************************************** 562 * ReleaseBindInfo (URLMON.@) 563 * 564 * Release the resources used by the specified BINDINFO structure. 565 * 566 * PARAMS 567 * pbindinfo [I] BINDINFO to release. 568 * 569 * RETURNS 570 * Nothing. 571 */ 572 void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo) 573 { 574 DWORD size; 575 576 TRACE("(%p)\n", pbindinfo); 577 578 if(!pbindinfo || !(size = pbindinfo->cbSize)) 579 return; 580 581 CoTaskMemFree(pbindinfo->szExtraInfo); 582 ReleaseStgMedium(&pbindinfo->stgmedData); 583 584 if(offsetof(BINDINFO, szExtraInfo) < size) 585 CoTaskMemFree(pbindinfo->szCustomVerb); 586 587 if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size) 588 IUnknown_Release(pbindinfo->pUnk); 589 590 memset(pbindinfo, 0, size); 591 pbindinfo->cbSize = size; 592 } 593 594 /*********************************************************************** 595 * CopyStgMedium (URLMON.@) 596 */ 597 HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst) 598 { 599 TRACE("(%p %p)\n", src, dst); 600 601 if(!src || !dst) 602 return E_POINTER; 603 604 *dst = *src; 605 606 switch(dst->tymed) { 607 case TYMED_NULL: 608 break; 609 case TYMED_FILE: 610 if(src->u.lpszFileName && !src->pUnkForRelease) { 611 DWORD size = (lstrlenW(src->u.lpszFileName)+1)*sizeof(WCHAR); 612 dst->u.lpszFileName = CoTaskMemAlloc(size); 613 if(!dst->u.lpszFileName) 614 return E_OUTOFMEMORY; 615 memcpy(dst->u.lpszFileName, src->u.lpszFileName, size); 616 } 617 break; 618 case TYMED_ISTREAM: 619 if(dst->u.pstm) 620 IStream_AddRef(dst->u.pstm); 621 break; 622 case TYMED_ISTORAGE: 623 if(dst->u.pstg) 624 IStorage_AddRef(dst->u.pstg); 625 break; 626 case TYMED_HGLOBAL: 627 if(dst->u.hGlobal) { 628 SIZE_T size = GlobalSize(src->u.hGlobal); 629 char *src_ptr, *dst_ptr; 630 631 dst->u.hGlobal = GlobalAlloc(GMEM_FIXED, size); 632 if(!dst->u.hGlobal) 633 return E_OUTOFMEMORY; 634 dst_ptr = GlobalLock(dst->u.hGlobal); 635 src_ptr = GlobalLock(src->u.hGlobal); 636 memcpy(dst_ptr, src_ptr, size); 637 GlobalUnlock(src_ptr); 638 GlobalUnlock(dst_ptr); 639 } 640 break; 641 default: 642 FIXME("Unimplemented tymed %d\n", src->tymed); 643 } 644 645 if(dst->pUnkForRelease) 646 IUnknown_AddRef(dst->pUnkForRelease); 647 648 return S_OK; 649 } 650 651 /*********************************************************************** 652 * CopyBindInfo (URLMON.@) 653 */ 654 HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest) 655 { 656 DWORD size; 657 HRESULT hres; 658 659 TRACE("(%p %p)\n", pcbiSrc, pcbiDest); 660 661 if(!pcbiSrc || !pcbiDest) 662 return E_POINTER; 663 if(!pcbiSrc->cbSize || !pcbiDest->cbSize) 664 return E_INVALIDARG; 665 666 size = pcbiDest->cbSize; 667 if(size > pcbiSrc->cbSize) { 668 memcpy(pcbiDest, pcbiSrc, pcbiSrc->cbSize); 669 memset((char*)pcbiDest+pcbiSrc->cbSize, 0, size-pcbiSrc->cbSize); 670 } else { 671 memcpy(pcbiDest, pcbiSrc, size); 672 } 673 pcbiDest->cbSize = size; 674 675 size = FIELD_OFFSET(BINDINFO, szExtraInfo)+sizeof(void*); 676 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szExtraInfo) { 677 size = (lstrlenW(pcbiSrc->szExtraInfo)+1)*sizeof(WCHAR); 678 pcbiDest->szExtraInfo = CoTaskMemAlloc(size); 679 if(!pcbiDest->szExtraInfo) 680 return E_OUTOFMEMORY; 681 memcpy(pcbiDest->szExtraInfo, pcbiSrc->szExtraInfo, size); 682 } 683 684 size = FIELD_OFFSET(BINDINFO, stgmedData)+sizeof(STGMEDIUM); 685 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size) { 686 hres = CopyStgMedium(&pcbiSrc->stgmedData, &pcbiDest->stgmedData); 687 if(FAILED(hres)) { 688 CoTaskMemFree(pcbiDest->szExtraInfo); 689 return hres; 690 } 691 } 692 693 size = FIELD_OFFSET(BINDINFO, szCustomVerb)+sizeof(void*); 694 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szCustomVerb) { 695 size = (lstrlenW(pcbiSrc->szCustomVerb)+1)*sizeof(WCHAR); 696 pcbiDest->szCustomVerb = CoTaskMemAlloc(size); 697 if(!pcbiDest->szCustomVerb) { 698 CoTaskMemFree(pcbiDest->szExtraInfo); 699 ReleaseStgMedium(&pcbiDest->stgmedData); 700 return E_OUTOFMEMORY; 701 } 702 memcpy(pcbiDest->szCustomVerb, pcbiSrc->szCustomVerb, size); 703 } 704 705 size = FIELD_OFFSET(BINDINFO, securityAttributes)+sizeof(SECURITY_ATTRIBUTES); 706 if(pcbiDest->cbSize >= size) 707 memset(&pcbiDest->securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES)); 708 709 if(pcbiSrc->pUnk) 710 IUnknown_AddRef(pcbiDest->pUnk); 711 712 return S_OK; 713 } 714 715 /*********************************************************************** 716 * GetClassFileOrMime (URLMON.@) 717 * 718 * Determines the class ID from the bind context, file name or MIME type. 719 */ 720 HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename, 721 LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved, 722 CLSID *pclsid) 723 { 724 FIXME("(%p, %s, %p, %d, %s, 0x%08x, %p): stub\n", pBC, debugstr_w(pszFilename), pBuffer, 725 cbBuffer, debugstr_w(pszMimeType), dwReserved, pclsid); 726 return E_NOTIMPL; 727 } 728 729 /*********************************************************************** 730 * Extract (URLMON.@) 731 */ 732 HRESULT WINAPI Extract(void *dest, LPCSTR szCabName) 733 { 734 HRESULT (WINAPI *pExtract)(void *, LPCSTR); 735 736 if (!hCabinet) 737 hCabinet = LoadLibraryA("cabinet.dll"); 738 739 if (!hCabinet) return HRESULT_FROM_WIN32(GetLastError()); 740 pExtract = (void *)GetProcAddress(hCabinet, "Extract"); 741 if (!pExtract) return HRESULT_FROM_WIN32(GetLastError()); 742 743 return pExtract(dest, szCabName); 744 } 745 746 /*********************************************************************** 747 * IsLoggingEnabledA (URLMON.@) 748 */ 749 BOOL WINAPI IsLoggingEnabledA(LPCSTR url) 750 { 751 FIXME("(%s)\n", debugstr_a(url)); 752 return FALSE; 753 } 754 755 /*********************************************************************** 756 * IsLoggingEnabledW (URLMON.@) 757 */ 758 BOOL WINAPI IsLoggingEnabledW(LPCWSTR url) 759 { 760 FIXME("(%s)\n", debugstr_w(url)); 761 return FALSE; 762 } 763 764 /*********************************************************************** 765 * IsProtectedModeURL (URLMON.111) 766 * Undocumented, added in IE7 767 */ 768 BOOL WINAPI IsProtectedModeURL(const WCHAR *url) 769 { 770 FIXME("stub: %s\n", debugstr_w(url)); 771 return TRUE; 772 } 773 774 /*********************************************************************** 775 * LogSqmBits (URLMON.410) 776 * Undocumented, added in IE8 777 */ 778 int WINAPI LogSqmBits(DWORD unk1, DWORD unk2) 779 { 780 FIXME("stub: %d %d\n", unk1, unk2); 781 return 0; 782 } 783 784 /*********************************************************************** 785 * LogSqmUXCommandOffsetInternal (URLMON.423) 786 * Undocumented, added in IE8 787 */ 788 void WINAPI LogSqmUXCommandOffsetInternal(DWORD unk1, DWORD unk2, DWORD unk3, DWORD unk4) 789 { 790 FIXME("stub: %d %d %d %d\n", unk1, unk2, unk3, unk4); 791 } 792 793 /*********************************************************************** 794 * MapUriToBrowserEmulationState (URLMON.444) 795 * Undocumented, added in IE8 796 */ 797 int WINAPI MapUriToBrowserEmulationState(DWORD unk1, DWORD unk2, DWORD unk3) 798 { 799 FIXME("stub: %d %d %d\n", unk1, unk2, unk3); 800 return 0; 801 } 802 803 /*********************************************************************** 804 * MapBrowserEmulationModeToUserAgent (URLMON.445) 805 * Undocumented, added in IE8 806 */ 807 int WINAPI MapBrowserEmulationModeToUserAgent(DWORD unk1, DWORD unk2) 808 { 809 FIXME("stub: %d %d\n", unk1, unk2); 810 return 0; 811 } 812 813 /*********************************************************************** 814 * CoInternetGetBrowserProfile (URLMON.446) 815 * Undocumented, added in IE8 816 */ 817 HRESULT WINAPI CoInternetGetBrowserProfile(DWORD unk) 818 { 819 FIXME("%x: stub\n", unk); 820 return E_NOTIMPL; 821 } 822 823 /*********************************************************************** 824 * FlushUrlmonZonesCache (URLMON.455) 825 * Undocumented, added in IE8 826 */ 827 void WINAPI FlushUrlmonZonesCache(void) 828 { 829 FIXME("stub\n"); 830 } 831 832 /*********************************************************************** 833 * RegisterMediaTypes 834 * Added in IE3, registers known MIME-type strings. 835 */ 836 HRESULT WINAPI RegisterMediaTypes(UINT types, LPCSTR *szTypes, CLIPFORMAT *cfTypes) 837 { 838 FIXME("stub: %u %p %p\n", types, szTypes, cfTypes); 839 return E_INVALIDARG; 840 } 841 842 /*********************************************************************** 843 * ShouldShowIntranetWarningSecband 844 * Undocumented, added in IE7 845 */ 846 BOOL WINAPI ShouldShowIntranetWarningSecband(DWORD unk) 847 { 848 FIXME("%x: stub\n", unk); 849 return FALSE; 850 } 851 852 /*********************************************************************** 853 * GetIUriPriv (urlmon.@) 854 * 855 * Not documented. 856 */ 857 HRESULT WINAPI GetIUriPriv(IUri *uri, void **p) 858 { 859 FIXME("(%p,%p): stub\n", uri, p); 860 *p = NULL; 861 return E_NOTIMPL; 862 } 863