//==============================================================; // // This source code is only intended as a supplement to existing Microsoft documentation. // // // // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. // // // //==============================================================; #include #include #include #include "globals.h" #include "resource.h" #include "guids.h" #include "basesnap.h" #include "CMenuExt.h" #include "About.h" #include "Registry.h" #include "Extend.h" // our globals HINSTANCE g_hinst; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, void* lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { g_hinst = hinstDLL; } return TRUE; } STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj) { if ((rclsid != CLSID_CContextMenuExtension) && (rclsid != CLSID_CSnapinAbout)) return CLASS_E_CLASSNOTAVAILABLE; if (!ppvObj) return E_FAIL; *ppvObj = NULL; // We can only hand out IUnknown and IClassFactory pointers. Fail // if they ask for anything else. if (!IsEqualIID(riid, IID_IUnknown) && !IsEqualIID(riid, IID_IClassFactory)) return E_NOINTERFACE; CClassFactory *pFactory = NULL; // make the factory passing in the creation function for the type of object they want if (rclsid == CLSID_CContextMenuExtension) pFactory = new CClassFactory(CClassFactory::CONTEXTEXTENSION); else if (rclsid == CLSID_CSnapinAbout) pFactory = new CClassFactory(CClassFactory::ABOUT); if (NULL == pFactory) return E_OUTOFMEMORY; HRESULT hr = pFactory->QueryInterface(riid, ppvObj); return hr; } STDAPI DllCanUnloadNow(void) { if (g_uObjects == 0 && g_uSrvLock == 0) return S_OK; else return S_FALSE; } CClassFactory::CClassFactory(FACTORY_TYPE factoryType) : m_cref(0), m_factoryType(factoryType) { OBJECT_CREATED } CClassFactory::~CClassFactory() { OBJECT_DESTROYED } STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID *ppv) { if (!ppv) return E_FAIL; *ppv = NULL; if (IsEqualIID(riid, IID_IUnknown)) *ppv = static_cast(this); else if (IsEqualIID(riid, IID_IClassFactory)) *ppv = static_cast(this); if (*ppv) { reinterpret_cast(*ppv)->AddRef(); return S_OK; } return E_NOINTERFACE; } STDMETHODIMP_(ULONG) CClassFactory::AddRef() { return InterlockedIncrement((LONG *)&m_cref); } STDMETHODIMP_(ULONG) CClassFactory::Release() { if (InterlockedDecrement((LONG *)&m_cref) == 0) { delete this; return 0; } return m_cref; } STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj) { HRESULT hr; void* pObj; if (!ppvObj) return E_FAIL; *ppvObj = NULL; // Our object does does not support aggregation, so we need to // fail if they ask us to do aggregation. if (pUnkOuter) return CLASS_E_NOAGGREGATION; if (CONTEXTEXTENSION == m_factoryType) { pObj = new CContextMenuExtension(); } else { pObj = new CSnapinAbout(); } if (!pObj) return E_OUTOFMEMORY; // QueryInterface will do the AddRef() for us, so we do not // do it in this function hr = ((LPUNKNOWN)pObj)->QueryInterface(riid, ppvObj); if (FAILED(hr)) delete pObj; return hr; } STDMETHODIMP CClassFactory::LockServer(BOOL fLock) { if (fLock) InterlockedIncrement((LONG *)&g_uSrvLock); else InterlockedDecrement((LONG *)&g_uSrvLock); return S_OK; } ////////////////////////////////////////////////////////// // // Exported functions // // // Server registration // STDAPI DllRegisterServer() { HRESULT hr = SELFREG_E_CLASS; _TCHAR szName[256]; _TCHAR szSnapInName[256]; LoadString(g_hinst, IDS_NAME, szName, sizeof(szName)); LoadString(g_hinst, IDS_SNAPINNAME, szSnapInName, sizeof(szSnapInName)); _TCHAR szAboutName[256]; LoadString(g_hinst, IDS_ABOUTNAME, szAboutName, sizeof(szAboutName)); // register our CoClasses hr = RegisterServer(g_hinst, CLSID_CContextMenuExtension, szName); if SUCCEEDED(hr) hr = RegisterServer(g_hinst, CLSID_CSnapinAbout, szAboutName); // place the registry information for SnapIns if SUCCEEDED(hr) hr = RegisterSnapin(CLSID_CContextMenuExtension, szSnapInName, CLSID_CSnapinAbout); return hr; } STDAPI DllUnregisterServer() { if (UnregisterServer(CLSID_CContextMenuExtension) == S_OK) return UnregisterSnapin(CLSID_CContextMenuExtension); else return E_FAIL; }