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.
860 lines
24 KiB
860 lines
24 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1998 - 1999
|
|
//
|
|
// File: connection.cpp
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#include <SnapBase.h>
|
|
|
|
#include "resource.h"
|
|
#include "createwiz.h"
|
|
#include "connection.h"
|
|
#include "connectionui.h"
|
|
#include "editorui.h"
|
|
#include "filterui.h"
|
|
#include "credui.h"
|
|
#include "queryui.h"
|
|
|
|
|
|
#ifdef DEBUG_ALLOCATOR
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
#endif
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern LPCWSTR g_lpszRootDSE;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// {5C225203-CFF7-11d2-8801-00C04F72ED31}
|
|
const GUID CADSIEditConnectionNode::NodeTypeGUID =
|
|
{ 0x5c225203, 0xcff7, 0x11d2, { 0x88, 0x1, 0x0, 0xc0, 0x4f, 0x72, 0xed, 0x31 } };
|
|
|
|
|
|
CADSIEditConnectionNode::~CADSIEditConnectionNode()
|
|
{
|
|
RemoveAndDeleteAllQueriesFromList();
|
|
delete m_pConnectData;
|
|
HRESULT hr = m_SchemaCache.Destroy();
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
|
|
bool CADSIEditConnectionNode::IsClassAContainer(CCredentialObject* pCredObject,
|
|
PCWSTR pszClass,
|
|
PCWSTR pszSchemaPath)
|
|
{
|
|
bool bContainer = false;
|
|
|
|
do // false loop
|
|
{
|
|
if (!pCredObject ||
|
|
!pszClass ||
|
|
!pszSchemaPath)
|
|
{
|
|
ASSERT(pCredObject);
|
|
ASSERT(pszClass);
|
|
ASSERT(pszSchemaPath);
|
|
bContainer = false;
|
|
break;
|
|
}
|
|
|
|
CADSIEditClassCacheItemBase* pSchemaCacheItem = m_SchemaCache.FindClassCacheItem(pCredObject,
|
|
pszClass,
|
|
pszSchemaPath);
|
|
if (pSchemaCacheItem)
|
|
{
|
|
bContainer = pSchemaCacheItem->IsContainer();
|
|
}
|
|
|
|
} while (false);
|
|
|
|
return bContainer;
|
|
}
|
|
|
|
BOOL CADSIEditConnectionNode::OnEnumerate(CComponentDataObject* pComponentData, BOOL bAsync)
|
|
{
|
|
|
|
CString path, basePath;
|
|
GetADsObject()->GetPath(path);
|
|
m_pConnectData->GetBasePath(basePath);
|
|
|
|
CComPtr<IDirectoryObject> spDirectoryObject;
|
|
HRESULT hr, hCredResult;
|
|
CADsObject* pObject = new CADsObject();
|
|
if (pObject)
|
|
{
|
|
if (m_pConnectData->IsRootDSE())
|
|
{
|
|
pObject->SetContainer(TRUE);
|
|
pObject->SetName(g_lpszRootDSE);
|
|
pObject->SetPath(path);
|
|
pObject->SetClass(g_lpszRootDSE);
|
|
pObject->SetConnectionNode(this);
|
|
pObject->SetIntermediateNode(TRUE);
|
|
pObject->SetComplete(TRUE);
|
|
CADSIEditContainerNode *pNewContNode = new CADSIEditContainerNode(pObject);
|
|
if (pNewContNode)
|
|
{
|
|
pNewContNode->SetDisplayName(g_lpszRootDSE);
|
|
|
|
VERIFY(AddChildToList(pNewContNode));
|
|
}
|
|
pComponentData->SetDescriptionBarText(this);
|
|
}
|
|
else
|
|
{
|
|
hr = OpenObjectWithCredentials(
|
|
m_pConnectData,
|
|
m_pConnectData->GetCredentialObject()->UseCredentials(),
|
|
path,
|
|
IID_IDirectoryObject,
|
|
(LPVOID*) &spDirectoryObject,
|
|
NULL,
|
|
hCredResult
|
|
);
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
if (SUCCEEDED(hCredResult))
|
|
{
|
|
ADSIEditErrorMessage(hr);
|
|
}
|
|
if (pObject)
|
|
{
|
|
delete pObject;
|
|
pObject = 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
ADS_OBJECT_INFO* pInfo = 0;
|
|
hr = spDirectoryObject->GetObjectInformation(&pInfo);
|
|
if (FAILED(hr))
|
|
{
|
|
ADSIEditErrorMessage(hr);
|
|
if (pObject)
|
|
{
|
|
delete pObject;
|
|
pObject = 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// Name
|
|
pObject->SetName(basePath);
|
|
pObject->SetDN(basePath);
|
|
pObject->SetPath(path);
|
|
|
|
// Make sure the prefix is uppercase
|
|
CString sBasePath(basePath);
|
|
int idx = sBasePath.Find(L'=');
|
|
|
|
if (idx != -1)
|
|
{
|
|
CString sPrefix, sRemaining;
|
|
sPrefix = sBasePath.Left(idx);
|
|
sPrefix.MakeUpper();
|
|
|
|
int iCount = sBasePath.GetLength();
|
|
sRemaining = sBasePath.Right(iCount - idx);
|
|
sBasePath = sPrefix + sRemaining;
|
|
}
|
|
|
|
// Class
|
|
pObject->SetClass(pInfo->pszClassName);
|
|
|
|
pObject->SetIntermediateNode(TRUE);
|
|
pObject->SetContainer(TRUE);
|
|
pObject->SetComplete(TRUE);
|
|
CADSIEditContainerNode *pNewContNode = new CADSIEditContainerNode(pObject);
|
|
if (pNewContNode)
|
|
{
|
|
CString sName;
|
|
pNewContNode->SetDisplayName(sBasePath);
|
|
|
|
GetConnectionData()->SetIDirectoryInterface(spDirectoryObject);
|
|
pNewContNode->GetADsObject()->SetConnectionNode(this);
|
|
VERIFY(AddChildToList(pNewContNode));
|
|
pComponentData->SetDescriptionBarText(this);
|
|
FreeADsMem(pInfo);
|
|
}
|
|
}
|
|
|
|
EnumerateQueries();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CADSIEditConnectionNode::EnumerateQueries()
|
|
{
|
|
POSITION pos = m_queryList.GetHeadPosition();
|
|
while(pos != NULL)
|
|
{
|
|
CADSIEditQueryData* pQueryData = m_queryList.GetNext(pos);
|
|
|
|
CADsObject* pObject = new CADsObject();
|
|
if (pObject)
|
|
{
|
|
|
|
CString sPath, sName;
|
|
pQueryData->GetName(sName);
|
|
pObject->SetName(sName);
|
|
|
|
pQueryData->GetRootPath(sPath);
|
|
pObject->SetPath(sPath);
|
|
|
|
pObject->SetComplete(TRUE);
|
|
pObject->SetConnectionNode(this);
|
|
pObject->SetContainer(TRUE);
|
|
pObject->SetIntermediateNode(TRUE);
|
|
|
|
CADSIEditQueryNode* pNewQuery = new CADSIEditQueryNode(pObject, pQueryData);
|
|
if (pNewQuery)
|
|
{
|
|
|
|
CString sDisplayName;
|
|
pQueryData->GetDisplayName(sDisplayName);
|
|
pNewQuery->SetDisplayName(sDisplayName);
|
|
VERIFY(AddChildToList(pNewQuery));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CADSIEditConnectionNode::HasPropertyPages(DATA_OBJECT_TYPES type,
|
|
BOOL* pbHideVerb,
|
|
CNodeList* pNodeList)
|
|
{
|
|
*pbHideVerb = TRUE; // always hide the verb
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CADSIEditConnectionNode::FindNode(LPCWSTR lpszPath, CList<CTreeNode*, CTreeNode*>& foundNodeList)
|
|
{
|
|
// NOTICE-NTRAID#NTBUG9-561513-2002/03/01-artm Validate lpszPath before using.
|
|
if (!lpszPath)
|
|
{
|
|
// This should never happen.
|
|
ASSERT(false);
|
|
return FALSE;
|
|
}
|
|
|
|
CString szPath;
|
|
GetADsObject()->GetPath(szPath);
|
|
|
|
if (wcscmp(lpszPath, (LPCWSTR)szPath) == 0)
|
|
{
|
|
foundNodeList.AddHead(this);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL bFound = FALSE;
|
|
POSITION pos;
|
|
for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
|
|
{
|
|
CTreeNode* pNode = m_containerChildList.GetNext(pos);
|
|
CADSIEditContainerNode* pContNode = dynamic_cast<CADSIEditContainerNode*>(pNode);
|
|
|
|
if (pContNode != NULL)
|
|
{
|
|
BOOL bTemp;
|
|
bTemp = pContNode->FindNode(lpszPath, foundNodeList);
|
|
if (!bFound)
|
|
{
|
|
bFound = bTemp;
|
|
}
|
|
}
|
|
}
|
|
return bFound;
|
|
}
|
|
|
|
int CADSIEditConnectionNode::GetImageIndex(BOOL bOpenImage)
|
|
{
|
|
int nIndex = 0;
|
|
switch (m_nState)
|
|
{
|
|
case notLoaded:
|
|
nIndex = SERVER_IMAGE_NOT_LOADED;
|
|
break;
|
|
case loading:
|
|
nIndex = SERVER_IMAGE_LOADING;
|
|
break;
|
|
case loaded:
|
|
nIndex = SERVER_IMAGE_LOADED;
|
|
break;
|
|
case unableToLoad:
|
|
nIndex = SERVER_IMAGE_UNABLE_TO_LOAD;
|
|
break;
|
|
case accessDenied:
|
|
nIndex = SERVER_IMAGE_ACCESS_DENIED;
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
return nIndex;
|
|
}
|
|
|
|
void CADSIEditConnectionNode::OnChangeState(CComponentDataObject* pComponentDataObject)
|
|
{
|
|
switch (m_nState)
|
|
{
|
|
case notLoaded:
|
|
case loaded:
|
|
case unableToLoad:
|
|
case accessDenied:
|
|
{
|
|
m_nState = loading;
|
|
m_dwErr = 0;
|
|
}
|
|
break;
|
|
case loading:
|
|
{
|
|
if (m_dwErr == 0)
|
|
m_nState = loaded;
|
|
else if (m_dwErr == ERROR_ACCESS_DENIED)
|
|
m_nState = accessDenied;
|
|
else
|
|
m_nState = unableToLoad;
|
|
}
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
VERIFY(SUCCEEDED(pComponentDataObject->ChangeNode(this, CHANGE_RESULT_ITEM_ICON)));
|
|
VERIFY(SUCCEEDED(pComponentDataObject->UpdateVerbState(this)));
|
|
}
|
|
|
|
|
|
BOOL CADSIEditConnectionNode::OnRefresh(CComponentDataObject* pComponentData,
|
|
CNodeList* pNodeList)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
DWORD dwCount = 0;
|
|
if (pNodeList == NULL)
|
|
{
|
|
dwCount = 1;
|
|
}
|
|
else
|
|
{
|
|
dwCount = pNodeList->GetCount();
|
|
}
|
|
|
|
if (dwCount > 1) // multiple selection
|
|
{
|
|
POSITION pos = pNodeList->GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
CTreeNode* pNode = pNodeList->GetNext(pos);
|
|
ASSERT(pNode != NULL);
|
|
|
|
CNodeList nodeList;
|
|
nodeList.AddTail(pNode);
|
|
|
|
if (!pNode->OnRefresh(pComponentData, &nodeList))
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else if (dwCount == 1) // single selection
|
|
{
|
|
if(CContainerNode::OnRefresh(pComponentData, pNodeList))
|
|
{
|
|
CADSIEditContainerNode * pNextNode;
|
|
POSITION pos = m_containerChildList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
pNextNode = dynamic_cast<CADSIEditContainerNode*>(m_containerChildList.GetNext(pos));
|
|
ASSERT(pNextNode != NULL);
|
|
|
|
CNodeList nodeList;
|
|
nodeList.AddTail(pNextNode);
|
|
|
|
pNextNode->OnRefresh(pComponentData, &nodeList);
|
|
}
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
HRESULT CADSIEditConnectionNode::OnCommand(long nCommandID,
|
|
DATA_OBJECT_TYPES type,
|
|
CComponentDataObject* pComponentData,
|
|
CNodeList* pNodeList)
|
|
{
|
|
ASSERT (pNodeList->GetCount() == 1); // should only be a single selection
|
|
|
|
switch (nCommandID)
|
|
{
|
|
case IDM_SETTINGS_CONNECTION :
|
|
OnSettings(pComponentData);
|
|
break;
|
|
case IDM_REMOVE_CONNECTION :
|
|
OnRemove(pComponentData);
|
|
break;
|
|
case IDM_NEW_OBJECT :
|
|
OnCreate(pComponentData);
|
|
break;
|
|
case IDM_FILTER :
|
|
OnFilter(pComponentData);
|
|
break;
|
|
case IDM_UPDATE_SCHEMA :
|
|
OnUpdateSchema();
|
|
break;
|
|
case IDM_NEW_QUERY :
|
|
OnNewQuery(pComponentData);
|
|
break;
|
|
default:
|
|
ASSERT(FALSE); // Unknown command!
|
|
return E_FAIL;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
void CADSIEditConnectionNode::OnUpdateSchema()
|
|
{
|
|
// Force an update of the schema cache
|
|
CString szRootDSE;
|
|
CConnectionData* pConnectData = GetConnectionData();
|
|
|
|
CComPtr<IADs> spDirObject;
|
|
HRESULT hr = GetRootDSEObject(pConnectData, &spDirObject);
|
|
if (FAILED(hr))
|
|
{
|
|
ADSIEditErrorMessage(hr);
|
|
return;
|
|
}
|
|
|
|
VARIANT var;
|
|
var.vt = VT_I4;
|
|
var.lVal = 1;
|
|
hr = spDirObject->Put(CComBSTR(L"updateSchemaNow"), var);
|
|
if (FAILED(hr))
|
|
{
|
|
ADSIEditErrorMessage(hr);
|
|
return;
|
|
}
|
|
|
|
CString szSchema;
|
|
pConnectData->GetAbstractSchemaPath(szSchema);
|
|
szSchema = szSchema.Left(szSchema.GetLength()- 1);
|
|
CComPtr<IADs> spSchemaObject;
|
|
HRESULT hCredResult;
|
|
hr = OpenObjectWithCredentials(
|
|
pConnectData,
|
|
pConnectData->GetCredentialObject()->UseCredentials(),
|
|
szSchema,
|
|
IID_IADs,
|
|
(LPVOID*) &spSchemaObject,
|
|
NULL,
|
|
hCredResult
|
|
);
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
if (SUCCEEDED(hCredResult))
|
|
{
|
|
ADSIEditErrorMessage(hr);
|
|
}
|
|
return;
|
|
}
|
|
|
|
hr = spSchemaObject->GetInfo();
|
|
if (FAILED(hr))
|
|
{
|
|
ADSIEditErrorMessage(hr);
|
|
}
|
|
|
|
//
|
|
// Now clear the schema cache
|
|
//
|
|
m_SchemaCache.Clear();
|
|
|
|
ADSIEditMessageBox(IDS_SCHEMA_UPDATE_SUCCESSFUL, MB_OK);
|
|
}
|
|
|
|
void CADSIEditConnectionNode::OnNewQuery(CComponentDataObject* pComponentData)
|
|
{
|
|
CThemeContextActivator activator;
|
|
|
|
CString sConnectPath;
|
|
GetADsObject()->GetPath(sConnectPath);
|
|
CConnectionData* pConnectData = GetConnectionData();
|
|
CCredentialObject* pCredObject = pConnectData->GetCredentialObject();
|
|
CString szServer;
|
|
pConnectData->GetDomainServer(szServer);
|
|
|
|
CADSIEditQueryDialog queryDialog(szServer, sConnectPath, pCredObject);
|
|
if (queryDialog.DoModal() == IDOK)
|
|
{
|
|
BOOL bOneLevel;
|
|
CString sQueryString, sName, sPath;
|
|
queryDialog.GetResults(sName, sQueryString, sPath, &bOneLevel);
|
|
|
|
CADSIEditConnectionNode* pConnectNode = GetADsObject()->GetConnectionNode();
|
|
|
|
CADsObject* pObject = new CADsObject();
|
|
if (pObject)
|
|
{
|
|
CADSIEditQueryData *pQueryData = new CADSIEditQueryData();
|
|
if (pQueryData)
|
|
{
|
|
|
|
// Name
|
|
pObject->SetName(sName);
|
|
pQueryData->SetName(sName);
|
|
|
|
// Set the root path of the query string
|
|
pObject->SetPath(sPath);
|
|
pQueryData->SetRootPath(sPath);
|
|
|
|
// Set the query string
|
|
pQueryData->SetFilter(sQueryString);
|
|
|
|
pObject->SetIntermediateNode(TRUE);
|
|
pObject->SetContainer(TRUE);
|
|
pObject->SetComplete(TRUE);
|
|
pObject->SetConnectionNode(pConnectNode);
|
|
|
|
// Set the scope of the query
|
|
ADS_SCOPEENUM scope;
|
|
scope = (bOneLevel) ? ADS_SCOPE_ONELEVEL : ADS_SCOPE_SUBTREE;
|
|
pQueryData->SetScope(scope);
|
|
|
|
// Create the query node with imbedded objects
|
|
CADSIEditQueryNode* pNewQueryNode = new CADSIEditQueryNode(pObject, pQueryData);
|
|
if (pNewQueryNode)
|
|
{
|
|
|
|
//
|
|
// Set the display name
|
|
//
|
|
CString sDisplayName;
|
|
pQueryData->GetDisplayName(sDisplayName);
|
|
pNewQueryNode->SetDisplayName(sDisplayName);
|
|
|
|
//
|
|
// Add to connection node's list of queries
|
|
//
|
|
pConnectNode->AddQueryToList(pQueryData);
|
|
|
|
if (pConnectNode->IsExpanded())
|
|
{
|
|
VERIFY(pConnectNode->AddChildToListAndUI(pNewQueryNode, pComponentData));
|
|
pComponentData->SetDescriptionBarText(this);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
delete pObject;
|
|
pObject = 0;
|
|
|
|
delete pQueryData;
|
|
pQueryData = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
delete pObject;
|
|
pObject = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CADSIEditConnectionNode::OnFilter(CComponentDataObject* pComponentData)
|
|
{
|
|
CThemeContextActivator activator;
|
|
CADSIFilterDialog filterDialog(m_pConnectData);
|
|
if (filterDialog.DoModal() == IDOK)
|
|
{
|
|
CNodeList nodeList;
|
|
nodeList.AddTail(this);
|
|
OnRefresh(pComponentData, &nodeList);
|
|
}
|
|
}
|
|
|
|
void CADSIEditConnectionNode::OnCreate(CComponentDataObject* pComponentData)
|
|
{
|
|
CThemeContextActivator activator;
|
|
CCreatePageHolder* pHolder = new CCreatePageHolder(GetContainer(), this, pComponentData);
|
|
ASSERT(pHolder != NULL);
|
|
pHolder->SetSheetTitle(IDS_PROP_CONTAINER_TITLE, this);
|
|
pHolder->DoModalWizard();
|
|
}
|
|
|
|
BOOL CADSIEditConnectionNode::OnSetDeleteVerbState(DATA_OBJECT_TYPES type,
|
|
BOOL* pbHideVerb,
|
|
CNodeList* pNodeList)
|
|
{
|
|
*pbHideVerb = TRUE; // always hid the verb
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CADSIEditConnectionNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem,
|
|
long *pInsertionAllowed)
|
|
{
|
|
if (IsThreadLocked() || IsSheetLocked())
|
|
{
|
|
pContextMenuItem->fFlags = MF_GRAYED;
|
|
return TRUE;
|
|
}
|
|
|
|
if (GetConnectionData()->GetFilter()->InUse())
|
|
{
|
|
pContextMenuItem->fFlags = MF_CHECKED;
|
|
return TRUE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT CADSIEditConnectionNode::OnRename(CComponentDataObject* pComponentData,
|
|
LPWSTR lpszNewName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bLocked = IsThreadLocked();
|
|
ASSERT(!bLocked); // cannot do refresh on locked node, the UI should prevent this
|
|
if (bLocked)
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
if (!lpszNewName)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
CString szDisplayExtra;
|
|
m_pConnectData->GetDomainServer(szDisplayExtra);
|
|
szDisplayExtra = L" [" + szDisplayExtra + L"]";
|
|
|
|
m_pConnectData->SetName(lpszNewName);
|
|
SetDisplayName(lpszNewName + szDisplayExtra);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
void CADSIEditConnectionNode::OnRemove(CComponentDataObject* pComponentData)
|
|
{
|
|
CString sLoadString, sCaption;
|
|
|
|
// NOTICE-2002/03/01-artm CString can throw out of memory exception,
|
|
// but that needs to be handled at a higher level so don't worry about
|
|
// it here.
|
|
if (sLoadString.LoadString(IDS_MSG_REMOVE_CONNECTION))
|
|
{
|
|
sCaption.Format((LPWSTR)(LPCWSTR)sLoadString, GetDisplayName());
|
|
}
|
|
|
|
if (ADSIEditMessageBox(sCaption, MB_YESNO | MB_DEFBUTTON2) == IDYES)
|
|
{
|
|
if (IsSheetLocked())
|
|
{
|
|
if (!CanCloseSheets())
|
|
return;
|
|
pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
|
|
}
|
|
ASSERT(!IsSheetLocked());
|
|
|
|
// now remove from the UI
|
|
DeleteHelper(pComponentData);
|
|
pComponentData->SetDescriptionBarText(GetContainer());
|
|
pComponentData->UpdateResultPaneView(GetContainer());
|
|
|
|
delete this; // gone
|
|
}
|
|
}
|
|
|
|
void CADSIEditConnectionNode::OnSettings(CComponentDataObject* pComponentData)
|
|
{
|
|
CWaitCursor cursor;
|
|
CThemeContextActivator activator;
|
|
CComponentDataObject* pComponentDataObject =
|
|
((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
|
|
ASSERT(pComponentDataObject != NULL);
|
|
|
|
CContainerNode* pContNode = dynamic_cast<CContainerNode*>(GetContainer());
|
|
ASSERT(pContNode != NULL);
|
|
|
|
CADSIEditConnectDialog ConnectDialog(pContNode,
|
|
this,
|
|
pComponentDataObject,
|
|
m_pConnectData);
|
|
if (ConnectDialog.DoModal() == IDOK)
|
|
{
|
|
cursor.Restore();
|
|
if (HasQueries())
|
|
{
|
|
if (AfxMessageBox(IDS_MSG_EXISTING_QUERIES, MB_YESNO) == IDYES)
|
|
{
|
|
RemoveAllQueriesFromList();
|
|
}
|
|
}
|
|
CNodeList nodeList;
|
|
nodeList.AddTail(this);
|
|
OnRefresh(pComponentData, &nodeList);
|
|
}
|
|
|
|
}
|
|
|
|
BOOL CADSIEditConnectionNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES type,
|
|
BOOL* pbHide,
|
|
CNodeList* pNodeList)
|
|
{
|
|
ASSERT(pNodeList->GetCount() == 1);
|
|
|
|
*pbHide = FALSE;
|
|
return !IsThreadLocked();
|
|
}
|
|
|
|
|
|
HRESULT CADSIEditConnectionNode::CreateFromStream(IStream* pStm, CADSIEditConnectionNode** ppConnectionNode)
|
|
{
|
|
WCHAR szBuffer[MAX_CONNECT_NAME_LENGTH + 1];
|
|
ULONG nLen; // WCHAR counting NULL
|
|
ULONG cbRead;
|
|
|
|
VERIFY(SUCCEEDED(pStm->Read((void*)&nLen,sizeof(UINT), &cbRead)));
|
|
ASSERT(cbRead == sizeof(UINT));
|
|
VERIFY(SUCCEEDED(pStm->Read((void*)szBuffer,sizeof(WCHAR)*nLen, &cbRead)));
|
|
ASSERT(cbRead == sizeof(WCHAR)*nLen);
|
|
|
|
CConnectionData* pConnect = CConnectionData::Load(pStm);
|
|
*ppConnectionNode = new CADSIEditConnectionNode(pConnect);
|
|
ASSERT(*ppConnectionNode != NULL);
|
|
|
|
CString szDisplayExtra, szDisplay;
|
|
pConnect->GetDomainServer(szDisplayExtra);
|
|
szDisplay = CString(szBuffer) + L" [" + szDisplayExtra + L"]";
|
|
(*ppConnectionNode)->SetDisplayName(szDisplay);
|
|
(*ppConnectionNode)->SetConnectionNode(*ppConnectionNode);
|
|
(*ppConnectionNode)->LoadQueryListFromStream(pStm);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CADSIEditConnectionNode::SaveToStream(IStream* pStm)
|
|
{
|
|
// for each connection name, write # of chars+NULL, and then the name
|
|
ULONG cbWrite;
|
|
CString szName;
|
|
m_pConnectData->GetName(szName);
|
|
SaveStringToStream(pStm, szName);
|
|
|
|
m_pConnectData->Save(pStm);
|
|
SaveQueryListToStream(pStm);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
void CADSIEditConnectionNode::LoadQueryListFromStream(IStream* pStm)
|
|
{
|
|
ULONG cbRead;
|
|
int iCount;
|
|
|
|
VERIFY(SUCCEEDED(pStm->Read((void*)&iCount,sizeof(int), &cbRead)));
|
|
ASSERT(cbRead == sizeof(int));
|
|
|
|
for (int idx = 0; idx < iCount; idx++)
|
|
{
|
|
CADSIEditQueryData* pQueryData = new CADSIEditQueryData();
|
|
|
|
CString sName, sQueryString, sPath;
|
|
// FUTURE-2002/03/01-artm Function LoadStringFromStream() should return
|
|
// success/error code and this function should call it.
|
|
// Who knows what kind of stream we've been given and how it could
|
|
// fail????
|
|
LoadStringFromStream(pStm, sName);
|
|
LoadStringFromStream(pStm, sQueryString);
|
|
LoadStringFromStream(pStm, sPath);
|
|
|
|
pQueryData->SetName(sName);
|
|
pQueryData->SetFilter(sQueryString);
|
|
CString sRootPath;
|
|
BuildQueryPath(sPath, sRootPath);
|
|
pQueryData->SetRootPath(sRootPath);
|
|
|
|
ADS_SCOPEENUM scope;
|
|
VERIFY(SUCCEEDED(pStm->Read((void*)&scope, sizeof(ADS_SCOPEENUM), &cbRead)));
|
|
ASSERT(cbRead == sizeof(ADS_SCOPEENUM));
|
|
|
|
pQueryData->SetScope(scope);
|
|
|
|
AddQueryToList(pQueryData);
|
|
}
|
|
}
|
|
|
|
void CADSIEditConnectionNode::BuildQueryPath(const CString& sPath, CString& sRootPath)
|
|
{
|
|
CConnectionData* pConnectData = GetConnectionData();
|
|
|
|
CString sServer, sLDAP, sPort, sTemp;
|
|
pConnectData->GetDomainServer(sServer);
|
|
pConnectData->GetLDAP(sLDAP);
|
|
pConnectData->GetPort(sPort);
|
|
|
|
if (sServer != _T(""))
|
|
{
|
|
sTemp = sLDAP + sServer;
|
|
if (sPort != _T(""))
|
|
{
|
|
sTemp = sTemp + _T(":") + sPort + _T("/");
|
|
}
|
|
else
|
|
{
|
|
sTemp = sTemp + _T("/");
|
|
}
|
|
sRootPath = sTemp + sPath;
|
|
}
|
|
else
|
|
{
|
|
sRootPath = sLDAP + sPath;
|
|
}
|
|
|
|
}
|
|
|
|
void CADSIEditConnectionNode::SaveQueryListToStream(IStream* pStm)
|
|
{
|
|
ULONG cbWrite;
|
|
int iCount = m_queryList.GetCount();
|
|
VERIFY(SUCCEEDED(pStm->Write((void*)&iCount, sizeof(int),&cbWrite)));
|
|
ASSERT(cbWrite == sizeof(int));
|
|
|
|
POSITION pos = m_queryList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
CADSIEditQueryData* pQueryData = m_queryList.GetNext(pos);
|
|
ASSERT(pQueryData != NULL);
|
|
|
|
ADS_SCOPEENUM scope;
|
|
CString sName, sQueryString, sRootPath;
|
|
pQueryData->GetName(sName);
|
|
pQueryData->GetFilter(sQueryString);
|
|
pQueryData->GetDisplayPath(sRootPath);
|
|
scope = pQueryData->GetScope();
|
|
|
|
// save the query info to stream
|
|
SaveStringToStream(pStm, sName);
|
|
SaveStringToStream(pStm, sQueryString);
|
|
SaveStringToStream(pStm, sRootPath);
|
|
|
|
// Save the scope
|
|
VERIFY(SUCCEEDED(pStm->Write((void*)&scope, sizeof(ADS_SCOPEENUM),&cbWrite)));
|
|
ASSERT(cbWrite == sizeof(ADS_SCOPEENUM));
|
|
}
|
|
}
|