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.
556 lines
14 KiB
556 lines
14 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
|
//
|
|
// File: libmain.cxx
|
|
//
|
|
// Contents: LibMain for oleds.dll
|
|
//
|
|
// Functions: LibMain, DllGetClassObject
|
|
//
|
|
// History: 25-Oct-94 KrishnaG Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "winnt.hxx"
|
|
#pragma hdrstop
|
|
|
|
|
|
HINSTANCE g_hInst = NULL;
|
|
extern HMODULE g_hActiveDs;
|
|
WCHAR * szWinNTPrefix = L"@WinNT!";
|
|
HANDLE FpnwLoadLibSemaphore = NULL;
|
|
|
|
//
|
|
// Strings that are loaded depending on locality
|
|
//
|
|
WCHAR g_szBuiltin[100];
|
|
WCHAR g_szNT_Authority[100];
|
|
WCHAR g_szEveryone[100];
|
|
BOOL g_fStringsLoaded = FALSE;
|
|
|
|
//
|
|
// 3rd party extension
|
|
//
|
|
extern PCLASS_ENTRY gpClassHead;
|
|
extern CRITICAL_SECTION g_ExtCritSect;
|
|
|
|
extern CRITICAL_SECTION g_TypeInfoCritSect;
|
|
|
|
//
|
|
// Disabled as it causes link warnings
|
|
// extern CRITICAL_SECTION g_DispTypeInfoCritSect;
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
// ADs debug print, mem leak and object tracking-related stuff
|
|
//---------------------------------------------------------------------------
|
|
|
|
DECLARE_INFOLEVEL(ADs)
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ShutDown
|
|
//
|
|
// Synopsis: Function to handle printing out heap debugging display
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
inline VOID ShutDown()
|
|
{
|
|
#if DBG==1
|
|
#ifndef MSVC
|
|
DUMP_TRACKING_INFO_DELETE();
|
|
DeleteCriticalSection(&g_csOT);
|
|
#endif // ifndef MSVC
|
|
DeleteCriticalSection(&g_csDP);
|
|
#endif
|
|
}
|
|
|
|
extern "C" DWORD heapInfoLevel;
|
|
extern "C" DWORD OtInfoLevel;
|
|
extern "C" DWORD ADsInfoLevel;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetINIHeapInfoLevel
|
|
//
|
|
// Synopsis: Gets various infolevel values from win.ini
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
inline VOID GetINIHeapInfoLevel()
|
|
{
|
|
#if DBG==1
|
|
const INT MAXINFOLEN=11;
|
|
WCHAR awcs[MAXINFOLEN];
|
|
|
|
#ifndef MSVC
|
|
if (GetProfileString(L"winnt",L"heapInfoLevel", L"00000003", awcs,MAXINFOLEN))
|
|
heapInfoLevel = wcstoul(awcs, NULL, 16);
|
|
|
|
if (GetProfileString(L"winnt",L"Ot", L"00000003", awcs, MAXINFOLEN))
|
|
OtInfoLevel = wcstoul(awcs, NULL, 16);
|
|
|
|
#endif // MSVC
|
|
|
|
if (GetProfileString(L"winnt",L"ADsInfoLevel", L"00000003", awcs,MAXINFOLEN))
|
|
ADsInfoLevel = wcstoul(awcs, NULL, 16);
|
|
#endif
|
|
}
|
|
|
|
// Globals
|
|
|
|
|
|
ULONG g_ulObjCount = 0; // Number of objects alive in oleds.dll
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Macro that calculates the number of elements in a statically-defined
|
|
// array.
|
|
//
|
|
// Note - I swiped this from ADsary.cxx - A type-safe array class. Remember
|
|
// to swipe the whole thing as required.
|
|
//-------------------------------------------------------------------------
|
|
#define ARRAY_SIZE(_a) (sizeof(_a) / sizeof(_a[0]))
|
|
|
|
CWinNTProviderCF g_cfProvider;
|
|
CWinNTNamespaceCF g_cfNamespace;
|
|
CWinNTSystemInfoCF g_cfWinNTSystemInfo;
|
|
//CWinNTDomainCF g_cfDomain;
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// oleds class factories
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
|
|
struct CLSCACHE
|
|
{
|
|
const CLSID * pclsid;
|
|
IClassFactory * pCF;
|
|
};
|
|
|
|
|
|
|
|
CLSCACHE g_aclscache[] =
|
|
{
|
|
&CLSID_WinNTProvider, &g_cfProvider,
|
|
&CLSID_WinNTNamespace, &g_cfNamespace,
|
|
&CLSID_WinNTSystemInfo, &g_cfWinNTSystemInfo
|
|
};
|
|
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: DllGetClassObject
|
|
//
|
|
// Synopsis: Standard DLL entrypoint for locating class factories
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDAPI
|
|
DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID FAR* ppv)
|
|
{
|
|
HRESULT hr;
|
|
size_t i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(g_aclscache); i++)
|
|
{
|
|
if (IsEqualCLSID(clsid, *g_aclscache[i].pclsid))
|
|
{
|
|
hr = g_aclscache[i].pCF->QueryInterface(iid, ppv);
|
|
RRETURN(hr);
|
|
}
|
|
}
|
|
|
|
*ppv = NULL;
|
|
|
|
//
|
|
// Add Debugging Code to indicate that the oleds.DllGetClassObject has been called with an unknown CLSID.
|
|
//
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: DllCanUnloadNow
|
|
//
|
|
// Synopsis: Standard DLL entrypoint to determine if DLL can be unloaded
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
STDAPI
|
|
DllCanUnloadNow(void)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = S_FALSE;
|
|
|
|
if (AggregatorDllCanUnload() ) {
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
void LoadLocalizedStrings()
|
|
{
|
|
if (g_fStringsLoaded) {
|
|
return;
|
|
}
|
|
|
|
if (!LoadStringW(
|
|
g_hInst,
|
|
ADS_WINNT_BUILTIN,
|
|
g_szBuiltin,
|
|
sizeof( g_szBuiltin ) / sizeof( WCHAR )
|
|
)
|
|
) {
|
|
wcscpy(g_szBuiltin, L"BUILTIN");
|
|
}
|
|
|
|
if (!LoadStringW(
|
|
g_hInst,
|
|
ADS_WINNT_NT_AUTHORITY,
|
|
g_szNT_Authority,
|
|
sizeof( g_szNT_Authority ) / sizeof( WCHAR )
|
|
)
|
|
) {
|
|
wcscpy(g_szNT_Authority, L"NT AUTHORITY");
|
|
}
|
|
|
|
if (!LoadStringW(
|
|
g_hInst,
|
|
ADS_WINNT_EVERYONE,
|
|
g_szEveryone,
|
|
sizeof( g_szEveryone ) / sizeof( WCHAR )
|
|
)
|
|
) {
|
|
wcscpy(g_szEveryone, L"Everyone");
|
|
}
|
|
|
|
}
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: LibMain
|
|
//
|
|
// Synopsis: Standard DLL initialization entrypoint
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
EXTERN_C BOOL __cdecl
|
|
LibMain(HINSTANCE hInst, ULONG ulReason, LPVOID pvReserved)
|
|
{
|
|
HRESULT hr;
|
|
static DWORD dwCriticalSectionsInitialized = 0;
|
|
|
|
switch (ulReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
//
|
|
// Catch case of init crit sect failing.
|
|
//
|
|
__try {
|
|
|
|
DisableThreadLibraryCalls(hInst);
|
|
|
|
g_hInst = hInst;
|
|
|
|
g_hActiveDs = GetModuleHandle(TEXT("activeds.dll"));
|
|
|
|
InitializeCriticalSection(&g_TypeInfoCritSect);
|
|
++dwCriticalSectionsInitialized;
|
|
//
|
|
// If the following code is ever uncommented, then the
|
|
// switch statement in the DLL_PROCESS_DETACH section
|
|
// also needs to be updated to take this into account.
|
|
//
|
|
// Disabled to avoid linker warnings
|
|
// InitializeCriticalSection(&g_DispTypeInfoCritSect);
|
|
//
|
|
|
|
//
|
|
// for 3rd party extension
|
|
//
|
|
|
|
InitializeCriticalSection(&g_ExtCritSect);
|
|
++dwCriticalSectionsInitialized;
|
|
|
|
//
|
|
// Initialize the loadlibs critsect.
|
|
//
|
|
InitializeCriticalSection(&g_csLoadLibs);
|
|
++dwCriticalSectionsInitialized;
|
|
|
|
#if DBG==1
|
|
InitializeCriticalSection(&g_csDP);
|
|
++dwCriticalSectionsInitialized;
|
|
#ifndef MSVC
|
|
InitializeCriticalSection(&g_csOT);
|
|
++dwCriticalSectionsInitialized;
|
|
InitializeCriticalSection(&g_csMem);
|
|
++dwCriticalSectionsInitialized;
|
|
#endif
|
|
#endif
|
|
|
|
//
|
|
// Load up localized strings.
|
|
//
|
|
LoadLocalizedStrings();
|
|
|
|
gpClassHead = BuildClassesList();
|
|
|
|
//
|
|
// Build the global object class cache
|
|
//
|
|
|
|
hr = CObjNameCache::CreateClassCache(
|
|
&pgPDCNameCache
|
|
);
|
|
if (FAILED(hr)) {
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// create semaphore used to protect global data (DLL handles and
|
|
// function pointers.
|
|
//
|
|
|
|
if ((FpnwLoadLibSemaphore = CreateSemaphore( NULL,1,1,NULL ))
|
|
== NULL)
|
|
{
|
|
return FALSE ;
|
|
}
|
|
|
|
g_pRtlEncryptMemory = (FRTLENCRYPTMEMORY) LoadAdvapi32Function(
|
|
STRINGIZE(RtlEncryptMemory));
|
|
g_pRtlDecryptMemory = (FRTLDECRYPTMEMORY) LoadAdvapi32Function(
|
|
STRINGIZE(RtlDecryptMemory));
|
|
|
|
if( (NULL == g_pRtlEncryptMemory) || (NULL == g_pRtlDecryptMemory) )
|
|
g_pRtlEncryptMemory = g_pRtlDecryptMemory = NULL;
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
//
|
|
// Critical failure
|
|
//
|
|
|
|
//
|
|
// Delete the critical sections. Note this must occur in reverse order
|
|
// to the order in which they were initialized. The fall through in
|
|
// each case statement is intentional.
|
|
//
|
|
switch(dwCriticalSectionsInitialized)
|
|
{
|
|
#if DBG==1
|
|
#ifndef MSVC
|
|
case 6:
|
|
DeleteCriticalSection(&g_csMem);
|
|
|
|
case 5:
|
|
DeleteCriticalSection(&g_csOT);
|
|
#endif
|
|
case 4:
|
|
DeleteCriticalSection(&g_csDP);
|
|
#endif
|
|
|
|
case 3:
|
|
DeleteCriticalSection(&g_csLoadLibs);
|
|
|
|
case 2:
|
|
//
|
|
// Causes link warnings if enabled
|
|
// DeleteCriticalSection(&g_DispTypeInfoCritSect);
|
|
//
|
|
DeleteCriticalSection(&g_ExtCritSect);
|
|
|
|
case 1:
|
|
DeleteCriticalSection(&g_TypeInfoCritSect);
|
|
}
|
|
//
|
|
// Reset the counts of critical sections that we have initialized, just
|
|
// in case LibMain(DLL_PROCESS_DETACH) does get called.
|
|
//
|
|
dwCriticalSectionsInitialized = 0;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
//
|
|
// Release semaphor if applicable.
|
|
//
|
|
if (FpnwLoadLibSemaphore) {
|
|
CloseHandle(FpnwLoadLibSemaphore);
|
|
FpnwLoadLibSemaphore = NULL;
|
|
}
|
|
//
|
|
// Del the name cache - delte should handle NULL btw.
|
|
//
|
|
delete pgPDCNameCache;
|
|
//
|
|
// free global list of class entries for 3rd party ext
|
|
//
|
|
|
|
FreeClassesList(gpClassHead);
|
|
|
|
//
|
|
// Delete the critical sections. Note this must occur in reverse order
|
|
// to the order in which they were initialized. The fall through in
|
|
// each case statement is intentional.
|
|
//
|
|
switch(dwCriticalSectionsInitialized)
|
|
{
|
|
#if DBG==1
|
|
#ifndef MSVC
|
|
case 6:
|
|
DeleteCriticalSection(&g_csMem);
|
|
|
|
case 5:
|
|
DeleteCriticalSection(&g_csOT);
|
|
#endif
|
|
case 4:
|
|
DeleteCriticalSection(&g_csDP);
|
|
#endif
|
|
|
|
case 3:
|
|
DeleteCriticalSection(&g_csLoadLibs);
|
|
|
|
case 2:
|
|
//
|
|
// Causes link warnings if enabled
|
|
// DeleteCriticalSection(&g_DispTypeInfoCritSect);
|
|
//
|
|
DeleteCriticalSection(&g_ExtCritSect);
|
|
|
|
case 1:
|
|
DeleteCriticalSection(&g_TypeInfoCritSect);
|
|
}
|
|
|
|
//
|
|
// Free libs we may have loaded dynamically.
|
|
//
|
|
if (g_hDllNetapi32) {
|
|
FreeLibrary((HMODULE) g_hDllNetapi32);
|
|
g_hDllNetapi32 = NULL;
|
|
}
|
|
|
|
if (g_hDllAdvapi32) {
|
|
FreeLibrary((HMODULE) g_hDllAdvapi32);
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: DllMain
|
|
//
|
|
// Synopsis: entry point for NT - post .546
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
|
{
|
|
return LibMain((HINSTANCE)hDll, dwReason, lpReserved);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: GetCachedClsidIndex
|
|
//
|
|
// Synopsis: Returns the index of the given CLSID in the cache, or
|
|
// -1 if the CLSID is not present in the cache
|
|
//
|
|
// Arguments: [clsid]
|
|
//
|
|
// Returns: int
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
|
|
int
|
|
GetCachedClsidIndex(REFCLSID clsid)
|
|
{
|
|
int i;
|
|
CLSCACHE * pclscache;
|
|
|
|
for (i = 0, pclscache = g_aclscache;
|
|
i < ARRAY_SIZE(g_aclscache);
|
|
i ++, pclscache++)
|
|
{
|
|
if (IsEqualCLSID(*pclscache->pclsid, clsid))
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: GetCachedClassFactory
|
|
//
|
|
// Synopsis: Returns the cached class factory with the given index.
|
|
// The pointer returned has been AddRef'd.
|
|
//
|
|
// Arguments: [iclsid]
|
|
//
|
|
// Returns: IClassFactory *
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
|
|
IClassFactory *
|
|
GetCachedClassFactory(int iclsid)
|
|
{
|
|
IClassFactory * pCF;
|
|
|
|
// Assert(iclsid >= 0);
|
|
// Assert(iclsid < ARRAY_SIZE(g_aclscache));
|
|
|
|
pCF = g_aclscache[iclsid].pCF;
|
|
pCF->AddRef();
|
|
|
|
return pCF;
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: GetCachedClsid
|
|
//
|
|
// Synopsis: Returns the CLSID corresponding to the given index.
|
|
// Normally, code should call GetCachedClassFactory to get
|
|
// the class factory directly.
|
|
//
|
|
// Arguments: [iclsid] -- Clsid index
|
|
// [pclsid] -- Matching clsid returned in *pclsid
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
|
|
void
|
|
GetCachedClsid(int iclsid, CLSID * pclsid)
|
|
{
|
|
// Assert(iclsid >= 0);
|
|
// Assert(iclsid < ARRAY_SIZE(g_aclscache));
|
|
|
|
*pclsid = *g_aclscache[iclsid].pclsid;
|
|
}
|