home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- //
- // Microsoft Active Directory 2.5 Sample Code
- //
- // Copyright (C) Microsoft Corporation, 1996 - 1999
- //
- // File: ADs.cpp
- //
- // Contents: IADs and IADsPathname 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
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CDlgIADs dialog
-
- #define STRING_SEPARATOR _T("----------")
-
- extern ADSIIF adsiIfs[];
-
- CDlgIADs::CDlgIADs(LPUNKNOWN pUnk, CWnd* pParent /*=NULL*/)
- : CDialog(CDlgIADs::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CDlgIADs)
- m_sADsPath = _T("");
- m_sClass = _T("");
- m_sName = _T("");
- m_sParent = _T("");
- m_sSchema = _T("");
- m_sGUID = _T("");
- //}}AFX_DATA_INIT
-
- ///////////////////////////////////////
- // Get the IADs pointer and save it
- /////////////////////////////////////
- HRESULT hr;
- m_pADs = NULL;
- hr = pUnk->QueryInterface( IID_IADs, (void **) &m_pADs );
- if ( !SUCCEEDED(hr) )
- {
- AfxMessageBox(_T("Fatal Error! QI for IADs failed"));
- return;
- }
- pUnk->Release();
-
-
- }
-
-
- CDlgIADs::~CDlgIADs()
- {
- if ( m_pADs )
- {
- m_pADs->Release();
- }
- }
-
- void CDlgIADs::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CDlgIADs)
- DDX_Control(pDX, IDC_ATTRVALUE, m_cValueList);
- DDX_Control(pDX, IDC_ATTRLIST, m_cAttrList);
- DDX_Text(pDX, IDC_ADSPATH, m_sADsPath);
- DDX_Text(pDX, IDC_CLASS, m_sClass);
- DDX_Text(pDX, IDC_NAME, m_sName);
- DDX_Text(pDX, IDC_PARENT, m_sParent);
- DDX_Text(pDX, IDC_SCHEMA, m_sSchema);
- DDX_Text(pDX, IDC_GUID, m_sGUID);
- //}}AFX_DATA_MAP
- }
-
-
- BEGIN_MESSAGE_MAP(CDlgIADs, CDialog)
- //{{AFX_MSG_MAP(CDlgIADs)
- ON_BN_CLICKED(IDC_GET, OnGet)
- ON_BN_CLICKED(IDC_GETEX, OnGetEx)
- ON_BN_CLICKED(IDC_GETINFO, OnGetInfo)
- ON_BN_CLICKED(IDC_SETINFO, OnSetInfo)
- ON_BN_CLICKED(IDC_GETINFOEX, OnGetInfoex)
- ON_BN_CLICKED(IDC_PUT, OnPut)
- ON_BN_CLICKED(IDC_PUTEX, OnPutEx)
- ON_BN_CLICKED(IDC_PARENTPATH, OnParentPath)
- ON_BN_CLICKED(IDC_SCHEMAPATH, OnSchemaPath)
- ON_BN_CLICKED(IDC_BINDGUID, OnBindGuid)
- ON_CBN_SELCHANGE(IDC_ATTRLIST, OnSelChangeAttrList)
- ON_LBN_DBLCLK(IDC_ATTRVALUE, OnDblClkAttrValue)
- ON_WM_HSCROLL()
- ON_BN_CLICKED(IDC_COPY, OnCopy)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CDlgIADs message handler
-
-
- BOOL CDlgIADs::OnInitDialog()
- {
- HRESULT hr;
- VARIANT var;
- BSTR bstr;
- CStringList sList;
-
- CDialog::OnInitDialog();
-
-
- ASSERT( m_pADs );
- VariantInit(&var);
- //////////////////////////
- // Get the IADs Properties
- /////////////////////////
-
- // Path
- hr = m_pADs->get_ADsPath( &bstr );
- if ( SUCCEEDED(hr) )
- {
- m_sADsPath = bstr;
- SysFreeString(bstr);
- }
-
- // Name
- hr = m_pADs->get_Name( &bstr );
- if ( SUCCEEDED(hr) )
- {
- m_sName = bstr;
- SysFreeString(bstr);
- }
-
- // Parent
- hr = m_pADs->get_Parent( &bstr );
- if ( SUCCEEDED(hr) )
- {
- m_sParent = bstr;
- SysFreeString(bstr);
- }
-
- // Schema
- hr = m_pADs->get_Schema( &bstr );
- if ( SUCCEEDED(hr) )
- {
- m_sSchema = bstr;
- SysFreeString(bstr);
- }
-
- // Class
- hr = m_pADs->get_Class( &bstr );
- if ( SUCCEEDED(hr) )
- {
- m_sClass = bstr;
- SysFreeString(bstr);
- }
-
- // GUID
- hr = m_pADs->get_GUID( &bstr );
- if ( SUCCEEDED(hr) )
- {
- m_sGUID = bstr;
- SysFreeString(bstr);
- }
-
- if ( m_sGUID.GetLength() == 0 )
- {
- GetDlgItem(IDC_BINDGUID)->EnableWindow( FALSE );
- }
-
- ///////////////////////////////////////////////////////////////
- //
- // Enumerate all attributes in this object
- // Steps:
- // 1. Get the object's schema information
- // 2. Bind to that schema
- // 3. QI for Class
- // 4. Enumerate the Mandatory and Optional Attributes
- //
- /////////////////////////////////////////////////////////////
- USES_CONVERSION;
- IADsClass *pClass;
- hr = App->ADsOpenObject(T2OLE(m_sSchema), IID_IADsClass, (void**) &pClass );
- if ( SUCCEEDED(hr) )
- {
- m_cAttrList.ResetContent(); // Clear the list box content.
-
- // Mandatory
- pClass->get_MandatoryProperties( &var );
- VariantToStringList( var, sList );
- PopulateComboBoxFromStringList( m_cAttrList, sList );
- VariantClear(&var);
-
- // A separator to seperate mandatory and optional attributes
- m_cAttrList.AddString( STRING_SEPARATOR);
-
- // Optional
- pClass->get_OptionalProperties( &var );
- VariantToStringList( var, sList );
- PopulateComboBoxFromStringList( m_cAttrList, sList );
- VariantClear(&var);
- }
-
-
- UpdateData(FALSE);
-
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
- }
-
- void CDlgIADs::OnGet()
- {
- CString sAttr;
- CStringList sList;
- VARIANT var;
- HRESULT hr;
- m_cAttrList.GetLBText( m_cAttrList.GetCurSel(), sAttr );
-
-
-
- if ( sAttr == STRING_SEPARATOR )
- {
- MessageBeep(0);
- return;
- }
-
- m_cValueList.ResetContent();
-
-
- USES_CONVERSION;
- /////////////////////////////
- // Get the attribute
- ////////////////////////////////
- hr = m_pADs->Get( T2OLE(sAttr), &var);
-
-
- ////////////////////////////////
- // UI: populate the listbox
- ////////////////////////////////
- if ( SUCCEEDED(hr) )
- {
-
- hr = VariantToStringList( var, sList );
-
- if ( SUCCEEDED(hr) )
- {
- PopulateListBoxFromStringList( m_cValueList, sList );
- }
-
-
- VariantClear(&var);
- }
- else
- {
- CString s;
- s = GetErrorMessage( hr );
- m_cValueList.AddString( s );
- }
-
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // IADs::GetEx is similar to Get. The GetEx always return an array of variant
- // regardless if the attribute is single or multi value.
- // This is useful for VB/VBS environment.
- ////////////////////////////////////////////////////////////////////////////////
- void CDlgIADs::OnGetEx()
- {
-
- CString sAttr;
- CStringList sList;
- VARIANT var;
- HRESULT hr;
- m_cAttrList.GetLBText( m_cAttrList.GetCurSel(), sAttr );
- m_cValueList.ResetContent();
-
- USES_CONVERSION;
- /////////////////////////////
- // GetEx the attribute
- ////////////////////////////////
- hr = m_pADs->GetEx( T2OLE(sAttr), &var);
-
-
- ////////////////////////////////
- // UI: populate the listbox
- ////////////////////////////////
- if ( SUCCEEDED(hr) )
- {
-
- hr = VariantToStringList( var, sList );
-
- if ( SUCCEEDED(hr) )
- {
- PopulateListBoxFromStringList( m_cValueList, sList );
- }
-
- VariantClear(&var);
- }
-
-
- }
-
- //////////////////////////////////////////////////////
- // GetInfo is to refresh the cache
- // All attributes in this object will be sent
- // to the client and be cached again
- //
- /////////////////////////////////////////////////////////
- void CDlgIADs::OnGetInfo()
- {
- HRESULT hr;
- ASSERT(m_pADs);
-
- hr = m_pADs->GetInfo();
- if (!SUCCEEDED(hr) )
- {
- AfxMessageBox(GetErrorMessage(hr));
- return;
- }
- else
- {
- AfxMessageBox(_T("Succeed"));
- }
- }
-
- /////////////////////////////////////////////////////////////
- // SetInfo will commit any changes since the last SetInfo //
- // //
- //////////////////////////////////////////////////////////////
- void CDlgIADs::OnSetInfo()
- {
- HRESULT hr;
- ASSERT(m_pADs);
-
- hr = m_pADs->GetInfo();
- if (!SUCCEEDED(hr) )
- {
- AfxMessageBox(GetErrorMessage(hr));
- return;
- }
- else
- {
- AfxMessageBox(_T("Succeed"));
- }
-
-
- }
-
- //////////////////////////////////////////////////
- // Similar to GetInfo. Unlike GetInfo, GetInfoEx
- // only brings the specified attributes to the client
- // This is for an optimization purpose.
- ///////////////////////////////////////////////////
- void CDlgIADs::OnGetInfoex()
- {
- CGetInfoExDlg dlg;
- VARIANT var;
- HRESULT hr;
-
- if ( dlg.DoModal() == IDOK )
- {
- CString s;
- CString sAttr;
- CStringList sList;
- int idx;
-
- s = dlg.GetAttribute();
- //////////////////////////////////////////
- // Parse and put them in the string list
- //////////////////////////////////////////
- idx = s.Find(_T(","));
- while( idx != -1 )
- {
- sAttr = s.Mid(0, idx );
- sAttr.TrimLeft(); sAttr.TrimRight();
- sList.AddTail( sAttr );
- s = s.Mid( idx + 1 );
- idx = s.Find(_T(","));
- }
- s.TrimLeft(); s.TrimRight();
- sList.AddTail( s );
-
- /////////////////////////////////
- // Convert stringlist to variant
- ////////////////////////////////
- hr = StringListToVariant( var, sList);
- if ( SUCCEEDED(hr) )
- {
- ///////////////////////////////
- // Now do the real work!!
- ///////////////////////////////
- hr = m_pADs->GetInfoEx( var, 0 );
- if (!SUCCEEDED(hr) )
- {
- AfxMessageBox(GetErrorMessage(hr));
- }
- VariantClear(&var);
- }
-
-
-
- }
-
- }
-
-
- void CDlgIADs::OnPut()
- {
- // TODO: Add your control notification handler code here
-
- }
-
- void CDlgIADs::OnPutEx()
- {
- // TODO: Add your control notification handler code here
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CGetInfoExDlg dialog
-
-
- CGetInfoExDlg::CGetInfoExDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CGetInfoExDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CGetInfoExDlg)
- m_sAttrText = _T("");
- //}}AFX_DATA_INIT
- }
-
-
- void CGetInfoExDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CGetInfoExDlg)
- DDX_Text(pDX, IDC_ATTR, m_sAttrText);
- //}}AFX_DATA_MAP
- }
-
-
- BEGIN_MESSAGE_MAP(CGetInfoExDlg, CDialog)
- //{{AFX_MSG_MAP(CGetInfoExDlg)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CGetInfoExDlg message handlers
-
- void CGetInfoExDlg::OnOK()
- {
- UpdateData(TRUE);
- m_sAttr = m_sAttrText;
- CDialog::OnOK();
- }
-
-
-
-
- void CDlgIADs::OnParentPath()
- {
- HRESULT hr;
- UpdateData(TRUE); // Retrieve from UI
-
-
- USES_CONVERSION;
- IUnknown *pUnk;
- CWaitCursor wait;
-
- hr = App->ADsOpenObject( T2OLE( m_sParent ), IID_IUnknown, (void**) &pUnk );
-
- /////////////////////////////////////
- // Bring up the IADsContainer Dialog
- ///////////////////////////////////////
- if ( SUCCEEDED(hr) )
- {
- pUnk->AddRef();
- CDlgIADsContainer dlg( pUnk, this );
- dlg.DoModal();
-
- pUnk->Release();
- }
- else
- {
- AfxMessageBox( GetErrorMessage(hr) );
- }
-
-
- }
-
-
- void CDlgIADs::OnSchemaPath()
- {
- HRESULT hr;
- UpdateData(TRUE); // Retrieve from UI
-
-
- USES_CONVERSION;
- IUnknown *pUnk;
- IADs *pADs;
- BSTR bstr;
- CWaitCursor wait;
-
-
- hr = App->ADsOpenObject( T2OLE( m_sSchema ), IID_IADs, (void**) &pADs );
- RETURN_ON_FAILURE(hr);
-
-
- hr = pADs->get_Parent( &bstr );
- pADs->Release();
-
- RETURN_ON_FAILURE(hr);
-
- hr = App->ADsOpenObject( bstr, IID_IUnknown, (void**) &pUnk );
- SysFreeString( bstr );
-
- /////////////////////////////////////
- // Bring up the IADsContainer Dialog
- ///////////////////////////////////////
- if ( SUCCEEDED(hr) )
- {
- pUnk->AddRef();
- CDlgIADsContainer dlg( pUnk, this );
- dlg.DoModal();
-
- pUnk->Release();
- }
-
-
-
- }
-
- //////////////////////////////////////////////////////
- //
- // GUID Binding: Only works with Active Directory
- //
- ////////////////////////////////////////////////////////
- void CDlgIADs::OnBindGuid()
- {
- CWaitCursor wait;
- CComBSTR bstrPath;
- IUnknown *pUnk = NULL;
- HRESULT hr;
- UpdateData(TRUE); // Retrieve from UI
-
-
-
- CComPtr<IADsPathname> pPathname=NULL;
- BSTR bstr;
- BSTR bstrProvider;
- BSTR bstrServer;
-
-
- hr = CoCreateInstance( CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (void**) &pPathname );
-
- RETURN_ON_FAILURE(hr);
-
-
- hr = m_pADs->get_ADsPath(&bstr);
-
- RETURN_ON_FAILURE(hr);
-
-
- /////////////////////////////////////////////////
- // Usage: PathName to find out the provider
- ///////////////////////////////////////////////////
- hr = pPathname->Set( bstr, ADS_SETTYPE_FULL );
- SysFreeString( bstr );
- RETURN_ON_FAILURE(hr);
-
- hr = pPathname->Retrieve(ADS_FORMAT_PROVIDER, &bstrProvider );
- RETURN_ON_FAILURE(hr);
-
- if ( wcscmp( bstrProvider, L"LDAP") != 0 )
- {
- AfxMessageBox(_T("Only LDAP: (Active Directory Provider) knows about <GUID=xxxx> syntax"));
- SysFreeString( bstrProvider );
- return;
- }
-
- /////////////////////////////////////////////////
- // Usage: PathName to find out the server
- ///////////////////////////////////////////////////
- hr = pPathname->Retrieve(ADS_FORMAT_SERVER, &bstrServer );
-
- if ( hr == E_ADS_BAD_PATHNAME ) // Serverless binding ( can work only from DS aware client )
- {
- bstrServer = SysAllocString(L"");
- }
-
-
-
-
-
- ///////////////////////////////////////////////
- // Now build the LDAP://server/<GUID=xxx
- //////////////////////////////////////////////
-
-
- bstrPath = bstrProvider;
- bstrPath.Append(_T("://"));
- if ( wcslen( bstrServer ) ) // Server based binding ?
- {
- bstrPath.AppendBSTR( bstrServer );
- bstrPath.Append(_T("/"));
- SysFreeString( bstrServer );
- }
- bstrPath.Append(_T("<GUID="));
- bstrPath.Append( m_sGUID );
- bstrPath.Append(_T(">") );
-
- // we don't need these bstrs anymore
- SysFreeString( bstrProvider );
-
-
-
- // Now Bind using GUID
-
- hr = App->ADsOpenObject( bstrPath, IID_IUnknown, (void**) &pUnk );
-
- /////////////////////////////////////
- // Bring up the IADs Dialog
- ///////////////////////////////////////
- if ( SUCCEEDED(hr) )
- {
- pUnk->AddRef();
- CDlgIADs dlg( pUnk, this );
- dlg.DoModal();
- pUnk->Release();
- }
- else
- {
- AfxMessageBox( GetErrorMessage(hr) );
- return;
- }
-
-
- }
-
- void CDlgIADs::OnSelChangeAttrList()
- {
- OnGet();
- }
-
- void CDlgIADs::OnDblClkAttrValue()
- {
- int idx;
- HRESULT hr;
-
- idx = m_cValueList.GetCurSel();
- if ( idx == LB_ERR )
- {
- return;
- }
-
- // If someone click this it may be an interface that has the UI.
- // The interface value start with --> in the UI
- CString s;
- int xx;
- CString sArrow = ARROW_SYMBOL;
- m_cValueList.GetText( idx, s );
-
- if ( s.Find(sArrow,0 ) == 0 )
- {
- s = s.Mid( sArrow.GetLength() );
-
- // Find the appropriate dialog box
- xx=0;
- while( !IsEqualIID( *adsiIfs[xx].pIID, IID_NULL ) && s != adsiIfs[xx].szIf )
- {
- xx++;
- }
-
-
- if ( adsiIfs[xx].pFn )
- {
-
- CString sAttr;
- VARIANT var;
-
- // We need to get the value again
- USES_CONVERSION;
- m_cAttrList.GetLBText( m_cAttrList.GetCurSel(), sAttr );
- hr = m_pADs->Get( T2OLE(sAttr), &var);
- if ( SUCCEEDED(hr) )
- {
- IUnknown *pUnk;
- hr = V_DISPATCH(&var)->QueryInterface( IID_IUnknown, (void**) &pUnk );
- if ( SUCCEEDED(hr) )
- {
- (*adsiIfs[xx].pFn)( pUnk, NULL );
- }
- }
- }
- else
- {
- AfxMessageBox(_T("No UI implemented yet"));
- }
-
-
-
- return;
-
- }
-
-
-
- }
-
- /////////////////////////////////
- // Copy to cliboard
- /////////////////////////////////
- void CDlgIADs::OnCopy()
- {
- CString s;
- HANDLE hMem;
- int idx;
-
-
- idx = m_cValueList.GetCurSel();
-
- if ( idx == LB_ERR )
- {
- return;
- }
-
- m_cValueList.GetText( idx, s );
-
- if ( !OpenClipboard() )
- {
- return;
- }
- EmptyClipboard();
-
-
- hMem = GlobalAlloc( GMEM_DDESHARE, sizeof(TCHAR) * (s.GetLength() + 1) );
- if ( hMem )
- {
- LPTSTR pMem;
- pMem = (LPTSTR) GlobalLock( hMem );
- lstrcpy( pMem, s );
- GlobalUnlock(hMem);
- SetClipboardData( CF_TEXT, hMem );
- }
-
- CloseClipboard();
-
- }
-