|
|
//+----------------------------------------------------------------------------
//
// DS Administration MMC snapin.
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: query.cpp
//
//--------------------------------------------------------------------------
#include "stdafx.h"
#include "resource.h"
#include "query.h"
#include "queryui.h"
#include "uiutil.h"
#include "xmlutil.h"
#include "ContextMenu.h"
#include "dataobj.h"
////////////////////////////////////////////////////////////////////////////
// CFavoritesNode
CFavoritesNode::CFavoritesNode() : CGenericUINode(FAVORITES_UI_NODE), m_bFavoritesRoot(0) { MakeContainer(); CDSColumnSet* pColumnSet = CDSColumnSet::CreateDescriptionColumnSet(); if (pColumnSet != NULL) { GetFolderInfo()->SetColumnSet(pColumnSet, true); } }
BOOL CFavoritesNode::DeepCopyChildren(CUINode* pUINodeToCopy) { if (pUINodeToCopy == NULL) { ASSERT(FALSE); return FALSE; }
//
// We have to do a deep copy of the children for the favorites nodes
//
CUINodeList* pCopyContList = pUINodeToCopy->GetFolderInfo()->GetContainerList(); CUINodeList* pNewContList = GetFolderInfo()->GetContainerList();
if (pCopyContList != NULL && pNewContList != NULL) { POSITION pos = pCopyContList->GetHeadPosition(); while (pos != NULL) { CUINode* pUINode = pCopyContList->GetNext(pos); if (pUINode != NULL) { if (IS_CLASS(pUINode, FAVORITES_UI_NODE)) { CFavoritesNode* pNewNode = new CFavoritesNode(*(dynamic_cast<CFavoritesNode*>(pUINode))); if (pNewNode != NULL) { pNewNode->DeepCopyChildren(pUINode); pNewNode->SetParent(this); pNewContList->AddTail(pNewNode); } } else if (IS_CLASS(pUINode, SAVED_QUERY_UI_NODE)) { CSavedQueryNode* pNewNode = new CSavedQueryNode(*(dynamic_cast<CSavedQueryNode*>(pUINode))); if (pNewNode != NULL) { pNewNode->SetParent(this); pNewContList->AddTail(pNewNode); } } else { //
// CFavoritesNode should only contain CFavoritesNodes and CSavedQueryNodes
//
ASSERT(FALSE); continue; } } } }
//
// There shouldn't be any leaf nodes but we will try to copy just in case
//
CUINodeList* pCopyLeafList = pUINodeToCopy->GetFolderInfo()->GetLeafList(); CUINodeList* pNewLeafList = GetFolderInfo()->GetLeafList();
if (pCopyLeafList != NULL && pNewLeafList != NULL) { POSITION pos = pCopyLeafList->GetHeadPosition(); while (pos != NULL) { CUINode* pUINode = pCopyLeafList->GetNext(pos); if (pUINode != NULL) { CUINode* pNewNode = NULL;
//
// In the future we would add class specific creation here as is above
//
//
// CFavoritesNode should only contain CFavoritesNodes and CSavedQueryNodes
//
ASSERT(FALSE);
if (pNewNode != NULL) { pNewLeafList->AddTail(pNewNode); } } } } return TRUE; }
void CFavoritesNode::RemoveQueryResults() { ASSERT(!IsSheetLocked()); ASSERT(GetFolderInfo()->GetLeafList()->IsEmpty());
CUINodeList* pContainerList = GetFolderInfo()->GetContainerList(); for (POSITION pos = pContainerList->GetHeadPosition(); pos != NULL; ) { CUINode* pCurrUINode = pContainerList->GetNext(pos);
// we reset the expanded flag only on nodes below
// the current node, because the current node is going
// to get results back from the refresh command, while
// the others will be added again and will be expanded as
// new nodes
pCurrUINode->GetFolderInfo()->ReSetExpanded();
if (IS_CLASS(pCurrUINode, SAVED_QUERY_UI_NODE)) { pCurrUINode->GetFolderInfo()->DeleteAllLeafNodes(); pCurrUINode->GetFolderInfo()->DeleteAllContainerNodes(); } else if (IS_CLASS(pCurrUINode, FAVORITES_UI_NODE)) { // recurse down to other query folders
dynamic_cast<CFavoritesNode*>(pCurrUINode)->RemoveQueryResults(); } }
}
void CFavoritesNode::FindCookiesInQueries(LPCWSTR lpszCookieDN, CUINodeList* pNodeList) { ASSERT(GetFolderInfo()->GetLeafList()->IsEmpty());
CUINodeList* pContainerList = GetFolderInfo()->GetContainerList(); for (POSITION pos = pContainerList->GetHeadPosition(); pos != NULL; ) { CUINode* pCurrUINode = pContainerList->GetNext(pos);
if (IS_CLASS(pCurrUINode, SAVED_QUERY_UI_NODE)) { CSavedQueryNode* pSavedQueryNode = dynamic_cast<CSavedQueryNode*>(pCurrUINode); pSavedQueryNode->FindCookieByDN(lpszCookieDN, pNodeList); } else if (IS_CLASS(pCurrUINode, FAVORITES_UI_NODE)) { // recurse down to other query folders
dynamic_cast<CFavoritesNode*>(pCurrUINode)->FindCookiesInQueries(lpszCookieDN, pNodeList); } } }
BOOL CFavoritesNode::IsDeleteAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { if (pComponentData->GetFavoritesNodeHolder()->GetFavoritesRoot() == this) { *pbHide = TRUE; return FALSE; } *pbHide = FALSE; return pComponentData->CanEnableVerb(this); }
BOOL CFavoritesNode::ArePropertiesAllowed(CDSComponentData*, BOOL* pbHide) { *pbHide = FALSE; return TRUE; }
BOOL CFavoritesNode::IsRenameAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { if (pComponentData->GetFavoritesNodeHolder()->GetFavoritesRoot() == this) { *pbHide = TRUE; return FALSE; } *pbHide = FALSE; return TRUE; }
BOOL CFavoritesNode::IsRefreshAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { *pbHide = FALSE;
bool enable = false; if (IsContainer()) { if (GetFolderInfo()->IsExpanded()) { enable = true; } }
return pComponentData->CanEnableVerb(this) && enable; }
BOOL CFavoritesNode::IsCutAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { // If the sheet is locked for properties, don't allow cut
if (IsSheetLocked()) { *pbHide = TRUE; return FALSE; }
//
// Don't allow cut on the favorites root
//
if (pComponentData->GetFavoritesNodeHolder()->GetFavoritesRoot() == this) { *pbHide = TRUE; return FALSE; }
*pbHide = FALSE;
// NTRAID#NTBUG9-702701-2002/09/12-artm
return pComponentData->CanEnableVerb(this); }
BOOL CFavoritesNode::IsCopyAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { //
// Don't allow copy on the favorites root
//
if (pComponentData->GetFavoritesNodeHolder()->GetFavoritesRoot() == this) { *pbHide = TRUE; return FALSE; }
*pbHide = FALSE;
return TRUE; }
BOOL CFavoritesNode::IsPasteAllowed(CDSComponentData*, BOOL* pbHide) { *pbHide = FALSE; return TRUE; }
void CFavoritesNode::Paste(IDataObject* pPasteData, CDSComponentData* pComponentData, LPDATAOBJECT* ppCutDataObj) { CThemeContextActivator activator;
bool bIsCopy = (ppCutDataObj == 0); //
// Extract the cookies from the data object
//
CInternalFormatCracker ifc; HRESULT hr = ifc.Extract(pPasteData); if (SUCCEEDED(hr)) { //
// Make sure all the nodes are either CFavoritesNode or CSavedQueryNode
// and not the same node or a relative
//
for (UINT nCount = 0; nCount < ifc.GetCookieCount(); nCount++) { CUINode* pNode = ifc.GetCookie(nCount); if (pNode != NULL) { if (!IS_CLASS(pNode, FAVORITES_UI_NODE) && !IS_CLASS(pNode, SAVED_QUERY_UI_NODE)) { //
// Note this should be caught on the query paste
//
ASSERT(FALSE && L"!IS_CLASS(pNode, FAVORITES_UI_NODE) || !IS_CLASS(pNode, SAVED_QUERY_UI_NODE)"); return; }
if (pNode == this) { return; }
if (IsRelative(pNode)) { return; } } }
//
// Add the nodes to this container
//
CUINodeList nodesAddedList; for (UINT nCount = 0; nCount < ifc.GetCookieCount(); nCount++) { CUINode* pNode = ifc.GetCookie(nCount); if (pNode != NULL) { if (IS_CLASS(pNode, FAVORITES_UI_NODE)) { //
// Use the copy constructor to copy the node
//
CFavoritesNode* pCopyNode = new CFavoritesNode(*(dynamic_cast<CFavoritesNode*>(pNode))); if (pCopyNode != NULL) { if (bIsCopy) { //
// Check to see if the name is unique and prepend "Copy of " if not
//
UINT nCopyOfCount = 0; CString szCopyOf; VERIFY(szCopyOf.LoadString(IDS_COPY_OF)); CString szOriginalName = pCopyNode->GetName(); CString szCopyName = szOriginalName;
if (szCopyName.Find(szCopyOf) != -1) { nCopyOfCount = 1; } CString szMultipleCopyOf; VERIFY(szMultipleCopyOf.LoadString(IDS_MULTIPLE_COPY_OF));
CUINode* pDupNode = NULL; while (!IsUniqueName(szCopyName, &pDupNode)) { //
// Puts the new name in the format "Copy of <original name>" or
// "Copy of (#) <original name>"
//
if (nCopyOfCount == 0) { szCopyName = szCopyOf + szOriginalName; } else { CString szTemp; szTemp.Format(szMultipleCopyOf, nCopyOfCount+1);
szCopyName = szTemp + szOriginalName; } ++nCopyOfCount; } pCopyNode->SetName(szCopyName); } else { CUINode* pDupNode = NULL; CString szNewName = pCopyNode->GetName(); if (!IsUniqueName(szNewName, &pDupNode)) { if (pDupNode == pCopyNode) { //
// We are moving the node to the same container. Just silently ignore
//
continue; }
CString szFormatMsg; VERIFY(szFormatMsg.LoadString(IDS_ERRMSG_NOT_UNIQUE_QUERY_NAME_INPLACE));
CString szErrMsg; szErrMsg.Format(szFormatMsg, szNewName);
CString szTitle; VERIFY(szTitle.LoadString(IDS_DSSNAPINNAME));
MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); return; } }
//
// Make copies of all the children too
//
pCopyNode->DeepCopyChildren(pNode); pCopyNode->SetParent(this);
//
// Add it to the successfully pasted list
//
nodesAddedList.AddTail(pCopyNode); } } else if (IS_CLASS(pNode, SAVED_QUERY_UI_NODE)) { CSavedQueryNode* pCopyNode = new CSavedQueryNode(*(dynamic_cast<CSavedQueryNode*>(pNode))); if (pCopyNode != NULL) { if (bIsCopy) { //
// Check to see if the name is unique and prepend "Copy of " if not
//
UINT nCopyOfCount = 0; CString szCopyOf; VERIFY(szCopyOf.LoadString(IDS_COPY_OF)); CString szOriginalName = pCopyNode->GetName(); CString szCopyName = szOriginalName;
if (szCopyName.Find(szCopyOf) != -1) { nCopyOfCount = 1; } CString szMultipleCopyOf; VERIFY(szMultipleCopyOf.LoadString(IDS_MULTIPLE_COPY_OF));
CUINode* pDupNode = NULL; while (!IsUniqueName(szCopyName, &pDupNode)) { //
// Puts the new name in the format "Copy of <original name>" or
// "Copy of (#) <original name>"
//
if (nCopyOfCount == 0) { szCopyName = szCopyOf + szOriginalName; } else { CString szTemp; szTemp.Format(szMultipleCopyOf, nCopyOfCount+1);
szCopyName = szTemp + szOriginalName; } ++nCopyOfCount; } pCopyNode->SetName(szCopyName); } else { CUINode* pDupNode = NULL; CString szNewName = pCopyNode->GetName(); if (!IsUniqueName(szNewName, &pDupNode)) { if (pDupNode == pCopyNode) { //
// We are moving the node to the same container. Just silently ignore
//
continue; }
CString szFormatMsg; VERIFY(szFormatMsg.LoadString(IDS_ERRMSG_NOT_UNIQUE_QUERY_NAME_INPLACE));
CString szErrMsg; szErrMsg.Format(szFormatMsg, szNewName);
CString szTitle; VERIFY(szTitle.LoadString(IDS_DSSNAPINNAME));
MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); return; } }
pCopyNode->SetParent(this);
//
// Add it to the successfully pasted list
//
nodesAddedList.AddTail(pCopyNode); } } else { //
// CFavoritesNode should only contain CFavoritesNodes and CSavedQueryNodes
//
ASSERT(FALSE); } } }
//
// if the node has been expanded then add the new nodes to the UI
//
if (GetFolderInfo()->IsExpanded()) { //
// add the items to the UI
//
pComponentData->AddListOfNodesToUI(this, &nodesAddedList); } else { //
// If not then just add them to the folder's list of children
//
GetFolderInfo()->AddListofNodes(&nodesAddedList); }
//
// Only set the output DataObject if it is a cut operation
//
if (ppCutDataObj != NULL) { *ppCutDataObj = pPasteData; pPasteData->AddRef(); } }
}
HRESULT CFavoritesNode::QueryPaste(IDataObject* pPasteData, CDSComponentData* pComponentData) { HRESULT hr = S_OK;
ASSERT(pComponentData);
//
// Extract the cookies from the data object
//
CInternalFormatCracker ifc; hr = ifc.Extract(pPasteData); if (SUCCEEDED(hr)) { //
// Don't allow drops across instances of the snapin
//
if (IsSameSnapin(pPasteData, pComponentData)) { //
// Make sure all the nodes are either CFavoritesNode or CSavedQueryNode
// and non are locked for properties
//
for (UINT nCount = 0; nCount < ifc.GetCookieCount(); nCount++) { CUINode* pNode = ifc.GetCookie(nCount); if (pNode != NULL) { if (!IS_CLASS(pNode, FAVORITES_UI_NODE) && !IS_CLASS(pNode, SAVED_QUERY_UI_NODE)) { hr = S_FALSE; break; }
if (pNode->IsSheetLocked()) { hr = S_FALSE; break; }
if (IsRelative(pNode)) { hr = S_FALSE; break; } } } } else { hr = S_FALSE; } } return hr; }
bool CFavoritesNode::IsSameSnapin(IDataObject* pPasteData, CDSComponentData* pComponentData) { bool bResult = true;
STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
do {
FORMATETC formatetc = { CDSDataObject::m_cfComponentData, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
HRESULT hr = pPasteData->GetData(&formatetc, &stgmedium); if (FAILED(hr)) { bResult = false; break; }
CDSComponentData** pPasteComponentData = reinterpret_cast<CDSComponentData**>(stgmedium.hGlobal); if (pPasteComponentData && pComponentData != *pPasteComponentData) { bResult = false; break; }
} while(false);
if (stgmedium.hGlobal) { GlobalFree(stgmedium.hGlobal); } return bResult; }
CContextMenuVerbs* CFavoritesNode::GetContextMenuVerbsObject(CDSComponentData* pComponentData) { TRACE(L"Entering CFavoritesNode::GetContextMenuVerbsObject\n");
if (m_pMenuVerbs == NULL) { TRACE(L"Creating new CFavoritesFolderMenuVerbs\n"); m_pMenuVerbs = new CFavoritesFolderMenuVerbs(pComponentData); } return m_pMenuVerbs; }
HRESULT CFavoritesNode::Delete(CDSComponentData* pComponentData) { HRESULT hr = S_OK;
//
// this is just a message box, using ReportErrorEx for consistency of look
//
int answer = ReportErrorEx(pComponentData->GetHWnd(),IDS_CONFIRM_DELETE_FAVORITES,S_OK, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2, NULL, 0); if (answer == IDNO) { return S_FALSE; // aborted by user
}
if (IsContainer()) { hr = pComponentData->RemoveContainerFromUI(this); delete this; } else { CUINode* pParentNode = GetParent(); ASSERT(pParentNode->IsContainer());
pParentNode->GetFolderInfo()->RemoveNode(this); //
// The CDSEvent::_DeleteSingleSel() handles removing the node from the UI
//
} return hr; }
HRESULT CFavoritesNode::DeleteMultiselect(CDSComponentData* pComponentData, CInternalFormatCracker* pObjCracker) { CThemeContextActivator activator;
ASSERT(pObjCracker != NULL); if (pObjCracker == NULL) { return S_FALSE; }
UINT nQueryCount = 0; UINT nFolderCount = 0; for (UINT nIdx = 0; nIdx < pObjCracker->GetCookieCount(); nIdx++) { CUINode* pUINode = pObjCracker->GetCookie(nIdx); if (pUINode != NULL) { if (IS_CLASS(pUINode, FAVORITES_UI_NODE)) { nFolderCount++; } else if (IS_CLASS(pUINode, SAVED_QUERY_UI_NODE)) { nQueryCount++; } else { //
// CFavoritesNode should only contain CFavoritesNodes and CSavedQueryNodes
//
ASSERT(FALSE); continue; } } }
CString szFormatMessage; VERIFY(szFormatMessage.LoadString(IDS_CONFIRM_MULTI_DELETE_FAVORITES));
if (!szFormatMessage.IsEmpty()) { CString szConfirmMessage; szConfirmMessage.Format(szFormatMessage, nFolderCount, nQueryCount);
CString szCaption; VERIFY(szCaption.LoadString(IDS_DSSNAPINNAME));
//
// this is just a message box, using ReportErrorEx for consistency of look
//
int answer = MessageBox(pComponentData->GetHWnd(),szConfirmMessage,szCaption, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2); if (answer == IDNO) { return S_FALSE; // aborted by user
} } else { return S_FALSE; }
return CUINode::DeleteMultiselect(pComponentData, pObjCracker); }
HRESULT CFavoritesNode::OnCommand(long lCommandID, CDSComponentData* pComponentData) { HRESULT hr = S_OK;
switch (lCommandID) { case IDM_NEW_FAVORITES_FOLDER: OnNewFavoritesFolder(pComponentData); break; case IDM_NEW_QUERY_FOLDER: OnNewSavedQuery(pComponentData); break; case IDM_IMPORT_QUERY: OnImportQuery(pComponentData); break; case IDM_GEN_TASK_MOVE: break; case IDM_VIEW_ADVANCED: { if (pComponentData->CanRefreshAll()) { ASSERT( SNAPINTYPE_SITE != pComponentData->QuerySnapinType() ); pComponentData->GetQueryFilter()->ToggleAdvancedView(); pComponentData->SetDirty(TRUE); pComponentData->RefreshAll(); } } break;
default : ASSERT(FALSE); break; } return hr; }
//
// Checks to see if any existing children of this container
// already exist with the passed in name
//
BOOL CFavoritesNode::IsUniqueName(PCWSTR pszName, CUINode** ppDuplicateNode) { BOOL bUnique = TRUE;
CString szNewName = pszName;
//
// Trim whitespace
//
szNewName.TrimLeft(); szNewName.TrimRight();
//
// Make sure the name is unique
//
CUINodeList* pNodeList = GetFolderInfo()->GetContainerList(); if (pNodeList != NULL) { POSITION pos = pNodeList->GetHeadPosition(); while (pos != NULL) { CUINode* pNode = pNodeList->GetNext(pos); if (pNode != NULL) { if (_wcsicmp(szNewName, pNode->GetName()) == 0) { bUnique = FALSE;
//
// Return the node that was found to have the duplicate name
//
if (ppDuplicateNode != NULL) { *ppDuplicateNode = pNode; } break; } } } }
return bUnique; }
HRESULT CFavoritesNode::Rename(LPCWSTR lpszNewName, CDSComponentData* pComponentData) { CThemeContextActivator activator;
HRESULT hr = S_OK; CString szNewName = lpszNewName;
CString szTitle; VERIFY(szTitle.LoadString(IDS_DSSNAPINNAME));
//
// Trim whitespace
//
szNewName.TrimLeft(); szNewName.TrimRight();
if (szNewName.IsEmpty()) { //
// Don't allow empty names
//
CString szMessage; VERIFY(szMessage.LoadString(IDS_ERRMSG_NO_EMPTY_NAMES)); MessageBox(pComponentData->GetHWnd(), szMessage, szTitle, MB_OK | MB_ICONSTOP); return S_FALSE; }
CUINode* pDupNode = NULL; if (GetFavoritesNode() != NULL && !GetFavoritesNode()->IsUniqueName(szNewName, &pDupNode)) { if (pDupNode == this) { //
// We are renaming the node to the same name. Just silently ignore
//
return S_FALSE; }
CString szFormatMsg; VERIFY(szFormatMsg.LoadString(IDS_ERRMSG_NOT_UNIQUE_QUERY_NAME_INPLACE));
CString szErrMsg; szErrMsg.Format(szFormatMsg, szNewName);
MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); return S_FALSE; }
//
// Set the name
//
SetName(szNewName); hr = pComponentData->UpdateItem(this); return hr; }
void CFavoritesNode::OnImportQuery(CDSComponentData* pComponentData) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CThemeContextActivator activator;
//
// Title for error message box
//
CString szTitle; VERIFY(szTitle.LoadString(IDS_DSSNAPINNAME));
CString szFilter; VERIFY(szFilter.LoadString(IDS_QUERY_EXPORT_FILTER));
CString szFileExt(L"xml"); CString szFileView(L"*.xml");
CFileDialog* pFileDlg = new CFileDialog(TRUE, szFileExt, szFileView, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, szFilter); if (pFileDlg == NULL) { return; }
if (pFileDlg->DoModal() == IDOK) { //
// create an instance of the XML document
//
CComPtr<IXMLDOMDocument> spXMLDoc;
HRESULT hr = ::CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&spXMLDoc); if (FAILED(hr)) { TRACE(L"CoCreateInstance(CLSID_DOMDocument) failed with hr = 0x%x\n", hr); return; }
//
// Retrieve the file and path
//
CString szFileName; szFileName = pFileDlg->GetPathName();
CSavedQueryNode* pNewSavedQuery = NULL; bool bQueryAdded = false; do // false loop
{ //
// load the document from file
//
CComVariant xmlSource; xmlSource = szFileName; VARIANT_BOOL isSuccessful; hr = spXMLDoc->load(xmlSource, &isSuccessful); if (FAILED(hr) || !isSuccessful) { CString szErrMsg; szErrMsg.LoadString(IDS_ERRMSG_FAILED_LOAD_QUERY); MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); break; } //
// Get the node interface to the beginning of the document
//
CComPtr<IXMLDOMNode> spXDOMNode; hr = spXMLDoc->QueryInterface(IID_IXMLDOMNode, (void **)&spXDOMNode); if (FAILED(hr)) { CString szErrMsg; szErrMsg.LoadString(IDS_ERRMSG_FAILED_LOAD_QUERY); MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); break; }
//
// Get its child
//
CComPtr<IXMLDOMNode> spXDOMChild; hr = spXDOMNode->get_firstChild(&spXDOMChild); if (FAILED(hr) || !spXDOMChild) { CString szErrMsg; szErrMsg.LoadString(IDS_ERRMSG_FAILED_LOAD_QUERY); MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); break; }
//
// Load the saved query node from this child
//
hr = CSavedQueryNode::XMLLoad(pComponentData, spXDOMChild, &pNewSavedQuery); if (FAILED(hr) || !pNewSavedQuery) { CString szErrMsg; szErrMsg.LoadString(IDS_ERRMSG_FAILED_LOAD_QUERY); MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); break; }
//
// Open query in edit mode
//
CQueryDialog dlg(pNewSavedQuery, this, pComponentData, FALSE, TRUE); if (dlg.DoModal() == IDOK) { //
// Add the node to the ui and select it
//
GetFolderInfo()->AddNode(pNewSavedQuery); pComponentData->AddScopeItemToUI(pNewSavedQuery, TRUE); bQueryAdded = true; } } while (false);
//
// There was an error or the user cancelled the dialog.
// Clean up the memory
//
if (!bQueryAdded && pNewSavedQuery) { delete pNewSavedQuery; pNewSavedQuery = 0; } }
if (pFileDlg != NULL) { delete pFileDlg; pFileDlg = NULL; } }
void CFavoritesNode::OnNewFavoritesFolder(CDSComponentData* pComponentData) { CFavoritesNode* pFav = new CFavoritesNode;
CString szNewFolder; VERIFY(szNewFolder.LoadString(IDS_NEW_FOLDER));
CUINodeList* pContainerList = GetFolderInfo()->GetContainerList(); if (pContainerList != NULL) { CString szSearchString; szSearchString.Format(L"%s (%%u)", szNewFolder);
//
// Search for containers under this node that start with "New Folder (<number>)"
//
UINT nLargestNum = 0; POSITION pos = pContainerList->GetHeadPosition(); while (pos != NULL) { CUINode* pUINode = pContainerList->GetNext(pos);
UINT nFolderNum = 0; CString szNodeName; szNodeName = pUINode->GetName();
if (szNodeName == szNewFolder) { if (nLargestNum < 1) { nLargestNum = 1; } continue; }
if (swscanf(szNodeName, szSearchString, &nFolderNum) == 1) { if (nFolderNum > nLargestNum) { nLargestNum = nFolderNum; } } }
CString szNewName; if (nLargestNum == 0) { szNewName = szNewFolder; } else { szNewName.Format(L"%s (%u)", szNewFolder, nLargestNum + 1); }
pFav->SetName(szNewName);
} else { pFav->SetName(szNewFolder); } pFav->SetDesc(L""); GetFolderInfo()->AddNode(pFav);
//
// Add node to UI and select it
//
pComponentData->AddScopeItemToUI(pFav, TRUE);
//
// Put the folder into rename mode
//
pComponentData->SetRenameMode(pFav);
}
void CFavoritesNode::OnNewSavedQuery(CDSComponentData* pComponentData) { CThemeContextActivator activator;
CSavedQueryNode* pQuery = new CSavedQueryNode(pComponentData->GetBasePathsInfo(), pComponentData->QuerySnapinType()); CQueryDialog dlg(pQuery, this, pComponentData, TRUE); if (dlg.DoModal() == IDOK) { GetFolderInfo()->AddNode(pQuery);
//
// Add new node to UI and select it
//
pComponentData->AddScopeItemToUI(pQuery, TRUE); } }
LPCWSTR CFavoritesNode::g_szObjXMLTag = L"FOLDER";
//
// This is used to start the loading at the embedded favorites root.
// All other favorites folders are loaded through the static method XMLLoad
//
HRESULT CFavoritesNode::Load(IXMLDOMNode* pXDN, CDSComponentData* pComponentData) { //
// check the name of the node
//
if (!XMLIsNodeName(pXDN, CFavoritesNode::g_szObjXMLTag)) { //
// should have checked before calling...
//
ASSERT(FALSE); return E_INVALIDARG; }
//
// get the list of child nodes
//
CComPtr<IXMLDOMNode> spCurrChild; pXDN->get_firstChild(&spCurrChild); if (spCurrChild == NULL) { return E_INVALIDARG; }
//
// recurse down on children
//
while (spCurrChild != NULL) { CComBSTR bstrName, bstrDescription; CComBSTR bstrChildName; spCurrChild->get_nodeName(&bstrChildName); if (CompareXMLTags(bstrChildName, CFavoritesNode::g_szObjXMLTag)) { //
// we got a subfolder, need to build the subtree
//
CFavoritesNode* pSubNode = NULL; CFavoritesNode::XMLLoad(pComponentData, spCurrChild, &pSubNode); if (pSubNode != NULL) { //
// got a subtree, add it to the list of children
//
GetFolderInfo()->AddNode(pSubNode); } } else if (CompareXMLTags(bstrChildName, CGenericUINode::g_szNameXMLTag)) { XML_GetNodeText(spCurrChild, &bstrName);
// Don't overwrite the name from the saved console if this is the query
// root because the default saved console is always english. In other
// languages we need to use the string from the resource file.
if (!IsFavoritesRoot()) { SetName(bstrName); } } else if (CompareXMLTags(bstrChildName, CGenericUINode::g_szDecriptionXMLTag)) { XML_GetNodeText(spCurrChild, &bstrDescription);
// Don't overwrite the description from the saved console if this is the query
// root because the default saved console is always english. In other
// languages we need to use the string from the resource file.
if (!IsFavoritesRoot()) { SetDesc(bstrDescription); } else { // If it is the favorites root and the description is not the same as the
// default english description, then set it. The user has the option to
// change the description. If IDS_SAVED_QUERIES_DESC gets changed this has
// to be changed as well.
if (bstrDescription && _wcsicmp(bstrDescription, L"Folder to store your favorite queries") !=0) { SetDesc(bstrDescription); } } } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szObjXMLTag)) { CSavedQueryNode* pQuery = NULL; CSavedQueryNode::XMLLoad(pComponentData, spCurrChild, &pQuery); if (pQuery != NULL) { GetFolderInfo()->AddNode(pQuery); } } CComPtr<IXMLDOMNode> temp = spCurrChild; spCurrChild = NULL; temp->get_nextSibling(&spCurrChild); } return S_OK; }
HRESULT CFavoritesNode::XMLLoad(CDSComponentData* pComponentData, IXMLDOMNode* pXDN, CFavoritesNode** ppNode) { // check the name of the node
if (!XMLIsNodeName(pXDN, CFavoritesNode::g_szObjXMLTag)) { // should have checked before calling...
ASSERT(FALSE); return E_INVALIDARG; }
// get the list of child nodes
CComPtr<IXMLDOMNode> spCurrChild; pXDN->get_firstChild(&spCurrChild); if (spCurrChild == NULL) { return E_INVALIDARG; }
// create a temporary node
(*ppNode) = new CFavoritesNode;
// recurse down on children
while (spCurrChild != NULL) { CComBSTR bstrName, bstrDescription; CComBSTR bstrChildName; spCurrChild->get_nodeName(&bstrChildName); if (CompareXMLTags(bstrChildName, CFavoritesNode::g_szObjXMLTag)) { // we got a subfolder, need to build the subtree
CFavoritesNode* pSubNode = NULL; CFavoritesNode::XMLLoad(pComponentData, spCurrChild, &pSubNode); if (pSubNode != NULL) { // got a subtree, add it to the list of children
(*ppNode)->GetFolderInfo()->AddNode(pSubNode); } } else if (CompareXMLTags(bstrChildName, CGenericUINode::g_szNameXMLTag)) { XML_GetNodeText(spCurrChild, &bstrName); (*ppNode)->SetName(bstrName); } else if (CompareXMLTags(bstrChildName, CGenericUINode::g_szDecriptionXMLTag)) { XML_GetNodeText(spCurrChild, &bstrDescription); (*ppNode)->SetDesc(bstrDescription); } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szObjXMLTag)) { CSavedQueryNode* pQuery = NULL; CSavedQueryNode::XMLLoad(pComponentData, spCurrChild, &pQuery); if (pQuery != NULL) { (*ppNode)->GetFolderInfo()->AddNode(pQuery); } } CComPtr<IXMLDOMNode> temp = spCurrChild; spCurrChild = NULL; temp->get_nextSibling(&spCurrChild); }
return S_OK; }
HRESULT CFavoritesNode::XMLSave(IXMLDOMDocument* pXMLDoc, IXMLDOMNode** ppXMLDOMNode) { CComPtr<IXMLDOMNode> spXMLDOMNode; HRESULT hr = XML_CreateDOMNode(pXMLDoc, NODE_ELEMENT, CFavoritesNode::g_szObjXMLTag, &spXMLDOMNode); if (FAILED(hr)) { return hr; }
hr = XMLSaveBase(pXMLDoc, spXMLDOMNode); if (FAILED(hr)) { return hr; }
// save the child nodes
CUINodeList* pNodeList = GetFolderInfo()->GetContainerList(); for (POSITION pos = pNodeList->GetHeadPosition(); pos != NULL; ) { CGenericUINode* pCurrChildNode = dynamic_cast<CGenericUINode*>(pNodeList->GetNext(pos)); if (pCurrChildNode == NULL) { ASSERT(FALSE); // should never happen
continue; } CComPtr<IXMLDOMNode> spXMLDOMChildNode; hr = pCurrChildNode->XMLSave(pXMLDoc, &spXMLDOMChildNode); if (SUCCEEDED(hr)) { CComPtr<IXMLDOMNode> p; CComVariant after; after.vt = VT_EMPTY; hr = spXMLDOMNode->appendChild(spXMLDOMChildNode, &p); } } // for
(*ppXMLDOMNode) = spXMLDOMNode; (*ppXMLDOMNode)->AddRef(); return S_OK; }
HRESULT CFavoritesNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK pCall, LONG_PTR lNotifyHandle, LPDATAOBJECT pDataObject, CDSComponentData* pComponentData) { HRESULT hr = S_FALSE;
CFavoritesNodePropertyPage* pPropertyPage = new CFavoritesNodePropertyPage(this, lNotifyHandle, pComponentData, pDataObject); if (pPropertyPage != NULL) { HPROPSHEETPAGE hPage = ::MyCreatePropertySheetPage(&pPropertyPage->m_psp); if (hPage != NULL) { hr = pCall->AddPage(hPage); pComponentData->SheetLockCookie(this); } else { hr = E_UNEXPECTED; } } else { hr = E_OUTOFMEMORY; } return hr; }
//
// Function used in a recursive search through the saved query tree looking
// for saved queries that contain objects with any of the DNs in the list
// and invalidates that query
//
void CFavoritesNode::InvalidateSavedQueriesContainingObjects(CDSComponentData* pComponentData, const CStringList& refDNList) { ASSERT(IsContainer());
//
// Note favorites nodes should only contain containers, so we only have to look
// through the folder list
//
CUINodeList* pContainerList = GetFolderInfo()->GetContainerList(); POSITION pos = pContainerList->GetHeadPosition(); while (pos) { CGenericUINode* pGenericUINode = dynamic_cast<CGenericUINode*>(pContainerList->GetNext(pos)); if (pGenericUINode) { pGenericUINode->InvalidateSavedQueriesContainingObjects(pComponentData, refDNList); } } }
////////////////////////////////////////////////////////////////////////////
// CSavedQueryNode
BOOL CSavedQueryNode::IsFilterLastLogon() { return m_bLastLogonFilter && m_dwLastLogonDays != (DWORD)-1; }
CSavedQueryNode::CSavedQueryNode(MyBasePathsInfo* pBasePathsInfo, SnapinType /*snapinType*/) : CGenericUINode(SAVED_QUERY_UI_NODE), m_szRelativeRootPath(L""), m_szCurrentFullPath(L""), m_szQueryString(L""), m_szColumnID(L""), m_bOneLevel(FALSE), m_bQueryValid(TRUE), m_pPersistQueryImpl(NULL), m_bLastLogonFilter(FALSE), m_dwLastLogonDays((DWORD)-1), m_pBasePathsInfo(pBasePathsInfo) { MakeContainer();
// Generate the unique column set ID
GUID guid = GUID_NULL; HRESULT hr = ::CoCreateGuid(&guid); if (SUCCEEDED(hr)) { WCHAR lpszGuid[40]; int iRet = ::StringFromGUID2(guid, lpszGuid, sizeof(lpszGuid)/sizeof(WCHAR)); if (iRet > 0) { m_szColumnID = lpszGuid; } } }
CSavedQueryNode::CSavedQueryNode(const CSavedQueryNode& copyNode) : CGenericUINode(copyNode) { m_szRelativeRootPath = copyNode.m_szRelativeRootPath; m_szQueryString = copyNode.m_szQueryString; m_bOneLevel = copyNode.m_bOneLevel; m_pBasePathsInfo = copyNode.m_pBasePathsInfo;
//
// Create the IPersistQuery object
//
CComObject<CDSAdminPersistQueryFilterImpl>::CreateInstance(&m_pPersistQueryImpl); ASSERT(m_pPersistQueryImpl != NULL);
if (m_pPersistQueryImpl != NULL) { //
// created with zero refcount,need to AddRef() to one
//
m_pPersistQueryImpl->AddRef(); copyNode.m_pPersistQueryImpl->Clone(m_pPersistQueryImpl); }
m_bQueryValid = TRUE;
m_bLastLogonFilter = copyNode.m_bLastLogonFilter; m_dwLastLogonDays = copyNode.m_dwLastLogonDays;
// Generate the unique ID for the column set
GUID guid = GUID_NULL; HRESULT hr = ::CoCreateGuid(&guid); if (SUCCEEDED(hr)) { WCHAR lpszGuid[40]; int iRet = ::StringFromGUID2(guid, lpszGuid, sizeof(lpszGuid)/sizeof(WCHAR)); if (iRet > 0) { m_szColumnID = lpszGuid; } } }
CSavedQueryNode::~CSavedQueryNode() { if (m_pPersistQueryImpl) { m_pPersistQueryImpl->Release(); m_pPersistQueryImpl = 0; } } void CSavedQueryNode::SetColumnID(CDSComponentData* pComponentData, PCWSTR pszColumnID) { m_szColumnID = pszColumnID; GetColumnSet(pComponentData)->SetColumnID(pszColumnID); }
CDSColumnSet* CSavedQueryNode::GetColumnSet(CDSComponentData* pComponentData) { CDSColumnSet* pColumnSet = NULL; if (IsContainer()) { pColumnSet = GetFolderInfo()->GetColumnSet(m_szColumnID, pComponentData); } return pColumnSet; }
void CSavedQueryNode::AppendLastLogonQuery(CString& szQuery, DWORD dwDays) { LARGE_INTEGER li; GetCurrentTimeStampMinusInterval(dwDays, &li);
CString szTime; litow(li, szTime); szQuery.Format(L"%s(lastLogonTimestamp<=%s)",szQuery, szTime); }
LPCWSTR CSavedQueryNode::GetRootPath() { m_szCurrentFullPath = m_szRelativeRootPath + m_pBasePathsInfo->GetDefaultRootNamingContext(); return m_szCurrentFullPath; }
void CSavedQueryNode::SetRootPath(LPCWSTR lpszRootPath) { //
// Strip the name down to make it a RDN to the defaultNamingContext
//
CString szTempPath = lpszRootPath;
ASSERT(m_pBasePathsInfo != NULL); if (m_pBasePathsInfo != NULL) { //
// We now have a full DN. Strip the default root naming context to get the RDN.
//
CString szDefaultRootNamingContext = m_pBasePathsInfo->GetDefaultRootNamingContext();
int iRootDN = szTempPath.Find(szDefaultRootNamingContext); if (iRootDN != -1) { szTempPath = szTempPath.Left(iRootDN); } } m_szRelativeRootPath = szTempPath; }
LPCWSTR CSavedQueryNode::GetQueryString() { //
// If we are doing a last logon query we have to check to be sure
// the lastLogonTimestamp is part of the query string. If not, we have
// to add it. There is a case when we load that the lastLogonTimestamp
// might not be present.
//
if (IsFilterLastLogon()) { int iFindLast = m_szQueryString.Find(L"lastLogonTimestamp"); if (iFindLast == -1) { //
// we didn't find it
//
CString szTemp; szTemp = m_szQueryString.Left(m_szQueryString.GetLength() - 1); AppendLastLogonQuery(szTemp, m_dwLastLogonDays); szTemp += L")"; m_szQueryString = szTemp; } } return m_szQueryString; }
void CSavedQueryNode::FindCookieByDN(LPCWSTR lpszCookieDN, CUINodeList* pNodeList) { ASSERT(IsContainer()); ASSERT(GetFolderInfo()->GetContainerList()->IsEmpty());
CUINodeList* pList = GetFolderInfo()->GetLeafList();
for (POSITION pos = pList->GetHeadPosition(); pos != NULL; ) { CUINode* pCurrentNode = pList->GetNext(pos); ASSERT(!pCurrentNode->IsContainer());
if (!IS_CLASS(pCurrentNode, DS_UI_NODE)) { // not a node with a cookie, just skip
ASSERT(FALSE); // should not be there
continue; }
// is this the right cookie?
CDSCookie* pCurrentCookie = GetDSCookieFromUINode(pCurrentNode); LPCWSTR lpszCurrentPath = pCurrentCookie->GetPath(); if (_wcsicmp(lpszCurrentPath, lpszCookieDN) == 0) { // found, add to list and bail out (cannot have more than one)
pNodeList->AddTail(pCurrentNode); return; } } // for
}
BOOL CSavedQueryNode::IsDeleteAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { *pbHide = FALSE; return pComponentData->CanEnableVerb(this); }
BOOL CSavedQueryNode::IsRenameAllowed(CDSComponentData*, BOOL* pbHide) { *pbHide = FALSE; return TRUE; }
BOOL CSavedQueryNode::IsRefreshAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { *pbHide = FALSE;
bool enable = false; if (IsContainer()) { if (GetFolderInfo()->IsExpanded()) { enable = true; } }
return pComponentData->CanEnableVerb(this) && enable; }
BOOL CSavedQueryNode::IsCutAllowed(CDSComponentData* pComponentData, BOOL* pbHide) { *pbHide = FALSE; // NTRAID#NTBUG9-702701-2002/09/12-artm
return pComponentData->CanEnableVerb(this); }
BOOL CSavedQueryNode::IsCopyAllowed(CDSComponentData*, BOOL* pbHide) { *pbHide = FALSE; return TRUE; }
BOOL CSavedQueryNode::IsPasteAllowed(CDSComponentData*, BOOL* pbHide) { *pbHide = FALSE; return TRUE; }
CContextMenuVerbs* CSavedQueryNode::GetContextMenuVerbsObject(CDSComponentData* pComponentData) { TRACE(L"Entering CSavedQueryNode::GetContextMenuVerbsObject\n");
if (m_pMenuVerbs == NULL) { TRACE(L"Creating new CSavedQueryMenuVerbs object\n"); m_pMenuVerbs = new CSavedQueryMenuVerbs(pComponentData); } return m_pMenuVerbs; }
HRESULT CSavedQueryNode::Delete(CDSComponentData* pComponentData) { HRESULT hr = S_OK;
//
// this is just a message box, using ReportErrorEx for consistency of look
//
int answer = ReportErrorEx(pComponentData->GetHWnd(),IDS_CONFIRM_DELETE_QUERY,S_OK, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2, NULL, 0); if (answer == IDNO) { return S_FALSE; // aborted by user
}
if (IsContainer()) { hr = pComponentData->RemoveContainerFromUI(this); delete this; } else { CUINode* pParentNode = GetParent(); ASSERT(pParentNode->IsContainer());
pParentNode->GetFolderInfo()->RemoveNode(this); //
// The CDSEvent::_DeleteSingleSel() handles removing the node from the UI
//
} return hr; }
HRESULT CSavedQueryNode::OnCommand(long lCommandID, CDSComponentData* pComponentData) { HRESULT hr = S_OK;
switch (lCommandID) { case IDM_EXPORT_QUERY: OnExportQuery(pComponentData); break; case IDM_EDIT_QUERY: OnEditQuery(pComponentData); break; case IDM_VIEW_ADVANCED: { if (pComponentData->CanRefreshAll()) { ASSERT( SNAPINTYPE_SITE != pComponentData->QuerySnapinType() ); pComponentData->GetQueryFilter()->ToggleAdvancedView(); pComponentData->SetDirty(TRUE); pComponentData->RefreshAll(); } } break; default: ASSERT(FALSE); break; }
return hr; }
void CSavedQueryNode::OnEditQuery(CDSComponentData* pComponentData) { CThemeContextActivator activator;
CFavoritesNode* pFavNode = dynamic_cast<CFavoritesNode*>(GetParent()); if (pFavNode != NULL) { CQueryDialog dlg(this, pFavNode, pComponentData, FALSE); if (dlg.DoModal() == IDOK) { pComponentData->UpdateItem(this);
//
// Removed on 11/06/2000 due to Whistler bug #120727:
// DS Admin snapin - query executes immediately after editting, even when editted from results pane
//
//pComponentData->Refresh(this);
} } else { //
// This should always succeed. Query nodes are only allowed as children of CFavoritesNode
//
ASSERT(FALSE); } }
HRESULT CSavedQueryNode::Rename(LPCWSTR lpszNewName, CDSComponentData* pComponentData) { CThemeContextActivator activator;
HRESULT hr = S_OK; CString szNewName = lpszNewName;
CString szTitle; VERIFY(szTitle.LoadString(IDS_DSSNAPINNAME));
//
// Trim whitespace
//
szNewName.TrimLeft(); szNewName.TrimRight();
if (szNewName.IsEmpty()) { //
// Don't allow empty names
//
CString szMessage; VERIFY(szMessage.LoadString(IDS_ERRMSG_NO_EMPTY_NAMES)); MessageBox(pComponentData->GetHWnd(), szMessage, szTitle, MB_OK | MB_ICONSTOP); return S_FALSE; }
CUINode* pDupNode = NULL; CFavoritesNode* pParent = GetFavoritesNode(); if (pParent != NULL && !pParent->IsUniqueName(szNewName, &pDupNode)) { if (pDupNode == this) { //
// We are renaming the node to the same name. Just silently ignore.
//
return S_FALSE; }
CString szFormatMsg; VERIFY(szFormatMsg.LoadString(IDS_ERRMSG_NOT_UNIQUE_QUERY_NAME_INPLACE));
CString szErrMsg; szErrMsg.Format(szFormatMsg, szNewName);
MessageBox(pComponentData->GetHWnd(), szErrMsg, szTitle, MB_OK | MB_ICONSTOP); return S_FALSE; }
//
// Set the name
//
SetName(szNewName); hr = pComponentData->UpdateItem(this); return hr; }
void CSavedQueryNode::OnExportQuery(CDSComponentData*) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CThemeContextActivator activator;
CString szFilter; VERIFY(szFilter.LoadString(IDS_QUERY_EXPORT_FILTER));
CString szFileExt(L"xml"); CString szFileView(L"*.xml");
CFileDialog* pFileDlg = new CFileDialog(FALSE, szFileExt, szFileView, OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT, szFilter);
if (pFileDlg == NULL) { return; }
if (pFileDlg->DoModal() == IDOK) { //
// create an instance of the XML document
//
CComPtr<IXMLDOMDocument> spXMLDoc;
HRESULT hr = ::CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&spXMLDoc); if (FAILED(hr)) { TRACE(L"CoCreateInstance(CLSID_DOMDocument) failed with hr = 0x%x\n", hr); return; }
//
// Retrieve the file and path
//
CString szFileName; szFileName = pFileDlg->GetPathName();
//
// save the node to the document
//
CComVariant xmlSource; xmlSource = szFileName; CComPtr<IXMLDOMNode> spXMLDOMChildNode; hr = XMLSave(spXMLDoc, &spXMLDOMChildNode); if (SUCCEEDED(hr)) { CComPtr<IXMLDOMNode> spXDOMNode; hr = spXMLDoc->QueryInterface(IID_IXMLDOMNode, (void **)&spXDOMNode); if (SUCCEEDED(hr)) { CComPtr<IXMLDOMNode> spXDOMNewNode; hr = spXDOMNode->appendChild(spXMLDOMChildNode, &spXDOMNewNode); if (SUCCEEDED(hr)) { //
// save the document to the file
//
hr = spXMLDoc->save(xmlSource); TRACE(L"Save returned with hr = 0x%x\n", hr); } } } }
if (pFileDlg != NULL) { delete pFileDlg; pFileDlg = NULL; } }
LPCWSTR CSavedQueryNode::g_szObjXMLTag = L"QUERY"; LPCWSTR CSavedQueryNode::g_szDnXMLTag = L"DN"; LPCWSTR CSavedQueryNode::g_szOneLevelXMLTag = L"ONELEVEL"; LPCWSTR CSavedQueryNode::g_szQueryStringXMLTag = L"LDAPQUERY"; LPCWSTR CSavedQueryNode::g_szLastLogonFilterTag = L"FILTERLASTLOGON"; LPCWSTR CSavedQueryNode::g_szDSQueryPersistTag = L"DSQUERYUIDATA"; LPCWSTR CSavedQueryNode::g_szColumnIDTag = L"COLUMNID";
HRESULT CSavedQueryNode::XMLLoad(CDSComponentData* pComponentData, IXMLDOMNode* pXDN, CSavedQueryNode** ppQuery) { *ppQuery = NULL;
// check the name of the node
if (!XMLIsNodeName(pXDN, CSavedQueryNode::g_szObjXMLTag)) { // should have checked before calling...
ASSERT(FALSE); return E_INVALIDARG; }
// get the list of child nodes
CComPtr<IXMLDOMNode> spCurrChild; pXDN->get_firstChild(&spCurrChild); if (spCurrChild == NULL) { return E_INVALIDARG; }
// allocate a query object
*ppQuery = new CSavedQueryNode(pComponentData->GetBasePathsInfo());
CComBSTR bstrName, bstrDescription, bstrDN, bstrQueryString, bstrColumnID; CComBSTR bstrChildName;
bool bGotName = false; bool bGotDN = false; bool bGotQuery = false; bool bGotScope = false;
while (spCurrChild != NULL) { spCurrChild->get_nodeName(&bstrChildName); if (CompareXMLTags(bstrChildName, CGenericUINode::g_szNameXMLTag)) { if (SUCCEEDED(XML_GetNodeText(spCurrChild, &bstrName))) { (*ppQuery)->SetName(bstrName); bGotName = true; } } else if (CompareXMLTags(bstrChildName, CGenericUINode::g_szDecriptionXMLTag)) { if (SUCCEEDED(XML_GetNodeText(spCurrChild, &bstrDescription))) { (*ppQuery)->SetDesc(bstrDescription); } } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szDnXMLTag)) { if (SUCCEEDED(XML_GetNodeText(spCurrChild, &bstrDN))) { (*ppQuery)->SetRootPath(bstrDN); bGotDN = true; } } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szQueryStringXMLTag)) { if (SUCCEEDED(XML_GetNodeText(spCurrChild, &bstrQueryString))) { (*ppQuery)->SetQueryString(bstrQueryString); bGotQuery = true; } } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szOneLevelXMLTag)) { BOOL b; if (SUCCEEDED(XML_GetNodeBOOL(spCurrChild, &b))) { (*ppQuery)->SetOneLevel(b); bGotScope = true; } } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szLastLogonFilterTag)) { DWORD dwDays; if (SUCCEEDED(XML_GetNodeDWORD(spCurrChild, &dwDays))) { (*ppQuery)->SetLastLogonQuery(dwDays); } else { (*ppQuery)->SetLastLogonQuery((DWORD)-1); } } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szColumnIDTag)) { if (SUCCEEDED(XML_GetNodeText(spCurrChild, &bstrColumnID))) { (*ppQuery)->SetColumnID(pComponentData, bstrColumnID); } } else if (CompareXMLTags(bstrChildName, CSavedQueryNode::g_szDSQueryPersistTag)) { BYTE* pByteArray = NULL; ULONG nByteCount = 0; if (SUCCEEDED(XML_GetNodeBlob(spCurrChild, &pByteArray, &nByteCount))) { if (pByteArray != NULL && nByteCount > 0) { //
// Create a dummy stream object
//
CComObject<CDummyStream>* pDummyStream; CComObject<CDummyStream>::CreateInstance(&pDummyStream); if (pDummyStream != NULL) { HRESULT hr = pDummyStream->SetStreamData(pByteArray, nByteCount); if (SUCCEEDED(hr)) { //
// Create a temporary CDSAdminPersistQueryFilterImpl object
//
CComObject<CDSAdminPersistQueryFilterImpl>* pPersistQueryImpl; CComObject<CDSAdminPersistQueryFilterImpl>::CreateInstance(&pPersistQueryImpl);
if (pPersistQueryImpl != NULL) { //
// Load the CDSAdminPersistQueryFilterImpl from the dummy stream
//
hr = pPersistQueryImpl->Load(pDummyStream); if (SUCCEEDED(hr)) { //
// Save the CDSAdminPersistQueryFilterImpl into the new query node
//
(*ppQuery)->SetQueryPersist(pPersistQueryImpl); } } } } } } }
// iterate to next item
CComPtr<IXMLDOMNode> temp = spCurrChild; spCurrChild = NULL; temp->get_nextSibling(&spCurrChild); }
if (!bGotName || !bGotDN || !bGotQuery || !bGotScope) { return E_FAIL; } return S_OK; }
HRESULT CSavedQueryNode::XMLSave(IXMLDOMDocument* pXMLDoc, IXMLDOMNode** ppXMLDOMNode) { // create the node for the object itself
CComPtr<IXMLDOMNode> spXMLDOMNode; HRESULT hr = XML_CreateDOMNode(pXMLDoc, NODE_ELEMENT, CSavedQueryNode::g_szObjXMLTag, &spXMLDOMNode); RETURN_IF_FAILED(hr);
// create inner nodes with member variables
hr = XMLSaveBase(pXMLDoc, spXMLDOMNode); RETURN_IF_FAILED(hr);
//
// Root path
//
hr = XML_AppendTextDataNode(pXMLDoc, spXMLDOMNode, CSavedQueryNode::g_szDnXMLTag, m_szRelativeRootPath); RETURN_IF_FAILED(hr);
//
// Filter on last logon timestamp
//
hr = XML_AppendDWORDDataNode(pXMLDoc, spXMLDOMNode, CSavedQueryNode::g_szLastLogonFilterTag, m_dwLastLogonDays); RETURN_IF_FAILED(hr);
//
// Query string
//
//
// Have to remove the last logon timestamp if its there
//
CString szSaveQueryString; if (IsFilterLastLogon()) { int iFindLast = m_szQueryString.Find(L"lastLogonTimestamp"); if (iFindLast != -1) { szSaveQueryString = m_szQueryString.Left(iFindLast - 1); szSaveQueryString += L")"; } else { szSaveQueryString = m_szQueryString; } } else { szSaveQueryString = m_szQueryString; } hr = XML_AppendTextDataNode(pXMLDoc, spXMLDOMNode, CSavedQueryNode::g_szQueryStringXMLTag, szSaveQueryString); RETURN_IF_FAILED(hr);
//
// Is one level query flag
//
hr = XML_AppendBOOLDataNode(pXMLDoc, spXMLDOMNode, CSavedQueryNode::g_szOneLevelXMLTag, IsOneLevel()); RETURN_IF_FAILED(hr);
//
// Column ID
//
hr = XML_AppendTextDataNode(pXMLDoc, spXMLDOMNode, CSavedQueryNode::g_szColumnIDTag, m_szColumnID); RETURN_IF_FAILED(hr);
//
// Create a dummy stream object to write the saved query UI info into
//
CComObject<CDummyStream>* pDummyStream; CComObject<CDummyStream>::CreateInstance(&pDummyStream);
if (pDummyStream != NULL) { if (m_pPersistQueryImpl != NULL) { hr = m_pPersistQueryImpl->Save(pDummyStream); if (SUCCEEDED(hr)) { BYTE* pByteArray = NULL; ULONG nByteCount = 0; nByteCount = pDummyStream->GetStreamData(&pByteArray); if (nByteCount > 0 && pByteArray != NULL) { hr = XML_AppendStructDataNode(pXMLDoc, spXMLDOMNode, CSavedQueryNode::g_szDSQueryPersistTag, pByteArray, nByteCount); RETURN_IF_FAILED(hr); delete[] pByteArray; } } } }
(*ppXMLDOMNode) = spXMLDOMNode; (*ppXMLDOMNode)->AddRef(); return hr; }
void CSavedQueryNode::SetQueryPersist(CComObject<CDSAdminPersistQueryFilterImpl>* pPersistQueryImpl) { if (m_pPersistQueryImpl != NULL) { m_pPersistQueryImpl->Release(); m_pPersistQueryImpl = NULL; } m_pPersistQueryImpl = pPersistQueryImpl; m_pPersistQueryImpl->AddRef(); }
//
// Function used in a recursive search through the saved query tree looking
// for saved queries that contain objects with any of the DNs in the list
// and invalidates that query
//
void CSavedQueryNode::InvalidateSavedQueriesContainingObjects(CDSComponentData* pComponentData, const CStringList& refDNList) { ASSERT(IsContainer());
CUINodeList nodeList;
POSITION pos = refDNList.GetHeadPosition(); while (pos) { CString szDN = refDNList.GetNext(pos); FindCookieByDN(szDN, &nodeList); if (nodeList.GetCount() > 0) { //
// An object from the list was found, make the saved query invalid and
// break
//
SetValid(FALSE); pComponentData->ChangeScopeItemIcon(this); break; } } }
////////////////////////////////////////////////////////////////////////////
// CFavoritesNodesHolder
/* For test purposes Only
void CFavoritesNodesHolder::BuildTestTree(LPCWSTR lpszXMLFileName, SnapinType snapinType) { if (lpszXMLFileName == NULL) { // no file name passed, build the hardwired version
BuildTestTreeHardWired(snapinType); return; }
if (!BuildTestTreefromXML(lpszXMLFileName, snapinType)) { // we failed, use hardwired
BuildTestTreeHardWired(snapinType); } } BOOL CFavoritesNodesHolder::BuildTestTreefromXML(LPCWSTR lpszXMLFileName, SnapinType) { // create an instance of the XML document
CComPtr<IXMLDOMDocument> spXMLDoc;
HRESULT hr = ::CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&spXMLDoc); if (FAILED(hr)) { TRACE(L"CoCreateInstance(CLSID_DOMDocument) failed with hr = 0x%x\n", hr); return FALSE; }
// load the document from file
CComVariant xmlSource; xmlSource = lpszXMLFileName; VARIANT_BOOL isSuccessful; hr = spXMLDoc->load(xmlSource, &isSuccessful); if (FAILED(hr)) { CString szMsg; szMsg.Format(L"spXMLDoc->load() failed with hr = 0x%x\n", hr); TRACE((LPCWSTR)szMsg); AFX_MANAGE_STATE(AfxGetStaticModuleState()); AfxMessageBox(szMsg); return FALSE; }
// get the root of the document
CComPtr<IXMLDOMNode> spXDN; hr = spXMLDoc->QueryInterface(IID_IXMLDOMNode, (void **)&spXDN); if (FAILED(hr)) { TRACE(L"spXMLDoc->QueryInterface(IID_IXMLDOMNode() failed with hr = 0x%x\n", hr); return FALSE; }
// find where the FOLDER tree starts in the document
CComPtr<IXMLDOMNode> spXMLFolderRootnode; hr = XML_FindSubtreeNode(spXDN, CFavoritesNode::g_szObjXMLTag, &spXMLFolderRootnode); if (FAILED(hr)) { wprintf(L"XML_FindSubtreeNode() on FOLDER failed with hr = 0x%x\n", hr); return FALSE; }
CFavoritesNode* pRootNode = NULL; if (spXMLFolderRootnode != NULL) { // have an XML root folder node, load it into the
// in memory tree
CFavoritesNode::XMLLoad(pComponentData, spXMLFolderRootnode, &pRootNode); } else { TRACE(L"XML_FindSubtreeNode() returned a NULL root folder node"); }
if (pRootNode == NULL) { TRACE(L"CFavoritesNode::XMLLoad() returned NULL root node\n"); return FALSE; }
// REVIEW_MARCOC: this is a hack to get things ported,
// need to review XML schema
// now we have a tree, need to graft underneath the folder root node
// move the first level of children
CUINodeList* pNodeList = pRootNode->GetFolderInfo()->GetContainerList(); while (!pNodeList->IsEmpty()) { CUINode* p = pNodeList->RemoveHead(); p->ClearParent(); m_favoritesRoot.GetFolderInfo()->AddNode(p); } // copy the info in the root
m_favoritesRoot.SetName(pRootNode->GetName()); m_favoritesRoot.SetDesc(pRootNode->GetDesc());
// delete root
delete pRootNode;
return TRUE; } */ /* For testing purposes only
void CFavoritesNodesHolder::BuildTestTreeHardWired(SnapinType snapinType) {
// fill in the root
m_favoritesRoot.SetName(L"Saved Queries"); m_favoritesRoot.SetDesc(L"Folder to store your favorite queries");
// first level of children
CFavoritesNode* pMostUsed = new CFavoritesNode; pMostUsed->SetName(L"Most Used"); pMostUsed->SetDesc(L"Very handy queries, used all the time"); m_favoritesRoot.GetFolderInfo()->AddNode(pMostUsed);
CFavoritesNode* pMarketing = new CFavoritesNode; pMarketing->SetName(L"Marketing"); m_favoritesRoot.GetFolderInfo()->AddNode(pMarketing);
CFavoritesNode* pDevelopment = new CFavoritesNode; pDevelopment->SetName(L"Development"); m_favoritesRoot.GetFolderInfo()->AddNode(pDevelopment);
CFavoritesNode* pCustomerSupport = new CFavoritesNode; pCustomerSupport->SetName(L"Customer Support"); m_favoritesRoot.GetFolderInfo()->AddNode(pCustomerSupport);
// fill in under most used
CSavedQueryNode* pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"My contacts"); pQuery->SetDesc(L"All the contacts in this domain"); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(FALSE); pQuery->SetQueryString(L"(objectClass=contact)");
pMostUsed->GetFolderInfo()->AddNode(pQuery);
CFavoritesNode* pMyComputersFolder = new CFavoritesNode; pMyComputersFolder->SetName(L"My Computers"); pMostUsed->GetFolderInfo()->AddNode(pMyComputersFolder);
pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"Workstations"); pQuery->SetDesc(L""); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(FALSE); pQuery->SetQueryString(L"(objectClass=computer)");
pMyComputersFolder->GetFolderInfo()->AddNode(pQuery);
pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"Servers"); pQuery->SetDesc(L""); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(FALSE); pQuery->SetQueryString(L"(objectClass=computer)");
pMyComputersFolder->GetFolderInfo()->AddNode(pQuery);
pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"All"); pQuery->SetDesc(L""); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(FALSE); pQuery->SetQueryString(L"(objectClass=computer)");
pMyComputersFolder->GetFolderInfo()->AddNode(pQuery);
// fill in under development
pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"Users"); pQuery->SetDesc(L""); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(TRUE); pQuery->SetQueryString(L"(objectClass=users)"); pDevelopment->GetFolderInfo()->AddNode(pQuery);
pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"Computers"); pQuery->SetDesc(L""); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(TRUE); pQuery->SetQueryString(L"(objectClass=computer)"); pDevelopment->GetFolderInfo()->AddNode(pQuery);
pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"Groups"); pQuery->SetDesc(L""); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(TRUE); pQuery->SetQueryString(L"(objectClass=group)"); pDevelopment->GetFolderInfo()->AddNode(pQuery);
pQuery = new CSavedQueryNode(snapinType); pQuery->SetName(L"Managers"); pQuery->SetDesc(L""); pQuery->SetRootPath(L"DC=marcocdev;DC=nttest;DC=microsoft;DC=com"); pQuery->SetOneLevel(TRUE); pQuery->SetQueryString(L"(objectClass=user)"); pDevelopment->GetFolderInfo()->AddNode(pQuery);
} */
HRESULT CFavoritesNodesHolder::Save(IStream* pStm) { //
// create an instance of the XML document
//
CComPtr<IXMLDOMDocument> spXMLDoc;
HRESULT hr = ::CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&spXMLDoc); if (FAILED(hr)) { TRACE(L"CoCreateInstance(CLSID_DOMDocument) failed with hr = 0x%x\n", hr); return hr; }
CComPtr<IXMLDOMNode> spXMLDOMChildNode; hr = m_favoritesRoot.XMLSave(spXMLDoc, &spXMLDOMChildNode); if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) { CComPtr<IXMLDOMNode> spXDOMNode; hr = spXMLDoc->QueryInterface(IID_IXMLDOMNode, (void **)&spXDOMNode); if (SUCCEEDED(hr)) { CComPtr<IXMLDOMNode> spXDOMNewNode; hr = spXDOMNode->appendChild(spXMLDOMChildNode, &spXDOMNewNode); if (SUCCEEDED(hr)) { //
// save the document to the file
//
CComVariant xmlSource; xmlSource = pStm; hr = spXMLDoc->save(xmlSource); TRACE(L"Save returned with hr = 0x%x\n", hr); } } } } return hr; }
HRESULT CFavoritesNodesHolder::Load(IStream* pStm, CDSComponentData* pComponentData) { //
// create an instance of the XML document
//
CComPtr<IXMLDOMDocument> spXMLDoc;
HRESULT hr = ::CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&spXMLDoc); if (FAILED(hr)) { TRACE(L"CoCreateInstance(CLSID_DOMDocument) failed with hr = 0x%x\n", hr); return hr; }
CComPtr<IUnknown> spUnknown; hr = pStm->QueryInterface(IID_IUnknown, (void**)&spUnknown); if (SUCCEEDED(hr)) { CComVariant xmlSource; xmlSource = spUnknown; VARIANT_BOOL isSuccess; hr = spXMLDoc->load(xmlSource, &isSuccess); if (SUCCEEDED(hr)) { //
// get the root of the document
//
CComPtr<IXMLDOMNode> spXDN; hr = spXMLDoc->QueryInterface(IID_IXMLDOMNode, (void **)&spXDN); if (SUCCEEDED(hr)) { //
// find where the FOLDER tree starts in the document
//
CComPtr<IXMLDOMNode> spXMLFolderRootnode; hr = XML_FindSubtreeNode(spXDN, CFavoritesNode::g_szObjXMLTag, &spXMLFolderRootnode); if (SUCCEEDED(hr)) { if (spXMLFolderRootnode != NULL) { //
// have an XML root folder node, load it into the
// in memory tree
//
hr = m_favoritesRoot.Load(spXMLFolderRootnode, pComponentData); if (FAILED(hr)) { //
// REVIEW_JEFFJON : provide a meaningful error message
//
} } } } } } return hr; }
//
// Starts a recursive search through the saved query tree looking for saved queries that
// contain objects with any of the DNs in the list and invalidates that query
//
void CFavoritesNodesHolder::InvalidateSavedQueriesContainingObjects(CDSComponentData* pComponentData, const CStringList& refDNList) { GetFavoritesRoot()->InvalidateSavedQueriesContainingObjects(pComponentData, refDNList); }
////////////////////////////////////////////////////////////////////////////////////
HRESULT CDummyStream::Read(void *pv, ULONG cb, ULONG *pcbRead) { if (m_pByteArray == NULL || m_nByteCount == 0) { *pcbRead = 0; return S_FALSE; }
if (pv == NULL) { *pcbRead = 0; return STG_E_INVALIDPOINTER; }
ULONG nBytesPossible = m_nByteCount - m_nReadIndex; if (nBytesPossible <= 0) { *pcbRead = 0; return S_FALSE; }
ULONG nBytesToRead = 0; if (nBytesPossible >= cb) { nBytesToRead = cb; } else { nBytesToRead = nBytesPossible; }
memcpy(pv, &(m_pByteArray[m_nReadIndex]), nBytesToRead); *pcbRead = nBytesToRead; m_nReadIndex += nBytesToRead; return S_OK; }
HRESULT CDummyStream::Write(void const *pv, ULONG cb, ULONG *pcbWritten) { BYTE* pNewByteArray = new BYTE[m_nByteCount + cb]; if (pNewByteArray == NULL) { *pcbWritten = 0; return E_OUTOFMEMORY; }
if (m_pByteArray != NULL && m_nByteCount > 0) { memcpy(pNewByteArray, m_pByteArray, m_nByteCount); } memcpy(&(pNewByteArray[m_nByteCount]), pv, cb);
if (m_pByteArray != NULL) { delete[] m_pByteArray; } m_pByteArray = pNewByteArray; *pcbWritten = cb; m_nByteCount = m_nByteCount + cb; return S_OK; }
ULONG CDummyStream::GetStreamData(BYTE** ppByteArray) { if (m_pByteArray == NULL) { *ppByteArray = NULL; return 0; }
*ppByteArray = new BYTE[m_nByteCount]; if (*ppByteArray == NULL) { return 0; }
memcpy(*ppByteArray, m_pByteArray, m_nByteCount); return m_nByteCount; }
HRESULT CDummyStream::SetStreamData(BYTE* pByteArray, ULONG nByteCount) { if (m_pByteArray != NULL) { delete[] m_pByteArray; m_pByteArray = NULL; }
m_pByteArray = pByteArray; m_nByteCount = nByteCount; m_nReadIndex = 0; return S_OK; }
|