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