540 lines
11 KiB
C++
540 lines
11 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Active Directory 2.5 Sample Code
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1996 - 2000
|
|
//
|
|
// File: ADsContainer.cpp
|
|
//
|
|
// Contents: IADsContainer usage
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include "ADQI.h"
|
|
#include "ads.h"
|
|
#include "ADsContainer.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgIADsContainer dialog
|
|
|
|
|
|
CDlgIADsContainer::CDlgIADsContainer(LPUNKNOWN pUnk, CWnd* pParent /*=NULL*/)
|
|
: CDialog(CDlgIADsContainer::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CDlgIADsContainer)
|
|
m_sFilter = _T("");
|
|
//}}AFX_DATA_INIT
|
|
|
|
///////////////////////////////////////
|
|
// Get the IADsContainer pointer and save it as a member
|
|
/////////////////////////////////////
|
|
HRESULT hr;
|
|
m_pCont = NULL;
|
|
hr = pUnk->QueryInterface( IID_IADsContainer, (void **) &m_pCont );
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
AfxMessageBox(_T("Fatal Error! QI for IADs failed"));
|
|
return;
|
|
}
|
|
pUnk->Release();
|
|
|
|
}
|
|
|
|
CDlgIADsContainer::~CDlgIADsContainer()
|
|
{
|
|
|
|
if ( m_pCont )
|
|
{
|
|
m_pCont->Release();
|
|
}
|
|
}
|
|
|
|
|
|
void CDlgIADsContainer::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CDlgIADsContainer)
|
|
DDX_Control(pDX, IDC_CHILDRENLIST, m_cChildList);
|
|
DDX_Text(pDX, IDC_FILTER, m_sFilter);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgIADsContainer, CDialog)
|
|
//{{AFX_MSG_MAP(CDlgIADsContainer)
|
|
ON_BN_CLICKED(IDC_VIEW, OnView)
|
|
ON_LBN_DBLCLK(IDC_CHILDRENLIST, OnDblClkChildrenList)
|
|
ON_BN_CLICKED(IDC_DELETE, OnDelete)
|
|
ON_BN_CLICKED(IDC_RENAME, OnRename)
|
|
ON_BN_CLICKED(IDC_SET, OnSet)
|
|
ON_BN_CLICKED(IDC_MOVE, OnMove)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgIADsContainer message handlers
|
|
|
|
BOOL CDlgIADsContainer::OnInitDialog()
|
|
{
|
|
|
|
CDialog::OnInitDialog();
|
|
EnumerateChildren();
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////
|
|
// On View demonstrate the IADsContainer::GetObject()
|
|
// This is when the user double click the list box or
|
|
// when the user select an item in the list and click "View"
|
|
/////////////////////////////////////////////////////////////
|
|
void CDlgIADsContainer::OnView()
|
|
{
|
|
ASSERT( m_pCont );
|
|
|
|
|
|
|
|
CString sName;
|
|
CString sClass;
|
|
HRESULT hr;
|
|
|
|
|
|
if ( !GetClassAndName( sClass, sName) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
USES_CONVERSION;
|
|
IDispatch *pDisp;
|
|
IUnknown *pUnk;
|
|
hr = m_pCont->GetObject(T2OLE(sClass), T2OLE(sName), &pDisp );
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
pDisp->QueryInterface( IID_IUnknown, (void**) &pUnk );
|
|
pDisp->Release();
|
|
|
|
|
|
/////////////////////////////////
|
|
// Bring up the dialog box
|
|
////////////////////////////////////
|
|
pUnk->AddRef();
|
|
CDlgIADs dlg( pUnk );
|
|
dlg.DoModal();
|
|
pUnk->Release();
|
|
|
|
}
|
|
|
|
void CDlgIADsContainer::OnDblClkChildrenList()
|
|
{
|
|
OnView();
|
|
}
|
|
|
|
////////////////////////////////
|
|
// IADsContainer::Delete
|
|
/////////////////////////////////
|
|
void CDlgIADsContainer::OnDelete()
|
|
{
|
|
CString sName;
|
|
CString sClass;
|
|
HRESULT hr;
|
|
|
|
|
|
if ( !GetClassAndName( sClass, sName) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
///////////////////////
|
|
// Delete Now
|
|
////////////////////////
|
|
USES_CONVERSION;
|
|
///////////////////////////////////////////////////////////////
|
|
// For example m_pCont->Delete(L"user", L"cn=jsmith");
|
|
////////////////////////////////////////////////////////////////
|
|
hr = m_pCont->Delete( T2OLE( sClass ), T2OLE( sName ) );
|
|
if (!SUCCEEDED(hr) )
|
|
{
|
|
AfxMessageBox( GetErrorMessage(hr));
|
|
return;
|
|
}
|
|
EnumerateChildren();
|
|
}
|
|
|
|
|
|
|
|
BOOL CDlgIADsContainer::GetClassAndName(CString & sClass, CString & sName)
|
|
{
|
|
int idx;
|
|
POSITION pos;
|
|
|
|
|
|
idx = m_cChildList.GetCurSel();
|
|
if ( idx == LB_ERR )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
m_cChildList.GetText( idx, sName );
|
|
pos = m_sClassList.FindIndex( idx );
|
|
if ( pos == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
sClass = m_sClassList.GetAt(pos);
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// EnumerateChildren Function
|
|
// IADsContainer::get_Enum
|
|
// ADsBuildEnumerator
|
|
// ADsEnumerateNext
|
|
// ADsFreeEnumerator
|
|
//
|
|
///////////////////////////////////////////////
|
|
HRESULT CDlgIADsContainer::EnumerateChildren()
|
|
{
|
|
HRESULT hr=S_OK;
|
|
VARIANT var;
|
|
ULONG lFetch;
|
|
|
|
m_cChildList.ResetContent();
|
|
m_sClassList.RemoveAll();
|
|
|
|
//////////////////////////////////////////////////////
|
|
// Use the ADSI Helper APIs to enumerate Children
|
|
////////////////////////////////////////////////////
|
|
IEnumVARIANT *pEnum;
|
|
IDispatch *pDisp;
|
|
IADs *pADs;
|
|
BSTR bstr;
|
|
CString s;
|
|
|
|
VariantInit(&var);
|
|
hr = ADsBuildEnumerator( m_pCont, &pEnum );
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
hr = ADsEnumerateNext( pEnum, 1, &var, &lFetch );
|
|
while( hr == S_OK )
|
|
{
|
|
if ( lFetch == 1 )
|
|
{
|
|
pDisp = V_DISPATCH(&var);
|
|
///////////////////////////
|
|
// Get the Child Name
|
|
/////////////////////////////
|
|
hr = pDisp->QueryInterface( IID_IADs, (void**)&pADs );
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
pADs->get_Name(&bstr);
|
|
s = bstr;
|
|
m_cChildList.AddString( s );
|
|
SysFreeString(bstr);
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// While we're holding the child's object
|
|
// let's get the class info for later use.
|
|
// The class info will be used for getting the actual object
|
|
// via IADsContainer::GetObject) when the user wants to view
|
|
// object in detail.
|
|
// We could have stored the ADsPath as well.
|
|
//////////////////////////////////////////////
|
|
pADs->get_Class(&bstr);
|
|
s = bstr;
|
|
m_sClassList.AddTail( s );
|
|
SysFreeString(bstr);
|
|
|
|
pADs->Release();
|
|
}
|
|
|
|
VariantClear(&var);
|
|
}
|
|
hr = ADsEnumerateNext( pEnum, 1, &var, &lFetch );
|
|
};
|
|
|
|
|
|
|
|
|
|
// Free Enumerator
|
|
ADsFreeEnumerator( pEnum );
|
|
|
|
return S_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////
|
|
// OnRename
|
|
// Demonstrate:
|
|
// IADsContainer::MoveHere
|
|
// IADsContainer::GetObject
|
|
//////////////////////////////////////////////
|
|
void CDlgIADsContainer::OnRename()
|
|
{
|
|
CString sName;
|
|
CString sNewName;
|
|
CString sClass;
|
|
|
|
if ( !GetClassAndName( sClass, sName) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
CRenameDlg dlg( sName );
|
|
|
|
if ( dlg.DoModal() == IDOK )
|
|
{
|
|
//////////////////////////////////////////////////////////////////
|
|
// To Rename we need:
|
|
// 1. A new name ( we'll get it from the rename dialog box )
|
|
// 2. ADsPath of the object to be renamed
|
|
// 3. The container where the child lives.
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
sNewName = dlg.GetName();
|
|
|
|
//////////////////////////////////////////////////
|
|
// Get the child's ADsPath,
|
|
// First we can use IADsContainer::GetObject
|
|
/////////////////////////////////////////////////////
|
|
USES_CONVERSION;
|
|
IDispatch *pDisp;
|
|
IADs *pADs;
|
|
BSTR bstrPath;
|
|
CString sADsPath;
|
|
HRESULT hr;
|
|
|
|
hr = m_pCont->GetObject(T2OLE(sClass), T2OLE(sName), &pDisp );
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
hr = pDisp->QueryInterface( IID_IADs, (void**) &pADs );
|
|
pDisp->Release();
|
|
|
|
////////////////////////////////
|
|
// Now get the child's ADsPath
|
|
//////////////////////////////////
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
pADs->get_ADsPath( &bstrPath );
|
|
pADs->Release();
|
|
|
|
////////////////////////////////////////////////////
|
|
// We have all the information, time to rename //
|
|
////////////////////////////////////////////////////
|
|
hr = m_pCont->MoveHere( bstrPath, T2OLE(sNewName), &pDisp );
|
|
SysFreeString( bstrPath );
|
|
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
AfxMessageBox(GetErrorMessage(hr));
|
|
return;
|
|
}
|
|
pDisp->Release();
|
|
|
|
// Refresh the list
|
|
EnumerateChildren();
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void CDlgIADsContainer::OnMove()
|
|
{
|
|
CMoveDlg dlg;
|
|
if ( dlg.DoModal() == IDOK )
|
|
{
|
|
CString sADsPath;
|
|
IDispatch *pDisp;
|
|
USES_CONVERSION;
|
|
HRESULT hr;
|
|
|
|
sADsPath = dlg.GetObjectPath();
|
|
hr = m_pCont->MoveHere( T2OLE(sADsPath), NULL, &pDisp );
|
|
pDisp->Release();
|
|
RETURN_ON_FAILURE(hr);
|
|
|
|
EnumerateChildren(); // Refresh the list
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void CDlgIADsContainer::OnOK()
|
|
{
|
|
m_sClassList.RemoveAll();
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
///////////////////////////////
|
|
// IADsContainer::put_Filter
|
|
//
|
|
void CDlgIADsContainer::OnSet()
|
|
{
|
|
CStringList sList;
|
|
VARIANT var;
|
|
HRESULT hr;
|
|
|
|
|
|
UpdateData(TRUE);
|
|
VariantInit(&var);
|
|
|
|
// The user may enter many classes to filter 'user,group'
|
|
StringToStringList( m_sFilter, sList );
|
|
StringListToVariant(var, sList );
|
|
|
|
hr = m_pCont->put_Filter( var );
|
|
|
|
VariantClear(&var);
|
|
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
AfxMessageBox(GetErrorMessage(hr));
|
|
return;
|
|
}
|
|
|
|
EnumerateChildren();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRenameDlg dialog
|
|
|
|
|
|
CRenameDlg::CRenameDlg(CString sOldName, CWnd* pParent /*=NULL*/)
|
|
: CDialog(CRenameDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CRenameDlg)
|
|
m_sName = _T("");
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_sOldName = _T("Rename '");
|
|
m_sOldName += sOldName;
|
|
m_sOldName += _T("'");
|
|
m_sNewName = _T("");
|
|
|
|
}
|
|
|
|
|
|
void CRenameDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CRenameDlg)
|
|
DDX_Text(pDX, IDC_NAME, m_sName);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CRenameDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CRenameDlg)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRenameDlg message handlers
|
|
|
|
void CRenameDlg::OnOK()
|
|
{
|
|
UpdateData(TRUE);
|
|
m_sNewName = m_sName;
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
|
|
|
|
BOOL CRenameDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
SetWindowText( m_sOldName );
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMoveDlg dialog
|
|
|
|
|
|
CMoveDlg::CMoveDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CMoveDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CMoveDlg)
|
|
m_sADsPath = _T("");
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
|
|
void CMoveDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CMoveDlg)
|
|
DDX_Text(pDX, IDC_ADSPATH, m_sADsPath);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CMoveDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CMoveDlg)
|
|
ON_EN_CHANGE(IDC_ADSPATH, OnChangeADspath)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMoveDlg message handlers
|
|
|
|
void CMoveDlg::OnOK()
|
|
{
|
|
UpdateData(TRUE); //Retrieve
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
|
|
void CMoveDlg::OnChangeADspath()
|
|
{
|
|
BOOL bEnabled;
|
|
bEnabled = GetDlgItem(IDC_ADSPATH)->GetWindowTextLength() > 0 ? TRUE : FALSE;
|
|
|
|
GetDlgItem(IDOK)->EnableWindow( bEnabled );
|
|
|
|
|
|
}
|