Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1206 lines
37 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: urldll.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 10-25-95 JohannP (Johann Posch) Created
//
//----------------------------------------------------------------------------
#include <mon.h>
#include "urlcf.hxx"
#include "selfreg.hxx"
#include <delaydll.h>
#include <tls.h>
#include <commctrl.h>
#include <shfusion.h>
#define MLUI_INIT
#include "mluisupp.h"
#ifdef _SBS_
#include "sbsclsid.hxx"
#else
#include "clsid.hxx"
#endif //_SBS_
//
// Downlevel delay load support (we forward to shlwapi)
//
#include <delayimp.h>
PfnDliHook __pfnDliFailureHook;
#ifdef unix
#define DllMain DllMainInternal
#endif /* unix */
COleAutDll g_OleAutDll;
PerfDbgTag(tagUrlDll, "Urlmon", "Log DllMain", DEB_URLMON);
DECLARE_INFOLEVEL(UrlMk)
DECLARE_INFOLEVEL(Trans)
DECLARE_INFOLEVEL(PProt)
DECLARE_INFOLEVEL(Notf)
DECLARE_INFOLEVEL(EProt)
DECLARE_INFOLEVEL(TNotf)
extern HINSTANCE g_hInst;
extern HMODULE g_hLibPluginOcx;
extern HMODULE g_hLibMlang;
extern ULONG Win4AssertLevel;
extern IEnumFORMATETC *g_pEFmtETC;
DWORD g_dwSettings = 0;
BOOL g_bCanUseSimpleBinding = TRUE;
BOOL CanUseSimpleBinding();
BOOL g_bHasMimeHandlerForTextHtml = TRUE;
LONG g_cTransLevelHandler = 0;
BOOL g_bGlobalUTF8Enabled = FALSE;
BOOL g_bGlobalUTF8hackEnabled = TRUE;
BOOL GlobalUTF8Enabled();
BOOL GlobalUTF8hackEnabled();
BOOL g_bNT5OrGreater = FALSE;
URLMON_TS* g_pHeadURLMONTSList;
HRESULT CleanupTSOnProcessDetach();
BOOL g_bUseImprovedZoneCheck;
BOOL CanUseImprovedZoneCheck();
// defined in calldatax.c
EXTERN_C HRESULT PrxDllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv);
EXTERN_C HRESULT PrxDllRegisterServer();
EXTERN_C HRESULT PrxDllUnregisterServer();
EXTERN_C HRESULT PrxDllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved);
// defined in zoneutil.c
EXTERN_C HRESULT ZonesDllInstall(BOOL bInstall, LPCWSTR pwStr);
// global variables
CRefCount g_cRef(0); // global dll refcount
CMutexSem g_mxsMedia; // single access to media holder
LPSTR g_pszUserAgentString = NULL; // Per-process configurable User Agent string
IInternetSecurityManager *g_pSecurityManager = NULL;
LPSTR g_pszUAInfoString = NULL;
LPSTR GetUAInfoString(void);
STDAPI_(BOOL) TlsDllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpvReserved);
#define STDCOURIER_CLSID "{c733e4af-576e-11d0-b28c-00c04fd7cd22}"
#define STDCOURIER_CLSID_REGKEY "CLSID\\"STDCOURIER_CLSID
#define STDCOURIER_CLSID_REGKEY "CLSID\\"STDCOURIER_CLSID
#define STDCOURIER_DESCRIP "Thread NotificationMgr"
const REGENTRY rgStdNotificationMgr[] =
{
//***** STDCOURIER ENTRIES *****
STD_ENTRY(STDCOURIER_CLSID_REGKEY, STDCOURIER_DESCRIP),
STD_ENTRY(STDCOURIER_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, STDCOURIER_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
///* Registration of urlmon class
// HKEY_CLASSES_ROOT
const REGENTRY rgClassesRoot[] =
{
//***** URLMONIKER ENTRIES *****
STD_ENTRY(URLMONIKER_CLSID_REGKEY, URLMONIKER_DESCRIP),
STD_ENTRY(URLMONIKER_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, URLMONIKER_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgClassesSoftDist[] =
{
//***** SOFTDIST ENTRIES *****
STD_ENTRY(SOFTDIST_CLSID_REGKEY, SOFTDIST_DESCRIP),
STD_ENTRY(SOFTDIST_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, SOFTDIST_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgClassesSecMgr[] =
{
//***** SECMGR ENTRIES *****
STD_ENTRY(SECMGR_CLSID_REGKEY, SECMGR_DESCRIP),
STD_ENTRY(SECMGR_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, SECMGR_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Both" },
};
const REGENTRY rgClassesZoneMgr[] =
{
//***** ZONEMGR ENTRIES *****
STD_ENTRY(ZONEMGR_CLSID_REGKEY, ZONEMGR_DESCRIP),
STD_ENTRY(ZONEMGR_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, ZONEMGR_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Both" },
};
const REGENTRY rgClassesBindCtx[] =
{
//***** URLBINDCTX ENTRIES *****
STD_ENTRY(URLBINDCTX_CLSID_REGKEY, URLBINDCTX_DESCRIP),
STD_ENTRY(URLBINDCTX_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, URLBINDCTX_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
// Registration of proxy/stub class id
const REGENTRY rgPSFactory[] =
{
//***** URLMONIKER PS ENTRIES *****
STD_ENTRY(URLMONIKER_PS_CLSID_REGKEY, URLMONIKER_PS_DESCRIP),
STD_ENTRY(URLMONIKER_PS_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, URLMONIKER_PS_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
// protocols
const REGENTRY rgClassesHttp[] =
{
//***** PROTOCOL_HTTP ENTRIES *****
STD_ENTRY(PROTOCOL_HTTP_CLSID_REGKEY, PROTOCOL_HTTP_DESCRIP),
STD_ENTRY(PROTOCOL_HTTP_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_HTTP_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgClassesFtp[] =
{
//***** PROTOCOL_FTP ENTRIES *****
STD_ENTRY(PROTOCOL_FTP_CLSID_REGKEY, PROTOCOL_FTP_DESCRIP),
STD_ENTRY(PROTOCOL_FTP_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_FTP_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgClassesGopher[] =
{
//***** PROTOCOL_GOPHER ENTRIES *****
STD_ENTRY(PROTOCOL_GOPHER_CLSID_REGKEY, PROTOCOL_GOPHER_DESCRIP),
STD_ENTRY(PROTOCOL_GOPHER_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_GOPHER_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgClassesHttpS[] =
{
//***** PROTOCOL_HTTPS ENTRIES *****
STD_ENTRY(PROTOCOL_HTTPS_CLSID_REGKEY, PROTOCOL_HTTPS_DESCRIP),
STD_ENTRY(PROTOCOL_HTTPS_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_HTTPS_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgClassesMk[] =
{
//***** PROTOCOL_MK ENTRIES *****
STD_ENTRY(PROTOCOL_MK_CLSID_REGKEY, PROTOCOL_MK_DESCRIP),
STD_ENTRY(PROTOCOL_MK_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_MK_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgClassesFile[] =
{
//***** PROTOCOL_FILE ENTRIES *****
STD_ENTRY(PROTOCOL_FILE_CLSID_REGKEY, PROTOCOL_FILE_DESCRIP),
STD_ENTRY(PROTOCOL_FILE_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_FILE_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
#define HANDLER_HTTP SZPROTOCOLROOT"http"
#define HANDLER_FTP SZPROTOCOLROOT"ftp"
#define HANDLER_GOPHER SZPROTOCOLROOT"gopher"
#define HANDLER_HTTPS SZPROTOCOLROOT"https"
#define HANDLER_MK SZPROTOCOLROOT"mk"
#define HANDLER_FILE SZPROTOCOLROOT"file"
#define HANDLER_LOCAL SZPROTOCOLROOT"local"
//const REGENTRY rgHandler[] = { STD_ENTRY(HANDLER_HTTP, PROTOCOL_HTTP_DESCRIP), { KEYTYPE_STRING, HANDLER_HTTP, "CLSID", REG_SZ, (BYTE*)PROTOCOL_HTTP_CLSID } };
const REGENTRY rgHandlerHttp [] = { STD_ENTRY(HANDLER_HTTP , PROTOCOL_HTTP_DESCRIP ), { KEYTYPE_STRING, HANDLER_HTTP , "CLSID", REG_SZ, (BYTE*)PROTOCOL_HTTP_CLSID } };
const REGENTRY rgHandlerFtp [] = { STD_ENTRY(HANDLER_FTP , PROTOCOL_FTP_DESCRIP ), { KEYTYPE_STRING, HANDLER_FTP , "CLSID", REG_SZ, (BYTE*)PROTOCOL_FTP_CLSID } };
const REGENTRY rgHandlerGopher [] = { STD_ENTRY(HANDLER_GOPHER, PROTOCOL_GOPHER_DESCRIP), { KEYTYPE_STRING, HANDLER_GOPHER, "CLSID", REG_SZ, (BYTE*)PROTOCOL_GOPHER_CLSID } };
const REGENTRY rgHandlerHttpS [] = { STD_ENTRY(HANDLER_HTTPS , PROTOCOL_HTTPS_DESCRIP ), { KEYTYPE_STRING, HANDLER_HTTPS , "CLSID", REG_SZ, (BYTE*)PROTOCOL_HTTPS_CLSID } };
const REGENTRY rgHandlerMk [] = { STD_ENTRY(HANDLER_MK , PROTOCOL_MK_DESCRIP ), { KEYTYPE_STRING, HANDLER_MK , "CLSID", REG_SZ, (BYTE*)PROTOCOL_MK_CLSID } };
const REGENTRY rgHandlerFile [] = { STD_ENTRY(HANDLER_FILE , PROTOCOL_FILE_DESCRIP ), { KEYTYPE_STRING, HANDLER_FILE , "CLSID", REG_SZ, (BYTE*)PROTOCOL_FILE_CLSID } };
const REGENTRY rgHandlerLocal [] = { STD_ENTRY(HANDLER_LOCAL , PROTOCOL_FILE_DESCRIP ), { KEYTYPE_STRING, HANDLER_LOCAL , "CLSID", REG_SZ, (BYTE*)PROTOCOL_FILE_CLSID } };
// From PlugProt.dll (merge)
#define SZFILTERROOT "PROTOCOLS\\Filter\\"
#define SZPROTOCOLROOT "PROTOCOLS\\Handler\\"
#define SZCLASS "CLSID"
#define SZHANDLER "HANDLER"
EXTERN_C const GUID CLSID_StdEncodingFilterFac;
EXTERN_C const GUID CLSID_DeCompMimeFilter;
EXTERN_C const GUID CLSID_CdlProtocol;
EXTERN_C const GUID CLSID_ClassInstallFilter;
//*************************** Registry keys for CDL protocol handler
const REGENTRY rgHandlerCdl[] =
{
STD_ENTRY(HANDLER_CDL , PROTOCOL_CDL_DESCRIP ),
{ KEYTYPE_STRING, HANDLER_CDL , "CLSID", REG_SZ, (BYTE*)PROTOCOL_CDL_CLSID }
};
const REGENTRY rgClassesCdl[] =
{
STD_ENTRY(PROTOCOL_CDL_CLSID_REGKEY, PROTOCOL_CDL_DESCRIP),
STD_ENTRY(PROTOCOL_CDL_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_CDL_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
//*************************** Registry keys for Class Install Handler protocol filter
const REGENTRY rgClassesMimeInstallHandler[] =
{
STD_ENTRY(PROT_FILTER_CLASS_CLSID_REGKEY, PROT_FILTER_CLASS_DESCRIP),
STD_ENTRY(PROT_FILTER_CLASS_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROT_FILTER_CLASS_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgMimeInstallHandler[] =
{
STD_ENTRY(PROT_FILTER_CLASS , PROT_FILTER_CLASS_DESCRIP ),
{ KEYTYPE_STRING, PROT_FILTER_CLASS, "CLSID", REG_SZ, (BYTE*)PROT_FILTER_CLASS_CLSID }
};
//*************************** Registry keys for ENC & Deflate protocol filters
const REGENTRY rgClassesMimeHandlerEnc[] =
{
STD_ENTRY(PROT_FILTER_ENC_CLSID_REGKEY, PROT_FILTER_ENC_DESCRIP),
STD_ENTRY(PROT_FILTER_ENC_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROT_FILTER_ENC_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRY rgMimeHandlerEnc [] =
{
STD_ENTRY(PROT_FILTER_ENC , PROT_FILTER_ENC_DESCRIP ),
{ KEYTYPE_STRING, PROT_FILTER_ENC , "CLSID", REG_SZ, (BYTE*)PROT_FILTER_ENC_CLSID }
};
const REGENTRY rgDeflateEnc [] =
{
STD_ENTRY(PROT_FILTER_DEFLATE , PROT_FILTER_DEFLATE_DESCRIP ),
{ KEYTYPE_STRING, PROT_FILTER_DEFLATE , "CLSID", REG_SZ, (BYTE*)PROT_FILTER_DEFLATE_CLSID }
};
const REGENTRY rgGZIPEnc [] =
{
STD_ENTRY(PROT_FILTER_GZIP , PROT_FILTER_GZIP_DESCRIP ),
{ KEYTYPE_STRING, PROT_FILTER_GZIP , "CLSID", REG_SZ, (BYTE*)PROT_FILTER_GZIP_CLSID }
};
const REGENTRY rgClassesStdEncFac[] =
{
STD_ENTRY(STD_ENC_FAC_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, STD_ENC_FAC_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
const REGENTRYGROUP rgRegEntryGroups[] = {
{ HKEY_CLASSES_ROOT, rgStdNotificationMgr, ARRAYSIZE(rgStdNotificationMgr) },
{ HKEY_CLASSES_ROOT, rgClassesRoot, ARRAYSIZE(rgClassesRoot) },
{ HKEY_CLASSES_ROOT, rgClassesSoftDist, ARRAYSIZE(rgClassesSoftDist) },
{ HKEY_CLASSES_ROOT, rgClassesSecMgr, ARRAYSIZE(rgClassesSecMgr) },
{ HKEY_CLASSES_ROOT, rgClassesZoneMgr, ARRAYSIZE(rgClassesZoneMgr) },
{ HKEY_CLASSES_ROOT, rgClassesBindCtx, ARRAYSIZE(rgClassesBindCtx) },
{ HKEY_CLASSES_ROOT, rgPSFactory, ARRAYSIZE(rgPSFactory) },
{ HKEY_CLASSES_ROOT, rgClassesHttp, ARRAYSIZE(rgClassesHttp) },
{ HKEY_CLASSES_ROOT, rgClassesFtp, ARRAYSIZE(rgClassesFtp) },
{ HKEY_CLASSES_ROOT, rgClassesGopher, ARRAYSIZE(rgClassesGopher) },
{ HKEY_CLASSES_ROOT, rgClassesHttpS, ARRAYSIZE(rgClassesHttpS) },
{ HKEY_CLASSES_ROOT, rgClassesMk, ARRAYSIZE(rgClassesMk) },
{ HKEY_CLASSES_ROOT, rgClassesFile, ARRAYSIZE(rgClassesFile) },
{ HKEY_CLASSES_ROOT, rgHandlerHttp , ARRAYSIZE(rgHandlerHttp ) },
{ HKEY_CLASSES_ROOT, rgHandlerFtp , ARRAYSIZE(rgHandlerFtp ) },
{ HKEY_CLASSES_ROOT, rgHandlerGopher, ARRAYSIZE(rgHandlerGopher) },
{ HKEY_CLASSES_ROOT, rgHandlerHttpS , ARRAYSIZE(rgHandlerHttpS ) },
{ HKEY_CLASSES_ROOT, rgHandlerMk , ARRAYSIZE(rgHandlerMk ) },
{ HKEY_CLASSES_ROOT, rgHandlerFile , ARRAYSIZE(rgHandlerFile ) },
{ HKEY_CLASSES_ROOT, rgHandlerLocal , ARRAYSIZE(rgHandlerLocal ) },
{ HKEY_CLASSES_ROOT, rgMimeHandlerEnc, ARRAYSIZE(rgMimeHandlerEnc) },
{ HKEY_CLASSES_ROOT, rgClassesMimeHandlerEnc, ARRAYSIZE(rgClassesMimeHandlerEnc) },
{ HKEY_CLASSES_ROOT, rgDeflateEnc, ARRAYSIZE(rgDeflateEnc) },
{ HKEY_CLASSES_ROOT, rgGZIPEnc, ARRAYSIZE(rgGZIPEnc) },
{ HKEY_CLASSES_ROOT, rgClassesStdEncFac, ARRAYSIZE(rgClassesStdEncFac) },
{ HKEY_CLASSES_ROOT, rgClassesMimeInstallHandler, ARRAYSIZE(rgClassesMimeInstallHandler) },
{ HKEY_CLASSES_ROOT, rgMimeInstallHandler, ARRAYSIZE(rgMimeInstallHandler) },
{ HKEY_CLASSES_ROOT, rgClassesCdl, ARRAYSIZE(rgClassesCdl) },
{ HKEY_CLASSES_ROOT, rgHandlerCdl , ARRAYSIZE(rgHandlerCdl) },
#ifdef TEST_JOHANNP
#if DBG==1
{ HKEY_CLASSES_ROOT, rgNameSpaceTest1 , ARRAYSIZE(rgNameSpaceTest1 ) },
{ HKEY_CLASSES_ROOT, rgNameSpaceTest2 , ARRAYSIZE(rgNameSpaceTest2 ) },
#endif // DBG
#endif //TEST_JOHANNP
{ NULL, NULL, 0 } // terminator
};
const REGENTRYGROUP rgRegEntryGroupsDel[] = {
{ HKEY_CLASSES_ROOT, rgStdNotificationMgr, ARRAYSIZE(rgStdNotificationMgr) },
{ HKEY_CLASSES_ROOT, rgClassesRoot, ARRAYSIZE(rgClassesRoot) },
{ HKEY_CLASSES_ROOT, rgClassesSoftDist, ARRAYSIZE(rgClassesSoftDist) },
{ HKEY_CLASSES_ROOT, rgClassesSecMgr, ARRAYSIZE(rgClassesSecMgr) },
{ HKEY_CLASSES_ROOT, rgClassesZoneMgr, ARRAYSIZE(rgClassesZoneMgr) },
{ HKEY_CLASSES_ROOT, rgClassesBindCtx, ARRAYSIZE(rgClassesBindCtx) },
{ HKEY_CLASSES_ROOT, rgPSFactory, ARRAYSIZE(rgPSFactory) },
{ HKEY_CLASSES_ROOT, rgClassesHttp, ARRAYSIZE(rgClassesHttp) },
{ HKEY_CLASSES_ROOT, rgClassesFtp, ARRAYSIZE(rgClassesFtp) },
{ HKEY_CLASSES_ROOT, rgClassesGopher, ARRAYSIZE(rgClassesGopher) },
{ HKEY_CLASSES_ROOT, rgClassesHttpS, ARRAYSIZE(rgClassesHttpS) },
{ HKEY_CLASSES_ROOT, rgClassesMk, ARRAYSIZE(rgClassesMk) },
{ HKEY_CLASSES_ROOT, rgClassesFile, ARRAYSIZE(rgClassesFile) },
{ HKEY_CLASSES_ROOT, rgHandlerFtp , ARRAYSIZE(rgHandlerFtp ) },
{ HKEY_CLASSES_ROOT, rgHandlerGopher, ARRAYSIZE(rgHandlerGopher) },
{ HKEY_CLASSES_ROOT, rgHandlerMk , ARRAYSIZE(rgHandlerMk ) },
{ HKEY_CLASSES_ROOT, rgHandlerFile , ARRAYSIZE(rgHandlerFile ) },
{ HKEY_CLASSES_ROOT, rgHandlerLocal , ARRAYSIZE(rgHandlerLocal ) },
{ HKEY_CLASSES_ROOT, rgMimeHandlerEnc, ARRAYSIZE(rgMimeHandlerEnc) },
{ HKEY_CLASSES_ROOT, rgClassesMimeHandlerEnc, ARRAYSIZE(rgClassesMimeHandlerEnc) },
{ HKEY_CLASSES_ROOT, rgDeflateEnc, ARRAYSIZE(rgDeflateEnc) },
{ HKEY_CLASSES_ROOT, rgGZIPEnc, ARRAYSIZE(rgGZIPEnc) },
{ HKEY_CLASSES_ROOT, rgClassesStdEncFac, ARRAYSIZE(rgClassesStdEncFac) },
{ HKEY_CLASSES_ROOT, rgClassesMimeInstallHandler, ARRAYSIZE(rgClassesMimeInstallHandler) },
{ HKEY_CLASSES_ROOT, rgMimeInstallHandler, ARRAYSIZE(rgMimeInstallHandler) },
{ HKEY_CLASSES_ROOT, rgClassesCdl, ARRAYSIZE(rgClassesCdl) },
{ HKEY_CLASSES_ROOT, rgHandlerCdl , ARRAYSIZE(rgHandlerCdl) },
#ifdef TEST_JOHANNP
#if DBG==1
{ HKEY_CLASSES_ROOT, rgNameSpaceTest1 , ARRAYSIZE(rgNameSpaceTest1 ) },
{ HKEY_CLASSES_ROOT, rgNameSpaceTest2 , ARRAYSIZE(rgNameSpaceTest2 ) },
#endif // DBG
#endif //TEST_JOHANNP
{ NULL, NULL, 0 } // terminator
};
//+---------------------------------------------------------------------------
//
// Function: DllAddRef
//
// Synopsis:
//
// Arguments: [void] --
//
// Returns:
//
// History: 12-10-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
void DllAddRef(void)
{
g_cRef++;
}
//+---------------------------------------------------------------------------
//
// Function: DllRelease
//
// Synopsis:
//
// Arguments: [void] --
//
// Returns:
//
// History: 12-10-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
void DllRelease(void)
{
UrlMkAssert((g_cRef > 0));
if (g_cRef > 0)
{
g_cRef--;
}
}
//+---------------------------------------------------------------------------
//
// Operator: new
//
// Synopsis:
//
// Arguments: [size] --
//
// Returns:
//
// History: 12-10-95 JohannP (Johann Posch) Created
//
// Notes: BUBUG: get and use IMalloc
//
//----------------------------------------------------------------------------
void * _cdecl operator new(size_t size)
{
void * pBuffer;
pBuffer = CoTaskMemAlloc(size);
if (pBuffer)
{
memset(pBuffer,0, size);
}
return pBuffer;
}
void * _cdecl operator new(size_t sizeEl, ULONG cEl)
{
void * pBuffer;
size_t size = sizeEl * cEl;
pBuffer = CoTaskMemAlloc(size);
if (pBuffer)
{
memset(pBuffer,0, size);
}
return pBuffer;
}
//+---------------------------------------------------------------------------
//
// Operator: delete
//
// Synopsis:
//
// Arguments: [lpv] --
//
// Returns:
//
// History: 2-14-96 JohannP (Johann Posch) Created
//
// Notes: BUBUG: get and use IMalloc
//
//----------------------------------------------------------------------------
void _cdecl operator delete(void *lpv)
{
//UrlMkAssert((lpv != NULL));
if (lpv == NULL)
{
return;
}
CoTaskMemFree(lpv);
}
#ifdef UNUSED
//
int _cdecl _purecall( void )
{
UrlMkAssert(FALSE);
return 0;
}
#endif //UNUSED
//+-------------------------------------------------------------------------
//
// Function: DllGetClassObject
//
// Synopsis: Dll entry point
//
// Arguments: [clsid] - class id for new class
// [iid] - interface required of class
// [ppv] - where to put new interface
//
// Returns: S_OK - class object created successfully created.
//
//
//--------------------------------------------------------------------------
STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv)
{
UrlMkDebugOut((DEB_URLMON, "API _IN DllGetClassObject\n"));
HRESULT hr = E_NOTIMPL;
if ( (clsid == CLSID_StdURLMoniker)
|| (clsid == CLSID_UrlMkBindCtx)
|| (clsid == CLSID_HttpSProtocol )
|| (clsid == CLSID_HttpProtocol )
|| (clsid == CLSID_FtpProtocol )
|| (clsid == CLSID_GopherProtocol)
|| (clsid == CLSID_FileProtocol )
|| (clsid == CLSID_MkProtocol )
|| (clsid == CLSID_SoftDistExt )
|| (clsid == CLSID_InternetSecurityManager )
|| (clsid == CLSID_InternetZoneManager )
|| (clsid == CLSID_DeCompMimeFilter)
|| (clsid == CLSID_StdEncodingFilterFac)
|| (clsid == CLSID_CdlProtocol)
|| (clsid == CLSID_ClassInstallFilter)
)
{
CUrlClsFact *pCF = NULL;
hr = CUrlClsFact::Create(clsid, &pCF);
if (hr == NOERROR)
{
UrlMkAssert((pCF != NULL));
hr = pCF->QueryInterface(iid, ppv);
pCF->Release();
}
}
else
{
hr = PrxDllGetClassObject(clsid, iid, ppv);
}
DumpIID(clsid);
UrlMkDebugOut((DEB_URLMON, "API OUT DllGetClassObject (hr:%lx, ppv:%p)\n",hr,*ppv));
return hr;
}
void SetupDelayloadErrorHandler()
{
__pfnDliFailureHook = (PfnDliHook)GetProcAddress(GetModuleHandleA("shlwapi.dll"), "DelayLoadFailureHook");
}
//+-------------------------------------------------------------------------
//
// Function: DllMain
//
// Synopsis:
//
// Arguments: [hDll] - a handle to the dll instance
// [dwReason] - the reason LibMain was called
// [lpvReserved] - NULL - called due to FreeLibrary
// - non-NULL - called due to process exit
//
// Returns: TRUE on success, FALSE otherwise
//
// Notes:
//
// The officially approved DLL entrypoint name is DllMain. This
// entry point will be called by the CRT Init function.
//
//
//--------------------------------------------------------------------------
BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved)
{
BOOL fResult = TRUE;
UrlMkDebugOut((DEB_DLL,"DllMain:%lx\n", dwReason));
PrxDllMain(hInstance, dwReason, lpvReserved);
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
#if DBG==1
{
UrlMkInfoLevel = (DWORD) GetProfileIntA("UrlMon","UrlMk", (DEB_ERROR | DEB_WARN)) & DEB_LEVEL_MASK;
TransInfoLevel = (DWORD) GetProfileIntA("UrlMon","Trans", (DEB_ERROR | DEB_WARN)) & DEB_LEVEL_MASK;
PProtInfoLevel = (DWORD) GetProfileIntA("UrlMon","PProt", (DEB_ERROR | DEB_WARN)) & DEB_LEVEL_MASK;
NotfInfoLevel = (DWORD) GetProfileIntA("UrlMon","Notf", (DEB_ERROR | DEB_WARN)) & DEB_LEVEL_MASK;
EProtInfoLevel = (DWORD) GetProfileIntA("UrlMon","EProt", (DEB_ERROR | DEB_WARN)) & DEB_LEVEL_MASK;
TNotfInfoLevel = (DWORD) GetProfileIntA("UrlMon","TNotf", (DEB_ERROR | DEB_WARN)) & DEB_LEVEL_MASK;
g_dwSettings = (DWORD) GetProfileIntA("UrlMon","Global", (DEB_ERROR | DEB_WARN));
Win4AssertLevel= (ULONG) GetProfileIntA("UrlMon","AssertLevel", 0);
// enable encoding handler
// g_dwSettings |= 0x00100000;
}
#endif //DBG==1
SHFusionInitializeFromModule((HMODULE)hInstance);
SetupDelayloadErrorHandler();
PerfDbgLog(tagUrlDll, NULL, "+URLMON DLL_PROCESS_ATTACH");
g_pszUserAgentString = NULL;
g_pszUAInfoString = GetUAInfoString();
// We ignore the return code of ZonesInit because other parts of urlmon
// could still function fine if we can't init zones.
ZonesInit( );
g_bCanUseSimpleBinding = CanUseSimpleBinding();
g_bGlobalUTF8Enabled = GlobalUTF8Enabled();
g_bGlobalUTF8hackEnabled = GlobalUTF8hackEnabled();
g_bUseImprovedZoneCheck = CanUseImprovedZoneCheck();
g_pHeadURLMONTSList = NULL;
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osvi))
{
g_bNT5OrGreater = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osvi.dwMajorVersion >= 5);
}
fResult = TlsDllMain(hInstance, dwReason, lpvReserved);
MLLoadResources(hInstance, TEXT("inetcplc.dll"));
//debug log related stuff
INET_DEBUG_START();
PerfDbgLog(tagUrlDll, NULL, "-URLMON DLL_PROCESS_ATTACH");
break;
case DLL_PROCESS_DETACH:
if (g_pszUserAgentString != NULL)
{
delete g_pszUserAgentString;
g_pszUserAgentString = NULL;
}
if (g_pSecurityManager)
{
g_pSecurityManager->Release();
g_pSecurityManager = NULL;
}
if (g_pszUAInfoString != NULL)
{
delete g_pszUAInfoString;
g_pszUAInfoString = NULL;
}
if (g_hLibPluginOcx)
{
FreeLibrary(g_hLibPluginOcx);
}
if (g_hLibMlang)
{
FreeLibrary(g_hLibMlang);
}
ZonesUnInit( );
g_bCanUseSimpleBinding = TRUE;
if (g_pEFmtETC)
{
g_pEFmtETC->Release();
}
if(g_pHeadURLMONTSList)
{
//
// if lpvReserved == NULL - called due to FreeLibrary
// else - called due to process Terminate
//
// Since we are using SendMessage to kill the thread notification
// window, we should only do that when FreeLibraray() happens
//
if( !lpvReserved )
{
CleanupTSOnProcessDetach();
}
}
MLFreeResources(hInstance);
//debug log related stuff
INET_DEBUG_FINISH();
// Fall through
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
fResult = TlsDllMain(hInstance, dwReason, lpvReserved);
if (dwReason==DLL_PROCESS_DETACH)
{
SHFusionUninitialize();
}
}
UrlMkDebugOut((DEB_DLL,"DllMain: done\n"));
return fResult;
}
//+---------------------------------------------------------------------------
//
// Function: DllCanUnloadNow
//
// Synopsis:
//
// Arguments: [void] --
//
// Returns:
//
// Notes:
//
//----------------------------------------------------------------------------
STDAPI DllCanUnloadNow(void)
{
return (g_cRef ? S_FALSE : S_OK);
}
//+---------------------------------------------------------------------------
//
// Function: DllRegisterServer
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 5-03-96 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDAPI DllRegisterServer()
{
UrlMkDebugOut((DEB_URLMON, "API _IN DllRegisterServer\n"));
HRESULT hr;
// don't register the proxies now
// PrxDllRegisterServer();
PrxDllRegisterServer();
hr = HrDllRegisterServer(rgRegEntryGroups, g_hInst, NULL /*pfnLoadString*/);
UrlMkDebugOut((DEB_URLMON, "API OUT DllRegisterServer (hr:%lx)\n",hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: DllUnregisterServer
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 5-03-96 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDAPI DllUnregisterServer()
{
UrlMkDebugOut((DEB_URLMON, "API _IN DllUnregisterServer\n"));
HRESULT hr;
// don't register the proxies now
//PrxDllUnregisterServer();
hr = HrDllUnregisterServer(rgRegEntryGroupsDel, g_hInst, NULL /*pfnLoadString*/);
UrlMkDebugOut((DEB_URLMON, "API OUT DllUnregisterServer (hr:%lx)\n",hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: DllRegisterServerEx
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 5-03-96 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDAPI DllRegisterServerEx()
{
UrlMkDebugOut((DEB_URLMON, "API _IN DllRegisterServerEx\n"));
HRESULT hr = E_NOTIMPL;
UrlMkDebugOut((DEB_URLMON, "API OUT DllRegisterServerEx (hr:%lx)\n",hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: DllInstall
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 6-17-97 SanjayS (Sanjay Shenoy) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDAPI DllInstall(BOOL bInstall, LPCWSTR pwStr)
{
UrlMkDebugOut((DEB_URLMON, "API _IN DllInstall\n"));
#ifdef UNIX
/*
* On Unix, regsetup always passes in L"" for pwStr.
*/
HRESULT hr;
if (pwStr && !wcscmp(pwStr, L""))
hr = ZonesDllInstall(bInstall, L"HKCU");
else
hr = ZonesDllInstall(bInstall, pwStr);
#else
HRESULT hr = ZonesDllInstall(bInstall, pwStr);
#endif /* UNIX */
UrlMkDebugOut((DEB_URLMON, "API OUT DllInstall (hr:%lx)\n", hr));
return hr;
}
//+-------------------------------------------------------------------------
//
// Function: CoBuildVersion
//
// Synopsis: Return build version DWORD
//
// Returns: DWORD hiword = 23
// DWORD loword = build number
//
// Notes: The high word must always be constant for a given platform.
// For Win16 it must be exactly 23 (because that's what 16-bit
// OLE 2.01 shipped with). We can choose a different high word
// for other platforms. The low word must be greater than 639
// (also because that's what 16-bit OLE 2.01 shipped with).
//
//--------------------------------------------------------------------------
STDAPI_(DWORD) UrlMkBuildVersion( VOID )
{
WORD wLowWord;
WORD wHighWord;
wHighWord = 23;
//wLowWord = rmm; // from ih\verole.h
wLowWord = 1; // from ih\verole.h
//Win4Assert(wHighWord == 23 && "CoBuildVersion high word magic number");
//Win4Assert(wLowWord > 639 && "CoBuildVersion low word not large enough");
DWORD dwVersion;
dwVersion = MAKELONG(wLowWord, wHighWord);
return dwVersion;
}
//+---------------------------------------------------------------------------
//
// Function: GetUAInfoString
//
// Synopsis: Creates the extra UA header string
//
// Arguments:
//
// Returns: pointer to newly allocated string
//
// History: 5-27-96 JoeS (Joe Souza) Created
//
// Notes:
//
//----------------------------------------------------------------------------
LPSTR GetUAInfoString(void)
{
BOOL bRet;
CHAR szINTEL[] = "x86";
CHAR szMIPS[] = "MIPS";
CHAR szALPHA[] = "Alpha";
CHAR szPPC[] = "PPC";
CHAR *pszProcessorString = szINTEL;
CHAR szExtraUAInfo[] = "UA-CPU: %s\r\n";
#define SZUSERAGENTMAX 256
static char vszBuffer[SZUSERAGENTMAX] = "";
LPSTR pszTmp;
BOOL fIsNT = FALSE;
// Get all needed info.
OSVERSIONINFO osvi;
SYSTEM_INFO si;
{
memset(&osvi, 0, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// We are running on NT
fIsNT = TRUE;
memset(&si, 0, sizeof(si));
GetSystemInfo(&si);
switch (si.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_MIPS:
pszProcessorString = szMIPS;
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
pszProcessorString = szALPHA;
break;
case PROCESSOR_ARCHITECTURE_PPC:
pszProcessorString = szPPC;
break;
}
}
}
// Build header string.
wsprintf(vszBuffer, szExtraUAInfo, pszProcessorString);
pszTmp = new CHAR [strlen(vszBuffer) + 1];
if (pszTmp )
{
if(fIsNT && si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL )
strcpy(pszTmp, vszBuffer);
else
pszTmp[0] = '\0';
}
return pszTmp;
}
#if DBG==1
#include <sem.hxx>
CMutexSem mxs;
IDebugOut *v_pPProtDbgOut = NULL;
IDebugOut *v_pTransDbgOut = NULL;
IDebugOut *v_pUrlMkDbgOut = NULL;
IDebugOut *v_pNotfDbgOut = NULL;
IDebugOut *v_pEProtDbgOut = NULL;
IDebugOut *v_pTNotfDbgOut = NULL;
void UrlSpyFn(int iOption, const char *pscFormat, ...)
{
CLock lck(mxs);
static char szOutBuffer[2048];
static DWORD * apiLevel[] = { &UrlMkInfoLevel, &TransInfoLevel, &PProtInfoLevel, &NotfInfoLevel, &EProtInfoLevel, &TNotfInfoLevel };
static IDebugOut ** apDbgOut[] = { &v_pUrlMkDbgOut, &v_pTransDbgOut, &v_pPProtDbgOut,&v_pNotfDbgOut, &v_pEProtDbgOut, &v_pTNotfDbgOut };
int iIndex = iOption >> DEB_LEVEL_SHIFT;
int iLevel = *apiLevel[iIndex];
if ((iOption & iLevel) == 0)
return;
DWORD tid = GetCurrentThreadId();
DWORD cbBufLen;
IDebugOut * pDbgOut = *apDbgOut[iIndex];
wsprintf(szOutBuffer, "%08x> ", tid);
cbBufLen = strlen(szOutBuffer);
va_list args;
va_start(args, pscFormat);
vsprintf(szOutBuffer + cbBufLen, pscFormat, args);
va_end(args);
UrlSpySendEntry(pDbgOut, szOutBuffer, tid, iOption & DEB_LEVEL_MASK, 0);
}
void PerfDbgLogFn(int tag, void * pvObj, const char * pchFmt, ...)
{
CLock lck(mxs);
static char szOutBuffer[2048];
static DWORD * apiLevel[] = { &UrlMkInfoLevel, &TransInfoLevel, &PProtInfoLevel, &NotfInfoLevel, &EProtInfoLevel, &TNotfInfoLevel };
static IDebugOut ** apDbgOut[] = { &v_pUrlMkDbgOut, &v_pTransDbgOut, &v_pPProtDbgOut, &v_pEProtDbgOut };
int iIndex = min(tag >> DEB_LEVEL_SHIFT, 2);
int iLevel = *apiLevel[iIndex];
if ((tag & iLevel) == 0)
return;
DWORD tid = GetCurrentThreadId();
DWORD cbBufLen;
IDebugOut * pDbgOut = *apDbgOut[iIndex];
sprintf(szOutBuffer, "%08x> %p %s", tid, pvObj,
*pchFmt == '+' ? "_IN " : (*pchFmt == '-' ? "OUT " : ""));
cbBufLen = strlen(szOutBuffer);
if (*pchFmt == '+' || *pchFmt == '-')
pchFmt += 1;
va_list args;
va_start(args, pchFmt);
vsprintf(szOutBuffer + cbBufLen, pchFmt, args);
lstrcat(szOutBuffer, "\n");
va_end(args);
UrlSpySendEntry(pDbgOut, szOutBuffer, tid, tag & DEB_LEVEL_MASK, 0);
}
void UrlSpySendEntry(IDebugOut *pDbgOut, LPSTR szOutBuffer, DWORD ThreadId, DWORD dwFlags, DWORD dwReserved)
{
if (pDbgOut)
{
pDbgOut->SendEntry(ThreadId, dwFlags, szOutBuffer, dwReserved);
}
else
{
OutputDebugString(szOutBuffer);
}
}
HRESULT RegisterDebugOut(LPCWSTR pwzName, DWORD dwOptions, IDebugOut *pDbgOut, DWORD dwReserved)
{
if (pwzName)
{
if (!wcsicmp(pwzName, L"UrlMk"))
{
UrlMkInfoLevel = dwOptions;
if (v_pUrlMkDbgOut)
{
v_pUrlMkDbgOut->Release();
v_pUrlMkDbgOut = NULL;
}
if (pDbgOut)
{
v_pUrlMkDbgOut = pDbgOut;
pDbgOut->AddRef();
}
}
if (!wcsicmp(pwzName, L"Trans"))
{
TransInfoLevel = dwOptions;
if (v_pTransDbgOut)
{
v_pTransDbgOut->Release();
v_pTransDbgOut = NULL;
}
if (pDbgOut)
{
v_pTransDbgOut = pDbgOut;
pDbgOut->AddRef();
}
}
if (!wcsicmp(pwzName, L"PProt"))
{
PProtInfoLevel = dwOptions;
if (v_pPProtDbgOut)
{
v_pPProtDbgOut->Release();
v_pPProtDbgOut = NULL;
}
if (pDbgOut)
{
v_pPProtDbgOut = pDbgOut;
pDbgOut->AddRef();
}
}
if (!wcsicmp(pwzName, L"Notf"))
{
NotfInfoLevel = dwOptions;
if (v_pNotfDbgOut)
{
v_pNotfDbgOut->Release();
v_pNotfDbgOut = NULL;
}
if (pDbgOut)
{
v_pNotfDbgOut = pDbgOut;
pDbgOut->AddRef();
}
}
if (!wcsicmp(pwzName, L"EProt"))
{
EProtInfoLevel = dwOptions;
if (v_pEProtDbgOut)
{
v_pEProtDbgOut->Release();
v_pEProtDbgOut = NULL;
}
if (pDbgOut)
{
v_pEProtDbgOut = pDbgOut;
pDbgOut->AddRef();
}
}
if (!wcsicmp(pwzName, L"TNotf"))
{
TNotfInfoLevel = dwOptions;
if (v_pTNotfDbgOut)
{
v_pTNotfDbgOut->Release();
v_pTNotfDbgOut = NULL;
}
if (pDbgOut)
{
v_pTNotfDbgOut = pDbgOut;
pDbgOut->AddRef();
}
}
}
return NOERROR;
}
#endif //DBG==1
/*
const REGENTRY rgClassesRes[] =
{
//***** PROTOCOL_RES ENTRIES *****
STD_ENTRY(PROTOCOL_RES_CLSID_REGKEY, PROTOCOL_RES_DESCRIP),
STD_ENTRY(PROTOCOL_RES_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, PROTOCOL_RES_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
*/
/*
const REGENTRY rgClasses[] =
{
//***** URLMONIKER ENTRIES *****
STD_ENTRY(URLMONIKER_CLSID_REGKEY, URLMONIKER_DESCRIP),
STD_ENTRY(URLMONIKER_CLSID_REGKEY"\\InprocServer32", "%s"URLMON_NAME),
{ KEYTYPE_STRING, URLMONIKER_CLSID_REGKEY"\\InprocServer32", "ThreadingModel", REG_SZ, (BYTE*)"Apartment" },
};
*/