290 lines
6.6 KiB
C++
290 lines
6.6 KiB
C++
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 2000.
|
||
|
//
|
||
|
// File: libmain.cxx
|
||
|
//
|
||
|
// Contents: Contains the implementation of DLL entry points.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#define INITGUID
|
||
|
|
||
|
#include "cadsxml.hxx"
|
||
|
#include "adsxmlcf.hxx"
|
||
|
#include <ole2.h>
|
||
|
|
||
|
DECLARE_INFOLEVEL(ADs)
|
||
|
|
||
|
CADsXMLCF g_cfADsXML;
|
||
|
CRITICAL_SECTION g_ADsXMLCritSect;
|
||
|
|
||
|
struct CLSCACHE
|
||
|
{
|
||
|
const CLSID *pclsid;
|
||
|
IClassFactory *pCF;
|
||
|
};
|
||
|
|
||
|
DEFINE_GUID(CLSID_ADsXML, 0x800fc136,0xb101,0x46c4,0xa5,0xd9,0x80,0xfb,0x31,0x4e,0x1a,0x13);
|
||
|
|
||
|
CLSCACHE g_aclscache[] =
|
||
|
{
|
||
|
&CLSID_ADsXML, &g_cfADsXML
|
||
|
};
|
||
|
|
||
|
#define ARRAY_SIZE(_a) (sizeof(_a) / sizeof(_a[0]))
|
||
|
#define EXTENSION_CLSID L"SOFTWARE\\Microsoft\\ADs\\Providers\\LDAP\\Extensions\\top\\{800fc136-b101-46c4-a5d9-80fb314e1a13}"
|
||
|
#define EXTENSION_IID L"{91e5c5dc-926b-46ff-9fdb-9fb112bf10e6}"
|
||
|
|
||
|
extern CRITICAL_SECTION g_ExtTypeInfoCritSect;
|
||
|
extern CRITICAL_SECTION g_DispTypeInfoCritSect;
|
||
|
|
||
|
//----------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DllGetClassObject
|
||
|
//
|
||
|
// Synopsis: Standard DLL entrypoint for locating class factories
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// clsid Class ID of object being created
|
||
|
// iid Interface requested
|
||
|
// ppv Returns interface requested
|
||
|
//
|
||
|
// Returns: S_OK on success, error otherwise
|
||
|
//
|
||
|
// Modifies: *ppv to return interface pointer
|
||
|
//
|
||
|
//----------------------------------------------------------------
|
||
|
|
||
|
STDAPI
|
||
|
DllGetClassObject(
|
||
|
REFCLSID clsid,
|
||
|
REFIID iid,
|
||
|
LPVOID FAR* ppv
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
size_t i = 0;
|
||
|
|
||
|
ADsAssert(ppv != NULL);
|
||
|
|
||
|
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;
|
||
|
|
||
|
RRETURN(E_NOINTERFACE);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DllCanUnloadNow
|
||
|
//
|
||
|
// Synopsis: Standard DLL entrypoint to determine if DLL can be unloaded
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Returns S_FALSE if the DLL cannot be unloaded, S_OK otherwise.
|
||
|
// The DLL can be unloaded if there are no outstanding objects.
|
||
|
//
|
||
|
// Modifies: Nothing
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
STDAPI
|
||
|
DllCanUnloadNow(void)
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
|
||
|
EnterCriticalSection(&g_ADsXMLCritSect);
|
||
|
if(0 == glnObjCnt) {
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
LeaveCriticalSection(&g_ADsXMLCritSect);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DllMain
|
||
|
//
|
||
|
// Synopsis: Standard DLL initialization entrypoint
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// hDll Handle to the DLL module
|
||
|
// dwReason Reason for calling this entry point
|
||
|
// lpReserved Reserved
|
||
|
//
|
||
|
// Returns: Returns FALSE on failure, TRUE otherwise.
|
||
|
//
|
||
|
// Modifies: Nothing
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
switch (dwReason) {
|
||
|
|
||
|
case DLL_PROCESS_ATTACH:
|
||
|
//
|
||
|
// Catch case of init crit sect failing.
|
||
|
//
|
||
|
__try {
|
||
|
|
||
|
DisableThreadLibraryCalls((HINSTANCE)hDll);
|
||
|
|
||
|
InitializeCriticalSection(&g_ADsXMLCritSect);
|
||
|
|
||
|
#if DBG==1
|
||
|
#ifndef MSVC
|
||
|
InitializeCriticalSection(&g_csOT);
|
||
|
InitializeCriticalSection(&g_csMem);
|
||
|
#endif
|
||
|
InitializeCriticalSection(&g_csDP);
|
||
|
#endif
|
||
|
|
||
|
InitializeCriticalSection(&g_ExtTypeInfoCritSect);
|
||
|
InitializeCriticalSection(&g_DispTypeInfoCritSect);
|
||
|
|
||
|
}
|
||
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
//
|
||
|
// Critical failure
|
||
|
//
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DLL_PROCESS_DETACH:
|
||
|
|
||
|
DeleteCriticalSection(&g_ADsXMLCritSect);
|
||
|
|
||
|
AggregateeFreeTypeInfoTable();
|
||
|
#if DBG==1
|
||
|
#ifndef MSVC
|
||
|
DeleteCriticalSection(&g_csOT);
|
||
|
DeleteCriticalSection(&g_csMem);
|
||
|
#endif
|
||
|
DeleteCriticalSection(&g_csDP);
|
||
|
#endif
|
||
|
|
||
|
DeleteCriticalSection(&g_ExtTypeInfoCritSect);
|
||
|
DeleteCriticalSection(&g_DispTypeInfoCritSect);
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DllRegisterServer
|
||
|
//
|
||
|
// Synopsis: Standard DLL entrypoint to create registry entries for classes
|
||
|
// supported by this DLL.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Returns S_OK on success, error otherwise.
|
||
|
//
|
||
|
// Modifies: Nothing
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
STDAPI DllRegisterServer(void)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
long lRetVal = 0;
|
||
|
HKEY hKey;
|
||
|
|
||
|
lRetVal = RegCreateKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
EXTENSION_CLSID,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hKey,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if(lRetVal != ERROR_SUCCESS)
|
||
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(lRetVal));
|
||
|
|
||
|
lRetVal = RegSetValueEx(
|
||
|
hKey,
|
||
|
L"Interfaces",
|
||
|
0,
|
||
|
REG_SZ,
|
||
|
(const BYTE *) EXTENSION_IID,
|
||
|
(wcslen(EXTENSION_IID) + 1) * 2
|
||
|
);
|
||
|
|
||
|
if(lRetVal != ERROR_SUCCESS)
|
||
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(lRetVal));
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
|
||
|
error:
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DllUnregisterServer
|
||
|
//
|
||
|
// Synopsis: Standard DLL entrypoint to remove registry entries for classes
|
||
|
// supported by this DLL.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Returns S_OK on success, error otherwise.
|
||
|
//
|
||
|
// Modifies: Nothing
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
STDAPI DllUnregisterServer(void)
|
||
|
{
|
||
|
LONG lRetVal = 0;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
lRetVal = RegDeleteKey(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
EXTENSION_CLSID
|
||
|
);
|
||
|
|
||
|
if(lRetVal != ERROR_SUCCESS)
|
||
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(lRetVal));
|
||
|
|
||
|
lRetVal = RegDeleteKey(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
L"SOFTWARE\\Microsoft\\ADs\\Providers\\LDAP\\Extensions\\top"
|
||
|
);
|
||
|
|
||
|
if(lRetVal != ERROR_SUCCESS)
|
||
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(lRetVal));
|
||
|
|
||
|
error:
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|