mstask: Use wide-char string literals.
[wine.git] / dlls / urlmon / urlmon_main.c
blob0e98b9e3fc94b2c1e6fb559f759d3f665f40f963
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 *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 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};
393 static const struct object_creation_info object_creation[] =
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 }
408 static void init_session(void)
410 unsigned int i;
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);
419 /*******************************************************************************
420 * DllGetClassObject [URLMON.@]
421 * Retrieves class object from a DLL object
423 * NOTES
424 * Docs say returns STDAPI
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
431 * RETURNS
432 * Success: S_OK
433 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
434 * E_UNEXPECTED
437 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
439 unsigned int i;
440 HRESULT hr;
442 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
444 for (i = 0; i < ARRAY_SIZE(object_creation); i++)
446 if (IsEqualGUID(object_creation[i].clsid, rclsid))
447 return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv);
450 hr = URLMON_DllGetClassObject(rclsid, riid, ppv);
451 if(SUCCEEDED(hr))
452 return hr;
454 FIXME("%s: no class found.\n", debugstr_guid(rclsid));
455 return CLASS_E_CLASSNOTAVAILABLE;
458 static HRESULT register_inf(BOOL doregister)
460 HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
461 HMODULE hAdvpack;
463 static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
465 hAdvpack = LoadLibraryW(wszAdvpack);
466 pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
468 return pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", NULL);
471 /***********************************************************************
472 * DllRegisterServer (URLMON.@)
474 HRESULT WINAPI DllRegisterServer(void)
476 HRESULT hr;
478 TRACE("\n");
480 hr = URLMON_DllRegisterServer();
481 return SUCCEEDED(hr) ? register_inf(TRUE) : hr;
484 /***********************************************************************
485 * DllUnregisterServer (URLMON.@)
487 HRESULT WINAPI DllUnregisterServer(void)
489 HRESULT hr;
491 TRACE("\n");
493 hr = URLMON_DllUnregisterServer();
494 return SUCCEEDED(hr) ? register_inf(FALSE) : hr;
497 /***********************************************************************
498 * DllRegisterServerEx (URLMON.@)
500 HRESULT WINAPI DllRegisterServerEx(void)
502 FIXME("(void): stub\n");
504 return E_FAIL;
507 /**************************************************************************
508 * IsValidURL (URLMON.@)
510 * Determines if a specified string is a valid URL.
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.
517 * RETURNS
518 * Success: S_OK.
519 * Failure: S_FALSE.
520 * returns E_INVALIDARG if one or more of the args is invalid.
522 * TODO:
523 * test functionality against windows to see what a valid URL is.
525 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
527 FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved);
529 if (dwReserved || !szURL)
530 return E_INVALIDARG;
532 return S_OK;
535 /**************************************************************************
536 * FaultInIEFeature (URLMON.@)
538 * Undocumented. Appears to be used by native shdocvw.dll.
540 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
541 QUERYCONTEXT *pQuery, DWORD flags )
543 FIXME("%p %p %p %08x\n", hwnd, pClassSpec, pQuery, flags);
544 return E_NOTIMPL;
547 /**************************************************************************
548 * CoGetClassObjectFromURL (URLMON.@)
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 )
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;
561 /***********************************************************************
562 * ReleaseBindInfo (URLMON.@)
564 * Release the resources used by the specified BINDINFO structure.
566 * PARAMS
567 * pbindinfo [I] BINDINFO to release.
569 * RETURNS
570 * Nothing.
572 void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo)
574 DWORD size;
576 TRACE("(%p)\n", pbindinfo);
578 if(!pbindinfo || !(size = pbindinfo->cbSize))
579 return;
581 CoTaskMemFree(pbindinfo->szExtraInfo);
582 ReleaseStgMedium(&pbindinfo->stgmedData);
584 if(offsetof(BINDINFO, szExtraInfo) < size)
585 CoTaskMemFree(pbindinfo->szCustomVerb);
587 if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size)
588 IUnknown_Release(pbindinfo->pUnk);
590 memset(pbindinfo, 0, size);
591 pbindinfo->cbSize = size;
594 /***********************************************************************
595 * CopyStgMedium (URLMON.@)
597 HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
599 TRACE("(%p %p)\n", src, dst);
601 if(!src || !dst)
602 return E_POINTER;
604 *dst = *src;
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);
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;
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);
640 break;
641 default:
642 FIXME("Unimplemented tymed %d\n", src->tymed);
645 if(dst->pUnkForRelease)
646 IUnknown_AddRef(dst->pUnkForRelease);
648 return S_OK;
651 /***********************************************************************
652 * CopyBindInfo (URLMON.@)
654 HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest)
656 DWORD size;
657 HRESULT hres;
659 TRACE("(%p %p)\n", pcbiSrc, pcbiDest);
661 if(!pcbiSrc || !pcbiDest)
662 return E_POINTER;
663 if(!pcbiSrc->cbSize || !pcbiDest->cbSize)
664 return E_INVALIDARG;
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);
673 pcbiDest->cbSize = size;
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);
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;
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;
702 memcpy(pcbiDest->szCustomVerb, pcbiSrc->szCustomVerb, size);
705 size = FIELD_OFFSET(BINDINFO, securityAttributes)+sizeof(SECURITY_ATTRIBUTES);
706 if(pcbiDest->cbSize >= size)
707 memset(&pcbiDest->securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
709 if(pcbiSrc->pUnk)
710 IUnknown_AddRef(pcbiDest->pUnk);
712 return S_OK;
715 /***********************************************************************
716 * GetClassFileOrMime (URLMON.@)
718 * Determines the class ID from the bind context, file name or MIME type.
720 HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename,
721 LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved,
722 CLSID *pclsid)
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;
729 /***********************************************************************
730 * Extract (URLMON.@)
732 HRESULT WINAPI Extract(void *dest, LPCSTR szCabName)
734 HRESULT (WINAPI *pExtract)(void *, LPCSTR);
736 if (!hCabinet)
737 hCabinet = LoadLibraryA("cabinet.dll");
739 if (!hCabinet) return HRESULT_FROM_WIN32(GetLastError());
740 pExtract = (void *)GetProcAddress(hCabinet, "Extract");
741 if (!pExtract) return HRESULT_FROM_WIN32(GetLastError());
743 return pExtract(dest, szCabName);
746 /***********************************************************************
747 * IsLoggingEnabledA (URLMON.@)
749 BOOL WINAPI IsLoggingEnabledA(LPCSTR url)
751 FIXME("(%s)\n", debugstr_a(url));
752 return FALSE;
755 /***********************************************************************
756 * IsLoggingEnabledW (URLMON.@)
758 BOOL WINAPI IsLoggingEnabledW(LPCWSTR url)
760 FIXME("(%s)\n", debugstr_w(url));
761 return FALSE;
764 /***********************************************************************
765 * IsProtectedModeURL (URLMON.111)
766 * Undocumented, added in IE7
768 BOOL WINAPI IsProtectedModeURL(const WCHAR *url)
770 FIXME("stub: %s\n", debugstr_w(url));
771 return TRUE;
774 /***********************************************************************
775 * LogSqmBits (URLMON.410)
776 * Undocumented, added in IE8
778 int WINAPI LogSqmBits(DWORD unk1, DWORD unk2)
780 FIXME("stub: %d %d\n", unk1, unk2);
781 return 0;
784 /***********************************************************************
785 * LogSqmUXCommandOffsetInternal (URLMON.423)
786 * Undocumented, added in IE8
788 void WINAPI LogSqmUXCommandOffsetInternal(DWORD unk1, DWORD unk2, DWORD unk3, DWORD unk4)
790 FIXME("stub: %d %d %d %d\n", unk1, unk2, unk3, unk4);
793 /***********************************************************************
794 * MapUriToBrowserEmulationState (URLMON.444)
795 * Undocumented, added in IE8
797 int WINAPI MapUriToBrowserEmulationState(DWORD unk1, DWORD unk2, DWORD unk3)
799 FIXME("stub: %d %d %d\n", unk1, unk2, unk3);
800 return 0;
803 /***********************************************************************
804 * MapBrowserEmulationModeToUserAgent (URLMON.445)
805 * Undocumented, added in IE8
807 int WINAPI MapBrowserEmulationModeToUserAgent(DWORD unk1, DWORD unk2)
809 FIXME("stub: %d %d\n", unk1, unk2);
810 return 0;
813 /***********************************************************************
814 * CoInternetGetBrowserProfile (URLMON.446)
815 * Undocumented, added in IE8
817 HRESULT WINAPI CoInternetGetBrowserProfile(DWORD unk)
819 FIXME("%x: stub\n", unk);
820 return E_NOTIMPL;
823 /***********************************************************************
824 * FlushUrlmonZonesCache (URLMON.455)
825 * Undocumented, added in IE8
827 void WINAPI FlushUrlmonZonesCache(void)
829 FIXME("stub\n");
832 /***********************************************************************
833 * RegisterMediaTypes
834 * Added in IE3, registers known MIME-type strings.
836 HRESULT WINAPI RegisterMediaTypes(UINT types, LPCSTR *szTypes, CLIPFORMAT *cfTypes)
838 FIXME("stub: %u %p %p\n", types, szTypes, cfTypes);
839 return E_INVALIDARG;
842 /***********************************************************************
843 * ShouldShowIntranetWarningSecband
844 * Undocumented, added in IE7
846 BOOL WINAPI ShouldShowIntranetWarningSecband(DWORD unk)
848 FIXME("%x: stub\n", unk);
849 return FALSE;
852 /***********************************************************************
853 * GetIUriPriv (urlmon.@)
855 * Not documented.
857 HRESULT WINAPI GetIUriPriv(IUri *uri, void **p)
859 FIXME("(%p,%p): stub\n", uri, p);
860 *p = NULL;
861 return E_NOTIMPL;