|
|
//+---------------------------------------------------------------------------
//
// 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; }
|