[INFO] IDirectorySearch::GetNextRow を呼び出すと結果が切り捨てられる

この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
概要
IDirectorySearch::GetNextRow 関数に関する MSDN ドキュメントは不完全です。 戻り値 S_ADS_NOMORE_ROWS の説明が誤っています。 このコードは "現在の行が最後の行で、変更されません" とはなっていません。 説明は "現時点では、現在の行が最終行です" とすべきです。これが本当に最終行であることを確認するには、ADsGetLastError を呼び出す必要があります。

処理が失敗するたびに、ADSI は拡張エラー コードを設定し、それは ADsGetLastError を使用して照会できます。 この拡張エラーが開発者によって処理されない場合、すべての行が処理済みになる前に、検索処理が途中で終了してしまうことがあります。 最新の Windows 2000 Service Pack の関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
260910 How to Obtain the Latest Windows 2000 Service Pack
260910 最新の Windows 2000 Service Pack の入手方法
詳細
IDirectorySearch::GetNextRow 関数により S_ADS_NOMORE_ROWS が返された場合、すべてのデータをサーバーから取得済みではないことがあります。 サーバーがあらかじめ設定された 2 分の制限時間内に検索条件に一致するエントリを見つけることができなかった場合、GetNextRow 関数により S_ADS_NOMORE_ROWS が返されることがあります。 この 2 分の時間制限は、LDAP ポリシーによって定義されます。 LDAP ポリシーの関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
315071 HOW TO: View and Set LDAP Policies by Using Ntdsutil.exe
サーバーが 2 分の時間制限を超えた場合、応答で LDAP Cookie が返されるため、中断された箇所から検索を再開できます。 非効率的な検索方法やシステムの負荷が高いことが原因で、サーバーがこの時間制限を超える可能性があります。 サーバーが検索に効果的なインデックスを見つけられない場合、サーバーはディレクトリ内のすべてのオブジェクトに対してフィルタを適用することが必要になる場合があります。その場合、多数のエントリを検索するため、2 分の制限時間内に一致を発見できない可能性があります。

S_ADS_NOMORE_ROWS が返された場合、ADSI により拡張エラー コードも設定されます。これは ADsGetLastError 関数を使用して照会できます。 ADsGetLastError により ERROR_MORE_DATA が返された場合、サーバーがクエリを未完了で、GetNextRow を再び呼び出す必要があることを示します。

次のコード サンプルに示すように、Platform SDK サンプル ファイル DsSrch を、この検索方法を処理するように変更できます。
"MAIN.CXX" file//------------------------------------------------------------------// //  Function:   Q325189_GetNextRow// //  Synopsis:// //------------------------------------------------------------------HRESULT Q325189_GetNextRow(IDirectorySearch *pDSSearch, ADS_SEARCH_HANDLE hSearchHandle){HRESULT hr = S_OK;DWORD dwADsExtError = ERROR_SUCCESS;WCHAR szErrorBuf[512];WCHAR szNameBuf[128];do{	// Clear ADSI extended error	dwADsExtError = ERROR_SUCCESS;	ADsSetLastError(ERROR_SUCCESS, NULL, NULL);	// Next row	hr = pDSSearch->GetNextRow(hSearchHandle);	BAIL_ON_FAILURE(hr);	// Check ADSI extend error if we got S_ADS_NOMORE_ROWS	if (S_ADS_NOMORE_ROWS == hr)	{		hr = ADsGetLastError(&dwADsExtError, szErrorBuf, 512, szNameBuf, 128);		BAIL_ON_FAILURE(hr);		if (ERROR_MORE_DATA != dwADsExtError)			// All data received			return ERROR_NO_DATA;	}} while (ERROR_MORE_DATA == dwADsExtError);return ERROR_MORE_DATA;error:return hr;}//------------------------------------------------------------------// //  Function:   main// //  Synopsis:// //------------------------------------------------------------------INT _CRTAPI1main(int argc, char * argv[]){...// *** MODIFIED FOR Q325189 *** //hr = pDSSearch->GetNextRow(//         hSearchHandle//         );//BAIL_ON_FAILURE(hr);hr = Q325189_GetNextRow(pDSSearch, hSearchHandle); // *** EOM ***// *** MODIFIED FOR Q325189 *** //while (hr != S_ADS_NOMORE_ROWS && nRows < dwMaxRows) {<BR/>         BAIL_ON_FAILURE(hr);while (nRows < dwMaxRows) {// *** EOM ***        nRows++;        if (dwNumberAttributes == -1) {            hr = pDSSearch->GetNextColumnName(                     hSearchHandle,                     &pszColumnName                     );            BAIL_ON_FAILURE(hr);            while (hr != S_ADS_NOMORE_COLUMNS) {                hr = pDSSearch->GetColumn(                         hSearchHandle,                         pszColumnName,                         &Column                         );                if (FAILED(hr)  && hr != E_ADS_COLUMN_NOT_SET)                    goto error;                if (SUCCEEDED(hr)) {                    PrintColumn(&Column, pszColumnName);                    pDSSearch->FreeColumn(&Column);                }                FreeADsMem(pszColumnName);                hr = pDSSearch->GetNextColumnName(                         hSearchHandle,                         &pszColumnName                         );                BAIL_ON_FAILURE(hr);            }            printf("\n");        }        else {            for (DWORD i=0; i<dwNumberAttributes; i++) {                hr = pDSSearch->GetColumn(                         hSearchHandle,                         pszAttrNames[i],                         &Column                         );                if (hr == E_ADS_COLUMN_NOT_SET)                    continue;                BAIL_ON_FAILURE(hr);                PrintColumn(&Column, pszAttrNames[i]);                pDSSearch->FreeColumn(&Column);            }        printf("\n");        }// *** MODIFIED FOR Q325189 ***         //hr = pDSSearch->GetNextRow(        //         hSearchHandle        //         );        //BAIL_ON_FAILURE(hr);	hr = Q325189_GetNextRow(pDSSearch, hSearchHandle); // *** END OF MODIFICATION ***    }    wprintf (L"Total Rows: %d\n", nRows);...}			
関連情報
詳細については、次の MSDN Web サイトを参照してください。
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 325189 (最終更新日 2003-06-12) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
IDirectorySearch GetNextRow S_ADS_NOMORE_ROWS ERROR_MORE_DATA ADsGetLastError truncated
プロパティ

文書番号:325189 - 最終更新日: 01/17/2015 16:41:44 - リビジョン: 2.1

  • Microsoft Active Directory Service Interfaces 2.5
  • Microsoft Active Directory Service Interfaces 2.5
  • kbnosurvey kbarchive kbinfo kbwin2ksp4fix KB325189
フィードバック