629 lines
18 KiB
C++
629 lines
18 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997 - 1999
|
|
//
|
|
// File: dsutil.h
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#ifndef __DSUTIL_H_
|
|
#define __DSUTIL_H_
|
|
|
|
#include "util.h"
|
|
#include "uiutil.h"
|
|
#include "dssnap.h"
|
|
#include "query.h"
|
|
|
|
//
|
|
// Common DS strings
|
|
//
|
|
extern PCWSTR g_pszAllowedAttributesEffective;
|
|
extern PCWSTR g_pszPwdLastSet;
|
|
|
|
HRESULT DSAdminOpenObject(PCWSTR pszPath,
|
|
REFIID refIID,
|
|
PVOID* ppInterface,
|
|
BOOL bServer = FALSE);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
// ADSI path helpers
|
|
//
|
|
HRESULT GetServerFromLDAPPath(IN LPCWSTR lpszLdapPath, OUT BSTR* pbstrServerName);
|
|
|
|
BOOL StripADsIPath(LPCWSTR lpszPath, CString& strref, bool bUseEscapedMode = true);
|
|
|
|
// remove escape characters from a path
|
|
// Arguments:
|
|
// lpszPath = path to be escaped
|
|
// bDN = if TRUE, the path os a distinguished name, if FALSE is an LDAP path
|
|
// bstrUnescaped = returned unescaped path
|
|
//
|
|
inline HRESULT UnescapePath(IN LPCWSTR lpszPath, IN BOOL bDN, OUT CComBSTR& bstrUnescaped)
|
|
{
|
|
CPathCracker pathCracker;
|
|
|
|
pathCracker.Set((LPWSTR)lpszPath, bDN ? ADS_SETTYPE_DN : ADS_SETTYPE_FULL);
|
|
pathCracker.put_EscapedMode(ADS_ESCAPEDMODE_OFF);
|
|
|
|
bstrUnescaped = (LPCWSTR)NULL;
|
|
HRESULT hr = pathCracker.Retrieve(bDN ? ADS_FORMAT_X500_DN : ADS_FORMAT_X500, &bstrUnescaped);
|
|
return hr;
|
|
}
|
|
|
|
class CObjectNamesFormatCracker; // fwd decl
|
|
|
|
HRESULT AddDataObjListToGroup(CObjectNamesFormatCracker * pNames,
|
|
HWND hwnd,
|
|
CDSComponentData* pComponentData);
|
|
|
|
HRESULT AddDataObjListToGivenGroup(CObjectNamesFormatCracker * pNames,
|
|
LPCWSTR lpszGroup,
|
|
LPCWSTR lpszGroupName,
|
|
HWND hwnd,
|
|
CDSComponentData* pComponentData);
|
|
|
|
|
|
BOOL IsValidSiteName( LPCTSTR lpctszSiteName, BOOL* pfNonRfc = NULL );
|
|
BOOL IsLocalLogin( void );
|
|
BOOL IsThisUserLoggedIn( LPCTSTR pwszUserDN );
|
|
|
|
BOOL CALLBACK AddPageProc(HPROPSHEETPAGE hPage, LPARAM pCall);
|
|
BOOL IsHomogenousDSSelection(LPDATAOBJECT pDataObject, CString& szClassName);
|
|
BOOL CALLBACK AddPageProc(HPROPSHEETPAGE hPage, LPARAM pCall);
|
|
HRESULT GetDisplaySpecifierProperty(PCWSTR pszClassName,
|
|
PCWSTR pszDisplayProperty,
|
|
MyBasePathsInfo* pBasePathsInfo,
|
|
CStringList& strListRef,
|
|
bool bEnglishOnly = false);
|
|
|
|
HRESULT TabCollect_GetDisplayGUIDs(LPCWSTR lpszClassName,
|
|
LPCWSTR lpszDisplayProperty,
|
|
MyBasePathsInfo* pBasePathsInfo,
|
|
UINT* pnCount,
|
|
GUID** ppGuids);
|
|
|
|
|
|
BOOL FindCookieInSubtree(IN CUINode* pContainerNode,
|
|
IN LPCWSTR lpszCookieDN,
|
|
IN SnapinType snapinType,
|
|
OUT CUINode** ppUINode);
|
|
|
|
bool CanUserChangePassword(IN IDirectoryObject* pDirObject);
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CChangePasswordPrivilegeAction
|
|
|
|
// helper class to handle the revoking and the reading of the
|
|
// change password control right on user objects
|
|
|
|
class CChangePasswordPrivilegeAction
|
|
{
|
|
public:
|
|
CChangePasswordPrivilegeAction() : m_pDacl(NULL)
|
|
{
|
|
}
|
|
|
|
HRESULT Load(IADs * pIADs);
|
|
HRESULT Read(BOOL* pbPasswordCannotChange);
|
|
HRESULT Revoke();
|
|
|
|
private:
|
|
HRESULT _SetSids();
|
|
|
|
CComBSTR m_bstrObjectLdapPath;
|
|
|
|
CSimpleSecurityDescriptorHolder m_SDHolder;
|
|
PACL m_pDacl;
|
|
CSidHolder m_SelfSid;
|
|
CSidHolder m_WorldSid;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDSNotifyHandlerTransaction
|
|
|
|
class CDSNotifyHandlerManager; // fwd decl
|
|
class CDSComponentData;
|
|
|
|
class CDSNotifyHandlerTransaction
|
|
{
|
|
public:
|
|
CDSNotifyHandlerTransaction(CDSComponentData* pCD);
|
|
~CDSNotifyHandlerTransaction()
|
|
{
|
|
if (m_bStarted)
|
|
End();
|
|
}
|
|
|
|
void SetEventType(ULONG uEvent)
|
|
{
|
|
ASSERT(m_uEvent == 0);
|
|
ASSERT(uEvent != 0);
|
|
m_uEvent = uEvent;
|
|
}
|
|
|
|
// state veriables check
|
|
UINT NeedNotifyCount();
|
|
|
|
// handlers for visualization in confirnation dialog
|
|
void SetCheckListBox(CCheckListBox* pCheckListBox);
|
|
void ReadFromCheckListBox(CCheckListBox* pCheckListBox);
|
|
|
|
// interfaces for transacted protocol
|
|
HRESULT Begin(LPCWSTR lpszArg1Path, LPCWSTR lpszArg1Class, BOOL bArg1Cont,
|
|
LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
|
|
HRESULT Begin(CDSCookie* pArg1Cookie,
|
|
LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
|
|
HRESULT Begin(IDataObject* pArg1,
|
|
LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
|
|
|
|
void Notify(ULONG nItem);
|
|
void End();
|
|
|
|
static HRESULT BuildTransactionDataObject(LPCWSTR lpszArgPath,
|
|
LPCWSTR lpszArgClass,
|
|
BOOL bContainer,
|
|
CDSComponentData* pCD,
|
|
IDataObject** ppArg);
|
|
private:
|
|
|
|
HRESULT _BuildDataObject(LPCWSTR lpszArgPath,
|
|
LPCWSTR lpszArgClass,
|
|
BOOL bContainer,
|
|
IDataObject** ppArg);
|
|
|
|
BOOL m_bStarted;
|
|
CDSComponentData* m_pCD;
|
|
CDSNotifyHandlerManager* m_pMgr;
|
|
ULONG m_uEvent;
|
|
|
|
CComPtr<IDataObject> m_spArg1;
|
|
CComPtr<IDataObject> m_spArg2;
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CUIOperationHandlerBase
|
|
|
|
class CUIOperationHandlerBase
|
|
{
|
|
public:
|
|
CUIOperationHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
|
|
: m_transaction(pComponentData)
|
|
{
|
|
m_pComponentData = pComponentData;
|
|
m_hWndFrame = m_hWndParent = hwnd;
|
|
}
|
|
virtual ~CUIOperationHandlerBase(){}
|
|
|
|
protected:
|
|
// accessor functions
|
|
HWND GetParentHwnd() { return m_hWndParent;}
|
|
void SetParentHwnd(HWND hwnd) { m_hWndParent = hwnd;}
|
|
|
|
CDSComponentData* GetComponentData() { return m_pComponentData;}
|
|
CDSNotifyHandlerTransaction* GetTransaction() { return &m_transaction;}
|
|
|
|
// JonN 6/2/00 99382
|
|
// SITEREPL: Run interference when administrator attempts to
|
|
// delete critical object (NTDS Settings)
|
|
// reports own errors, returns true iff deletion should proceed
|
|
/* bool CheckForNTDSDSAInSubtree(
|
|
LPCTSTR lpszX500Path,
|
|
LPCTSTR lpszItemName);
|
|
*/
|
|
//
|
|
// JeffJon 8/10/00 27377
|
|
// Check for critical system objects in the subtree before
|
|
// attempting a subtree delete. This includes objects with
|
|
// isCriticalSystemObject=TRUE and NTDS Settings objects
|
|
//
|
|
bool CheckForCriticalSystemObjectInSubtree(
|
|
LPCTSTR lpszX500Path,
|
|
LPCTSTR lpszItemName);
|
|
|
|
// JonN 6/15/00 13574
|
|
// Centralizes the checks to make sure this is an OK object to delete
|
|
// returns HRESULT_FROM_WIN32(ERROR_CANCELLED) on cancellation
|
|
// returns fAlternateDeleteMethod=true iff ObjectDeletionCheck already
|
|
// attempted an alternate deletion method (e.g. DsRemoveDsServer).
|
|
HRESULT ObjectDeletionCheck(
|
|
LPCTSTR lpszADsPath,
|
|
LPCTSTR lpszName, // shortname to display to user, may be NULL
|
|
LPCTSTR lpszClass,
|
|
bool& fAlternateDeleteMethod );
|
|
|
|
private:
|
|
CDSComponentData* m_pComponentData;
|
|
CDSNotifyHandlerTransaction m_transaction;
|
|
|
|
HWND m_hWndFrame; // MMC frame window
|
|
HWND m_hWndParent; // window to parent any UI created in the handler
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CSingleDeleteHandlerBase
|
|
|
|
class CSingleDeleteHandlerBase : public CUIOperationHandlerBase
|
|
{
|
|
public:
|
|
CSingleDeleteHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
|
|
: CUIOperationHandlerBase(pComponentData, hwnd)
|
|
{
|
|
GetTransaction()->SetEventType(DSA_NOTIFY_DEL);
|
|
}
|
|
|
|
HRESULT Delete();
|
|
|
|
protected:
|
|
// hooks for customization
|
|
virtual HRESULT BeginTransaction() = 0;
|
|
virtual HRESULT DeleteObject() = 0;
|
|
virtual HRESULT DeleteSubtree() = 0;
|
|
virtual void GetItemName(OUT CString& szName) = 0;
|
|
virtual LPCWSTR GetItemClass() = 0;
|
|
virtual LPCWSTR GetItemPath() = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CMultipleDeleteHandlerBase
|
|
|
|
class CMultipleDeleteHandlerBase : public CUIOperationHandlerBase
|
|
{
|
|
public:
|
|
CMultipleDeleteHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
|
|
: CUIOperationHandlerBase(pComponentData, hwnd)
|
|
{
|
|
GetTransaction()->SetEventType(DSA_NOTIFY_DEL);
|
|
}
|
|
|
|
void Delete();
|
|
|
|
protected:
|
|
|
|
// hooks for customization
|
|
virtual UINT GetItemCount() = 0;
|
|
virtual HRESULT BeginTransaction() = 0;
|
|
virtual HRESULT DeleteObject(UINT i) = 0;
|
|
virtual HRESULT DeleteSubtree(UINT i) = 0;
|
|
virtual void OnItemDeleted(UINT) {}
|
|
virtual void GetItemName(IN UINT i, OUT CString& szName) = 0;
|
|
virtual void GetItemPath(UINT i, CString& szPath) = 0;
|
|
virtual PCWSTR GetItemClass(UINT i) = 0;
|
|
|
|
private:
|
|
CMultipleDeletionConfirmationUI m_confirmationUI;
|
|
|
|
void OnStart(HWND hwnd);
|
|
HRESULT OnDeleteStep(UINT i,
|
|
BOOL* pbContinue,
|
|
CString& strrefPath,
|
|
CString& strrefClass,
|
|
BOOL bSilent = TRUE);
|
|
|
|
friend class CMultipleDeleteProgressDialog; // for m_confirmationUI
|
|
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CMoveHandlerBase
|
|
|
|
class CMultipleMoveProgressDialog; // fwd decl
|
|
|
|
class CMoveHandlerBase : public CUIOperationHandlerBase
|
|
{
|
|
public:
|
|
CMoveHandlerBase(CDSComponentData* pComponentData, HWND hwnd,
|
|
LPCWSTR lpszBrowseRootPath)
|
|
: CUIOperationHandlerBase(pComponentData, hwnd)
|
|
{
|
|
m_lpszBrowseRootPath = lpszBrowseRootPath;
|
|
GetTransaction()->SetEventType(DSA_NOTIFY_MOV);
|
|
}
|
|
|
|
HRESULT Move(LPCWSTR lpszDestinationPath = NULL);
|
|
|
|
|
|
protected:
|
|
// hooks for customization
|
|
virtual UINT GetItemCount() = 0;
|
|
virtual HRESULT BeginTransaction() = 0;
|
|
virtual void GetNewPath(UINT i, CString& szNewPath) = 0;
|
|
virtual void GetName(UINT i, CString& strref) = 0;
|
|
virtual HRESULT OnItemMoved(UINT i, IADs* pIADs) = 0;
|
|
virtual void GetClassOfMovedItem(CString& szClass) = 0;
|
|
virtual void GetItemPath(UINT i, CString& szPath) = 0;
|
|
virtual PCWSTR GetItemClass(UINT i) = 0;
|
|
|
|
LPCWSTR GetDestPath() { return m_szDestPath;}
|
|
LPCWSTR GetDestClass() { return m_szDestClass;}
|
|
BOOL IsDestContainer() { return m_bDestContainer; }
|
|
|
|
private:
|
|
LPCWSTR m_lpszBrowseRootPath; // LDAP path where to point the browser dialog
|
|
|
|
CComPtr<IADsContainer> m_spDSDestination;
|
|
CString m_szDestPath;
|
|
CString m_szDestClass;
|
|
BOOL m_bDestContainer;
|
|
|
|
BOOL _ReportFailure(BOOL bLast, HRESULT hr, LPCWSTR lpszName);
|
|
HRESULT _BrowseForDestination(LPCWSTR lpszDestinationPath);
|
|
BOOL _BeginTransactionAndConfirmOperation();
|
|
|
|
HRESULT _MoveSingleSel(PCWSTR pszNewName);
|
|
HRESULT _MoveMultipleSel();
|
|
HRESULT _OnMoveStep(IN UINT i,
|
|
OUT BOOL* pbCanContinue,
|
|
OUT CString& strrefPath,
|
|
OUT CString& strrefClass);
|
|
|
|
friend class CMultipleMoveProgressDialog;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CMultiselectMoveHandler
|
|
|
|
class CMultiselectMoveHandler : public CMoveHandlerBase
|
|
{
|
|
private:
|
|
struct CMovedState
|
|
{
|
|
CMovedState()
|
|
{
|
|
m_bMoved = FALSE;
|
|
}
|
|
BOOL m_bMoved;
|
|
CString m_szNewPath;
|
|
};
|
|
|
|
public:
|
|
CMultiselectMoveHandler(CDSComponentData* pComponentData, HWND hwnd,
|
|
LPCWSTR lpszBrowseRootPath)
|
|
: CMoveHandlerBase(pComponentData, hwnd, lpszBrowseRootPath)
|
|
{
|
|
m_pMovedArr = NULL;
|
|
}
|
|
|
|
virtual ~CMultiselectMoveHandler()
|
|
{
|
|
if (m_pMovedArr != NULL)
|
|
delete[] m_pMovedArr;
|
|
}
|
|
|
|
BOOL WasItemMoved(UINT i)
|
|
{
|
|
ASSERT(i < GetItemCount());
|
|
return m_pMovedArr[i].m_bMoved;
|
|
}
|
|
LPCWSTR GetNewItemPath(UINT i)
|
|
{
|
|
ASSERT(WasItemMoved(i));
|
|
return m_pMovedArr[i].m_szNewPath;
|
|
}
|
|
|
|
|
|
HRESULT Initialize(IDataObject* pDataObject,
|
|
CObjectNamesFormatCracker* pObjectNamesFormatCracker,
|
|
CInternalFormatCracker* pInternalFormatCracker)
|
|
{
|
|
if ((pDataObject == NULL) || (pObjectNamesFormatCracker == NULL))
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_INVALIDARG;
|
|
}
|
|
m_pDataObject = pDataObject;
|
|
m_pInternalFormatCracker = pInternalFormatCracker;
|
|
m_pObjectNamesFormatCracker = pObjectNamesFormatCracker;
|
|
|
|
if (m_pObjectNamesFormatCracker->GetCount() < 1)
|
|
{
|
|
ASSERT(FALSE); // something is just wrong...
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// allocate an array of CMovedState structs to keep track of what actually got moved
|
|
// and what the new name is
|
|
m_pMovedArr = new CMovedState[GetItemCount()];
|
|
return S_OK;
|
|
}
|
|
|
|
protected:
|
|
virtual UINT GetItemCount() { return m_pObjectNamesFormatCracker->GetCount();}
|
|
virtual HRESULT BeginTransaction()
|
|
{
|
|
return GetTransaction()->Begin(m_pDataObject,
|
|
GetDestPath(), GetDestClass(), IsDestContainer());
|
|
}
|
|
virtual void GetNewPath(UINT i, CString& szNewPath)
|
|
{
|
|
szNewPath = m_pObjectNamesFormatCracker->GetName(i);
|
|
}
|
|
virtual void GetName(UINT i, CString& strref)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if ((m_pInternalFormatCracker != NULL) && m_pInternalFormatCracker->HasData())
|
|
{
|
|
CUINode* pUINode = m_pInternalFormatCracker->GetCookie(i);
|
|
CDSCookie* pCookie = GetDSCookieFromUINode(pUINode);
|
|
strref = pCookie->GetName();
|
|
}
|
|
else
|
|
{
|
|
// REVIEW_MARCOC_PORT: this might be inefficent, need to make a member variable
|
|
CPathCracker pathCracker;
|
|
hr = pathCracker.Set((LPWSTR)m_pObjectNamesFormatCracker->GetName(i),
|
|
ADS_SETTYPE_FULL);
|
|
hr = pathCracker.SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
|
|
|
|
CComBSTR DestName;
|
|
hr = pathCracker.GetElement( 0, &DestName );
|
|
strref = DestName;
|
|
}
|
|
}
|
|
virtual void GetItemPath(UINT i, CString& szPath)
|
|
{
|
|
szPath = m_pObjectNamesFormatCracker->GetName(i);
|
|
}
|
|
|
|
virtual PCWSTR GetItemClass(UINT i)
|
|
{
|
|
return m_pObjectNamesFormatCracker->GetClass(i);
|
|
}
|
|
virtual HRESULT OnItemMoved(UINT i, IADs* pIADs)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
m_pMovedArr[i].m_bMoved = TRUE;
|
|
|
|
CComBSTR bsPath;
|
|
hr = pIADs->get_ADsPath(&bsPath);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// save the new LDAP path in the array
|
|
m_pMovedArr[i].m_szNewPath = bsPath;
|
|
}
|
|
|
|
if ((m_pInternalFormatCracker != NULL) && m_pInternalFormatCracker->HasData())
|
|
{
|
|
CUINode* pUINode = m_pInternalFormatCracker->GetCookie(i);
|
|
CDSCookie* pCookie = GetDSCookieFromUINode(pUINode);
|
|
pUINode->SetExtOp(OPCODE_MOVE);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CUINode* pParentNode = pUINode->GetParent();
|
|
if (pParentNode != NULL)
|
|
{
|
|
if (!IS_CLASS(*pParentNode, CSavedQueryNode))
|
|
{
|
|
//
|
|
// set the new DN in the cookie
|
|
//
|
|
CString szPath;
|
|
StripADsIPath(bsPath, szPath);
|
|
pCookie->SetPath(szPath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
virtual void GetClassOfMovedItem(CString& szClass)
|
|
{
|
|
szClass.Empty();
|
|
if (NULL == m_pObjectNamesFormatCracker)
|
|
return;
|
|
UINT nCount = GetItemCount();
|
|
if (0 == nCount)
|
|
return;
|
|
szClass = m_pObjectNamesFormatCracker->GetClass(0);
|
|
for (UINT i = 1; i < nCount; i++)
|
|
{
|
|
if (0 != szClass.CompareNoCase( m_pObjectNamesFormatCracker->GetClass(i) ))
|
|
{
|
|
szClass.Empty();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected:
|
|
CMovedState* m_pMovedArr;
|
|
CInternalFormatCracker* m_pInternalFormatCracker;
|
|
|
|
private:
|
|
IDataObject* m_pDataObject;
|
|
CObjectNamesFormatCracker* m_pObjectNamesFormatCracker;
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CMultiselectMoveDataObject
|
|
|
|
class CMultiselectMoveDataObject : public IDataObject, public CComObjectRoot
|
|
{
|
|
// ATL Maps
|
|
DECLARE_NOT_AGGREGATABLE(CMultiselectMoveDataObject)
|
|
BEGIN_COM_MAP(CMultiselectMoveDataObject)
|
|
COM_INTERFACE_ENTRY(IDataObject)
|
|
END_COM_MAP()
|
|
|
|
// Construction/Destruction
|
|
CMultiselectMoveDataObject()
|
|
{
|
|
m_pDSObjCached = NULL;
|
|
m_nDSObjCachedBytes = 0;
|
|
}
|
|
~CMultiselectMoveDataObject()
|
|
{
|
|
_Clear();
|
|
}
|
|
|
|
// Standard IDataObject methods
|
|
public:
|
|
// Implemented
|
|
STDMETHOD(GetData)(FORMATETC * pformatetcIn, STGMEDIUM * pmedium);
|
|
|
|
// Not Implemented
|
|
private:
|
|
STDMETHOD(GetDataHere)(FORMATETC*, STGMEDIUM*) { return E_NOTIMPL; };
|
|
STDMETHOD(EnumFormatEtc)(DWORD, IEnumFORMATETC**) { return E_NOTIMPL; };
|
|
STDMETHOD(SetData)(FORMATETC*, STGMEDIUM*,BOOL) { return E_NOTIMPL; };
|
|
STDMETHOD(QueryGetData)(FORMATETC*) { return E_NOTIMPL; };
|
|
STDMETHOD(GetCanonicalFormatEtc)(FORMATETC*, FORMATETC*) { return E_NOTIMPL; };
|
|
STDMETHOD(DAdvise)(FORMATETC*, DWORD, IAdviseSink*, DWORD*) { return E_NOTIMPL; };
|
|
STDMETHOD(DUnadvise)(DWORD) { return E_NOTIMPL; };
|
|
STDMETHOD(EnumDAdvise)(IEnumSTATDATA**) { return E_NOTIMPL; };
|
|
|
|
public:
|
|
// Property Page Clipboard formats
|
|
static CLIPFORMAT m_cfDsObjectNames;
|
|
|
|
static HRESULT BuildPastedDataObject(
|
|
IN CObjectNamesFormatCracker* pObjectNamesFormatPaste,
|
|
IN CMultiselectMoveHandler* pMoveHandler,
|
|
IN CDSComponentData* pCD,
|
|
OUT IDataObject** ppSuccesfullyPastedDataObject);
|
|
|
|
protected:
|
|
// initialization
|
|
HRESULT Init(IN CObjectNamesFormatCracker* pObjectNamesFormatPaste,
|
|
IN CMultiselectMoveHandler* pMoveHandler,
|
|
IN CDSComponentData* pCD);
|
|
|
|
// Implementation
|
|
private:
|
|
void _Clear()
|
|
{
|
|
if (m_pDSObjCached != NULL)
|
|
{
|
|
::free(m_pDSObjCached);
|
|
m_pDSObjCached = NULL;
|
|
m_nDSObjCachedBytes = 0;
|
|
}
|
|
}
|
|
|
|
// chunk of memory with the clpboard format already computed
|
|
LPDSOBJECTNAMES m_pDSObjCached;
|
|
DWORD m_nDSObjCachedBytes;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void EscapeFilterElement(PCWSTR pszElement, CString& refszEscapedElement);
|
|
|
|
|
|
#endif // __DSUTIL_H_
|