windows-nt/Source/XPSP1/NT/sdktools/mtscript/localobj/factory.cxx
2020-09-26 16:20:57 +08:00

343 lines
7.2 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: factory.cxx
//
// Contents: Contains the class factory implementation and other DLL
// functions for the mtlocal DLL.
//
//----------------------------------------------------------------------------
#include "headers.hxx"
#include "mtscript.h" // MIDL generated file
#include "localobj.h"
#include <advpub.h> // for RegInstall
HINSTANCE g_hInstDll;
HINSTANCE g_hinstAdvPack = NULL;
REGINSTALL g_pfnRegInstall = NULL;
// Globals used by our utilities.
DWORD g_dwFALSE = 0;
EXTERN_C HANDLE g_hProcessHeap = NULL;
// Global class factory
CMTLocalFactory g_LocalFactory;
// ***************************************************************
CMTLocalFactory::CMTLocalFactory()
{
_ulRefs = 0;
}
STDMETHODIMP
CMTLocalFactory::QueryInterface(REFIID iid, void ** ppvObject)
{
if (iid == IID_IClassFactory || iid == IID_IUnknown)
{
*ppvObject = (IClassFactory*)this;
}
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
((IUnknown *)*ppvObject)->AddRef();
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CMTLocalFactory::CreateInstance, public
//
// Synopsis: Creates the CLocalMTProxy object
//
//----------------------------------------------------------------------------
STDMETHODIMP
CMTLocalFactory::CreateInstance(IUnknown * pUnkOuter,
REFIID riid,
void ** ppvObject)
{
HRESULT hr = E_FAIL;
CLocalMTProxy *pMTP;
*ppvObject = NULL;
if (pUnkOuter != NULL)
{
hr = CLASS_E_NOAGGREGATION;
}
pMTP = new CLocalMTProxy();
if (!pMTP)
{
return E_OUTOFMEMORY;
}
hr = pMTP->QueryInterface(riid, ppvObject);
pMTP->Release();
#if DBG == 1
if (hr)
TraceTag((tagError, "CreateInstance failed with %x", hr));
#endif
return hr;
}
//+---------------------------------------------------------------------------
//
// Member: CMTLocalFactory::LockServer, public
//
// Synopsis: Keeps the DLL from being unloaded
//
//----------------------------------------------------------------------------
STDMETHODIMP
CMTLocalFactory::LockServer(BOOL fLock)
{
// Because we implement our class factory as a global object, we don't
// need to worry about keeping it in memory if LockServer is called.
if (fLock)
{
InterlockedIncrement(&g_lObjectCount);
}
else
{
InterlockedDecrement(&g_lObjectCount);
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Function: DllMain
//
// Synopsis: Main DLL entrypoint.
//
// Returns: Doesn't do much except unload advpack.dll if we loaded it.
//
//----------------------------------------------------------------------------
BOOL
WINAPI
DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
BOOL fOk = TRUE;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
g_hInstDll = (HINSTANCE)hDll;
Assert(g_hInstDll != NULL);
DisableThreadLibraryCalls(g_hInstDll);
// Set the variable used by our memory allocator.
g_hProcessHeap = GetProcessHeap();
break;
case DLL_PROCESS_DETACH:
if (g_hinstAdvPack)
{
FreeLibrary(g_hinstAdvPack);
}
break;
case DLL_THREAD_DETACH:
break;
}
return fOk;
}
//+---------------------------------------------------------------------------
//
// Function: LoadAdvPack
//
// Synopsis: Loads AdvPack.dll for DLL registration.
//
//----------------------------------------------------------------------------
HRESULT
LoadAdvPack()
{
HRESULT hr = S_OK;
g_hinstAdvPack = LoadLibrary(_T("ADVPACK.DLL"));
if (!g_hinstAdvPack)
goto Error;
g_pfnRegInstall = (REGINSTALL)GetProcAddress(g_hinstAdvPack, achREGINSTALL);
if (!g_pfnRegInstall)
goto Error;
Cleanup:
return hr;
Error:
hr = HRESULT_FROM_WIN32(GetLastError());
if (g_hinstAdvPack)
{
FreeLibrary(g_hinstAdvPack);
}
goto Cleanup;
}
//+---------------------------------------------------------------------------
//
// Function: DllRegisterServer
//
// Synopsis: Register the various important information needed by our
// class.
//
// Notes: Uses AdvPack.dll and an INF file to do the registration
//
//----------------------------------------------------------------------------
STDAPI
DllRegisterServer()
{
HRESULT hr;
STRTABLE stReg = { 0, NULL };
ITypeLib *pTypeLibDLL = NULL;
TCHAR achDll[MAX_PATH];
Assert(g_hInstDll != NULL);
// Make sure the type library is registered
GetModuleFileName(g_hInstDll, achDll, MAX_PATH);
hr = THR(LoadTypeLib(achDll, &pTypeLibDLL));
if (hr)
goto Cleanup;
// This may fail if the user is not an administrator on this machine.
// It's not a big deal unless they try to run mtscript.exe, but the UI
// will still work.
(void) RegisterTypeLib(pTypeLibDLL, achDll, NULL);
if (!g_hinstAdvPack)
{
hr = LoadAdvPack();
if (hr)
goto Cleanup;
}
hr = g_pfnRegInstall(g_hInstDll, "Register", &stReg);
Cleanup:
if (pTypeLibDLL)
{
pTypeLibDLL->Release();
}
RegFlushKey(HKEY_CLASSES_ROOT);
return hr;
}
//+------------------------------------------------------------------------
//
// Function: DllUnregisterServer
//
// Synopsis: Undo the actions of DllRegisterServer.
//
//-------------------------------------------------------------------------
STDAPI
DllUnregisterServer()
{
HRESULT hr;
STRTABLE stReg = { 0, NULL };
Assert(g_hInstDll != NULL);
if (!g_hinstAdvPack)
{
hr = LoadAdvPack();
if (hr)
goto Cleanup;
}
hr = g_pfnRegInstall(g_hInstDll, "Unregister", &stReg);
// Unregister the type library
if (!hr)
{
(void) UnRegisterTypeLib(LIBID_MTScriptEngine, 1, 0, 0, SYS_WIN32);
}
Cleanup:
RegFlushKey(HKEY_CLASSES_ROOT);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: DllGetClassObject
//
// Synopsis: Returns the class factory for a particular object
//
//----------------------------------------------------------------------------
STDAPI
DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *ppv)
{
HRESULT hr;
if (clsid == CLSID_RemoteMTScriptProxy)
{
hr = g_LocalFactory.QueryInterface(iid, ppv);
}
else
{
hr = CLASS_E_CLASSNOTAVAILABLE;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: DllCanUnloadNow
//
// Synopsis: Indicates if we can be unloaded.
//
// Notes: Returns OK if we currently have no objects running.
//
//----------------------------------------------------------------------------
STDAPI
DllCanUnloadNow()
{
if (g_lObjectCount == 0)
{
return S_OK;
}
return S_FALSE;
}