vcomp/tests: Add tests for atomic double functions.
[wine.git] / dlls / urlmon / urlmon_main.c
blobc4f1cec5fa0855505eb484e3eca389bbd45bb20f
1 /*
2 * UrlMon
4 * Copyright (c) 2000 Patrik Stridvall
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.
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.
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
21 #include <stdarg.h>
23 #define NONAMELESSUNION
25 #include "urlmon_main.h"
27 #include "winreg.h"
29 #define NO_SHLWAPI_REG
30 #include "shlwapi.h"
31 #include "advpub.h"
32 #include "initguid.h"
34 #include "wine/debug.h"
36 #include "urlmon.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
40 DEFINE_GUID(CLSID_CUri, 0xDF2FCE13, 0x25EC, 0x45BB, 0x9D,0x4C, 0xCE,0xCD,0x47,0xC2,0x43,0x0C);
42 LONG URLMON_refCount = 0;
43 HINSTANCE urlmon_instance;
45 static HMODULE hCabinet = NULL;
46 static DWORD urlmon_tls = TLS_OUT_OF_INDEXES;
48 static void init_session(void);
50 static struct list tls_list = LIST_INIT(tls_list);
52 static CRITICAL_SECTION tls_cs;
53 static CRITICAL_SECTION_DEBUG tls_cs_dbg =
55 0, 0, &tls_cs,
56 { &tls_cs_dbg.ProcessLocksList, &tls_cs_dbg.ProcessLocksList },
57 0, 0, { (DWORD_PTR)(__FILE__ ": tls") }
60 static CRITICAL_SECTION tls_cs = { &tls_cs_dbg, -1, 0, 0, 0, 0 };
62 tls_data_t *get_tls_data(void)
64 tls_data_t *data;
66 if(urlmon_tls == TLS_OUT_OF_INDEXES) {
67 DWORD tls = TlsAlloc();
68 if(tls == TLS_OUT_OF_INDEXES)
69 return NULL;
71 tls = InterlockedCompareExchange((LONG*)&urlmon_tls, tls, TLS_OUT_OF_INDEXES);
72 if(tls != urlmon_tls)
73 TlsFree(tls);
76 data = TlsGetValue(urlmon_tls);
77 if(!data) {
78 data = heap_alloc_zero(sizeof(tls_data_t));
79 if(!data)
80 return NULL;
82 EnterCriticalSection(&tls_cs);
83 list_add_tail(&tls_list, &data->entry);
84 LeaveCriticalSection(&tls_cs);
86 TlsSetValue(urlmon_tls, data);
89 return data;
92 static void free_tls_list(void)
94 tls_data_t *data;
96 if(urlmon_tls == TLS_OUT_OF_INDEXES)
97 return;
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);
105 TlsFree(urlmon_tls);
108 static void detach_thread(void)
110 tls_data_t *data;
112 if(urlmon_tls == TLS_OUT_OF_INDEXES)
113 return;
115 data = TlsGetValue(urlmon_tls);
116 if(!data)
117 return;
119 EnterCriticalSection(&tls_cs);
120 list_remove(&data->entry);
121 LeaveCriticalSection(&tls_cs);
123 if(data->notif_hwnd) {
124 WARN("notif_hwnd not destroyed\n");
125 DestroyWindow(data->notif_hwnd);
128 heap_free(data);
131 static void process_detach(void)
133 HINTERNET internet_session;
135 internet_session = get_internet_session(NULL);
136 if(internet_session)
137 InternetCloseHandle(internet_session);
139 if (hCabinet)
140 FreeLibrary(hCabinet);
142 free_session();
143 free_tls_list();
144 unregister_notif_wnd_class();
147 /***********************************************************************
148 * DllMain (URLMON.init)
150 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
152 TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
154 URLMON_DllMain( hinstDLL, fdwReason, fImpLoad );
156 switch(fdwReason) {
157 case DLL_PROCESS_ATTACH:
158 urlmon_instance = hinstDLL;
159 init_session();
160 break;
162 case DLL_PROCESS_DETACH:
163 if (fImpLoad) break;
164 process_detach();
165 DeleteCriticalSection(&tls_cs);
166 break;
168 case DLL_THREAD_DETACH:
169 detach_thread();
170 break;
172 return TRUE;
175 const char *debugstr_bindstatus(ULONG status)
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);
237 /***********************************************************************
238 * DllInstall (URLMON.@)
240 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
242 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
243 debugstr_w(cmdline));
245 return S_OK;
248 /***********************************************************************
249 * DllCanUnloadNow (URLMON.@)
251 HRESULT WINAPI DllCanUnloadNow(void)
253 return URLMON_refCount != 0 ? S_FALSE : S_OK;
258 /******************************************************************************
259 * Urlmon ClassFactory
261 typedef struct {
262 IClassFactory IClassFactory_iface;
264 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
265 } ClassFactory;
267 static inline ClassFactory *impl_from_IClassFactory(IClassFactory *iface)
269 return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface);
272 static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv)
274 *ppv = NULL;
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;
284 if(*ppv) {
285 IUnknown_AddRef((IUnknown*)*ppv);
286 return S_OK;
289 WARN("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ppv);
290 return E_NOINTERFACE;
293 static ULONG WINAPI CF_AddRef(IClassFactory *iface)
295 URLMON_LockModule();
296 return 2;
299 static ULONG WINAPI CF_Release(IClassFactory *iface)
301 URLMON_UnlockModule();
302 return 1;
306 static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
307 REFIID riid, LPVOID *ppobj)
309 ClassFactory *This = impl_from_IClassFactory(iface);
310 HRESULT hres;
311 LPUNKNOWN punk;
313 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
315 *ppobj = NULL;
316 if(SUCCEEDED(hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk))) {
317 hres = IUnknown_QueryInterface(punk, riid, ppobj);
318 IUnknown_Release(punk);
320 return hres;
323 static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
325 TRACE("(%d)\n", dolock);
327 if (dolock)
328 URLMON_LockModule();
329 else
330 URLMON_UnlockModule();
332 return S_OK;
335 static const IClassFactoryVtbl ClassFactoryVtbl =
337 CF_QueryInterface,
338 CF_AddRef,
339 CF_Release,
340 CF_CreateInstance,
341 CF_LockServer
344 static ClassFactory FileProtocolCF =
345 { { &ClassFactoryVtbl }, FileProtocol_Construct};
346 static ClassFactory FtpProtocolCF =
347 { { &ClassFactoryVtbl }, FtpProtocol_Construct};
348 static ClassFactory GopherProtocolCF =
349 { { &ClassFactoryVtbl }, GopherProtocol_Construct};
350 static ClassFactory HttpProtocolCF =
351 { { &ClassFactoryVtbl }, HttpProtocol_Construct};
352 static ClassFactory HttpSProtocolCF =
353 { { &ClassFactoryVtbl }, HttpSProtocol_Construct};
354 static ClassFactory MkProtocolCF =
355 { { &ClassFactoryVtbl }, MkProtocol_Construct};
356 static ClassFactory SecurityManagerCF =
357 { { &ClassFactoryVtbl }, SecManagerImpl_Construct};
358 static ClassFactory ZoneManagerCF =
359 { { &ClassFactoryVtbl }, ZoneMgrImpl_Construct};
360 static ClassFactory StdURLMonikerCF =
361 { { &ClassFactoryVtbl }, StdURLMoniker_Construct};
362 static ClassFactory MimeFilterCF =
363 { { &ClassFactoryVtbl }, MimeFilter_Construct};
364 static ClassFactory CUriCF =
365 { { &ClassFactoryVtbl }, Uri_Construct};
367 struct object_creation_info
369 const CLSID *clsid;
370 IClassFactory *cf;
371 LPCWSTR protocol;
374 static const WCHAR wszFile[] = {'f','i','l','e',0};
375 static const WCHAR wszFtp[] = {'f','t','p',0};
376 static const WCHAR wszGopher[] = {'g','o','p','h','e','r',0};
377 static const WCHAR wszHttp[] = {'h','t','t','p',0};
378 static const WCHAR wszHttps[] = {'h','t','t','p','s',0};
379 static const WCHAR wszMk[] = {'m','k',0};
381 static const struct object_creation_info object_creation[] =
383 { &CLSID_FileProtocol, &FileProtocolCF.IClassFactory_iface, wszFile },
384 { &CLSID_FtpProtocol, &FtpProtocolCF.IClassFactory_iface, wszFtp },
385 { &CLSID_GopherProtocol, &GopherProtocolCF.IClassFactory_iface, wszGopher },
386 { &CLSID_HttpProtocol, &HttpProtocolCF.IClassFactory_iface, wszHttp },
387 { &CLSID_HttpSProtocol, &HttpSProtocolCF.IClassFactory_iface, wszHttps },
388 { &CLSID_MkProtocol, &MkProtocolCF.IClassFactory_iface, wszMk },
389 { &CLSID_InternetSecurityManager, &SecurityManagerCF.IClassFactory_iface, NULL },
390 { &CLSID_InternetZoneManager, &ZoneManagerCF.IClassFactory_iface, NULL },
391 { &CLSID_StdURLMoniker, &StdURLMonikerCF.IClassFactory_iface, NULL },
392 { &CLSID_DeCompMimeFilter, &MimeFilterCF.IClassFactory_iface, NULL },
393 { &CLSID_CUri, &CUriCF.IClassFactory_iface, NULL }
396 static void init_session(void)
398 unsigned int i;
400 for(i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) {
401 if(object_creation[i].protocol)
402 register_namespace(object_creation[i].cf, object_creation[i].clsid,
403 object_creation[i].protocol, TRUE);
407 /*******************************************************************************
408 * DllGetClassObject [URLMON.@]
409 * Retrieves class object from a DLL object
411 * NOTES
412 * Docs say returns STDAPI
414 * PARAMS
415 * rclsid [I] CLSID for the class object
416 * riid [I] Reference to identifier of interface for class object
417 * ppv [O] Address of variable to receive interface pointer for riid
419 * RETURNS
420 * Success: S_OK
421 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
422 * E_UNEXPECTED
425 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
427 unsigned int i;
428 HRESULT hr;
430 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
432 for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
434 if (IsEqualGUID(object_creation[i].clsid, rclsid))
435 return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv);
438 hr = URLMON_DllGetClassObject(rclsid, riid, ppv);
439 if(SUCCEEDED(hr))
440 return hr;
442 FIXME("%s: no class found.\n", debugstr_guid(rclsid));
443 return CLASS_E_CLASSNOTAVAILABLE;
446 static HRESULT register_inf(BOOL doregister)
448 HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
449 HMODULE hAdvpack;
451 static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
453 hAdvpack = LoadLibraryW(wszAdvpack);
454 pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
456 return pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", NULL);
459 /***********************************************************************
460 * DllRegisterServer (URLMON.@)
462 HRESULT WINAPI DllRegisterServer(void)
464 HRESULT hr;
466 TRACE("\n");
468 hr = URLMON_DllRegisterServer();
469 return SUCCEEDED(hr) ? register_inf(TRUE) : hr;
472 /***********************************************************************
473 * DllUnregisterServer (URLMON.@)
475 HRESULT WINAPI DllUnregisterServer(void)
477 HRESULT hr;
479 TRACE("\n");
481 hr = URLMON_DllUnregisterServer();
482 return SUCCEEDED(hr) ? register_inf(FALSE) : hr;
485 /***********************************************************************
486 * DllRegisterServerEx (URLMON.@)
488 HRESULT WINAPI DllRegisterServerEx(void)
490 FIXME("(void): stub\n");
492 return E_FAIL;
495 /**************************************************************************
496 * IsValidURL (URLMON.@)
498 * Determines if a specified string is a valid URL.
500 * PARAMS
501 * pBC [I] ignored, should be NULL.
502 * szURL [I] string that represents the URL in question.
503 * dwReserved [I] reserved and must be zero.
505 * RETURNS
506 * Success: S_OK.
507 * Failure: S_FALSE.
508 * returns E_INVALIDARG if one or more of the args is invalid.
510 * TODO:
511 * test functionality against windows to see what a valid URL is.
513 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
515 FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved);
517 if (dwReserved || !szURL)
518 return E_INVALIDARG;
520 return S_OK;
523 /**************************************************************************
524 * FaultInIEFeature (URLMON.@)
526 * Undocumented. Appears to be used by native shdocvw.dll.
528 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
529 QUERYCONTEXT *pQuery, DWORD flags )
531 FIXME("%p %p %p %08x\n", hwnd, pClassSpec, pQuery, flags);
532 return E_NOTIMPL;
535 /**************************************************************************
536 * CoGetClassObjectFromURL (URLMON.@)
538 HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS,
539 DWORD dwFileVersionLS, LPCWSTR szContentType,
540 LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
541 REFIID riid, LPVOID *ppv )
543 FIXME("(%s %s %d %d %s %p %d %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
544 dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
545 debugstr_guid(riid), ppv);
546 return E_NOINTERFACE;
549 /***********************************************************************
550 * ReleaseBindInfo (URLMON.@)
552 * Release the resources used by the specified BINDINFO structure.
554 * PARAMS
555 * pbindinfo [I] BINDINFO to release.
557 * RETURNS
558 * Nothing.
560 void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo)
562 DWORD size;
564 TRACE("(%p)\n", pbindinfo);
566 if(!pbindinfo || !(size = pbindinfo->cbSize))
567 return;
569 CoTaskMemFree(pbindinfo->szExtraInfo);
570 ReleaseStgMedium(&pbindinfo->stgmedData);
572 if(offsetof(BINDINFO, szExtraInfo) < size)
573 CoTaskMemFree(pbindinfo->szCustomVerb);
575 if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size)
576 IUnknown_Release(pbindinfo->pUnk);
578 memset(pbindinfo, 0, size);
579 pbindinfo->cbSize = size;
582 /***********************************************************************
583 * CopyStgMedium (URLMON.@)
585 HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
587 TRACE("(%p %p)\n", src, dst);
589 if(!src || !dst)
590 return E_POINTER;
592 *dst = *src;
594 switch(dst->tymed) {
595 case TYMED_NULL:
596 break;
597 case TYMED_FILE:
598 if(src->u.lpszFileName && !src->pUnkForRelease) {
599 DWORD size = (strlenW(src->u.lpszFileName)+1)*sizeof(WCHAR);
600 dst->u.lpszFileName = CoTaskMemAlloc(size);
601 if(!dst->u.lpszFileName)
602 return E_OUTOFMEMORY;
603 memcpy(dst->u.lpszFileName, src->u.lpszFileName, size);
605 break;
606 case TYMED_ISTREAM:
607 if(dst->u.pstm)
608 IStream_AddRef(dst->u.pstm);
609 break;
610 case TYMED_ISTORAGE:
611 if(dst->u.pstg)
612 IStorage_AddRef(dst->u.pstg);
613 break;
614 case TYMED_HGLOBAL:
615 if(dst->u.hGlobal) {
616 SIZE_T size = GlobalSize(src->u.hGlobal);
617 char *src_ptr, *dst_ptr;
619 dst->u.hGlobal = GlobalAlloc(GMEM_FIXED, size);
620 if(!dst->u.hGlobal)
621 return E_OUTOFMEMORY;
622 dst_ptr = GlobalLock(dst->u.hGlobal);
623 src_ptr = GlobalLock(src->u.hGlobal);
624 memcpy(dst_ptr, src_ptr, size);
625 GlobalUnlock(src_ptr);
626 GlobalUnlock(dst_ptr);
628 break;
629 default:
630 FIXME("Unimplemented tymed %d\n", src->tymed);
633 if(dst->pUnkForRelease)
634 IUnknown_AddRef(dst->pUnkForRelease);
636 return S_OK;
639 /***********************************************************************
640 * CopyBindInfo (URLMON.@)
642 HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest)
644 DWORD size;
645 HRESULT hres;
647 TRACE("(%p %p)\n", pcbiSrc, pcbiDest);
649 if(!pcbiSrc || !pcbiDest)
650 return E_POINTER;
651 if(!pcbiSrc->cbSize || !pcbiDest->cbSize)
652 return E_INVALIDARG;
654 size = pcbiDest->cbSize;
655 if(size > pcbiSrc->cbSize) {
656 memcpy(pcbiDest, pcbiSrc, pcbiSrc->cbSize);
657 memset((char*)pcbiDest+pcbiSrc->cbSize, 0, size-pcbiSrc->cbSize);
658 } else {
659 memcpy(pcbiDest, pcbiSrc, size);
661 pcbiDest->cbSize = size;
663 size = FIELD_OFFSET(BINDINFO, szExtraInfo)+sizeof(void*);
664 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szExtraInfo) {
665 size = (strlenW(pcbiSrc->szExtraInfo)+1)*sizeof(WCHAR);
666 pcbiDest->szExtraInfo = CoTaskMemAlloc(size);
667 if(!pcbiDest->szExtraInfo)
668 return E_OUTOFMEMORY;
669 memcpy(pcbiDest->szExtraInfo, pcbiSrc->szExtraInfo, size);
672 size = FIELD_OFFSET(BINDINFO, stgmedData)+sizeof(STGMEDIUM);
673 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size) {
674 hres = CopyStgMedium(&pcbiSrc->stgmedData, &pcbiDest->stgmedData);
675 if(FAILED(hres)) {
676 CoTaskMemFree(pcbiDest->szExtraInfo);
677 return hres;
681 size = FIELD_OFFSET(BINDINFO, szCustomVerb)+sizeof(void*);
682 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szCustomVerb) {
683 size = (strlenW(pcbiSrc->szCustomVerb)+1)*sizeof(WCHAR);
684 pcbiDest->szCustomVerb = CoTaskMemAlloc(size);
685 if(!pcbiDest->szCustomVerb) {
686 CoTaskMemFree(pcbiDest->szExtraInfo);
687 ReleaseStgMedium(&pcbiDest->stgmedData);
688 return E_OUTOFMEMORY;
690 memcpy(pcbiDest->szCustomVerb, pcbiSrc->szCustomVerb, size);
693 size = FIELD_OFFSET(BINDINFO, securityAttributes)+sizeof(SECURITY_ATTRIBUTES);
694 if(pcbiDest->cbSize >= size)
695 memset(&pcbiDest->securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
697 if(pcbiSrc->pUnk)
698 IUnknown_AddRef(pcbiDest->pUnk);
700 return S_OK;
703 /***********************************************************************
704 * GetClassFileOrMime (URLMON.@)
706 * Determines the class ID from the bind context, file name or MIME type.
708 HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename,
709 LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved,
710 CLSID *pclsid)
712 FIXME("(%p, %s, %p, %d, %s, 0x%08x, %p): stub\n", pBC, debugstr_w(pszFilename), pBuffer,
713 cbBuffer, debugstr_w(pszMimeType), dwReserved, pclsid);
714 return E_NOTIMPL;
717 /***********************************************************************
718 * Extract (URLMON.@)
720 HRESULT WINAPI Extract(void *dest, LPCSTR szCabName)
722 HRESULT (WINAPI *pExtract)(void *, LPCSTR);
724 if (!hCabinet)
725 hCabinet = LoadLibraryA("cabinet.dll");
727 if (!hCabinet) return HRESULT_FROM_WIN32(GetLastError());
728 pExtract = (void *)GetProcAddress(hCabinet, "Extract");
729 if (!pExtract) return HRESULT_FROM_WIN32(GetLastError());
731 return pExtract(dest, szCabName);
734 /***********************************************************************
735 * IsLoggingEnabledA (URLMON.@)
737 BOOL WINAPI IsLoggingEnabledA(LPCSTR url)
739 FIXME("(%s)\n", debugstr_a(url));
740 return FALSE;
743 /***********************************************************************
744 * IsLoggingEnabledW (URLMON.@)
746 BOOL WINAPI IsLoggingEnabledW(LPCWSTR url)
748 FIXME("(%s)\n", debugstr_w(url));
749 return FALSE;
752 /***********************************************************************
753 * IsProtectedModeURL (URLMON.111)
754 * Undocumented, added in IE7
756 BOOL WINAPI IsProtectedModeURL(const WCHAR *url)
758 FIXME("stub: %s\n", debugstr_w(url));
759 return TRUE;
762 /***********************************************************************
763 * LogSqmBits (URLMON.410)
764 * Undocumented, added in IE8
766 int WINAPI LogSqmBits(DWORD unk1, DWORD unk2)
768 FIXME("stub: %d %d\n", unk1, unk2);
769 return 0;
772 /***********************************************************************
773 * LogSqmUXCommandOffsetInternal (URLMON.423)
774 * Undocumented, added in IE8
776 void WINAPI LogSqmUXCommandOffsetInternal(DWORD unk1, DWORD unk2, DWORD unk3, DWORD unk4)
778 FIXME("stub: %d %d %d %d\n", unk1, unk2, unk3, unk4);
781 /***********************************************************************
782 * MapUriToBrowserEmulationState (URLMON.444)
783 * Undocumented, added in IE8
785 int WINAPI MapUriToBrowserEmulationState(DWORD unk1, DWORD unk2, DWORD unk3)
787 FIXME("stub: %d %d %d\n", unk1, unk2, unk3);
788 return 0;
791 /***********************************************************************
792 * MapBrowserEmulationModeToUserAgent (URLMON.445)
793 * Undocumented, added in IE8
795 int WINAPI MapBrowserEmulationModeToUserAgent(DWORD unk1, DWORD unk2)
797 FIXME("stub: %d %d\n", unk1, unk2);
798 return 0;
801 /***********************************************************************
802 * FlushUrlmonZonesCache (URLMON.455)
803 * Undocumented, added in IE8
805 void WINAPI FlushUrlmonZonesCache(void)
807 FIXME("stub\n");
810 /***********************************************************************
811 * RegisterMediaTypes
812 * Added in IE3, registers known MIME-type strings.
814 HRESULT WINAPI RegisterMediaTypes(UINT types, LPCSTR *szTypes, CLIPFORMAT *cfTypes)
816 FIXME("stub: %u %p %p\n", types, szTypes, cfTypes);
817 return E_INVALIDARG;