194 lines
5.1 KiB
C++
194 lines
5.1 KiB
C++
|
// Implements Mounted Volume
|
||
|
|
||
|
#include "shellprv.h"
|
||
|
#include "clsobj.h"
|
||
|
|
||
|
EXTERN_C CLIPFORMAT g_cfMountedVolume = 0;
|
||
|
|
||
|
class CMountedVolume : public IMountedVolume, IDataObject
|
||
|
{
|
||
|
public:
|
||
|
//IUnknown methods
|
||
|
STDMETHODIMP QueryInterface(REFIID,void **);
|
||
|
STDMETHODIMP_(ULONG) AddRef(void);
|
||
|
STDMETHODIMP_(ULONG) Release(void);
|
||
|
|
||
|
//IDataObject methods
|
||
|
STDMETHODIMP GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium);
|
||
|
STDMETHODIMP GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium);
|
||
|
STDMETHODIMP QueryGetData(LPFORMATETC pformatetcIn);
|
||
|
STDMETHODIMP GetCanonicalFormatEtc(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut);
|
||
|
STDMETHODIMP SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
|
||
|
STDMETHODIMP EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC *ppenumFormatEtc);
|
||
|
STDMETHODIMP DAdvise(FORMATETC *pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD *pdwConnection);
|
||
|
STDMETHODIMP DUnadvise(DWORD dwConnection);
|
||
|
STDMETHODIMP EnumDAdvise(LPENUMSTATDATA *ppenumAdvise);
|
||
|
|
||
|
// IMountedVolume methods
|
||
|
STDMETHODIMP Initialize(LPCWSTR pcszMountPoint);
|
||
|
protected:
|
||
|
CMountedVolume();
|
||
|
~CMountedVolume();
|
||
|
|
||
|
friend HRESULT CMountedVolume_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppv);
|
||
|
|
||
|
private:
|
||
|
LONG _cRef;
|
||
|
TCHAR _szMountPoint[MAX_PATH];
|
||
|
};
|
||
|
|
||
|
//constructor/destructor and related functions
|
||
|
|
||
|
CMountedVolume::CMountedVolume() :
|
||
|
_cRef(1)
|
||
|
{
|
||
|
_szMountPoint[0] = 0;
|
||
|
DllAddRef();
|
||
|
}
|
||
|
|
||
|
CMountedVolume::~CMountedVolume()
|
||
|
{
|
||
|
DllRelease();
|
||
|
}
|
||
|
|
||
|
STDAPI CMountedVolume_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppv)
|
||
|
{
|
||
|
HRESULT hr = E_OUTOFMEMORY;
|
||
|
*ppv = NULL;
|
||
|
|
||
|
if (!g_cfMountedVolume)
|
||
|
g_cfMountedVolume = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_MOUNTEDVOLUME);
|
||
|
|
||
|
// aggregation checking is handled in class factory
|
||
|
CMountedVolume* pMountedVolume = new CMountedVolume();
|
||
|
if (pMountedVolume)
|
||
|
{
|
||
|
hr = pMountedVolume->QueryInterface(riid, ppv);
|
||
|
pMountedVolume->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//IUnknown handling
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::QueryInterface(REFIID riid,void **ppvObj)
|
||
|
{
|
||
|
static const QITAB qit[] = {
|
||
|
QITABENT(CMountedVolume, IDataObject),
|
||
|
QITABENT(CMountedVolume, IMountedVolume),
|
||
|
{ 0 },
|
||
|
};
|
||
|
return QISearch(this, qit, riid, ppvObj);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CMountedVolume::AddRef()
|
||
|
{
|
||
|
return InterlockedIncrement(&_cRef);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CMountedVolume::Release()
|
||
|
{
|
||
|
if (InterlockedDecrement(&_cRef))
|
||
|
return _cRef;
|
||
|
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//IDataObject handling
|
||
|
STDMETHODIMP CMountedVolume::GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
|
||
|
//make sure IMountedVolume::Initialize was called
|
||
|
if (TEXT('\0') != _szMountPoint[0])
|
||
|
{
|
||
|
pmedium->hGlobal = NULL;
|
||
|
pmedium->pUnkForRelease = NULL;
|
||
|
pmedium->tymed = TYMED_HGLOBAL;
|
||
|
|
||
|
if ((g_cfMountedVolume == pformatetcIn->cfFormat) && (TYMED_HGLOBAL & pformatetcIn->tymed))
|
||
|
{
|
||
|
pmedium->hGlobal = GlobalAlloc(GPTR, (MAX_PATH + 1) * SIZEOF(TCHAR) + SIZEOF(DROPFILES));
|
||
|
|
||
|
if (pmedium->hGlobal)
|
||
|
{
|
||
|
LPDROPFILES pdf = (LPDROPFILES)pmedium->hGlobal;
|
||
|
LPTSTR pszMountPoint = (LPTSTR)(pdf + 1);
|
||
|
pdf->pFiles = SIZEOF(DROPFILES);
|
||
|
ASSERT(pdf->pt.x==0);
|
||
|
ASSERT(pdf->pt.y==0);
|
||
|
ASSERT(pdf->fNC==FALSE);
|
||
|
ASSERT(pdf->fWide==FALSE);
|
||
|
#ifdef UNICODE
|
||
|
pdf->fWide = TRUE;
|
||
|
#endif
|
||
|
//do the copy
|
||
|
lstrcpy(pszMountPoint, _szMountPoint);
|
||
|
hr = S_OK; // success
|
||
|
}
|
||
|
else
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
ASSERTMSG(0, "IMountedVolume::Initialize was NOT called prior to IMountedVolume::GetData");
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::QueryGetData(LPFORMATETC pformatetcIn)
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
|
||
|
if ((g_cfMountedVolume == pformatetcIn->cfFormat) && (TYMED_HGLOBAL & pformatetcIn->tymed))
|
||
|
hr = S_OK;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium )
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::GetCanonicalFormatEtc(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC *ppenumFormatEtc)
|
||
|
{
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::DAdvise(FORMATETC *pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD *pdwConnection)
|
||
|
{
|
||
|
return OLE_E_ADVISENOTSUPPORTED;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::DUnadvise(DWORD dwConnection)
|
||
|
{
|
||
|
return OLE_E_ADVISENOTSUPPORTED;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMountedVolume::EnumDAdvise(LPENUMSTATDATA *ppenumAdvise)
|
||
|
{
|
||
|
return OLE_E_ADVISENOTSUPPORTED;
|
||
|
}
|
||
|
|
||
|
// IMountedVolume methods
|
||
|
STDMETHODIMP CMountedVolume::Initialize(LPCWSTR pcszMountPoint)
|
||
|
{
|
||
|
lstrcpy(_szMountPoint, pcszMountPoint);
|
||
|
PathAddBackslash(_szMountPoint);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|