297 lines
7.2 KiB
C++
297 lines
7.2 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997 - 1999
|
|
//
|
|
// File: dll.cpp
|
|
//
|
|
// Core entry points for the DLL
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#define INITGUID
|
|
#include <initguid.h>
|
|
#include "iids.h"
|
|
|
|
/*----------------------------------------------------------------------------
|
|
/ Globals
|
|
/----------------------------------------------------------------------------*/
|
|
|
|
HINSTANCE g_hInstance = NULL;
|
|
HINSTANCE g_hAclEditDll = NULL;
|
|
DWORD g_tls = 0xffffffffL;
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
/ DllMain
|
|
/ -------
|
|
/ Main entry point. We are passed reason codes and assored other
|
|
/ information when loaded or closed down.
|
|
/
|
|
/ In:
|
|
/ hInstance = our instance handle
|
|
/ dwReason = reason code
|
|
/ pReserved = depends on the reason code.
|
|
/
|
|
/ Out:
|
|
/ -
|
|
/----------------------------------------------------------------------------*/
|
|
STDAPI_(BOOL)
|
|
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*pReserved*/)
|
|
{
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
g_hInstance = hInstance;
|
|
g_tls = TlsAlloc();
|
|
DebugProcessAttach();
|
|
TraceSetMaskFromCLSID(CLSID_DsSecurity);
|
|
#ifndef DEBUG
|
|
DisableThreadLibraryCalls(hInstance);
|
|
#endif
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
SchemaCache_Destroy();
|
|
if (g_hAclEditDll)
|
|
FreeLibrary(g_hAclEditDll);
|
|
TlsFree(g_tls);
|
|
DebugProcessDetach();
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
DebugThreadDetach();
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
/ DllCanUnloadNow
|
|
/ ---------------
|
|
/ Called by the outside world to determine if our DLL can be unloaded. If we
|
|
/ have any objects in existance then we must not unload.
|
|
/
|
|
/ In:
|
|
/ -
|
|
/ Out:
|
|
/ BOOL inidicate unload state.
|
|
/----------------------------------------------------------------------------*/
|
|
STDAPI
|
|
DllCanUnloadNow(void)
|
|
{
|
|
return GLOBAL_REFCOUNT ? S_FALSE : S_OK;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
/ DllGetClassObject
|
|
/ -----------------
|
|
/ Given a class ID and an interface ID, return the relevant object. This used
|
|
/ by the outside world to access the objects contained here in.
|
|
/
|
|
/ In:
|
|
/ rCLISD = class ID required
|
|
/ riid = interface within that class required
|
|
/ ppv -> receives the newly created object.
|
|
/
|
|
/ Out:
|
|
/ -
|
|
/----------------------------------------------------------------------------*/
|
|
STDAPI
|
|
DllGetClassObject(REFCLSID rCLSID, REFIID riid, LPVOID *ppv)
|
|
{
|
|
HRESULT hr;
|
|
CDsSecurityClassFactory *pClassFactory;
|
|
|
|
TraceEnter(TRACE_CORE, "DllGetClassObject");
|
|
TraceGUID("Object requested", rCLSID);
|
|
TraceGUID("Interface requested", riid);
|
|
|
|
*ppv = NULL;
|
|
|
|
if (!IsEqualIID(rCLSID, CLSID_DsSecurity))
|
|
ExitGracefully(hr, CLASS_E_CLASSNOTAVAILABLE, "CLSID not supported");
|
|
|
|
pClassFactory = new CDsSecurityClassFactory;
|
|
|
|
if (!pClassFactory)
|
|
ExitGracefully(hr, E_OUTOFMEMORY, "Failed to create class factory");
|
|
|
|
hr = pClassFactory->QueryInterface(riid, ppv);
|
|
|
|
if (FAILED(hr))
|
|
delete pClassFactory;
|
|
|
|
exit_gracefully:
|
|
|
|
TraceLeaveResult(hr);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
/ WaitOnThread
|
|
/ -----------------
|
|
/ If a thread is running (if the handle is non-NULL) wait for it to complete.
|
|
/ Then set the handle to NULL.
|
|
/
|
|
/ In:
|
|
/ phThread = address of thread handle
|
|
/
|
|
/ Out:
|
|
/ Result of WaitForSingleObject, or zero.
|
|
/----------------------------------------------------------------------------*/
|
|
DWORD
|
|
WaitOnThread(HANDLE *phThread)
|
|
{
|
|
DWORD dwResult = 0;
|
|
|
|
if (phThread != NULL && *phThread != NULL)
|
|
{
|
|
HCURSOR hcurPrevious = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
SetThreadPriority(*phThread, THREAD_PRIORITY_HIGHEST);
|
|
|
|
dwResult = WaitForSingleObject(*phThread, INFINITE);
|
|
|
|
CloseHandle(*phThread);
|
|
*phThread = NULL;
|
|
|
|
SetCursor(hcurPrevious);
|
|
}
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
/ Thread Local Storage helpers
|
|
/----------------------------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
/ ThreadCoInitialize
|
|
/ ------------------
|
|
/ There is some thread local storage that indicates if we have called
|
|
/ CoInitialize. If CoInitialize has not yet been called, call it now.
|
|
/ Otherwise, do nothing.
|
|
/
|
|
/ In:
|
|
/ -
|
|
/ Out:
|
|
/ HRESULT
|
|
/----------------------------------------------------------------------------*/
|
|
|
|
HRESULT
|
|
ThreadCoInitialize(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceEnter(TRACE_CORE, "ThreadCoInitialize");
|
|
|
|
if (!TlsGetValue(g_tls))
|
|
{
|
|
TraceMsg("Calling CoInitialize");
|
|
hr = CoInitialize(NULL);
|
|
TlsSetValue(g_tls, (LPVOID)SUCCEEDED(hr));
|
|
}
|
|
|
|
TraceLeaveResult(hr);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
/ ThreadCoUninitialize
|
|
/ ------------------
|
|
/ There is some thread local storage that indicates if we have called
|
|
/ CoInitialize. If CoInitialize has been called, call CoUninitialize now.
|
|
/ Otherwise, do nothing.
|
|
/
|
|
/ In:
|
|
/ -
|
|
/ Out:
|
|
/ HRESULT
|
|
/----------------------------------------------------------------------------*/
|
|
|
|
void
|
|
ThreadCoUninitialize(void)
|
|
{
|
|
TraceEnter(TRACE_CORE, "ThreadCoUninitialize");
|
|
|
|
if (TlsGetValue(g_tls))
|
|
{
|
|
TraceMsg("Calling CoUninitialize");
|
|
CoUninitialize();
|
|
TlsSetValue(g_tls, NULL);
|
|
}
|
|
|
|
TraceLeaveVoid();
|
|
}
|
|
|
|
|
|
//
|
|
// Wrappers for delay-loading aclui.dll
|
|
//
|
|
char const c_szCreateSecurityPage[] = "CreateSecurityPage";
|
|
char const c_szEditSecurity[] = "EditSecurity";
|
|
typedef HPROPSHEETPAGE (WINAPI *PFN_CREATESECPAGE)(LPSECURITYINFO);
|
|
typedef BOOL (WINAPI *PFN_EDITSECURITY)(HWND, LPSECURITYINFO);
|
|
|
|
HRESULT
|
|
_CreateSecurityPage(LPSECURITYINFO pSI, HPROPSHEETPAGE *phPage)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (NULL == g_hAclEditDll)
|
|
g_hAclEditDll = LoadLibrary(c_szAclUI);
|
|
|
|
if (g_hAclEditDll)
|
|
{
|
|
static PFN_CREATESECPAGE s_pfnCreateSecPage = NULL;
|
|
|
|
if (NULL == s_pfnCreateSecPage)
|
|
s_pfnCreateSecPage = (PFN_CREATESECPAGE)GetProcAddress(g_hAclEditDll, c_szCreateSecurityPage);
|
|
|
|
if (s_pfnCreateSecPage)
|
|
{
|
|
hr = S_OK;
|
|
|
|
*phPage = (*s_pfnCreateSecPage)(pSI);
|
|
|
|
if (NULL == *phPage)
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
_EditSecurity(HWND hwndOwner, LPSECURITYINFO pSI)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (NULL == g_hAclEditDll)
|
|
g_hAclEditDll = LoadLibrary(c_szAclUI);
|
|
|
|
if (g_hAclEditDll)
|
|
{
|
|
static PFN_EDITSECURITY s_pfnEditSecurity = NULL;
|
|
|
|
if (NULL == s_pfnEditSecurity)
|
|
s_pfnEditSecurity = (PFN_EDITSECURITY)GetProcAddress(g_hAclEditDll, c_szEditSecurity);
|
|
|
|
if (s_pfnEditSecurity)
|
|
{
|
|
hr = S_OK;
|
|
(*s_pfnEditSecurity)(hwndOwner, pSI);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|