windows.applicationmodel/tests: Use PathRemoveFileSpecW() instead of PathCchRemoveFil...
[wine.git] / dlls / urlmon / urlmon_main.c
blob491313b7cf8c12da7c3397a4e912b544d3c2e1d2
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 #include "urlmon_main.h"
25 #include "winreg.h"
27 #define NO_SHLWAPI_REG
28 #include "shlwapi.h"
29 #include "advpub.h"
30 #include "initguid.h"
32 #include "wine/debug.h"
34 #include "urlmon.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
38 DEFINE_GUID(CLSID_CUri, 0xDF2FCE13, 0x25EC, 0x45BB, 0x9D,0x4C, 0xCE,0xCD,0x47,0xC2,0x43,0x0C);
40 LONG URLMON_refCount = 0;
41 HINSTANCE urlmon_instance;
43 static HMODULE hCabinet = NULL;
44 static DWORD urlmon_tls = TLS_OUT_OF_INDEXES;
46 static void init_session(void);
48 static struct list tls_list = LIST_INIT(tls_list);
50 static CRITICAL_SECTION tls_cs;
51 static CRITICAL_SECTION_DEBUG tls_cs_dbg =
53 0, 0, &tls_cs,
54 { &tls_cs_dbg.ProcessLocksList, &tls_cs_dbg.ProcessLocksList },
55 0, 0, { (DWORD_PTR)(__FILE__ ": tls") }
58 static CRITICAL_SECTION tls_cs = { &tls_cs_dbg, -1, 0, 0, 0, 0 };
60 tls_data_t *get_tls_data(void)
62 tls_data_t *data;
64 if(urlmon_tls == TLS_OUT_OF_INDEXES) {
65 DWORD tls = TlsAlloc();
66 if(tls == TLS_OUT_OF_INDEXES)
67 return NULL;
69 tls = InterlockedCompareExchange((LONG*)&urlmon_tls, tls, TLS_OUT_OF_INDEXES);
70 if(tls != urlmon_tls)
71 TlsFree(tls);
74 data = TlsGetValue(urlmon_tls);
75 if(!data) {
76 data = calloc(1, sizeof(tls_data_t));
77 if(!data)
78 return NULL;
80 EnterCriticalSection(&tls_cs);
81 list_add_tail(&tls_list, &data->entry);
82 LeaveCriticalSection(&tls_cs);
84 TlsSetValue(urlmon_tls, data);
87 return data;
90 static void free_tls_list(void)
92 tls_data_t *data;
94 if(urlmon_tls == TLS_OUT_OF_INDEXES)
95 return;
97 while(!list_empty(&tls_list)) {
98 data = LIST_ENTRY(list_head(&tls_list), tls_data_t, entry);
99 list_remove(&data->entry);
100 free(data);
103 TlsFree(urlmon_tls);
106 static void detach_thread(void)
108 tls_data_t *data;
110 if(urlmon_tls == TLS_OUT_OF_INDEXES)
111 return;
113 data = TlsGetValue(urlmon_tls);
114 if(!data)
115 return;
117 EnterCriticalSection(&tls_cs);
118 list_remove(&data->entry);
119 LeaveCriticalSection(&tls_cs);
121 if(data->notif_hwnd) {
122 WARN("notif_hwnd not destroyed\n");
123 DestroyWindow(data->notif_hwnd);
126 free(data);
129 static void process_detach(void)
131 HINTERNET internet_session;
133 internet_session = get_internet_session(NULL);
134 if(internet_session)
135 InternetCloseHandle(internet_session);
137 if (hCabinet)
138 FreeLibrary(hCabinet);
140 free_session();
141 free_tls_list();
142 unregister_notif_wnd_class();
145 /***********************************************************************
146 * DllMain (URLMON.init)
148 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
150 TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
152 URLMON_DllMain( hinstDLL, fdwReason, fImpLoad );
154 switch(fdwReason) {
155 case DLL_PROCESS_ATTACH:
156 urlmon_instance = hinstDLL;
157 init_session();
158 break;
160 case DLL_PROCESS_DETACH:
161 if (fImpLoad) break;
162 process_detach();
163 DeleteCriticalSection(&tls_cs);
164 break;
166 case DLL_THREAD_DETACH:
167 detach_thread();
168 break;
170 return TRUE;
173 const char *debugstr_bindstatus(ULONG status)
175 switch(status) {
176 #define X(x) case x: return #x
177 X(BINDSTATUS_FINDINGRESOURCE);
178 X(BINDSTATUS_CONNECTING);
179 X(BINDSTATUS_REDIRECTING);
180 X(BINDSTATUS_BEGINDOWNLOADDATA);
181 X(BINDSTATUS_DOWNLOADINGDATA);
182 X(BINDSTATUS_ENDDOWNLOADDATA);
183 X(BINDSTATUS_BEGINDOWNLOADCOMPONENTS);
184 X(BINDSTATUS_INSTALLINGCOMPONENTS);
185 X(BINDSTATUS_ENDDOWNLOADCOMPONENTS);
186 X(BINDSTATUS_USINGCACHEDCOPY);
187 X(BINDSTATUS_SENDINGREQUEST);
188 X(BINDSTATUS_CLASSIDAVAILABLE);
189 X(BINDSTATUS_MIMETYPEAVAILABLE);
190 X(BINDSTATUS_CACHEFILENAMEAVAILABLE);
191 X(BINDSTATUS_BEGINSYNCOPERATION);
192 X(BINDSTATUS_ENDSYNCOPERATION);
193 X(BINDSTATUS_BEGINUPLOADDATA);
194 X(BINDSTATUS_UPLOADINGDATA);
195 X(BINDSTATUS_ENDUPLOADINGDATA);
196 X(BINDSTATUS_PROTOCOLCLASSID);
197 X(BINDSTATUS_ENCODING);
198 X(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE);
199 X(BINDSTATUS_CLASSINSTALLLOCATION);
200 X(BINDSTATUS_DECODING);
201 X(BINDSTATUS_LOADINGMIMEHANDLER);
202 X(BINDSTATUS_CONTENTDISPOSITIONATTACH);
203 X(BINDSTATUS_FILTERREPORTMIMETYPE);
204 X(BINDSTATUS_CLSIDCANINSTANTIATE);
205 X(BINDSTATUS_IUNKNOWNAVAILABLE);
206 X(BINDSTATUS_DIRECTBIND);
207 X(BINDSTATUS_RAWMIMETYPE);
208 X(BINDSTATUS_PROXYDETECTING);
209 X(BINDSTATUS_ACCEPTRANGES);
210 X(BINDSTATUS_COOKIE_SENT);
211 X(BINDSTATUS_COMPACT_POLICY_RECEIVED);
212 X(BINDSTATUS_COOKIE_SUPPRESSED);
213 X(BINDSTATUS_COOKIE_STATE_UNKNOWN);
214 X(BINDSTATUS_COOKIE_STATE_ACCEPT);
215 X(BINDSTATUS_COOKIE_STATE_REJECT);
216 X(BINDSTATUS_COOKIE_STATE_PROMPT);
217 X(BINDSTATUS_COOKIE_STATE_LEASH);
218 X(BINDSTATUS_COOKIE_STATE_DOWNGRADE);
219 X(BINDSTATUS_POLICY_HREF);
220 X(BINDSTATUS_P3P_HEADER);
221 X(BINDSTATUS_SESSION_COOKIE_RECEIVED);
222 X(BINDSTATUS_PERSISTENT_COOKIE_RECEIVED);
223 X(BINDSTATUS_SESSION_COOKIES_ALLOWED);
224 X(BINDSTATUS_CACHECONTROL);
225 X(BINDSTATUS_CONTENTDISPOSITIONFILENAME);
226 X(BINDSTATUS_MIMETEXTPLAINMISMATCH);
227 X(BINDSTATUS_PUBLISHERAVAILABLE);
228 X(BINDSTATUS_DISPLAYNAMEAVAILABLE);
229 #undef X
230 default:
231 return wine_dbg_sprintf("(invalid status %lu)", status);
235 /***********************************************************************
236 * DllInstall (URLMON.@)
238 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
240 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
241 debugstr_w(cmdline));
243 return S_OK;
246 /***********************************************************************
247 * DllCanUnloadNow (URLMON.@)
249 HRESULT WINAPI DllCanUnloadNow(void)
251 return URLMON_refCount != 0 ? S_FALSE : S_OK;
256 /******************************************************************************
257 * Urlmon ClassFactory
259 typedef struct {
260 IClassFactory IClassFactory_iface;
262 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
263 } ClassFactory;
265 static inline ClassFactory *impl_from_IClassFactory(IClassFactory *iface)
267 return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface);
270 static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv)
272 *ppv = NULL;
274 if(IsEqualGUID(riid, &IID_IUnknown)) {
275 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
276 *ppv = iface;
277 }else if(IsEqualGUID(riid, &IID_IClassFactory)) {
278 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
279 *ppv = iface;
282 if(*ppv) {
283 IUnknown_AddRef((IUnknown*)*ppv);
284 return S_OK;
287 WARN("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ppv);
288 return E_NOINTERFACE;
291 static ULONG WINAPI CF_AddRef(IClassFactory *iface)
293 URLMON_LockModule();
294 return 2;
297 static ULONG WINAPI CF_Release(IClassFactory *iface)
299 URLMON_UnlockModule();
300 return 1;
304 static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *outer,
305 REFIID riid, void **ppv)
307 ClassFactory *This = impl_from_IClassFactory(iface);
308 IUnknown *unk;
309 HRESULT hres;
311 TRACE("(%p)->(%p %s %p)\n", This, outer, debugstr_guid(riid), ppv);
313 if(outer && !IsEqualGUID(riid, &IID_IUnknown)) {
314 *ppv = NULL;
315 return CLASS_E_NOAGGREGATION;
318 hres = This->pfnCreateInstance(outer, (void**)&unk);
319 if(FAILED(hres)) {
320 *ppv = NULL;
321 return hres;
324 if(!IsEqualGUID(riid, &IID_IUnknown)) {
325 hres = IUnknown_QueryInterface(unk, riid, ppv);
326 IUnknown_Release(unk);
327 }else {
328 *ppv = unk;
330 return hres;
333 static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
335 TRACE("(%d)\n", dolock);
337 if (dolock)
338 URLMON_LockModule();
339 else
340 URLMON_UnlockModule();
342 return S_OK;
345 static const IClassFactoryVtbl ClassFactoryVtbl =
347 CF_QueryInterface,
348 CF_AddRef,
349 CF_Release,
350 CF_CreateInstance,
351 CF_LockServer
354 static ClassFactory FileProtocolCF =
355 { { &ClassFactoryVtbl }, FileProtocol_Construct};
356 static ClassFactory FtpProtocolCF =
357 { { &ClassFactoryVtbl }, FtpProtocol_Construct};
358 static ClassFactory GopherProtocolCF =
359 { { &ClassFactoryVtbl }, GopherProtocol_Construct};
360 static ClassFactory HttpProtocolCF =
361 { { &ClassFactoryVtbl }, HttpProtocol_Construct};
362 static ClassFactory HttpSProtocolCF =
363 { { &ClassFactoryVtbl }, HttpSProtocol_Construct};
364 static ClassFactory MkProtocolCF =
365 { { &ClassFactoryVtbl }, MkProtocol_Construct};
366 static ClassFactory SecurityManagerCF =
367 { { &ClassFactoryVtbl }, SecManagerImpl_Construct};
368 static ClassFactory ZoneManagerCF =
369 { { &ClassFactoryVtbl }, ZoneMgrImpl_Construct};
370 static ClassFactory StdURLMonikerCF =
371 { { &ClassFactoryVtbl }, StdURLMoniker_Construct};
372 static ClassFactory MimeFilterCF =
373 { { &ClassFactoryVtbl }, MimeFilter_Construct};
374 static ClassFactory CUriCF =
375 { { &ClassFactoryVtbl }, Uri_Construct};
377 struct object_creation_info
379 const CLSID *clsid;
380 IClassFactory *cf;
381 LPCWSTR protocol;
384 static const struct object_creation_info object_creation[] =
386 { &CLSID_FileProtocol, &FileProtocolCF.IClassFactory_iface, L"file" },
387 { &CLSID_FtpProtocol, &FtpProtocolCF.IClassFactory_iface, L"ftp" },
388 { &CLSID_GopherProtocol, &GopherProtocolCF.IClassFactory_iface, L"gopher" },
389 { &CLSID_HttpProtocol, &HttpProtocolCF.IClassFactory_iface, L"http" },
390 { &CLSID_HttpSProtocol, &HttpSProtocolCF.IClassFactory_iface, L"https" },
391 { &CLSID_MkProtocol, &MkProtocolCF.IClassFactory_iface, L"mk" },
392 { &CLSID_InternetSecurityManager, &SecurityManagerCF.IClassFactory_iface, NULL },
393 { &CLSID_InternetZoneManager, &ZoneManagerCF.IClassFactory_iface, NULL },
394 { &CLSID_StdURLMoniker, &StdURLMonikerCF.IClassFactory_iface, NULL },
395 { &CLSID_DeCompMimeFilter, &MimeFilterCF.IClassFactory_iface, NULL },
396 { &CLSID_CUri, &CUriCF.IClassFactory_iface, NULL }
399 static void init_session(void)
401 unsigned int i;
403 for(i = 0; i < ARRAY_SIZE(object_creation); i++) {
404 if(object_creation[i].protocol)
405 register_namespace(object_creation[i].cf, object_creation[i].clsid,
406 object_creation[i].protocol, TRUE);
410 /*******************************************************************************
411 * DllGetClassObject [URLMON.@]
412 * Retrieves class object from a DLL object
414 * NOTES
415 * Docs say returns STDAPI
417 * PARAMS
418 * rclsid [I] CLSID for the class object
419 * riid [I] Reference to identifier of interface for class object
420 * ppv [O] Address of variable to receive interface pointer for riid
422 * RETURNS
423 * Success: S_OK
424 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
425 * E_UNEXPECTED
428 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
430 unsigned int i;
431 HRESULT hr;
433 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
435 for (i = 0; i < ARRAY_SIZE(object_creation); i++)
437 if (IsEqualGUID(object_creation[i].clsid, rclsid))
438 return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv);
441 hr = URLMON_DllGetClassObject(rclsid, riid, ppv);
442 if(SUCCEEDED(hr))
443 return hr;
445 FIXME("%s: no class found.\n", debugstr_guid(rclsid));
446 return CLASS_E_CLASSNOTAVAILABLE;
449 static HRESULT register_inf(BOOL doregister)
451 HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
452 HMODULE hAdvpack;
454 hAdvpack = LoadLibraryW(L"advpack.dll");
455 pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
457 return pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", NULL);
460 /***********************************************************************
461 * DllRegisterServer (URLMON.@)
463 HRESULT WINAPI DllRegisterServer(void)
465 HRESULT hr;
467 TRACE("\n");
469 hr = URLMON_DllRegisterServer();
470 return SUCCEEDED(hr) ? register_inf(TRUE) : hr;
473 /***********************************************************************
474 * DllUnregisterServer (URLMON.@)
476 HRESULT WINAPI DllUnregisterServer(void)
478 HRESULT hr;
480 TRACE("\n");
482 hr = URLMON_DllUnregisterServer();
483 return SUCCEEDED(hr) ? register_inf(FALSE) : hr;
486 /***********************************************************************
487 * DllRegisterServerEx (URLMON.@)
489 HRESULT WINAPI DllRegisterServerEx(void)
491 FIXME("(void): stub\n");
493 return E_FAIL;
496 /**************************************************************************
497 * IsValidURL (URLMON.@)
499 * Determines if a specified string is a valid URL.
501 * PARAMS
502 * pBC [I] ignored, should be NULL.
503 * szURL [I] string that represents the URL in question.
504 * dwReserved [I] reserved and must be zero.
506 * RETURNS
507 * Success: S_OK.
508 * Failure: S_FALSE.
509 * returns E_INVALIDARG if one or more of the args is invalid.
511 * TODO:
512 * test functionality against windows to see what a valid URL is.
514 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
516 FIXME("(%p, %s, %ld): stub\n", pBC, debugstr_w(szURL), dwReserved);
518 if (dwReserved || !szURL)
519 return E_INVALIDARG;
521 return S_OK;
524 /**************************************************************************
525 * FaultInIEFeature (URLMON.@)
527 * Undocumented. Appears to be used by native shdocvw.dll.
529 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
530 QUERYCONTEXT *pQuery, DWORD flags )
532 FIXME("%p %p %p %08lx\n", hwnd, pClassSpec, pQuery, flags);
533 return E_NOTIMPL;
536 /**************************************************************************
537 * CoGetClassObjectFromURL (URLMON.@)
539 HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS,
540 DWORD dwFileVersionLS, LPCWSTR szContentType,
541 LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
542 REFIID riid, LPVOID *ppv )
544 FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
545 dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
546 debugstr_guid(riid), ppv);
547 return E_NOINTERFACE;
550 /***********************************************************************
551 * ReleaseBindInfo (URLMON.@)
553 * Release the resources used by the specified BINDINFO structure.
555 * PARAMS
556 * pbindinfo [I] BINDINFO to release.
558 * RETURNS
559 * Nothing.
561 void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo)
563 DWORD size;
565 TRACE("(%p)\n", pbindinfo);
567 if(!pbindinfo || !(size = pbindinfo->cbSize))
568 return;
570 CoTaskMemFree(pbindinfo->szExtraInfo);
571 ReleaseStgMedium(&pbindinfo->stgmedData);
573 if(offsetof(BINDINFO, szExtraInfo) < size)
574 CoTaskMemFree(pbindinfo->szCustomVerb);
576 if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size)
577 IUnknown_Release(pbindinfo->pUnk);
579 memset(pbindinfo, 0, size);
580 pbindinfo->cbSize = size;
583 /***********************************************************************
584 * CopyStgMedium (URLMON.@)
586 HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
588 TRACE("(%p %p)\n", src, dst);
590 if(!src || !dst)
591 return E_POINTER;
593 *dst = *src;
595 switch(dst->tymed) {
596 case TYMED_NULL:
597 break;
598 case TYMED_FILE:
599 if(src->lpszFileName && !src->pUnkForRelease) {
600 DWORD size = (lstrlenW(src->lpszFileName)+1)*sizeof(WCHAR);
601 dst->lpszFileName = CoTaskMemAlloc(size);
602 if(!dst->lpszFileName)
603 return E_OUTOFMEMORY;
604 memcpy(dst->lpszFileName, src->lpszFileName, size);
606 break;
607 case TYMED_ISTREAM:
608 if(dst->pstm)
609 IStream_AddRef(dst->pstm);
610 break;
611 case TYMED_ISTORAGE:
612 if(dst->pstg)
613 IStorage_AddRef(dst->pstg);
614 break;
615 case TYMED_HGLOBAL:
616 if(dst->hGlobal) {
617 SIZE_T size = GlobalSize(src->hGlobal);
618 char *src_ptr, *dst_ptr;
620 dst->hGlobal = GlobalAlloc(GMEM_FIXED, size);
621 if(!dst->hGlobal)
622 return E_OUTOFMEMORY;
623 dst_ptr = GlobalLock(dst->hGlobal);
624 src_ptr = GlobalLock(src->hGlobal);
625 memcpy(dst_ptr, src_ptr, size);
626 GlobalUnlock(src_ptr);
627 GlobalUnlock(dst_ptr);
629 break;
630 default:
631 FIXME("Unimplemented tymed %ld\n", src->tymed);
634 if(dst->pUnkForRelease)
635 IUnknown_AddRef(dst->pUnkForRelease);
637 return S_OK;
640 /***********************************************************************
641 * CopyBindInfo (URLMON.@)
643 HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest)
645 DWORD size;
646 HRESULT hres;
648 TRACE("(%p %p)\n", pcbiSrc, pcbiDest);
650 if(!pcbiSrc || !pcbiDest)
651 return E_POINTER;
652 if(!pcbiSrc->cbSize || !pcbiDest->cbSize)
653 return E_INVALIDARG;
655 size = pcbiDest->cbSize;
656 if(size > pcbiSrc->cbSize) {
657 memcpy(pcbiDest, pcbiSrc, pcbiSrc->cbSize);
658 memset((char*)pcbiDest+pcbiSrc->cbSize, 0, size-pcbiSrc->cbSize);
659 } else {
660 memcpy(pcbiDest, pcbiSrc, size);
662 pcbiDest->cbSize = size;
664 size = FIELD_OFFSET(BINDINFO, szExtraInfo)+sizeof(void*);
665 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szExtraInfo) {
666 size = (lstrlenW(pcbiSrc->szExtraInfo)+1)*sizeof(WCHAR);
667 pcbiDest->szExtraInfo = CoTaskMemAlloc(size);
668 if(!pcbiDest->szExtraInfo)
669 return E_OUTOFMEMORY;
670 memcpy(pcbiDest->szExtraInfo, pcbiSrc->szExtraInfo, size);
673 size = FIELD_OFFSET(BINDINFO, stgmedData)+sizeof(STGMEDIUM);
674 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size) {
675 hres = CopyStgMedium(&pcbiSrc->stgmedData, &pcbiDest->stgmedData);
676 if(FAILED(hres)) {
677 CoTaskMemFree(pcbiDest->szExtraInfo);
678 return hres;
682 size = FIELD_OFFSET(BINDINFO, szCustomVerb)+sizeof(void*);
683 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szCustomVerb) {
684 size = (lstrlenW(pcbiSrc->szCustomVerb)+1)*sizeof(WCHAR);
685 pcbiDest->szCustomVerb = CoTaskMemAlloc(size);
686 if(!pcbiDest->szCustomVerb) {
687 CoTaskMemFree(pcbiDest->szExtraInfo);
688 ReleaseStgMedium(&pcbiDest->stgmedData);
689 return E_OUTOFMEMORY;
691 memcpy(pcbiDest->szCustomVerb, pcbiSrc->szCustomVerb, size);
694 size = FIELD_OFFSET(BINDINFO, securityAttributes)+sizeof(SECURITY_ATTRIBUTES);
695 if(pcbiDest->cbSize >= size)
696 memset(&pcbiDest->securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
698 if(pcbiSrc->pUnk)
699 IUnknown_AddRef(pcbiDest->pUnk);
701 return S_OK;
704 /***********************************************************************
705 * GetClassFileOrMime (URLMON.@)
707 * Determines the class ID from the bind context, file name or MIME type.
709 HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename,
710 LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved,
711 CLSID *pclsid)
713 FIXME("(%p, %s, %p, %ld, %s, 0x%08lx, %p): stub\n", pBC, debugstr_w(pszFilename), pBuffer,
714 cbBuffer, debugstr_w(pszMimeType), dwReserved, pclsid);
715 return E_NOTIMPL;
718 /***********************************************************************
719 * Extract (URLMON.@)
721 HRESULT WINAPI Extract(void *dest, LPCSTR szCabName)
723 HRESULT (WINAPI *pExtract)(void *, LPCSTR);
725 if (!hCabinet)
726 hCabinet = LoadLibraryA("cabinet.dll");
728 if (!hCabinet) return HRESULT_FROM_WIN32(GetLastError());
729 pExtract = (void *)GetProcAddress(hCabinet, "Extract");
730 if (!pExtract) return HRESULT_FROM_WIN32(GetLastError());
732 return pExtract(dest, szCabName);
735 /***********************************************************************
736 * IsLoggingEnabledA (URLMON.@)
738 BOOL WINAPI IsLoggingEnabledA(LPCSTR url)
740 FIXME("(%s)\n", debugstr_a(url));
741 return FALSE;
744 /***********************************************************************
745 * IsLoggingEnabledW (URLMON.@)
747 BOOL WINAPI IsLoggingEnabledW(LPCWSTR url)
749 FIXME("(%s)\n", debugstr_w(url));
750 return FALSE;
753 /***********************************************************************
754 * IsProtectedModeURL (URLMON.111)
755 * Undocumented, added in IE7
757 BOOL WINAPI IsProtectedModeURL(const WCHAR *url)
759 FIXME("stub: %s\n", debugstr_w(url));
760 return TRUE;
763 /***********************************************************************
764 * LogSqmBits (URLMON.410)
765 * Undocumented, added in IE8
767 int WINAPI LogSqmBits(DWORD unk1, DWORD unk2)
769 FIXME("stub: %ld %ld\n", unk1, unk2);
770 return 0;
773 /***********************************************************************
774 * LogSqmUXCommandOffsetInternal (URLMON.423)
775 * Undocumented, added in IE8
777 void WINAPI LogSqmUXCommandOffsetInternal(DWORD unk1, DWORD unk2, DWORD unk3, DWORD unk4)
779 FIXME("stub: %ld %ld %ld %ld\n", unk1, unk2, unk3, unk4);
782 /***********************************************************************
783 * MapUriToBrowserEmulationState (URLMON.444)
784 * Undocumented, added in IE8
786 int WINAPI MapUriToBrowserEmulationState(DWORD unk1, DWORD unk2, DWORD unk3)
788 FIXME("stub: %ld %ld %ld\n", unk1, unk2, unk3);
789 return 0;
792 /***********************************************************************
793 * CoInternetGetBrowserProfile (URLMON.446)
794 * Undocumented, added in IE8
796 HRESULT WINAPI CoInternetGetBrowserProfile(DWORD unk)
798 FIXME("%lx: stub\n", unk);
799 return E_NOTIMPL;
802 /***********************************************************************
803 * FlushUrlmonZonesCache (URLMON.455)
804 * Undocumented, added in IE8
806 void WINAPI FlushUrlmonZonesCache(void)
808 FIXME("stub\n");
811 /***********************************************************************
812 * RegisterMediaTypes
813 * Added in IE3, registers known MIME-type strings.
815 HRESULT WINAPI RegisterMediaTypes(UINT types, LPCSTR *szTypes, CLIPFORMAT *cfTypes)
817 FIXME("stub: %u %p %p\n", types, szTypes, cfTypes);
818 return E_INVALIDARG;
821 /***********************************************************************
822 * ShouldShowIntranetWarningSecband
823 * Undocumented, added in IE7
825 BOOL WINAPI ShouldShowIntranetWarningSecband(DWORD unk)
827 FIXME("%lx: stub\n", unk);
828 return FALSE;
831 /***********************************************************************
832 * GetIUriPriv (urlmon.@)
834 * Not documented.
836 HRESULT WINAPI GetIUriPriv(IUri *uri, void **p)
838 FIXME("(%p,%p): stub\n", uri, p);
839 *p = NULL;
840 return E_NOTIMPL;