IDirectorySearch
COM公式ドキュメント
IDirectorySearch インターフェイスは、非オートメーションクライアントが基になるディレクトリに対してクエリを実行するために使用できる、オーバーヘッドの少ないメソッドを提供する純粋な COM インターフェイスです。
メソッド 10
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
後続の検索でデータを取得するための検索設定を指定します。
| pSearchPrefs | ADS_SEARCHPREF_INFO* | in | 設定する検索設定を格納した、呼び出し元が割り当てた ADS_SEARCHPREF_INFO 構造体の配列を指定します。 |
| dwNumPrefs | DWORD | in | pSearchPrefs 配列のサイズを指定します。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値をサポートします。
詳細およびその他の戻り値については、ADSI エラーコードを参照してください。
IDirectorySearch::ExecuteSearch メソッドは、検索を実行し、その結果を呼び出し元に渡します。
| pszSearchFilter | LPWSTR | in | "(objectClass=user)" のような、LDAP 形式の検索フィルター文字列です。 |
| pAttributeNames | LPWSTR* | in | データを要求する属性名の配列です。NULL の場合、dwNumberAttributes は 0 または 0xFFFFFFFF でなければなりません。 |
| dwNumberAttributes | DWORD | in | pAttributeNames 配列のサイズです。特別な値 0xFFFFFFFF は、pAttributeNames が無視され、NULL にできることを示します。この特別な値は、設定されているすべての属性が要求されることを意味します。この値が 0 の場合、pAttributeNames 配列は NULL にできます。属性は一切要求されません。 |
| phSearchResult | ADS_SEARCH_HANDLE* | out | 検索コンテキストへの、メソッドが割り当てるハンドルのアドレスです。呼び出し元は、このハンドルを IDirectorySearch の他のメソッドに渡して検索結果を調べます。NULL の場合、検索を実行できません。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
詳細およびその他の戻り値については、ADSI エラーコードを参照してください。
解説(Remarks)
検索フィルター (pszSearchFilter) に ADS_UTC_TIME 型の属性が含まれる場合、その値は "yymmddhhmmssZ" 形式でなければなりません。ここで "y"、"m"、"d"、"h"、"m"、"s" はそれぞれ年、月、日、時、分、秒を表します。この形式では、たとえば "1999 年 5 月 13th 日 10:20:00" は "990513102000Z" になります。末尾の文字 "Z" は必須の構文で、Zulu 時間 (協定世界時) を示します。
呼び出し元は、検索ハンドルおよび結果に割り当てられたメモリを解放するために IDirectorySearch::CloseSearchHandle を呼び出す必要があります。
dwNumberAttributes に特別な値 0xFFFFFFFF を使用する場合、ADsPath または distinguishedName の LDAP 取得に追加のリソースや時間のコストはかかりません。
例
次の C++ コード例は、IDirectorySearch::ExecuteSearch の呼び出し方法を示しています。
LPWSTR pszAttr[] = { L"ADsPath", L"Name", L"samAccountName" };
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount= sizeof(pszAttr)/sizeof(LPWSTR);
// Search for users with a last name that begins with "h".
hr = m_pSearch->ExecuteSearch(L"(&(objectClass=user)(sn=h*))", pszAttr, dwCount, &hSearch );
IDirectorySearch::AbandonSearch メソッドは、以前の ExecuteSearch メソッドの呼び出しによって開始された検索を中止します。
| phSearchResult | ADS_SEARCH_HANDLE | in | 検索コンテキストへのハンドルを指定します。 |
戻り値
このメソッドは標準の戻り値を返します。最初の行が正常に取得された場合は S_OK を含みます。
その他の戻り値については、ADSI エラーコードを参照してください。
解説(Remarks)
IDirectorySearch::AbandonSearch は、検索の実行前に IDirectorySearch::SetSearchPreference を通じて Page_Size または Asynchronous オプションを指定できる場合に使用できます。
例
LPWSTR pszAttr[] = { L"ADsPath", L"Name", L"samAccountName" };
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount= sizeof(pszAttr)/sizeof(LPWSTR);
////////////////////////////////////////////////////////////////////
// NOTE: Assume that m_pSearch is an IDirectorySearch pointer to the
// object at the base of the search, and that the appropriate search
// preferences have been set.
// For brevity, omit error handling.
////////////////////////////////////////////////////////////////////
// Search for all users with a last name that starts with h.
hr = m_pSearch->ExecuteSearch(L"(&(objectClass=user)(sn=h*))", pszAttr, dwCount, &hSearch );
while( m_pSearch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
{
// Get the samAccountName
hr = m_pSearch->GetColumn( hSearch, pszAttr[2], &col );
if ( FAILED(hr) )
{
hr = m_pSearch->AbandonSearch( hSearch );
hr = m_pSearch->CloseSearchHandle(hSearch);
m_pSearch->Release();
break;
}
if (col.dwADsType == ADSTYPE_CASE_IGNORE_STRING)
printf("%S\n", col.pADsValues->CaseIgnoreString);
m_pSearch->FreeColumn( &col );
}
m_pSearch->CloseSearchHandle( hSearch );
GetFirstRow メソッドは、検索結果の最初の行を取得します。このメソッドは、以前に呼び出されたことがある場合でも、新しい検索を発行または再発行します。
| hSearchResult | ADS_SEARCH_HANDLE | in | IDirectorySearch::ExecuteSearch を呼び出して取得した検索ハンドルを格納します。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
詳細については、ADSI エラーコードを参照してください。
解説(Remarks)
ADS_SEARCHPREF_CACHE_RESULTS フラグが設定されていない場合、つまり FALSE の場合、クライアントがすべてのクエリ結果をキャッシュしていない可能性があるため、前方へのスクロールのみが許可されます。同じ行から GetFirstRow を複数回呼び出すと、ある程度の後方スクロールが必要になり、結果がキャッシュに残っている保証がない場合、OLE DB を通じて開始されたページ検索や非同期検索で誤った結果になる可能性があります。
例
hr = m_pSearch->ExecuteSearch(L"(objectCategory=contact)", pszAttr, dwCount, &hSearch);
if(SUCCEEDED(hr))
{
while(SUCCEEDED(hr = m_pSearch->GetNextRow(hSearch)))
{
if(S_OK == hr)
{
// Get the data.
}
else if(S_ADS_NOMORE_ROWS == hr)
{
// Call ADsGetLastError to see if the search is waiting for a response.
DWORD dwError = ERROR_SUCCESS;
WCHAR szError[512];
WCHAR szProvider[512];
ADsGetLastError(&dwError, szError, 512, szProvider, 512);
if(ERROR_MORE_DATA != dwError)
{
break;
}
}
else
{
break;
}
}
m_pSearch->CloseSearchHandle(hSearch);
}
検索結果の次の行を取得します。
| hSearchResult | ADS_SEARCH_HANDLE | in | IDirectorySearch::ExecuteSearch を呼び出して取得した検索ハンドルを格納します。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
詳細については、ADSI エラーコードを参照してください。
解説(Remarks)
ADS_SEARCHPREF_CACHE_RESULTS フラグが設定されていない場合、クライアントがすべてのクエリ結果をキャッシュしていない可能性があるため、前方へのスクロールのみが許可されます。
ディレクトリプロバイダーは、検索で取得できる最大行数を制限する場合があります。たとえば、Windows ドメインでは、Active Directory 検索で提供される最大行数は 1000 行です。検索結果がこの行数の上限を超える場合、検索内のすべての行を取得するにはページ検索を実行する必要があります。ページ検索の詳細については、Paging with IDirectorySearch を参照してください。
例
hr = m_pSearch->ExecuteSearch(L"(objectCategory=contact)", pszAttr, dwCount, &hSearch);
if(SUCCEEDED(hr))
{
while(SUCCEEDED(hr = m_pSearch->GetNextRow(hSearch)))
{
if(S_OK == hr)
{
// Get the data.
}
else if(S_ADS_NOMORE_ROWS == hr)
{
// Call ADsGetLastError to see if the search is waiting for a response.
DWORD dwError = ERROR_SUCCESS;
WCHAR szError[512];
WCHAR szProvider[512];
ADsGetLastError(&dwError, szError, 512, szProvider, 512);
if(ERROR_MORE_DATA != dwError)
{
break;
}
}
else
{
break;
}
}
m_pSearch->CloseSearchHandle(hSearch);
}
IDirectorySearch::GetPreviousRow メソッドは、検索結果の前の行を取得します。プロバイダーがカーソルをサポートしていない場合は、E_NOTIMPL を返す必要があります。
| hSearchResult | ADS_SEARCH_HANDLE | in | 検索コンテキストへのハンドルを指定します。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
その他の戻り値については、ADSI エラーコードを参照してください。
解説(Remarks)
ADS_SEARCHPREF_CACHE_RESULTS フラグが設定されていない場合、クライアントがすべてのクエリ結果をキャッシュしていない可能性があるため、前方へのスクロールのみが許可されます。
例
hr = m_pSearch->ExecuteSearch(L"(&(objectCategory=user)(st=WA))", pszAttr, dwCount, &hSearch );
if ( SUCCEEDED(hr) )
{
while( m_pSearch->GetNextRow(hSearch) != S_ADS_NOMORE_ROWS )
{
/* Get the data */
}
// Print it backward
hr = m_pSearch->GetPreviousRow( hSearch );
while( hr != S_ADS_NOMORE_ROWS && hr != E_NOTIMPL)
{
/* Get the data */
}
m_pSearch->CloseSearchHandle(hSearch);
}
IDirectorySearch::GetNextColumnName メソッドは、検索結果の中でデータを含む次の列の名前を取得します。
| hSearchHandle | ADS_SEARCH_HANDLE | in | 検索コンテキストへのハンドルを指定します。 |
| ppszColumnName | LPWSTR* | out | 要求された列名を格納する、メソッドが割り当てる文字列へのポインターのアドレスを指定します。NULL の場合、後続の行にデータは含まれません。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
その他の戻り値については、ADSI エラーコードを参照してください。
解説(Remarks)
このメソッドは列名に十分なメモリを割り当てますが、呼び出し元は、このメモリが不要になったときに FreeADsMem ヘルパー関数を呼び出して解放する必要があります。
例
LPWSTR pszColumn;
m_pSearch->GetFirstRow( hSearch );
printf("Column names are: ");
while( m_pSearch->GetNextColumnName( hSearch, &pszColumn ) != S_ADS_NOMORE_COLUMNS )
{
printf("%S ", pszColumn );
FreeADsMem( pszColumn );
}
IDirectorySearch::GetColumn メソッドは、検索結果の名前付き列からデータを取得します。
| hSearchResult | ADS_SEARCH_HANDLE | in | 検索コンテキストへのハンドルを指定します。 |
| szColumnName | LPWSTR | in | データを要求する列の名前を指定します。 |
| pSearchColumn | ADS_SEARCH_COLUMN* | out | 検索結果の現在の行の列を格納する、メソッドが割り当てる ADS_SEARCH_COLUMN 構造体のアドレスを指定します。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
その他の戻り値については、ADSI エラーコードを参照してください。
解説(Remarks)
このメソッドは、列のデータを保持するために ADS_SEARCH_COLUMN 構造体のメモリを割り当てます。ただし、呼び出し元は IDirectorySearch::FreeColumn を呼び出してメモリを解放する必要があります。
IDirectorySearch::GetColumn メソッドは、要求された属性のスキーマ定義を読み取ろうとし、ADS_SEARCH_COLUMN 構造体に含まれる ADSVALUE 構造体で属性値を適切な形式で返せるようにします。ただし、GetColumn は、スキーマ定義が利用できない場合でも成功することがあります。その場合、ADS_SEARCH_COLUMN 構造体の dwADsType メンバーは ADSTYPE_PROV_SPECIFIC を返し、値は ADS_PROV_SPECIFIC 構造体で返されます。GetColumn 呼び出しの結果を処理する際には、データが期待される形式で返されたことを確認するために dwADsType を検証する必要があります。
例
ADS_SEARCH_COLUMN col;
/*.. Omit the set preference and execute*/
while( m_pSearch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
{
// Get the Name and display it in the list.
hr = m_pSearch->GetColumn( hSearch, pszAttr[0], &col );
if ( SUCCEEDED(hr) )
{
switch (col.dwADsType)
{
case ADSTYPE_CASE_IGNORE_STRING:
printf("%S\n", col.pADsValues->CaseIgnoreString);
break;
case ADSTYPE_PROV_SPECIFIC:
printf("%S\n", col.pADsValues->ProviderSpecific.lpValue);
break;
default:
printf("Unexpected ADsType: %d\n", col.dwADsType);
break;
}
{
m_pSearch->FreeColumn( &col );
}
}
}
m_pSearch->CloseSearchHandle( hSearch );
IDirectorySearch::FreeColumn メソッドは、IDirectorySearch::GetColumn メソッドが列のデータのために割り当てたメモリを解放します。
| pSearchColumn | ADS_SEARCH_COLUMN* | in | 解放する列へのポインターを指定します。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
その他の戻り値については、ADSI エラーコードを参照してください。
IDirectorySearch::CloseSearchHandle メソッドは、検索結果へのハンドルを閉じ、関連するメモリを解放します。
| hSearchResult | ADS_SEARCH_HANDLE | in | 閉じる検索結果へのハンドルを指定します。 |
戻り値
このメソッドは、標準の戻り値に加えて次の値を返します。
その他の戻り値については、ADSI エラーコードを参照してください。
解説(Remarks)
IDirectorySearch::CloseSearchHandle メソッドを実装するプロセスは、検索結果および検索結果ハンドルを含め、IDirectorySearch::ExecuteSearch メソッドによって割り当てられたすべてのメモリの解放も担当する必要があります。
呼び出し元は、開かれた各検索ハンドルに対してこのメソッドを 1 回だけ呼び出すことができ、IDirectorySearch::CloseSearchHandle を発行した後に新しい検索ハンドルを取得するには IDirectorySearch::ExecuteSearch メソッドを使用する必要があります。
例
ADS_SEARCH_HANDLE hSearch;
HRESULT hr;
hr = m_pSearch->ExecuteSearch(L"(&(objectCategory=user)(l=Redmond))", pszAttr, dwCount, &hSearch );
if ( SUCCEEDED(hr) )
{
// Omit getting the data
m_pSearch->CloseSearchHandle(hSearch);
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDirectorySearch "{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}" #usecom global IDirectorySearch IID_IDirectorySearch "{}" #comfunc global IDirectorySearch_SetSearchPreference 3 var,int #comfunc global IDirectorySearch_ExecuteSearch 4 wstr,var,int,var #comfunc global IDirectorySearch_AbandonSearch 5 sptr #comfunc global IDirectorySearch_GetFirstRow 6 sptr #comfunc global IDirectorySearch_GetNextRow 7 sptr #comfunc global IDirectorySearch_GetPreviousRow 8 sptr #comfunc global IDirectorySearch_GetNextColumnName 9 sptr,var #comfunc global IDirectorySearch_GetColumn 10 sptr,wstr,var #comfunc global IDirectorySearch_FreeColumn 11 var #comfunc global IDirectorySearch_CloseSearchHandle 12 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDirectorySearch "{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}" #usecom global IDirectorySearch IID_IDirectorySearch "{}" #comfunc global IDirectorySearch_SetSearchPreference 3 sptr,int #comfunc global IDirectorySearch_ExecuteSearch 4 wstr,sptr,int,sptr #comfunc global IDirectorySearch_AbandonSearch 5 sptr #comfunc global IDirectorySearch_GetFirstRow 6 sptr #comfunc global IDirectorySearch_GetNextRow 7 sptr #comfunc global IDirectorySearch_GetPreviousRow 8 sptr #comfunc global IDirectorySearch_GetNextColumnName 9 sptr,sptr #comfunc global IDirectorySearch_GetColumn 10 sptr,wstr,sptr #comfunc global IDirectorySearch_FreeColumn 11 sptr #comfunc global IDirectorySearch_CloseSearchHandle 12 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。