343 lines
7.2 KiB
C++
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;
|
|
}
|