ntdll: Use a separate memory allocation for the kernel stack.
[wine.git] / dlls / urlmon / urlmon_main.c
blob00ccc449e15e1e328e159806d2a0055e913725d3
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 = calloc(1, 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 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 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%lx %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 %lu)", 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 *outer,
307 REFIID riid, void **ppv)
309 ClassFactory *This = impl_from_IClassFactory(iface);
310 IUnknown *unk;
311 HRESULT hres;
313 TRACE("(%p)->(%p %s %p)\n", This, outer, debugstr_guid(riid), ppv);
315 if(outer && !IsEqualGUID(riid, &IID_IUnknown)) {
316 *ppv = NULL;
317 return CLASS_E_NOAGGREGATION;
320 hres = This->pfnCreateInstance(outer, (void**)&unk);
321 if(FAILED(hres)) {
322 *ppv = NULL;
323 return hres;
326 if(!IsEqualGUID(riid, &IID_IUnknown)) {
327 hres = IUnknown_QueryInterface(unk, riid, ppv);
328 IUnknown_Release(unk);
329 }else {
330 *ppv = unk;
332 return hres;
335 static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
337 TRACE("(%d)\n", dolock);
339 if (dolock)
340 URLMON_LockModule();
341 else
342 URLMON_UnlockModule();
344 return S_OK;
347 static const IClassFactoryVtbl ClassFactoryVtbl =
349 CF_QueryInterface,
350 CF_AddRef,
351 CF_Release,
352 CF_CreateInstance,
353 CF_LockServer
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};
379 struct object_creation_info
381 const CLSID *clsid;
382 IClassFactory *cf;
383 LPCWSTR protocol;
386 static const struct object_creation_info object_creation[] =
388 { &CLSID_FileProtocol, &FileProtocolCF.IClassFactory_iface, L"file" },
389 { &CLSID_FtpProtocol, &FtpProtocolCF.IClassFactory_iface, L"ftp" },
390 { &CLSID_GopherProtocol, &GopherProtocolCF.IClassFactory_iface, L"gopher" },
391 { &CLSID_HttpProtocol, &HttpProtocolCF.IClassFactory_iface, L"http" },
392 { &CLSID_HttpSProtocol, &HttpSProtocolCF.IClassFactory_iface, L"https" },
393 { &CLSID_MkProtocol, &MkProtocolCF.IClassFactory_iface, L"mk" },
394 { &CLSID_InternetSecurityManager, &SecurityManagerCF.IClassFactory_iface, NULL },
395 { &CLSID_InternetZoneManager, &ZoneManagerCF.IClassFactory_iface, NULL },
396 { &CLSID_StdURLMoniker, &StdURLMonikerCF.IClassFactory_iface, NULL },
397 { &CLSID_DeCompMimeFilter, &MimeFilterCF.IClassFactory_iface, NULL },
398 { &CLSID_CUri, &CUriCF.IClassFactory_iface, NULL }
401 static void init_session(void)
403 unsigned int i;
405 for(i = 0; i < ARRAY_SIZE(object_creation); i++) {
406 if(object_creation[i].protocol)
407 register_namespace(object_creation[i].cf, object_creation[i].clsid,
408 object_creation[i].protocol, TRUE);
412 /*******************************************************************************
413 * DllGetClassObject [URLMON.@]
414 * Retrieves class object from a DLL object
416 * NOTES
417 * Docs say returns STDAPI
419 * PARAMS
420 * rclsid [I] CLSID for the class object
421 * riid [I] Reference to identifier of interface for class object
422 * ppv [O] Address of variable to receive interface pointer for riid
424 * RETURNS
425 * Success: S_OK
426 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
427 * E_UNEXPECTED
430 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
432 unsigned int i;
433 HRESULT hr;
435 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
437 for (i = 0; i < ARRAY_SIZE(object_creation); i++)
439 if (IsEqualGUID(object_creation[i].clsid, rclsid))
440 return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv);
443 hr = URLMON_DllGetClassObject(rclsid, riid, ppv);
444 if(SUCCEEDED(hr))
445 return hr;
447 FIXME("%s: no class found.\n", debugstr_guid(rclsid));
448 return CLASS_E_CLASSNOTAVAILABLE;
451 static HRESULT register_inf(BOOL doregister)
453 HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
454 HMODULE hAdvpack;
456 hAdvpack = LoadLibraryW(L"advpack.dll");
457 pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
459 return pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", NULL);
462 /***********************************************************************
463 * DllRegisterServer (URLMON.@)
465 HRESULT WINAPI DllRegisterServer(void)
467 HRESULT hr;
469 TRACE("\n");
471 hr = URLMON_DllRegisterServer();
472 return SUCCEEDED(hr) ? register_inf(TRUE) : hr;
475 /***********************************************************************
476 * DllUnregisterServer (URLMON.@)
478 HRESULT WINAPI DllUnregisterServer(void)
480 HRESULT hr;
482 TRACE("\n");
484 hr = URLMON_DllUnregisterServer();
485 return SUCCEEDED(hr) ? register_inf(FALSE) : hr;
488 /***********************************************************************
489 * DllRegisterServerEx (URLMON.@)
491 HRESULT WINAPI DllRegisterServerEx(void)
493 FIXME("(void): stub\n");
495 return E_FAIL;
498 /**************************************************************************
499 * IsValidURL (URLMON.@)
501 * Determines if a specified string is a valid URL.
503 * PARAMS
504 * pBC [I] ignored, should be NULL.
505 * szURL [I] string that represents the URL in question.
506 * dwReserved [I] reserved and must be zero.
508 * RETURNS
509 * Success: S_OK.
510 * Failure: S_FALSE.
511 * returns E_INVALIDARG if one or more of the args is invalid.
513 * TODO:
514 * test functionality against windows to see what a valid URL is.
516 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
518 FIXME("(%p, %s, %ld): stub\n", pBC, debugstr_w(szURL), dwReserved);
520 if (dwReserved || !szURL)
521 return E_INVALIDARG;
523 return S_OK;
526 /**************************************************************************
527 * FaultInIEFeature (URLMON.@)
529 * Undocumented. Appears to be used by native shdocvw.dll.
531 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
532 QUERYCONTEXT *pQuery, DWORD flags )
534 FIXME("%p %p %p %08lx\n", hwnd, pClassSpec, pQuery, flags);
535 return E_NOTIMPL;
538 /**************************************************************************
539 * CoGetClassObjectFromURL (URLMON.@)
541 HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS,
542 DWORD dwFileVersionLS, LPCWSTR szContentType,
543 LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
544 REFIID riid, LPVOID *ppv )
546 FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
547 dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
548 debugstr_guid(riid), ppv);
549 return E_NOINTERFACE;
552 /***********************************************************************
553 * ReleaseBindInfo (URLMON.@)
555 * Release the resources used by the specified BINDINFO structure.
557 * PARAMS
558 * pbindinfo [I] BINDINFO to release.
560 * RETURNS
561 * Nothing.
563 void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo)
565 DWORD size;
567 TRACE("(%p)\n", pbindinfo);
569 if(!pbindinfo || !(size = pbindinfo->cbSize))
570 return;
572 CoTaskMemFree(pbindinfo->szExtraInfo);
573 ReleaseStgMedium(&pbindinfo->stgmedData);
575 if(offsetof(BINDINFO, szExtraInfo) < size)
576 CoTaskMemFree(pbindinfo->szCustomVerb);
578 if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size)
579 IUnknown_Release(pbindinfo->pUnk);
581 memset(pbindinfo, 0, size);
582 pbindinfo->cbSize = size;
585 /***********************************************************************
586 * CopyStgMedium (URLMON.@)
588 HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
590 TRACE("(%p %p)\n", src, dst);
592 if(!src || !dst)
593 return E_POINTER;
595 *dst = *src;
597 switch(dst->tymed) {
598 case TYMED_NULL:
599 break;
600 case TYMED_FILE:
601 if(src->u.lpszFileName && !src->pUnkForRelease) {
602 DWORD size = (lstrlenW(src->u.lpszFileName)+1)*sizeof(WCHAR);
603 dst->u.lpszFileName = CoTaskMemAlloc(size);
604 if(!dst->u.lpszFileName)
605 return E_OUTOFMEMORY;
606 memcpy(dst->u.lpszFileName, src->u.lpszFileName, size);
608 break;
609 case TYMED_ISTREAM:
610 if(dst->u.pstm)
611 IStream_AddRef(dst->u.pstm);
612 break;
613 case TYMED_ISTORAGE:
614 if(dst->u.pstg)
615 IStorage_AddRef(dst->u.pstg);
616 break;
617 case TYMED_HGLOBAL:
618 if(dst->u.hGlobal) {
619 SIZE_T size = GlobalSize(src->u.hGlobal);
620 char *src_ptr, *dst_ptr;
622 dst->u.hGlobal = GlobalAlloc(GMEM_FIXED, size);
623 if(!dst->u.hGlobal)
624 return E_OUTOFMEMORY;
625 dst_ptr = GlobalLock(dst->u.hGlobal);
626 src_ptr = GlobalLock(src->u.hGlobal);
627 memcpy(dst_ptr, src_ptr, size);
628 GlobalUnlock(src_ptr);
629 GlobalUnlock(dst_ptr);
631 break;
632 default:
633 FIXME("Unimplemented tymed %ld\n", src->tymed);
636 if(dst->pUnkForRelease)
637 IUnknown_AddRef(dst->pUnkForRelease);
639 return S_OK;
642 /***********************************************************************
643 * CopyBindInfo (URLMON.@)
645 HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest)
647 DWORD size;
648 HRESULT hres;
650 TRACE("(%p %p)\n", pcbiSrc, pcbiDest);
652 if(!pcbiSrc || !pcbiDest)
653 return E_POINTER;
654 if(!pcbiSrc->cbSize || !pcbiDest->cbSize)
655 return E_INVALIDARG;
657 size = pcbiDest->cbSize;
658 if(size > pcbiSrc->cbSize) {
659 memcpy(pcbiDest, pcbiSrc, pcbiSrc->cbSize);
660 memset((char*)pcbiDest+pcbiSrc->cbSize, 0, size-pcbiSrc->cbSize);
661 } else {
662 memcpy(pcbiDest, pcbiSrc, size);
664 pcbiDest->cbSize = size;
666 size = FIELD_OFFSET(BINDINFO, szExtraInfo)+sizeof(void*);
667 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szExtraInfo) {
668 size = (lstrlenW(pcbiSrc->szExtraInfo)+1)*sizeof(WCHAR);
669 pcbiDest->szExtraInfo = CoTaskMemAlloc(size);
670 if(!pcbiDest->szExtraInfo)
671 return E_OUTOFMEMORY;
672 memcpy(pcbiDest->szExtraInfo, pcbiSrc->szExtraInfo, size);
675 size = FIELD_OFFSET(BINDINFO, stgmedData)+sizeof(STGMEDIUM);
676 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size) {
677 hres = CopyStgMedium(&pcbiSrc->stgmedData, &pcbiDest->stgmedData);
678 if(FAILED(hres)) {
679 CoTaskMemFree(pcbiDest->szExtraInfo);
680 return hres;
684 size = FIELD_OFFSET(BINDINFO, szCustomVerb)+sizeof(void*);
685 if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szCustomVerb) {
686 size = (lstrlenW(pcbiSrc->szCustomVerb)+1)*sizeof(WCHAR);
687 pcbiDest->szCustomVerb = CoTaskMemAlloc(size);
688 if(!pcbiDest->szCustomVerb) {
689 CoTaskMemFree(pcbiDest->szExtraInfo);
690 ReleaseStgMedium(&pcbiDest->stgmedData);
691 return E_OUTOFMEMORY;
693 memcpy(pcbiDest->szCustomVerb, pcbiSrc->szCustomVerb, size);
696 size = FIELD_OFFSET(BINDINFO, securityAttributes)+sizeof(SECURITY_ATTRIBUTES);
697 if(pcbiDest->cbSize >= size)
698 memset(&pcbiDest->securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
700 if(pcbiSrc->pUnk)
701 IUnknown_AddRef(pcbiDest->pUnk);
703 return S_OK;
706 /***********************************************************************
707 * GetClassFileOrMime (URLMON.@)
709 * Determines the class ID from the bind context, file name or MIME type.
711 HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename,
712 LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved,
713 CLSID *pclsid)
715 FIXME("(%p, %s, %p, %ld, %s, 0x%08lx, %p): stub\n", pBC, debugstr_w(pszFilename), pBuffer,
716 cbBuffer, debugstr_w(pszMimeType), dwReserved, pclsid);
717 return E_NOTIMPL;
720 /***********************************************************************
721 * Extract (URLMON.@)
723 HRESULT WINAPI Extract(void *dest, LPCSTR szCabName)
725 HRESULT (WINAPI *pExtract)(void *, LPCSTR);
727 if (!hCabinet)
728 hCabinet = LoadLibraryA("cabinet.dll");
730 if (!hCabinet) return HRESULT_FROM_WIN32(GetLastError());
731 pExtract = (void *)GetProcAddress(hCabinet, "Extract");
732 if (!pExtract) return HRESULT_FROM_WIN32(GetLastError());
734 return pExtract(dest, szCabName);
737 /***********************************************************************
738 * IsLoggingEnabledA (URLMON.@)
740 BOOL WINAPI IsLoggingEnabledA(LPCSTR url)
742 FIXME("(%s)\n", debugstr_a(url));
743 return FALSE;
746 /***********************************************************************
747 * IsLoggingEnabledW (URLMON.@)
749 BOOL WINAPI IsLoggingEnabledW(LPCWSTR url)
751 FIXME("(%s)\n", debugstr_w(url));
752 return FALSE;
755 /***********************************************************************
756 * IsProtectedModeURL (URLMON.111)
757 * Undocumented, added in IE7
759 BOOL WINAPI IsProtectedModeURL(const WCHAR *url)
761 FIXME("stub: %s\n", debugstr_w(url));
762 return TRUE;
765 /***********************************************************************
766 * LogSqmBits (URLMON.410)
767 * Undocumented, added in IE8
769 int WINAPI LogSqmBits(DWORD unk1, DWORD unk2)
771 FIXME("stub: %ld %ld\n", unk1, unk2);
772 return 0;
775 /***********************************************************************
776 * LogSqmUXCommandOffsetInternal (URLMON.423)
777 * Undocumented, added in IE8
779 void WINAPI LogSqmUXCommandOffsetInternal(DWORD unk1, DWORD unk2, DWORD unk3, DWORD unk4)
781 FIXME("stub: %ld %ld %ld %ld\n", unk1, unk2, unk3, unk4);
784 /***********************************************************************
785 * MapUriToBrowserEmulationState (URLMON.444)
786 * Undocumented, added in IE8
788 int WINAPI MapUriToBrowserEmulationState(DWORD unk1, DWORD unk2, DWORD unk3)
790 FIXME("stub: %ld %ld %ld\n", unk1, unk2, unk3);
791 return 0;
794 /***********************************************************************
795 * CoInternetGetBrowserProfile (URLMON.446)
796 * Undocumented, added in IE8
798 HRESULT WINAPI CoInternetGetBrowserProfile(DWORD unk)
800 FIXME("%lx: stub\n", unk);
801 return E_NOTIMPL;
804 /***********************************************************************
805 * FlushUrlmonZonesCache (URLMON.455)
806 * Undocumented, added in IE8
808 void WINAPI FlushUrlmonZonesCache(void)
810 FIXME("stub\n");
813 /***********************************************************************
814 * RegisterMediaTypes
815 * Added in IE3, registers known MIME-type strings.
817 HRESULT WINAPI RegisterMediaTypes(UINT types, LPCSTR *szTypes, CLIPFORMAT *cfTypes)
819 FIXME("stub: %u %p %p\n", types, szTypes, cfTypes);
820 return E_INVALIDARG;
823 /***********************************************************************
824 * ShouldShowIntranetWarningSecband
825 * Undocumented, added in IE7
827 BOOL WINAPI ShouldShowIntranetWarningSecband(DWORD unk)
829 FIXME("%lx: stub\n", unk);
830 return FALSE;
833 /***********************************************************************
834 * GetIUriPriv (urlmon.@)
836 * Not documented.
838 HRESULT WINAPI GetIUriPriv(IUri *uri, void **p)
840 FIXME("(%p,%p): stub\n", uri, p);
841 *p = NULL;
842 return E_NOTIMPL;