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
23 #include "urlmon_main.h"
27 #define NO_SHLWAPI_REG
29 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
35 LONG URLMON_refCount = 0;
37 HINSTANCE URLMON_hInstance = 0;
38 static HMODULE hCabinet = NULL;
40 static void init_session(BOOL);
42 /***********************************************************************
43 * DllMain (URLMON.init)
45 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
47 TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
50 case DLL_PROCESS_ATTACH:
51 DisableThreadLibraryCalls(hinstDLL);
52 URLMON_hInstance = hinstDLL;
56 case DLL_PROCESS_DETACH:
58 FreeLibrary(hCabinet);
68 /***********************************************************************
69 * DllInstall (URLMON.@)
71 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
73 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
79 /***********************************************************************
80 * DllCanUnloadNow (URLMON.@)
82 HRESULT WINAPI DllCanUnloadNow(void)
84 return URLMON_refCount != 0 ? S_FALSE : S_OK;
89 /******************************************************************************
93 const IClassFactoryVtbl *lpClassFactoryVtbl;
95 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
98 #define CLASSFACTORY(x) ((IClassFactory*) &(x)->lpClassFactoryVtbl)
100 static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv)
104 if(IsEqualGUID(riid, &IID_IUnknown)) {
105 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
107 }else if(IsEqualGUID(riid, &IID_IClassFactory)) {
108 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
113 IUnknown_AddRef((IUnknown*)*ppv);
117 WARN("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ppv);
118 return E_NOINTERFACE;
121 static ULONG WINAPI CF_AddRef(IClassFactory *iface)
127 static ULONG WINAPI CF_Release(IClassFactory *iface)
129 URLMON_UnlockModule();
134 static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
135 REFIID riid, LPVOID *ppobj)
137 ClassFactory *This = (ClassFactory*)iface;
141 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
144 if(SUCCEEDED(hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk))) {
145 hres = IUnknown_QueryInterface(punk, riid, ppobj);
146 IUnknown_Release(punk);
151 static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
153 TRACE("(%d)\n", dolock);
158 URLMON_UnlockModule();
163 static const IClassFactoryVtbl ClassFactoryVtbl =
172 static const ClassFactory FileProtocolCF =
173 { &ClassFactoryVtbl, FileProtocol_Construct};
174 static const ClassFactory FtpProtocolCF =
175 { &ClassFactoryVtbl, FtpProtocol_Construct};
176 static const ClassFactory GopherProtocolCF =
177 { &ClassFactoryVtbl, GopherProtocol_Construct};
178 static const ClassFactory HttpProtocolCF =
179 { &ClassFactoryVtbl, HttpProtocol_Construct};
180 static const ClassFactory HttpSProtocolCF =
181 { &ClassFactoryVtbl, HttpSProtocol_Construct};
182 static const ClassFactory MkProtocolCF =
183 { &ClassFactoryVtbl, MkProtocol_Construct};
184 static const ClassFactory SecurityManagerCF =
185 { &ClassFactoryVtbl, SecManagerImpl_Construct};
186 static const ClassFactory ZoneManagerCF =
187 { &ClassFactoryVtbl, ZoneMgrImpl_Construct};
188 static const ClassFactory StdURLMonikerCF =
189 { &ClassFactoryVtbl, StdURLMoniker_Construct};
191 struct object_creation_info
198 static const WCHAR wszFile[] = {'f','i','l','e',0};
199 static const WCHAR wszFtp[] = {'f','t','p',0};
200 static const WCHAR wszGopher[] = {'g','o','p','h','e','r',0};
201 static const WCHAR wszHttp[] = {'h','t','t','p',0};
202 static const WCHAR wszHttps[] = {'h','t','t','p','s',0};
203 static const WCHAR wszMk[] = {'m','k',0};
205 static const struct object_creation_info object_creation[] =
207 { &CLSID_FileProtocol, CLASSFACTORY(&FileProtocolCF), wszFile },
208 { &CLSID_FtpProtocol, CLASSFACTORY(&FtpProtocolCF), wszFtp },
209 { &CLSID_GopherProtocol, CLASSFACTORY(&GopherProtocolCF), wszGopher },
210 { &CLSID_HttpProtocol, CLASSFACTORY(&HttpProtocolCF), wszHttp },
211 { &CLSID_HttpSProtocol, CLASSFACTORY(&HttpSProtocolCF), wszHttps },
212 { &CLSID_MkProtocol, CLASSFACTORY(&MkProtocolCF), wszMk },
213 { &CLSID_InternetSecurityManager, CLASSFACTORY(&SecurityManagerCF), NULL },
214 { &CLSID_InternetZoneManager, CLASSFACTORY(&ZoneManagerCF), NULL },
215 { &CLSID_StdURLMoniker, CLASSFACTORY(&StdURLMonikerCF), NULL }
218 static void init_session(BOOL init)
222 for(i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) {
224 if(object_creation[i].protocol)
225 register_urlmon_namespace(object_creation[i].cf, object_creation[i].clsid,
226 object_creation[i].protocol, init);
230 /*******************************************************************************
231 * DllGetClassObject [URLMON.@]
232 * Retrieves class object from a DLL object
235 * Docs say returns STDAPI
238 * rclsid [I] CLSID for the class object
239 * riid [I] Reference to identifier of interface for class object
240 * ppv [O] Address of variable to receive interface pointer for riid
244 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
248 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
252 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
254 for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
256 if (IsEqualGUID(object_creation[i].clsid, rclsid))
257 return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv);
260 FIXME("%s: no class found.\n", debugstr_guid(rclsid));
261 return CLASS_E_CLASSNOTAVAILABLE;
265 /***********************************************************************
266 * DllRegisterServerEx (URLMON.@)
268 HRESULT WINAPI DllRegisterServerEx(void)
270 FIXME("(void): stub\n");
275 /**************************************************************************
276 * UrlMkSetSessionOption (URLMON.@)
278 HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
281 FIXME("(%#x, %p, %#x): stub\n", dwOption, pBuffer, dwBufferLength);
286 static const CHAR Agent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
288 /**************************************************************************
289 * ObtainUserAgentString (URLMON.@)
291 HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbSize)
293 FIXME("(%d, %p, %p): stub\n", dwOption, pcszUAOut, cbSize);
295 if (pcszUAOut == NULL || cbSize == NULL)
298 if (*cbSize < sizeof(Agent))
300 *cbSize = sizeof(Agent);
301 return E_OUTOFMEMORY;
304 if (sizeof(Agent) < *cbSize)
305 *cbSize = sizeof(Agent);
306 lstrcpynA(pcszUAOut, Agent, *cbSize);
311 /**************************************************************************
312 * IsValidURL (URLMON.@)
314 * Determines if a specified string is a valid URL.
317 * pBC [I] ignored, must be NULL.
318 * szURL [I] string that represents the URL in question.
319 * dwReserved [I] reserved and must be zero.
324 * returns E_INVALIDARG if one or more of the args is invalid.
327 * test functionality against windows to see what a valid URL is.
329 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
331 FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved);
333 if (pBC != NULL || dwReserved != 0)
339 /**************************************************************************
340 * FaultInIEFeature (URLMON.@)
342 * Undocumented. Appears to be used by native shdocvw.dll.
344 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
345 QUERYCONTEXT *pQuery, DWORD flags )
347 FIXME("%p %p %p %08x\n", hwnd, pClassSpec, pQuery, flags);
351 /**************************************************************************
352 * CoGetClassObjectFromURL (URLMON.@)
354 HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS,
355 DWORD dwFileVersionLS, LPCWSTR szContentType,
356 LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
357 REFIID riid, LPVOID *ppv )
359 FIXME("(%s %s %d %d %s %p %d %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
360 dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
361 debugstr_guid(riid), ppv);
362 return E_NOINTERFACE;
365 /***********************************************************************
366 * ReleaseBindInfo (URLMON.@)
368 * Release the resources used by the specified BINDINFO structure.
371 * pbindinfo [I] BINDINFO to release.
376 void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo)
380 TRACE("(%p)\n", pbindinfo);
382 if(!pbindinfo || !(size = pbindinfo->cbSize))
385 CoTaskMemFree(pbindinfo->szExtraInfo);
386 ReleaseStgMedium(&pbindinfo->stgmedData);
388 if(offsetof(BINDINFO, szExtraInfo) < size)
389 CoTaskMemFree(pbindinfo->szCustomVerb);
391 if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size)
392 IUnknown_Release(pbindinfo->pUnk);
394 memset(pbindinfo, 0, size);
395 pbindinfo->cbSize = size;
398 /***********************************************************************
399 * CopyStgMedium (URLMON.@)
401 HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
403 TRACE("(%p %p)\n", src, dst);
414 if(src->u.lpszFileName && !src->pUnkForRelease) {
415 DWORD size = (strlenW(src->u.lpszFileName)+1)*sizeof(WCHAR);
416 dst->u.lpszFileName = CoTaskMemAlloc(size);
417 memcpy(dst->u.lpszFileName, src->u.lpszFileName, size);
422 IStream_AddRef(dst->u.pstm);
426 IStorage_AddRef(dst->u.pstg);
429 FIXME("Unimplemented tymed %d\n", src->tymed);
432 if(dst->pUnkForRelease)
433 IUnknown_AddRef(dst->pUnkForRelease);
438 static BOOL text_richtext_filter(const BYTE *b, DWORD size)
440 return size > 5 && !memcmp(b, "{\\rtf", 5);
443 static BOOL text_html_filter(const BYTE *b, DWORD size)
450 for(i=0; i < size-5; i++) {
452 && (b[i+1] == 'h' || b[i+1] == 'H')
453 && (b[i+2] == 't' || b[i+2] == 'T')
454 && (b[i+3] == 'm' || b[i+3] == 'M')
455 && (b[i+4] == 'l' || b[i+4] == 'L'))
462 static BOOL audio_basic_filter(const BYTE *b, DWORD size)
465 && b[0] == '.' && b[1] == 's' && b[2] == 'n' && b[3] == 'd';
468 static BOOL audio_wav_filter(const BYTE *b, DWORD size)
471 && b[0] == 'R' && b[1] == 'I' && b[2] == 'F' && b[3] == 'F'
472 && b[8] == 'W' && b[9] == 'A' && b[10] == 'V' && b[11] == 'E';
475 static BOOL image_gif_filter(const BYTE *b, DWORD size)
478 && (b[0] == 'G' || b[0] == 'g')
479 && (b[1] == 'I' || b[1] == 'i')
480 && (b[2] == 'F' || b[2] == 'f')
482 && (b[4] == '7' || b[4] == '9')
483 && (b[5] == 'A' || b[5] == 'a');
486 static BOOL image_pjpeg_filter(const BYTE *b, DWORD size)
488 return size > 2 && b[0] == 0xff && b[1] == 0xd8;
491 static BOOL image_tiff_filter(const BYTE *b, DWORD size)
493 return size > 2 && b[0] == 0x4d && b[1] == 0x4d;
496 static BOOL image_xpng_filter(const BYTE *b, DWORD size)
498 static const BYTE xpng_header[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a};
499 return size > sizeof(xpng_header) && !memcmp(b, xpng_header, sizeof(xpng_header));
502 static BOOL image_bmp_filter(const BYTE *b, DWORD size)
505 && b[0] == 0x42 && b[1] == 0x4d
506 && *(const DWORD *)(b+6) == 0;
509 static BOOL video_avi_filter(const BYTE *b, DWORD size)
512 && b[0] == 'R' && b[1] == 'I' && b[2] == 'F' && b[3] == 'F'
513 && b[8] == 'A' && b[9] == 'V' && b[10] == 'I' && b[11] == 0x20;
516 static BOOL video_mpeg_filter(const BYTE *b, DWORD size)
519 && !b[0] && !b[1] && b[2] == 0x01
520 && (b[3] == 0xb3 || b[3] == 0xba);
523 static BOOL application_postscript_filter(const BYTE *b, DWORD size)
525 return size > 2 && b[0] == '%' && b[1] == '!';
528 static BOOL application_pdf_filter(const BYTE *b, DWORD size)
530 return size > 4 && b[0] == 0x25 && b[1] == 0x50 && b[2] == 0x44 && b[3] == 0x46;
533 static BOOL application_xzip_filter(const BYTE *b, DWORD size)
535 return size > 2 && b[0] == 0x50 && b[1] == 0x4b;
538 static BOOL application_xgzip_filter(const BYTE *b, DWORD size)
540 return size > 2 && b[0] == 0x1f && b[1] == 0x8b;
543 static BOOL application_java_filter(const BYTE *b, DWORD size)
545 return size > 4 && b[0] == 0xca && b[1] == 0xfe && b[2] == 0xba && b[3] == 0xbe;
548 static BOOL application_xmsdownload(const BYTE *b, DWORD size)
550 return size > 2 && b[0] == 'M' && b[1] == 'Z';
553 static BOOL text_plain_filter(const BYTE *b, DWORD size)
557 for(ptr = b; ptr < b+size-1; ptr++) {
558 if(*ptr < 0x20 && *ptr != '\n' && *ptr != '\r' && *ptr != '\t')
565 static BOOL application_octet_stream_filter(const BYTE *b, DWORD size)
570 /***********************************************************************
571 * FindMimeFromData (URLMON.@)
573 * Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided.
575 HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer,
576 DWORD cbSize, LPCWSTR pwzMimeProposed, DWORD dwMimeFlags,
577 LPWSTR* ppwzMimeOut, DWORD dwReserved)
579 TRACE("(%p,%s,%p,%d,%s,0x%x,%p,0x%x)\n", pBC, debugstr_w(pwzUrl), pBuffer, cbSize,
580 debugstr_w(pwzMimeProposed), dwMimeFlags, ppwzMimeOut, dwReserved);
583 WARN("dwMimeFlags=%08x\n", dwMimeFlags);
585 WARN("dwReserved=%d\n", dwReserved);
587 /* pBC seams to not be used */
589 if(!ppwzMimeOut || (!pwzUrl && !pBuffer))
592 if(pwzMimeProposed && (!pBuffer || (pBuffer && !cbSize))) {
598 len = strlenW(pwzMimeProposed)+1;
599 *ppwzMimeOut = CoTaskMemAlloc(len*sizeof(WCHAR));
600 memcpy(*ppwzMimeOut, pwzMimeProposed, len*sizeof(WCHAR));
605 const BYTE *buf = pBuffer;
610 static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
611 static const WCHAR wszTextRichtext[] = {'t','e','x','t','/','r','i','c','h','t','e','x','t',0};
612 static const WCHAR wszAudioBasic[] = {'a','u','d','i','o','/','b','a','s','i','c',0};
613 static const WCHAR wszAudioWav[] = {'a','u','d','i','o','/','w','a','v',0};
614 static const WCHAR wszImageGif[] = {'i','m','a','g','e','/','g','i','f',0};
615 static const WCHAR wszImagePjpeg[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
616 static const WCHAR wszImageTiff[] = {'i','m','a','g','e','/','t','i','f','f',0};
617 static const WCHAR wszImageXPng[] = {'i','m','a','g','e','/','x','-','p','n','g',0};
618 static const WCHAR wszImageBmp[] = {'i','m','a','g','e','/','b','m','p',0};
619 static const WCHAR wszVideoAvi[] = {'v','i','d','e','o','/','a','v','i',0};
620 static const WCHAR wszVideoMpeg[] = {'v','i','d','e','o','/','m','p','e','g',0};
621 static const WCHAR wszAppPostscript[] =
622 {'a','p','p','l','i','c','a','t','i','o','n','/','p','o','s','t','s','c','r','i','p','t',0};
623 static const WCHAR wszAppPdf[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
625 static const WCHAR wszAppXZip[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
626 'x','-','z','i','p','-','c','o','m','p','r','e','s','s','e','d',0};
627 static const WCHAR wszAppXGzip[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
628 'x','-','g','z','i','p','-','c','o','m','p','r','e','s','s','e','d',0};
629 static const WCHAR wszAppJava[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
631 static const WCHAR wszAppXMSDownload[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
632 'x','-','m','s','d','o','w','n','l','o','a','d',0};
633 static const WCHAR wszTextPlain[] = {'t','e','x','t','/','p','l','a','i','n','\0'};
634 static const WCHAR wszAppOctetStream[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
635 'o','c','t','e','t','-','s','t','r','e','a','m','\0'};
637 static const struct {
639 BOOL (*filter)(const BYTE *,DWORD);
641 {wszTextHtml, text_html_filter},
642 {wszTextRichtext, text_richtext_filter},
643 /* {wszAudioXAiff, audio_xaiff_filter}, */
644 {wszAudioBasic, audio_basic_filter},
645 {wszAudioWav, audio_wav_filter},
646 {wszImageGif, image_gif_filter},
647 {wszImagePjpeg, image_pjpeg_filter},
648 {wszImageTiff, image_tiff_filter},
649 {wszImageXPng, image_xpng_filter},
650 /* {wszImageXBitmap, image_xbitmap_filter}, */
651 {wszImageBmp, image_bmp_filter},
652 /* {wszImageXJg, image_xjg_filter}, */
653 /* {wszImageXEmf, image_xemf_filter}, */
654 /* {wszImageXWmf, image_xwmf_filter}, */
655 {wszVideoAvi, video_avi_filter},
656 {wszVideoMpeg, video_mpeg_filter},
657 {wszAppPostscript, application_postscript_filter},
658 /* {wszAppBase64, application_base64_filter}, */
659 /* {wszAppMacbinhex40, application_macbinhex40_filter}, */
660 {wszAppPdf, application_pdf_filter},
661 /* {wszAppXCompressed, application_xcompressed_filter}, */
662 {wszAppXZip, application_xzip_filter},
663 {wszAppXGzip, application_xgzip_filter},
664 {wszAppJava, application_java_filter},
665 {wszAppXMSDownload, application_xmsdownload},
666 {wszTextPlain, text_plain_filter},
667 {wszAppOctetStream, application_octet_stream_filter}
673 if(pwzMimeProposed && strcmpW(pwzMimeProposed, wszAppOctetStream)) {
674 for(i=0; i < sizeof(mime_filters)/sizeof(*mime_filters); i++) {
675 if(!strcmpW(pwzMimeProposed, mime_filters[i].mime))
679 if(i == sizeof(mime_filters)/sizeof(*mime_filters)
680 || mime_filters[i].filter(buf, cbSize)) {
681 len = strlenW(pwzMimeProposed)+1;
682 *ppwzMimeOut = CoTaskMemAlloc(len*sizeof(WCHAR));
683 memcpy(*ppwzMimeOut, pwzMimeProposed, len*sizeof(WCHAR));
690 if(mime_filters[i].filter(buf, cbSize))
691 ret = mime_filters[i].mime;
695 TRACE("found %s for data\n"
696 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
697 debugstr_w(ret), buf[0],buf[1],buf[2],buf[3], buf[4],buf[5],buf[6],buf[7],
698 buf[8],buf[9],buf[10],buf[11], buf[12],buf[13],buf[14],buf[15]);
700 if(pwzMimeProposed) {
701 if(i == sizeof(mime_filters)/sizeof(*mime_filters))
702 ret = pwzMimeProposed;
704 /* text/html is a special case */
705 if(!strcmpW(pwzMimeProposed, wszTextHtml) && !strcmpW(ret, wszTextPlain))
709 len = strlenW(ret)+1;
710 *ppwzMimeOut = CoTaskMemAlloc(len*sizeof(WCHAR));
711 memcpy(*ppwzMimeOut, ret, len*sizeof(WCHAR));
721 static const WCHAR wszContentType[] =
722 {'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
724 ptr = strrchrW(pwzUrl, '.');
728 res = RegOpenKeyW(HKEY_CLASSES_ROOT, ptr, &hkey);
729 if(res != ERROR_SUCCESS)
730 return HRESULT_FROM_WIN32(res);
733 res = RegQueryValueExW(hkey, wszContentType, NULL, NULL, (LPBYTE)mime, &size);
735 if(res != ERROR_SUCCESS)
736 return HRESULT_FROM_WIN32(res);
738 *ppwzMimeOut = CoTaskMemAlloc(size);
739 memcpy(*ppwzMimeOut, mime, size);
746 /***********************************************************************
747 * GetClassFileOrMime (URLMON.@)
749 * Determines the class ID from the bind context, file name or MIME type.
751 HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename,
752 LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved,
755 FIXME("(%p, %s, %p, %d, %p, 0x%08x, %p): stub\n", pBC,
756 debugstr_w(pszFilename), pBuffer, cbBuffer, debugstr_w(pszMimeType),
761 /***********************************************************************
764 HRESULT WINAPI Extract(void *dest, LPCSTR szCabName)
766 HRESULT (WINAPI *pExtract)(void *, LPCSTR);
769 hCabinet = LoadLibraryA("cabinet.dll");
771 if (!hCabinet) return HRESULT_FROM_WIN32(GetLastError());
772 pExtract = (void *)GetProcAddress(hCabinet, "Extract");
773 if (!pExtract) return HRESULT_FROM_WIN32(GetLastError());
775 return pExtract(dest, szCabName);
778 /***********************************************************************
779 * IsLoggingEnabledA (URLMON.@)
781 BOOL WINAPI IsLoggingEnabledA(LPCSTR url)
783 FIXME("(%s)\n", debugstr_a(url));
787 /***********************************************************************
788 * IsLoggingEnabledW (URLMON.@)
790 BOOL WINAPI IsLoggingEnabledW(LPCWSTR url)
792 FIXME("(%s)\n", debugstr_w(url));