You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
5.8 KiB
213 lines
5.8 KiB
// ShlExt.cpp : Implementation of CVSSShellExt
|
|
#include "stdafx.h"
|
|
#include "Vssui.h"
|
|
#include "ShlExt.h"
|
|
#include "vssprop.h"
|
|
|
|
#include <shellapi.h>
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CVSSShellExt
|
|
|
|
CVSSShellExt::CVSSShellExt()
|
|
{
|
|
#ifdef DEBUG
|
|
OutputDebugString(_T("CVSSShellExt::CVSSShellExt\n"));
|
|
#endif
|
|
m_lpszFile = NULL;
|
|
}
|
|
|
|
CVSSShellExt::~CVSSShellExt()
|
|
{
|
|
#ifdef DEBUG
|
|
OutputDebugString(_T("CVSSShellExt::~CVSSShellExt\n"));
|
|
#endif
|
|
if (m_lpszFile)
|
|
{
|
|
delete [] m_lpszFile;
|
|
m_lpszFile = NULL;
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP CVSSShellExt::Initialize(
|
|
IN LPCITEMIDLIST pidlFolder, // For property sheet extensions, this parameter is NULL
|
|
IN LPDATAOBJECT lpdobj,
|
|
IN HKEY hkeyProgID // not used in property sheet extensions
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if ((IDataObject *)m_spiDataObject)
|
|
m_spiDataObject.Release();
|
|
|
|
if (lpdobj)
|
|
{
|
|
m_spiDataObject = lpdobj;
|
|
|
|
STGMEDIUM medium;
|
|
FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
|
UINT uCount = 0;
|
|
|
|
hr = m_spiDataObject->GetData(&fe, &medium);
|
|
if (FAILED(hr))
|
|
{
|
|
fe.cfFormat = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_MOUNTEDVOLUME);
|
|
hr = m_spiDataObject->GetData(&fe, &medium);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (m_lpszFile)
|
|
{
|
|
delete [] m_lpszFile;
|
|
m_lpszFile = NULL;
|
|
}
|
|
|
|
uCount = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
|
|
if (uCount > 0)
|
|
{
|
|
UINT uiChars = DragQueryFile ((HDROP) medium.hGlobal, 0, NULL, 0);
|
|
m_lpszFile = new TCHAR [uiChars + 1];
|
|
if (!m_lpszFile)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
} else
|
|
{
|
|
ZeroMemory(m_lpszFile, sizeof(TCHAR) * (uiChars + 1));
|
|
DragQueryFile ((HDROP) medium.hGlobal, 0, m_lpszFile, uiChars + 1);
|
|
}
|
|
|
|
} else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
ReleaseStgMedium(&medium);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
LPFNPSPCALLBACK _OldPropertyPageCallback;
|
|
|
|
UINT CALLBACK _NewPropertyPageCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
|
|
{
|
|
ASSERT(_OldPropertyPageCallback);
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
//
|
|
// First, let the old callback function handles the msg.
|
|
//
|
|
UINT i = _OldPropertyPageCallback(hwnd, uMsg, ppsp);
|
|
|
|
//
|
|
// Then, we release our page here
|
|
//
|
|
if (uMsg == PSPCB_RELEASE)
|
|
{
|
|
ASSERT(ppsp);
|
|
CVSSProp* pPage = (CVSSProp*)(ppsp->lParam);
|
|
ASSERT(pPage);
|
|
delete pPage;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
void ReplacePropertyPageCallback(void* vpsp)
|
|
{
|
|
ASSERT(vpsp);
|
|
LPPROPSHEETPAGE ppsp = (LPPROPSHEETPAGE)vpsp;
|
|
_OldPropertyPageCallback = ppsp->pfnCallback; // save the old callback function
|
|
ppsp->pfnCallback = _NewPropertyPageCallback; // replace with our own callback
|
|
}
|
|
|
|
//
|
|
// From RaymondC:
|
|
// If you didn't add a page, you still return S_OK -- you successfully added zero pages.
|
|
// If you add some pages and then you want one of those added pages to be the default,
|
|
// you return ResultFromShort(pagenumber+1). S_FALSE = ResultFromShort(1).
|
|
//
|
|
STDMETHODIMP CVSSShellExt::AddPages(
|
|
IN LPFNADDPROPSHEETPAGE lpfnAddPage,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
//
|
|
// we only add our page if local machine is postW2K server
|
|
//
|
|
if (!IsPostW2KServer(NULL))
|
|
return S_OK;
|
|
|
|
//
|
|
// we only add our page for local fixed non-FAT drive
|
|
//
|
|
if (DRIVE_FIXED != GetDriveType(m_lpszFile))
|
|
return S_OK;
|
|
|
|
TCHAR szFileSystemName[MAX_PATH] = _T("");
|
|
DWORD dwMaxCompLength = 0, dwFileSystemFlags = 0;
|
|
GetVolumeInformation(m_lpszFile, NULL, 0, NULL, &dwMaxCompLength,
|
|
&dwFileSystemFlags, szFileSystemName, MAX_PATH);
|
|
if (CSTR_EQUAL != CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, _T("NTFS"), -1, szFileSystemName, -1))
|
|
return S_OK;
|
|
|
|
CVSSProp *pPage = new CVSSProp(_T(""), m_lpszFile);
|
|
if (!pPage)
|
|
return E_OUTOFMEMORY;
|
|
|
|
if (pPage->m_psp.dwFlags & PSP_USECALLBACK)
|
|
{
|
|
//
|
|
// Replace with our own callback function such that we can delete pPage
|
|
// when the property sheet is closed.
|
|
//
|
|
// Note: don't change m_psp.lParam, which has to point to CVSSProp object;
|
|
// otherwise, MFC won't hook up message handler correctly.
|
|
//
|
|
ReplacePropertyPageCallback(&(pPage->m_psp));
|
|
|
|
//
|
|
// Fusion MFC-based property page
|
|
//
|
|
PROPSHEETPAGE_V3 sp_v3 = {0};
|
|
CopyMemory (&sp_v3, &(pPage->m_psp), (pPage->m_psp).dwSize);
|
|
sp_v3.dwSize = sizeof(sp_v3);
|
|
|
|
HPROPSHEETPAGE hPage = CreatePropertySheetPage(&sp_v3);
|
|
if (hPage)
|
|
{
|
|
if (lpfnAddPage(hPage, lParam))
|
|
{
|
|
// Store this pointer in pPage in order to keep our dll loaded,
|
|
// it will be released when pPage gets deleted.
|
|
pPage->StoreShellExtPointer((IShellPropSheetExt *)this);
|
|
return S_OK;
|
|
}
|
|
|
|
DestroyPropertySheetPage(hPage);
|
|
hPage = NULL;
|
|
}
|
|
}
|
|
|
|
delete pPage;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// The shell doesn't call ReplacePage
|
|
//
|
|
STDMETHODIMP CVSSShellExt::ReplacePage(
|
|
IN UINT uPageID,
|
|
IN LPFNADDPROPSHEETPAGE lpfnReplaceWith,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|