//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1995 - 1995. // // File: ole.cxx // // Contents: IUnknown & IClassFactory for all OLE objects // // History: 13-Dec-95 BruceFo Created // // Note: There are three types of IUnknown implementations here. The first // is for the "Shared Folders" COM objects. Each of these interfaces can be // QueryInterface'd from the others, and all return the same IUnknown. There // is a single shared object reference count (not interface reference count). // These interfaces include: IShellFolder, IPersistFolder, IRemoteComputer. // // The second type is standard, separate interfaces that get interface-specific // reference counts. This includes: IShellDetails, IEnumIDList, // IExtractIcon, IExtractIconA. // // The third type is the IUnknown implementation for the "Shared Folders" // COM object class factory. This object is a global static object, so it // never gets destructed. // //---------------------------------------------------------------------------- #include "headers.hxx" #pragma hdrstop #include #include "guids.h" #include "ole.hxx" #include "shares.h" #include "shares.hxx" #include "sdetails.hxx" #include "sfolder.hxx" #include "pfolder.hxx" #include "rcomp.hxx" #include "menu.hxx" #include "menusp.hxx" #include "menubg.hxx" #include "enum.hxx" #include "xicon.hxx" ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ULONG g_ulcInstances = 0; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CShares::QueryInterface(REFIID riid, LPVOID* ppvObj) { HRESULT hr; if (IsEqualIID(IID_IUnknown, riid)) { AddRef(); *ppvObj = (IUnknown*) this; hr = S_OK; } else if (IsEqualIID(IID_IShellFolder, riid)) { hr = m_ShellFolder.QueryInterface(riid, ppvObj); } else if (IsEqualIID(IID_IPersistFolder, riid)) { hr = m_PersistFolder.QueryInterface(riid, ppvObj); } else if (IsEqualIID(IID_IRemoteComputer, riid)) { hr = m_RemoteComputer.QueryInterface(riid, ppvObj); } else { *ppvObj = NULL; hr = E_NOINTERFACE; } return hr; } STDMETHODIMP_(ULONG) CShares::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CShares::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesSF::QueryInterface(REFIID riid, LPVOID* ppvObj) { HRESULT hr; if (IsEqualIID(IID_IShellFolder, riid)) { AddRef(); *ppvObj = (IShellFolder*) this; hr = S_OK; } else { CShares* This = IMPL(CShares,m_ShellFolder,this); hr = This->QueryInterface(riid, ppvObj); } return hr; } STDMETHODIMP_(ULONG) CSharesSF::AddRef() { CShares* This = IMPL(CShares,m_ShellFolder,this); return This->AddRef(); } STDMETHODIMP_(ULONG) CSharesSF::Release() { CShares* This = IMPL(CShares,m_ShellFolder,this); return This->Release(); } ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesPF::QueryInterface(REFIID riid, LPVOID* ppvObj) { HRESULT hr; if (IsEqualIID(IID_IPersistFolder, riid)) { AddRef(); *ppvObj = (IPersistFolder*) this; hr = S_OK; } else { CShares* This = IMPL(CShares,m_PersistFolder,this); hr = This->QueryInterface(riid, ppvObj); } return hr; } STDMETHODIMP_(ULONG) CSharesPF::AddRef() { CShares* This = IMPL(CShares,m_PersistFolder,this); return This->AddRef(); } STDMETHODIMP_(ULONG) CSharesPF::Release() { CShares* This = IMPL(CShares,m_PersistFolder,this); return This->Release(); } ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesRC::QueryInterface(REFIID riid, LPVOID* ppvObj) { HRESULT hr; if (IsEqualIID(IID_IRemoteComputer, riid)) { AddRef(); *ppvObj = (IRemoteComputer*) this; hr = S_OK; } else { CShares* This = IMPL(CShares,m_RemoteComputer,this); hr = This->QueryInterface(riid, ppvObj); } return hr; } STDMETHODIMP_(ULONG) CSharesRC::AddRef() { CShares* This = IMPL(CShares,m_RemoteComputer,this); return This->AddRef(); } STDMETHODIMP_(ULONG) CSharesRC::Release() { CShares* This = IMPL(CShares,m_RemoteComputer,this); return This->Release(); } ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesSD::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IShellDetails*) this; } else if (IsEqualIID(IID_IShellDetails, riid)) { pUnkTemp = (IUnknown*)(IShellDetails*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesSD::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CSharesSD::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesCM::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IContextMenu*) this; } else if (IsEqualIID(IID_IContextMenu, riid)) { pUnkTemp = (IUnknown*)(IContextMenu*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesCM::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CSharesCM::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } ////////////////////////////////////////////////////////////////////////////// #ifdef WIZARDS STDMETHODIMP CSharesCMSpecial::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IContextMenu*) this; } else if (IsEqualIID(IID_IContextMenu, riid)) { pUnkTemp = (IUnknown*)(IContextMenu*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesCMSpecial::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CSharesCMSpecial::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } #endif // WIZARDS ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesCMBG::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IContextMenu*) this; } else if (IsEqualIID(IID_IContextMenu, riid)) { pUnkTemp = (IUnknown*)(IContextMenu*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesCMBG::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CSharesCMBG::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesEnum::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IEnumIDList*) this; } else if (IsEqualIID(IID_IEnumIDList, riid)) { pUnkTemp = (IUnknown*)(IEnumIDList*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesEnum::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CSharesEnum::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesEI::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IExtractIcon*) this; } else if (IsEqualIID(IID_IExtractIcon, riid)) { pUnkTemp = (IUnknown*)(IExtractIcon*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesEI::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CSharesEI::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } ////////////////////////////////////////////////////////////////////////////// #ifdef UNICODE STDMETHODIMP CSharesEIA::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IExtractIconA*) this; } else if (IsEqualIID(IID_IExtractIcon, riid)) { pUnkTemp = (IUnknown*)(IExtractIconA*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesEIA::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); InterlockedIncrement((LONG*)&m_ulRefs); return m_ulRefs; } STDMETHODIMP_(ULONG) CSharesEIA::Release() { ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == cRef) { delete this; } InterlockedDecrement((LONG*)&g_ulcInstances); return cRef; } #endif // UNICODE ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CSharesCF::QueryInterface(REFIID riid, LPVOID* ppvObj) { *ppvObj = NULL; IUnknown* pUnkTemp = NULL; HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid)) { pUnkTemp = (IUnknown*)(IClassFactory*) this; } else if (IsEqualIID(IID_IClassFactory, riid)) { pUnkTemp = (IUnknown*)(IClassFactory*) this; } else { hr = E_NOINTERFACE; } if (pUnkTemp != NULL) { pUnkTemp->AddRef(); } *ppvObj = pUnkTemp; return hr; } STDMETHODIMP_(ULONG) CSharesCF::AddRef() { InterlockedIncrement((LONG*)&g_ulcInstances); return g_ulcInstances; } STDMETHODIMP_(ULONG) CSharesCF::Release() { InterlockedDecrement((LONG*)&g_ulcInstances); return g_ulcInstances; } STDMETHODIMP CSharesCF::CreateInstance(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObj) { if (pUnkOuter != NULL) { // don't support aggregation return E_NOTIMPL; } CShares* pShare = new CShares(); if (NULL == pShare) { return E_OUTOFMEMORY; } HRESULT hr = pShare->QueryInterface(riid, ppvObj); pShare->Release(); return hr; } STDMETHODIMP CSharesCF::LockServer(BOOL fLock) { return S_OK; // FEATURE: Whats supposed to happen here? } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// STDAPI DllCanUnloadNow( VOID ) { if (0 == g_ulcInstances && 0 == g_NonOLEDLLRefs) { return S_OK; } else { return S_FALSE; } } CSharesCF cfCShares; STDAPI DllGetClassObject( REFCLSID cid, REFIID iid, LPVOID* ppvObj ) { InterlockedIncrement((LONG*)&g_ulcInstances); // don't nuke me now! HRESULT hr = E_NOINTERFACE; if (IsEqualCLSID(cid, CLSID_CShares)) { hr = cfCShares.QueryInterface(iid, ppvObj); } InterlockedDecrement((LONG*)&g_ulcInstances); return hr; }