|
|
// AclPage.cpp : Implementation of ISecurityInformation and IDataObject
#include "stdafx.h"
#include "AclPage.h"
#include "windns.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////
// class CFileSecurityDataObject
CFileSecurityDataObject::CFileSecurityDataObject() : m_cRef(1) { }
CFileSecurityDataObject::~CFileSecurityDataObject() { TRACE(_T("CFileSecurityDataObject::~CFileSecurityDataObject m_cRef=%d\n"), m_cRef); }
void CFileSecurityDataObject::Initialize( IN LPCTSTR lpszComputerName, IN LPCTSTR lpszFolder ) { m_cstrComputerName = lpszComputerName; m_cstrFolder = lpszFolder;
GetFullPathLocalOrRemote(lpszComputerName, lpszFolder, m_cstrPath);
m_cfIDList = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_SHELLIDLIST); }
////////////////////////////////
// IUnknown methods
////////////////////////////////
STDMETHODIMP CFileSecurityDataObject::QueryInterface(REFIID riid, LPVOID *ppv) { if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDataObject)) { *ppv = this; m_cRef++; return S_OK; } else { *ppv = NULL; return E_NOINTERFACE; } }
STDMETHODIMP_(ULONG) CFileSecurityDataObject::AddRef() { return ++m_cRef; }
STDMETHODIMP_(ULONG) CFileSecurityDataObject::Release() { if (--m_cRef == 0) { delete this; return 0; }
return m_cRef; }
STDMETHODIMP CFileSecurityDataObject::GetData( FORMATETC __RPC_FAR * pFormatEtcIn, STGMEDIUM __RPC_FAR * pMedium ) { ASSERT(pFormatEtcIn); ASSERT(pMedium);
if (m_cfIDList != pFormatEtcIn->cfFormat) return DV_E_FORMATETC;
LPITEMIDLIST pidl = NULL; LPITEMIDLIST pidlR = NULL; HRESULT hr = GetFolderPIDList(&pidl); if (SUCCEEDED(hr)) { pidlR = ILClone(ILFindLastID(pidl)); // relative IDList
ILRemoveLastID(pidl); // folder IDList
int cidl = 1; UINT offset = sizeof(CIDA) + sizeof(UINT)*cidl; UINT cbFolder = ILGetSize(pidl); UINT cbRelative = ILGetSize(pidlR); UINT cbTotal = offset + cbFolder + cbRelative;
HGLOBAL hGlobal = ::GlobalAlloc (GPTR, cbTotal); if ( hGlobal ) { LPIDA pida = (LPIDA)hGlobal;
pida->cidl = cidl; pida->aoffset[0] = offset; MoveMemory(((LPBYTE)hGlobal+offset), pidl, cbFolder);
offset += cbFolder; pida->aoffset[1] = offset; MoveMemory(((LPBYTE)hGlobal+offset), pidlR, cbRelative);
pMedium->hGlobal = hGlobal; } else { hr = E_OUTOFMEMORY; }
if (pidl) ILFree(pidl); if (pidlR) ILFree(pidlR); }
return hr; }
HRESULT CFileSecurityDataObject::GetFolderPIDList( OUT LPITEMIDLIST *ppidl ) { ASSERT(!m_cstrPath.IsEmpty()); ASSERT(ppidl); ASSERT(!*ppidl); // prevent memory leak
*ppidl = ILCreateFromPath(m_cstrPath);
return ((*ppidl) ? S_OK : E_FAIL); }
///////////////////////////////////////////////
// File security
// Security Shell extension CLSID - {1F2E5C40-9550-11CE-99D2-00AA006E086C}
const CLSID CLSID_ShellExtSecurity = {0x1F2E5C40, 0x9550, 0x11CE, {0x99, 0xD2, 0x0, 0xAA, 0x0, 0x6E, 0x08, 0x6C}};
BOOL CALLBACK AddPageProc(HPROPSHEETPAGE hPage, LPARAM lParam) { // pass out the created page handle
*((HPROPSHEETPAGE *)lParam) = hPage;
return TRUE; }
HRESULT CreateFileSecurityPropPage( HPROPSHEETPAGE *phOutPage, LPDATAOBJECT pDataObject ) { ASSERT(phOutPage); ASSERT(pDataObject);
IShellExtInit *piShellExtInit = NULL; HRESULT hr = CoCreateInstance(CLSID_ShellExtSecurity, NULL, CLSCTX_INPROC_SERVER, IID_IShellExtInit, (void **)&piShellExtInit); if (SUCCEEDED(hr)) { hr = piShellExtInit->Initialize(NULL, pDataObject, 0); if (SUCCEEDED(hr)) { IShellPropSheetExt *piSPSE = NULL; hr = piShellExtInit->QueryInterface(IID_IShellPropSheetExt, (void **)&piSPSE); if (SUCCEEDED(hr)) { hr = piSPSE->AddPages(AddPageProc, (LPARAM)phOutPage); piSPSE->Release(); } } piShellExtInit->Release(); }
return hr; }
INT_PTR PopupPermissionDialog( HWND hWnd, LPCTSTR target, LPCTSTR folder ) { INT_PTR iReturn = -2; HPROPSHEETPAGE phPages[1]; int cPages = 1; CString cstrSheetTitle = folder; CString path;
GetFullPathLocalOrRemote(target, folder, path); if (!SupportsSecurityACLs(path)) { DoHelpMessageBox(hWnd,IDS_FAT_DRIVE_WARNING, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION, 0); return 0; }
phPages[0] = 0; HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) {return iReturn;}
// create "File Security" property page
CFileSecurityDataObject *pfsDataObject = new CFileSecurityDataObject; if (!pfsDataObject) { hr = E_OUTOFMEMORY; // destroy pages that have not been passed to the PropertySheet function
DestroyPropertySheetPage(phPages[0]); goto PopupPermissionDialog_Exit; } pfsDataObject->Initialize(target, folder); hr = CreateFileSecurityPropPage(&(phPages[0]), pfsDataObject); if (SUCCEEDED(hr)) { cPages = 1;
PROPSHEETHEADER psh; ZeroMemory(&psh, sizeof(psh)); psh.dwSize = sizeof(psh); psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW; psh.hwndParent = hWnd; psh.hInstance = AfxGetResourceHandle(); psh.pszCaption = cstrSheetTitle; psh.nPages = cPages; psh.phpage = phPages;
// create the property sheet
iReturn = PropertySheet(&psh); } pfsDataObject->Release();
PopupPermissionDialog_Exit: CoUninitialize(); return iReturn; }
|