📄 urlmon_main.c
字号:
/*
* UrlMon
*
* Copyright (c) 2000 Patrik Stridvall
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#define NO_SHLWAPI_REG
#include "shlwapi.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "winuser.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "ole2.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
LONG URLMON_refCount = 0;
HINSTANCE URLMON_hInstance = 0;
static HMODULE hCabinet = NULL;
static void init_session(BOOL);
/***********************************************************************
* DllMain (URLMON.init)
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
URLMON_hInstance = hinstDLL;
init_session(TRUE);
break;
case DLL_PROCESS_DETACH:
if (hCabinet)
FreeLibrary(hCabinet);
hCabinet = NULL;
init_session(FALSE);
URLMON_hInstance = 0;
break;
}
return TRUE;
}
/***********************************************************************
* DllInstall (URLMON.@)
*/
HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
{
FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
debugstr_w(cmdline));
return S_OK;
}
/***********************************************************************
* DllCanUnloadNow (URLMON.@)
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
return URLMON_refCount != 0 ? S_FALSE : S_OK;
}
/******************************************************************************
* Urlmon ClassFactory
*/
typedef struct {
const IClassFactoryVtbl *lpClassFactoryVtbl;
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
} ClassFactory;
#define CLASSFACTORY(x) ((IClassFactory*) &(x)->lpClassFactoryVtbl)
static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if(IsEqualGUID(riid, &IID_IUnknown)) {
TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
*ppv = iface;
}else if(IsEqualGUID(riid, &IID_IClassFactory)) {
TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
*ppv = iface;
}
if(*ppv) {
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
WARN("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ppv);
return E_NOINTERFACE;
}
static ULONG WINAPI CF_AddRef(IClassFactory *iface)
{
URLMON_LockModule();
return 2;
}
static ULONG WINAPI CF_Release(IClassFactory *iface)
{
URLMON_UnlockModule();
return 1;
}
static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
REFIID riid, LPVOID *ppobj)
{
ClassFactory *This = (ClassFactory*)iface;
HRESULT hres;
LPUNKNOWN punk;
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
*ppobj = NULL;
if(SUCCEEDED(hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk))) {
hres = IUnknown_QueryInterface(punk, riid, ppobj);
IUnknown_Release(punk);
}
return hres;
}
static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
{
TRACE("(%d)\n", dolock);
if (dolock)
URLMON_LockModule();
else
URLMON_UnlockModule();
return S_OK;
}
static const IClassFactoryVtbl ClassFactoryVtbl =
{
CF_QueryInterface,
CF_AddRef,
CF_Release,
CF_CreateInstance,
CF_LockServer
};
static const ClassFactory FileProtocolCF =
{ &ClassFactoryVtbl, FileProtocol_Construct};
static const ClassFactory FtpProtocolCF =
{ &ClassFactoryVtbl, FtpProtocol_Construct};
static const ClassFactory HttpProtocolCF =
{ &ClassFactoryVtbl, HttpProtocol_Construct};
static const ClassFactory MkProtocolCF =
{ &ClassFactoryVtbl, MkProtocol_Construct};
static const ClassFactory SecurityManagerCF =
{ &ClassFactoryVtbl, SecManagerImpl_Construct};
static const ClassFactory ZoneManagerCF =
{ &ClassFactoryVtbl, ZoneMgrImpl_Construct};
struct object_creation_info
{
const CLSID *clsid;
IClassFactory *cf;
LPCWSTR protocol;
};
static const WCHAR wszFile[] = {'f','i','l','e',0};
static const WCHAR wszFtp[] = {'f','t','p',0};
static const WCHAR wszHttp[] = {'h','t','t','p',0};
static const WCHAR wszMk[] = {'m','k',0};
static const struct object_creation_info object_creation[] =
{
{ &CLSID_FileProtocol, CLASSFACTORY(&FileProtocolCF), wszFile },
{ &CLSID_FtpProtocol, CLASSFACTORY(&FtpProtocolCF), wszFtp },
{ &CLSID_HttpProtocol, CLASSFACTORY(&HttpProtocolCF), wszHttp },
{ &CLSID_MkProtocol, CLASSFACTORY(&MkProtocolCF), wszMk },
{ &CLSID_InternetSecurityManager, CLASSFACTORY(&SecurityManagerCF), NULL },
{ &CLSID_InternetZoneManager, CLASSFACTORY(&ZoneManagerCF), NULL }
};
static void init_session(BOOL init)
{
IInternetSession *session;
int i;
CoInternetGetSession(0, &session, 0);
for(i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) {
if(object_creation[i].protocol) {
if(init)
{
IInternetSession_RegisterNameSpace(session, object_creation[i].cf,
object_creation[i].clsid, object_creation[i].protocol, 0, NULL, 0);
/* make sure that the AddRef on the class factory doesn't keep us loaded */
URLMON_UnlockModule();
}
else
{
/* make sure that the Release on the class factory doesn't unload us */
URLMON_LockModule();
IInternetSession_UnregisterNameSpace(session, object_creation[i].cf,
object_creation[i].protocol);
}
}
}
IInternetSession_Release(session);
}
/*******************************************************************************
* DllGetClassObject [URLMON.@]
* Retrieves class object from a DLL object
*
* NOTES
* Docs say returns STDAPI
*
* PARAMS
* rclsid [I] CLSID for the class object
* riid [I] Reference to identifier of interface for class object
* ppv [O] Address of variable to receive interface pointer for riid
*
* RETURNS
* Success: S_OK
* Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
* E_UNEXPECTED
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
int i;
TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
{
if (IsEqualGUID(object_creation[i].clsid, rclsid))
return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv);
}
FIXME("%s: no class found.\n", debugstr_guid(rclsid));
return CLASS_E_CLASSNOTAVAILABLE;
}
/***********************************************************************
* DllRegisterServerEx (URLMON.@)
*/
HRESULT WINAPI DllRegisterServerEx(void)
{
FIXME("(void): stub\n");
return E_FAIL;
}
/**************************************************************************
* UrlMkSetSessionOption (URLMON.@)
*/
HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
DWORD Reserved)
{
FIXME("(%#x, %p, %#x): stub\n", dwOption, pBuffer, dwBufferLength);
return S_OK;
}
static const CHAR Agent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
/**************************************************************************
* ObtainUserAgentString (URLMON.@)
*/
HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbSize)
{
FIXME("(%d, %p, %p): stub\n", dwOption, pcszUAOut, cbSize);
if (pcszUAOut == NULL || cbSize == NULL)
return E_INVALIDARG;
if (*cbSize < sizeof(Agent))
{
*cbSize = sizeof(Agent);
return E_OUTOFMEMORY;
}
if (sizeof(Agent) < *cbSize)
*cbSize = sizeof(Agent);
lstrcpynA(pcszUAOut, Agent, *cbSize);
return S_OK;
}
/**************************************************************************
* IsValidURL (URLMON.@)
*
* Determines if a specified string is a valid URL.
*
* PARAMS
* pBC [I] ignored, must be NULL.
* szURL [I] string that represents the URL in question.
* dwReserved [I] reserved and must be zero.
*
* RETURNS
* Success: S_OK.
* Failure: S_FALSE.
* returns E_INVALIDARG if one or more of the args is invalid.
*
* TODO:
* test functionality against windows to see what a valid URL is.
*/
HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
{
FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved);
if (pBC != NULL || dwReserved != 0)
return E_INVALIDARG;
return S_OK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -