975 lines
20 KiB
C++
975 lines
20 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Active Directory 2.5 Sample Code
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1996 - 2000
|
|
//
|
|
// File: DirectorySearch.cpp
|
|
//
|
|
// Contents: IDirectorySearch usage
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include "ADQI.h"
|
|
#include "DirectorySearch.h"
|
|
#include "ads.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgIDirectorySearch dialog
|
|
|
|
|
|
CDlgIDirectorySearch::CDlgIDirectorySearch(LPUNKNOWN pUnk, CWnd* pParent /*=NULL*/)
|
|
: CDialog(CDlgIDirectorySearch::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CDlgIDirectorySearch)
|
|
m_sFilter = _T("");
|
|
m_bEnableFilter = FALSE;
|
|
m_nTimeOut = 0;
|
|
m_bCacheResult = FALSE;
|
|
m_nPageSize = 0;
|
|
m_sSortOn = _T("");
|
|
m_nTimeLimit = 0;
|
|
m_nSizeLimit = 0;
|
|
m_bAsynch = FALSE;
|
|
m_bAttrib = FALSE;
|
|
m_nDeref = -1;
|
|
//}}AFX_DATA_INIT
|
|
HRESULT hr;
|
|
m_pSearch = NULL;
|
|
hr = pUnk->QueryInterface( IID_IDirectorySearch, (void **) &m_pSearch );
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
AfxMessageBox(_T("Fatal Error! QI for IDirectorySearch failed"));
|
|
return;
|
|
}
|
|
pUnk->Release();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
CDlgIDirectorySearch::~CDlgIDirectorySearch()
|
|
{
|
|
if ( m_pSearch )
|
|
{
|
|
m_pSearch->Release();
|
|
}
|
|
}
|
|
|
|
void CDlgIDirectorySearch::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CDlgIDirectorySearch)
|
|
DDX_Control(pDX, IDC_ATTRIBUTE, m_cAttrList);
|
|
DDX_Control(pDX, IDC_LISTVIEW, m_cListView);
|
|
DDX_Control(pDX, IDC_CHASEREFERRAL, m_cChaseReferrals);
|
|
DDX_Control(pDX, IDC_CACHERESULTS, m_cCacheResult);
|
|
DDX_Control(pDX, IDC_SEARCHSCOPE, m_CADsSearchScope);
|
|
DDX_Control(pDX, IDC_ENABLED, m_cEnableFilter);
|
|
DDX_Control(pDX, IDC_EXECUTE, m_cExecute);
|
|
DDX_Control(pDX, IDC_FILTER, m_cFilter);
|
|
DDX_Text(pDX, IDC_FILTER, m_sFilter);
|
|
DDX_Check(pDX, IDC_ENABLED, m_bEnableFilter);
|
|
DDX_Text(pDX, IDC_TIMEOUT, m_nTimeOut);
|
|
DDX_Check(pDX, IDC_CACHERESULTS, m_bCacheResult);
|
|
DDX_Text(pDX, IDC_PAGESIZE, m_nPageSize);
|
|
DDX_Text(pDX, IDC_SORTON, m_sSortOn);
|
|
DDX_Text(pDX, IDC_TIMELIMIT, m_nTimeLimit);
|
|
DDX_Text(pDX, IDC_SIZELIMIT, m_nSizeLimit);
|
|
DDX_Check(pDX, IDC_ASYNCH, m_bAsynch);
|
|
DDX_Check(pDX, IDC_ATTRIBONLY, m_bAttrib);
|
|
DDX_CBIndex(pDX, IDC_DEREF, m_nDeref);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgIDirectorySearch, CDialog)
|
|
//{{AFX_MSG_MAP(CDlgIDirectorySearch)
|
|
ON_BN_CLICKED(IDC_EXECUTE, OnExecute)
|
|
ON_EN_CHANGE(IDC_FILTER, OnChangeFilter)
|
|
ON_BN_CLICKED(IDC_ENABLED, OnEnabled)
|
|
ON_NOTIFY(NM_DBLCLK, IDC_LISTVIEW, OnDblClickListView)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgIDirectorySearch message handlers
|
|
//
|
|
|
|
////////////////////////////////////////////
|
|
// OnExecute
|
|
// Demonstrate:
|
|
// IDirectorySearch::ExecuteSearch
|
|
// IDirectorySearch::GetNextRow
|
|
// IDirectorySearch::GetColumn
|
|
// IDirectorySearch::SetSearchPreference
|
|
//
|
|
/////////////////////////////////////////////
|
|
void CDlgIDirectorySearch::OnExecute()
|
|
{
|
|
ASSERT( m_pSearch );
|
|
CWaitCursor wait;
|
|
|
|
UpdateData(TRUE); // Get data from the Dialog Box
|
|
HRESULT hr;
|
|
ADS_SEARCH_HANDLE hSearch;
|
|
ADS_SEARCH_COLUMN col;
|
|
CString s;
|
|
int idx=0;
|
|
int nCount;
|
|
LPWSTR *pszAttr=NULL;
|
|
POSITION pos;
|
|
USES_CONVERSION;
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////
|
|
// Reset the Total Number
|
|
//////////////////////////////////
|
|
SetDlgItemText( IDC_TOTAL, _T(""));
|
|
|
|
|
|
/////////////////////////////////////////////
|
|
// Get the attribute list, and preparing..
|
|
///////////////////////////////////////////
|
|
CStringList sAttrList;
|
|
m_cListView.DeleteAllItems(); // Reset the UI
|
|
|
|
while( m_cListView.DeleteColumn(0))
|
|
{
|
|
;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
// Preparing for attribute list
|
|
// and columns to display
|
|
CString sTemp;
|
|
m_cAttrList.GetWindowText(s);
|
|
|
|
// we need to add adspath, so that we can refer to this object later when user dblclk the item
|
|
if ( !s.IsEmpty() )
|
|
{
|
|
sTemp = s;
|
|
sTemp.MakeLower();
|
|
if ( s.Find(_T("adspath"),0) == -1 )
|
|
{
|
|
s += _T(",ADsPath");
|
|
}
|
|
}
|
|
|
|
// convert to string list for easy manipulation
|
|
StringToStringList( s, sAttrList );
|
|
|
|
|
|
|
|
nCount = sAttrList.GetCount();
|
|
idx=0;
|
|
if ( nCount )
|
|
{
|
|
|
|
pszAttr = (LPWSTR*) AllocADsMem( nCount * sizeof(LPWSTR));
|
|
|
|
pos = sAttrList.GetHeadPosition();
|
|
while ( pos != NULL )
|
|
{
|
|
s = sAttrList.GetAt(pos);
|
|
pszAttr[idx] = T2OLE(s);
|
|
sAttrList.GetNext(pos );
|
|
idx++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nCount = -1;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////
|
|
// BEGIN Set the preferences
|
|
///////////////////////////////////////
|
|
DWORD dwCountPref = 0;
|
|
ADS_SEARCHPREF_INFO prefInfo[ MAX_SEARCH_PREF ];
|
|
ADS_SORTKEY *pSortKey = NULL;
|
|
|
|
if ( m_bEnableFilter == FALSE )
|
|
{
|
|
// Reset the preference
|
|
m_pSearch->SetSearchPreference( prefInfo, dwCountPref );
|
|
}
|
|
else // Preferences are specified
|
|
{
|
|
////////////////////////
|
|
// Timeout Pref
|
|
////////////////////////////
|
|
if ( m_nTimeOut != 0 )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_TIMEOUT;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER;
|
|
prefInfo[dwCountPref].vValue.Integer = m_nTimeOut;
|
|
dwCountPref++;
|
|
}
|
|
|
|
//////////////////////////////
|
|
// Search Scope
|
|
/////////////////////////////
|
|
idx = m_CADsSearchScope.GetCurSel();
|
|
if ( idx != CB_ERR )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER;
|
|
prefInfo[dwCountPref].vValue.Integer = idx;
|
|
dwCountPref++;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////
|
|
// Cache Result. The default is to cache the result
|
|
/////////////////////////////////////////////////
|
|
if ( !m_bCacheResult )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_BOOLEAN;
|
|
prefInfo[dwCountPref].vValue.Boolean = FALSE;
|
|
dwCountPref++;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
// Page Size
|
|
///////////////////////////////////////////////////
|
|
if ( m_nPageSize > 0 )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER;;
|
|
prefInfo[dwCountPref].vValue.Integer = m_nPageSize;
|
|
dwCountPref++;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
// Chase Referrals
|
|
///////////////////////////////////////////////
|
|
idx = m_cChaseReferrals.GetCurSel();
|
|
if ( idx != CB_ERR )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER;
|
|
switch( idx )
|
|
{
|
|
case 0:
|
|
prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_NEVER;
|
|
break;
|
|
case 1:
|
|
prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_SUBORDINATE;
|
|
break;
|
|
case 2:
|
|
prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_EXTERNAL;
|
|
break;
|
|
default:
|
|
prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_EXTERNAL;
|
|
|
|
}
|
|
|
|
dwCountPref++;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Sort On
|
|
////////////////////////////////////////////////
|
|
if ( !m_sSortOn.IsEmpty() )
|
|
{
|
|
CStringList sList;
|
|
UINT nCount;
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SORT_ON;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
|
|
StringToStringList( m_sSortOn, sList );
|
|
|
|
nCount = sList.GetCount();
|
|
if ( nCount > 0 )
|
|
{
|
|
POSITION pos;
|
|
pos= sList.GetHeadPosition();
|
|
pSortKey = (ADS_SORTKEY *) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, sizeof(ADS_SORTKEY) * nCount );
|
|
idx = 0;
|
|
while( pos != NULL )
|
|
{
|
|
pSortKey[idx].pszAttrType = T2OLE(sList.GetAt(pos));
|
|
pSortKey[idx].pszReserved = NULL;
|
|
pSortKey[idx].fReverseorder =0;
|
|
|
|
// Next
|
|
idx++;
|
|
sList.GetNext( pos );
|
|
}
|
|
|
|
prefInfo[dwCountPref].vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY) * nCount;
|
|
prefInfo[dwCountPref].vValue.ProviderSpecific.lpValue = (LPBYTE) pSortKey;
|
|
dwCountPref++;
|
|
}
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////
|
|
// Size Limit
|
|
//////////////////////////////////////////////
|
|
if ( m_nSizeLimit > 0 )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER;
|
|
prefInfo[dwCountPref].vValue.Integer = m_nSizeLimit;
|
|
dwCountPref++;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// A Synchronous
|
|
///////////////////////////////////////////////////
|
|
if ( m_bAsynch )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_ASYNCHRONOUS;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_BOOLEAN;
|
|
prefInfo[dwCountPref].vValue.Integer = TRUE;
|
|
dwCountPref++;
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////
|
|
// Attribute Type Only
|
|
//////////////////////////////////////////////////////
|
|
if ( m_bAttrib )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_ATTRIBTYPES_ONLY;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_BOOLEAN;
|
|
prefInfo[dwCountPref].vValue.Integer = TRUE;
|
|
dwCountPref++;
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
// Derefence Alias
|
|
//////////////////////////////////////////////////////
|
|
if ( m_nDeref != CB_ERR )
|
|
{
|
|
prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_DEREF_ALIASES;
|
|
prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER;
|
|
prefInfo[dwCountPref].vValue.Integer = m_nDeref;
|
|
dwCountPref++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Now Set the selected preferences
|
|
//////////////////////////////////////////////
|
|
hr = m_pSearch->SetSearchPreference( prefInfo, dwCountPref );
|
|
|
|
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////
|
|
// END Set the preferences
|
|
///////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////
|
|
// Execute the Search
|
|
//////////////////////////////////////
|
|
DWORD dwCount=0;
|
|
|
|
hr = m_pSearch->ExecuteSearch(T2OLE(m_sFilter), pszAttr, nCount, &hSearch );
|
|
|
|
|
|
////////////////////////////////
|
|
//// cleanup
|
|
////////////////////////////////
|
|
if ( pszAttr )
|
|
{
|
|
FreeADsMem( pszAttr );
|
|
}
|
|
|
|
if ( pSortKey )
|
|
{
|
|
LocalFree( pSortKey );
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
AfxMessageBox(GetErrorMessage(hr));
|
|
return;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// Enumerate the rows
|
|
////////////////////////////////////////////////////////
|
|
|
|
sAttrList.RemoveAll();
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// Retrieve the column names returned from the server
|
|
///////////////////////////////////////////////////////////
|
|
LPWSTR pszColumn;
|
|
hr = m_pSearch->GetFirstRow( hSearch );
|
|
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
idx=0;
|
|
while( (hr=m_pSearch->GetNextColumnName( hSearch, &pszColumn )) != S_ADS_NOMORE_COLUMNS )
|
|
{
|
|
s = OLE2T( pszColumn );
|
|
m_cListView.InsertColumn(idx, s, LVCFMT_LEFT, 150 ); // adding columns to the UI
|
|
sAttrList.AddTail(s);
|
|
FreeADsMem( pszColumn );
|
|
idx++;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////
|
|
// Start iterating the result set
|
|
////////////////////////////////////////////
|
|
int nCol;
|
|
CStringList sValueList;
|
|
|
|
do
|
|
{
|
|
nCol=0;
|
|
pos = sAttrList.GetHeadPosition();
|
|
|
|
while( pos != NULL )
|
|
{
|
|
|
|
s = sAttrList.GetAt(pos); //column name
|
|
|
|
// Get the Name and display it in the list
|
|
hr = m_pSearch->GetColumn( hSearch, T2OLE(s), &col );
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
s =_T("");
|
|
|
|
if ( col.dwADsType != ADSTYPE_INVALID ) // if we request for attrib only, no value will be returned
|
|
{
|
|
ADsToStringList(col.pADsValues, col.dwNumValues, sValueList );
|
|
StringListToString( sValueList, s );
|
|
}
|
|
|
|
if ( nCol )
|
|
{
|
|
m_cListView.SetItemText(0,nCol, s);
|
|
}
|
|
else
|
|
{
|
|
m_cListView.InsertItem(0, s);
|
|
}
|
|
|
|
m_pSearch->FreeColumn( &col );
|
|
}
|
|
|
|
|
|
|
|
|
|
nCol++;
|
|
sAttrList.GetNext(pos);
|
|
|
|
}
|
|
dwCount++;
|
|
/////////////////////////////
|
|
//Display the total so far
|
|
////////////////////////////////
|
|
s.Format("%ld object(s)", dwCount );
|
|
SetDlgItemText( IDC_TOTAL, s );
|
|
|
|
}
|
|
while( (hr=m_pSearch->GetNextRow( hSearch)) != S_ADS_NOMORE_ROWS );
|
|
|
|
|
|
|
|
m_pSearch->CloseSearchHandle( hSearch );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
void CDlgIDirectorySearch::OnChangeFilter()
|
|
{
|
|
BOOL bExecEnabled;
|
|
|
|
bExecEnabled = m_cFilter.GetWindowTextLength() > 0 ? TRUE :FALSE;
|
|
m_cExecute.EnableWindow( bExecEnabled );
|
|
}
|
|
|
|
BOOL CDlgIDirectorySearch::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
// Initialize to a default search
|
|
m_cFilter.SetWindowText(_T("(objectClass=*)"));
|
|
m_cAttrList.SetWindowText(_T("cn"));
|
|
|
|
OnChangeFilter();
|
|
OnEnabled();
|
|
|
|
m_cCacheResult.SetCheck( 1 );
|
|
|
|
|
|
|
|
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
void CDlgIDirectorySearch::OnEnabled()
|
|
{
|
|
UpdateData(TRUE);
|
|
|
|
// Enable/Disable Edit Boxes
|
|
GetDlgItem( IDC_TIMEOUT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_SEARCHSCOPE )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_PAGESIZE )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_SORTON )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_CHASEREFERRAL )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_TIMELIMIT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_SIZELIMIT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_ASYNCH )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_CACHERESULTS )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_ATTRIBONLY )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_DEREF )->EnableWindow(m_bEnableFilter);
|
|
|
|
|
|
// Enabled/Disabled Texts
|
|
GetDlgItem( IDC_TIMEOUT_TXT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_SEARCHSCOPE_TXT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_PAGESIZE_TXT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_SORTON_TXT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_CHASEREFERRAL_TXT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_TIMELIMIT_TXT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_SIZELIMIT_TXT )->EnableWindow(m_bEnableFilter);
|
|
GetDlgItem( IDC_DEREF_TXT )->EnableWindow(m_bEnableFilter);
|
|
|
|
|
|
|
|
}
|
|
|
|
void CDlgIDirectorySearch::OnOK()
|
|
{
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDlgIDirectorySearch::OnDblClickListView(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
int idx;
|
|
*pResult = 0;
|
|
|
|
|
|
idx = m_cListView.GetNextItem(-1, LVNI_SELECTED);
|
|
if ( idx == -1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
CHeaderCtrl *pHeader;
|
|
int nCount;
|
|
pHeader = m_cListView.GetHeaderCtrl();
|
|
if ( !pHeader )
|
|
{
|
|
return;
|
|
}
|
|
nCount = pHeader->GetItemCount();
|
|
|
|
|
|
// Get the text
|
|
CString s;
|
|
s = m_cListView.GetItemText( idx, nCount-1 );
|
|
|
|
if ( !s.GetLength() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
USES_CONVERSION;
|
|
HRESULT hr;
|
|
IUnknown *pUnk=NULL;
|
|
CString sUserName;
|
|
|
|
|
|
hr = App->ADsOpenObject( T2OLE( s ), IID_IUnknown, (void**) &pUnk );
|
|
|
|
|
|
/////////////////////////////////////
|
|
// Bring up the IADs Dialog
|
|
///////////////////////////////////////
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
pUnk->AddRef();
|
|
CDlgIADs dlg( pUnk );
|
|
dlg.DoModal();
|
|
pUnk->Release();
|
|
}
|
|
else
|
|
{
|
|
AfxMessageBox(GetErrorMessage(hr));
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CADsSearch
|
|
// This is a convient C++ wrapper for IDirectorySearch
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CADsSearch::CADsSearch( IADs *pADs )
|
|
{
|
|
CADsSearch();
|
|
SetInterface( pADs );
|
|
|
|
}
|
|
|
|
CADsSearch::CADsSearch()
|
|
{
|
|
m_pSearch = NULL;
|
|
m_hSearch = NULL;
|
|
m_dwPrefCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT CADsSearch::SetInterface( IUnknown *pUnk )
|
|
{
|
|
if ( pUnk != NULL )
|
|
{
|
|
HRESULT hr;
|
|
//////////////////////////////////////////
|
|
// Remove the current search if any
|
|
////////////////////////////////////////
|
|
if ( m_pSearch )
|
|
{
|
|
if ( m_hSearch )
|
|
{
|
|
m_pSearch->CloseSearchHandle( m_hSearch );
|
|
}
|
|
m_pSearch->Release();
|
|
}
|
|
|
|
|
|
m_pSearch = NULL;
|
|
m_hSearch = NULL;
|
|
m_dwPrefCount = 0;
|
|
hr = pUnk->QueryInterface( IID_IDirectorySearch, (LPVOID*) &m_pSearch );
|
|
pUnk->Release();
|
|
return hr;
|
|
}
|
|
|
|
return E_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CADsSearch::~CADsSearch()
|
|
{
|
|
if ( m_pSearch )
|
|
{
|
|
if ( m_hSearch )
|
|
{
|
|
m_pSearch->CloseSearchHandle( m_hSearch );
|
|
}
|
|
m_pSearch->Release();
|
|
}
|
|
}
|
|
|
|
HRESULT CADsSearch::GetNextRow()
|
|
{
|
|
HRESULT hr;
|
|
if ( !m_pSearch || !m_hSearch)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
hr = m_pSearch->GetNextRow( m_hSearch );
|
|
return hr;
|
|
}
|
|
|
|
void CADsSearch::AddColumn( LPCTSTR pszColumn )
|
|
{
|
|
ASSERT( pszColumn );
|
|
|
|
m_sColumnList.AddTail( pszColumn );
|
|
}
|
|
|
|
|
|
HRESULT CADsSearch::SetScope( ADS_SCOPEENUM flag )
|
|
{
|
|
|
|
if ( !m_pSearch )
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
|
|
ADS_SEARCHPREF_INFO info;
|
|
|
|
info.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
|
|
info.vValue.dwType = ADSTYPE_INTEGER;
|
|
info.vValue.Integer = flag;
|
|
return AddSearchPref( &info );
|
|
|
|
}
|
|
|
|
|
|
HRESULT CADsSearch::SetAttribOnly( BOOL bAttribOnly )
|
|
{
|
|
ADS_SEARCHPREF_INFO info;
|
|
|
|
info.dwSearchPref = ADS_SEARCHPREF_ATTRIBTYPES_ONLY;
|
|
info.vValue.dwType = ADSTYPE_BOOLEAN;
|
|
info.vValue.Integer = bAttribOnly;
|
|
|
|
return AddSearchPref( &info );
|
|
|
|
}
|
|
|
|
HRESULT CADsSearch::SetPageSize( UINT nPageSize )
|
|
{
|
|
ADS_SEARCHPREF_INFO info;
|
|
|
|
info.dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
|
|
info.vValue.dwType = ADSTYPE_INTEGER;
|
|
info.vValue.Integer = nPageSize;
|
|
|
|
return AddSearchPref( &info );
|
|
}
|
|
|
|
|
|
|
|
// TODO: More Options...
|
|
|
|
HRESULT CADsSearch::AddSearchPref( PADS_SEARCHPREF_INFO pSearchPrefs, DWORD dwNumPref )
|
|
{
|
|
PADS_SEARCHPREF_INFO pInfo;
|
|
|
|
for( UINT idx=0; idx < dwNumPref; idx++ )
|
|
{
|
|
pInfo = FindSearchPrefence( pSearchPrefs->dwSearchPref );
|
|
if ( pInfo )
|
|
{
|
|
*(pInfo) = *(pSearchPrefs);
|
|
}
|
|
else
|
|
{
|
|
if ( m_dwPrefCount == MAX_SEARCH_PREF )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
m_srchInfo[m_dwPrefCount] = *(pSearchPrefs);
|
|
m_dwPrefCount++;
|
|
}
|
|
|
|
pSearchPrefs++;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
PADS_SEARCHPREF_INFO CADsSearch::FindSearchPrefence( ADS_SEARCHPREF pref )
|
|
{
|
|
for(UINT idx=0; idx < MAX_SEARCH_PREF; idx++ )
|
|
{
|
|
if( m_srchInfo[idx].dwSearchPref == pref )
|
|
{
|
|
return &m_srchInfo[idx];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
HRESULT CADsSearch::Execute( LPCTSTR pszFilter )
|
|
{
|
|
USES_CONVERSION;
|
|
HRESULT hr;
|
|
|
|
|
|
if ( !m_pSearch )
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
m_hSearch = NULL;
|
|
|
|
//////////////////////////////////////////////
|
|
// Set the search preference if any
|
|
///////////////////////////////////////////////
|
|
if ( m_dwPrefCount )
|
|
{
|
|
hr = m_pSearch->SetSearchPreference( m_srchInfo, m_dwPrefCount);
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
if ( m_sColumnList.IsEmpty() )
|
|
{
|
|
hr = m_pSearch->ExecuteSearch( T2OLE(pszFilter), NULL, -1, &m_hSearch );
|
|
}
|
|
else // Columns is specified
|
|
{
|
|
unsigned int count, xx;
|
|
LPWSTR *pColumns = NULL;
|
|
POSITION pos;
|
|
CString s;
|
|
|
|
count = m_sColumnList.GetCount();
|
|
pColumns = (LPWSTR*)AllocADsMem( sizeof(LPWSTR)*count);
|
|
pos = m_sColumnList.GetHeadPosition();
|
|
for(xx=0; xx < count; xx++)
|
|
{
|
|
s = m_sColumnList.GetAt(pos);
|
|
pColumns[xx] = T2OLE(s);
|
|
m_sColumnList.GetNext(pos);
|
|
}
|
|
|
|
hr = m_pSearch->ExecuteSearch( T2OLE(pszFilter), pColumns, count, &m_hSearch );
|
|
if ( pColumns )
|
|
{
|
|
FreeADsMem( pColumns );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT CADsSearch::GetColumn( UINT nIndex, CStringList &sList )
|
|
{
|
|
CString s;
|
|
|
|
if ( m_sColumnList.IsEmpty() )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
POSITION pos;
|
|
pos = m_sColumnList.FindIndex( nIndex );
|
|
|
|
if ( pos == NULL )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
s = m_sColumnList.GetAt(pos);
|
|
return GetColumn( s, sList );
|
|
|
|
}
|
|
|
|
|
|
HRESULT CADsSearch::GetColumn( LPCTSTR pszCol, PADS_SEARCH_COLUMN pCol )
|
|
{
|
|
LPWSTR pszAttrName;
|
|
USES_CONVERSION;
|
|
|
|
pszAttrName = T2OLE(pszCol);
|
|
|
|
return m_pSearch->GetColumn( m_hSearch, pszAttrName, pCol );
|
|
|
|
}
|
|
|
|
HRESULT CADsSearch::FreeColumn( PADS_SEARCH_COLUMN pCol )
|
|
{
|
|
return m_pSearch->FreeColumn( pCol );
|
|
}
|
|
|
|
|
|
|
|
HRESULT CADsSearch::GetColumn(CString &sCol, CStringList &sList )
|
|
{
|
|
LPWSTR pszAttrName;
|
|
ADS_SEARCH_COLUMN col;
|
|
HRESULT hr;
|
|
USES_CONVERSION;
|
|
CString s;
|
|
|
|
|
|
pszAttrName = T2OLE(sCol);
|
|
|
|
hr = m_pSearch->GetColumn( m_hSearch, pszAttrName, &col );
|
|
|
|
if ( !SUCCEEDED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = FormatColumn( &col, sList );
|
|
m_pSearch->FreeColumn( &col );
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
HRESULT CADsSearch::FormatColumn(PADS_SEARCH_COLUMN pColumn, CStringList &sList)
|
|
{
|
|
|
|
ADsToStringList( pColumn->pADsValues, pColumn->dwNumValues, sList );
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|