在我的应用程序中,我需要使用活动目录进行DirSync。但是,当我尝试为页面大小提供搜索首选项参数时,它向我显示错误(0x80005008,ADS_BAD_PARAMETER)。如果我不这样做,那就很好。我在下面给出代码片段:
HRESULT DoDirSyncSearch(
LPWSTR pszSearchFilter, // Search filter.
LPWSTR *pAttributeNames, // Attributes to retrieve.
DWORD dwAttributes, // Number of attributes.
PUCHAR *ppCookie, // Pointer to previous cookie.
PULONG pulCookieLength, // Length of previous cookie.
LPWSTR szDC) // Name of DC to bind to.
{
IADs *pRootDSE = NULL;
IDirectorySearch *pSearch = NULL;
ADS_SEARCH_HANDLE hSearch = NULL;
ADS_SEARCHPREF_INFO arSearchPrefs[4];
ADS_PROV_SPECIFIC dirsync;
ADS_SEARCH_COLUMN col;
HRESULT hr = S_OK;
VARIANT var;
BOOL bUpdate = FALSE;
DWORD dwCount = 0;
BOOL noMoreData = false;
DWORD dwError = ERROR_SUCCESS;
WCHAR szError[512];
WCHAR szProvider[512];
// Validate input parameters.
if (!pulCookieLength || !ppCookie || !szDC)
{
wprintf(L"Invalid parameter.\n");
return E_FAIL;
}
LPOLESTR szDSPath = new OLECHAR[MAX_PATH];
LPOLESTR szServerPath = new OLECHAR[MAX_PATH];
VariantInit(&var);
// If cookie is non-NULL, this is an update. Otherwise, it is a full-read.
if (*ppCookie)
bUpdate = TRUE;
CoInitialize(NULL);
// If there is a DC name from the previous USN sync,
// include it in the binding string.
if (szDC[0])
{
wcsncpy_s(szServerPath,MAX_PATH,L"LDAP://",MAX_PATH);
wcsncat_s(szServerPath, MAX_PATH,szDC,MAX_PATH-wcslen(szServerPath));
wcsncat_s(szServerPath, MAX_PATH,L"/",MAX_PATH-wcslen(szServerPath));
}
else
wcsncpy_s(szServerPath, MAX_PATH,L"LDAP://",MAX_PATH);
// Bind to root DSE.
wcsncpy_s(szDSPath,MAX_PATH,szServerPath,MAX_PATH);
wcsncat_s(szDSPath, MAX_PATH,L"rootDSE",MAX_PATH-wcslen(szDSPath));
wprintf(L"RootDSE binding string: %s\n", szDSPath);
hr = ADsGetObject(szDSPath,
IID_IADs,
(void**)&pRootDSE);
if (FAILED(hr))
{
wprintf(L"failed to bind to rootDSE: 0x%x\n", hr);
goto cleanup;
}
// Save the name of the DC connected to in order to connect to
// the same DC on the next dirsync operation.
if (! szDC[0])
{
hr = pRootDSE->Get(CComBSTR("DnsHostName"), &var);
wcsncpy_s(szServerPath,MAX_PATH,L"LDAP://",MAX_PATH);
wcsncat_s(szServerPath, MAX_PATH,var.bstrVal, MAX_PATH-wcslen(szServerPath));
wcsncat_s(szServerPath, MAX_PATH,L"/", MAX_PATH-wcslen(szServerPath));
}
// Get an IDirectorySearch pointer to the root of the domain partition.
hr = pRootDSE->Get(CComBSTR("defaultNamingContext"), &var);
wcsncpy_s(szDSPath,MAX_PATH,szServerPath,MAX_PATH);
wcsncat_s(szDSPath, MAX_PATH,var.bstrVal, MAX_PATH - wcslen(szDSPath));
hr = ADsGetObject(szDSPath, IID_IDirectorySearch, (void**) &pSearch);
if (FAILED(hr))
{
wprintf(L"failed to get IDirectorySearch: 0x%x\n", hr);
goto cleanup;
}
while(noMoreData == false) {
// Initialize the structure to pass in the cookie.
// On the first call, the cookie is NULL and the length is zero.
// On later calls, the cookie and length are the values returned by
// the previous call.
dirsync.dwLength = *pulCookieLength;
dirsync.lpValue = *ppCookie;
arSearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
arSearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER;
arSearchPrefs[0].vValue.Integer = ADS_SCOPE_SUBTREE;
arSearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_DIRSYNC;
arSearchPrefs[1].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
arSearchPrefs[1].vValue.ProviderSpecific = dirsync;
arSearchPrefs[2].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
arSearchPrefs[2].vValue.dwType = ADSTYPE_INTEGER;
arSearchPrefs[2].vValue.Integer = 100;
hr = pSearch->SetSearchPreference(arSearchPrefs, 3); // this is where error is happening
if (FAILED(hr))
{
wprintf(L"failed to set search prefs: 0x%x\n", hr);
goto cleanup;
}
// Search for the objects indicated by the search filter.
hr = pSearch->ExecuteSearch(pszSearchFilter,
pAttributeNames, dwAttributes, &hSearch );
if (FAILED(hr))
{
wprintf(L"failed to set execute search: 0x%x\n", hr);
goto cleanup;
}
// Loop through the rows of the search result
// Each row is an object that has changed since the previous call.
hr = pSearch->GetNextRow(hSearch);
while ( SUCCEEDED(hr) && hr != S_ADS_NOMORE_ROWS )
{
hr = pSearch->GetColumn( hSearch, L"distinguishedName", &col );
if ( SUCCEEDED(hr) )
{
wprintf(L"Distinguished Name: %s\n",col.pADsValues->CaseIgnoreString);
pSearch->FreeColumn( &col );
}
dwCount++;
hr = pSearch->GetNextRow( hSearch);
}
ADsGetLastError(&dwError, szError, 512, szProvider, 512);
if(ERROR_MORE_DATA == dwError)
{
noMoreData = false;
wprintf(L"Trying to get cookie...\n");
wprintf(L"Page ends here...\n");
hr = pSearch->GetColumn( hSearch, ADS_DIRSYNC_COOKIE, &col );
if ( SUCCEEDED(hr) ) {
if (col.dwADsType == ADSTYPE_PROV_SPECIFIC && col.pADsValues)
{
wprintf(L"Got cookie\n");
*pulCookieLength = col.pADsValues->ProviderSpecific.dwLength;
*ppCookie = (PUCHAR) AllocADsMem (*pulCookieLength);
memcpy(*ppCookie, col.pADsValues->ProviderSpecific.lpValue,
*pulCookieLength);
}
pSearch->FreeColumn( &col );
} else {
wprintf(L"no cookie: 0x%x\n", hr);
wprintf(L"Error!! More data available but could not continue because of error in cookie retrieval...\n");
noMoreData = true;
}
}
else
noMoreData = true;
}
wprintf(L"dwCount: %d\n", dwCount);
// After looping through the results, get the cookie.
if (hr == S_ADS_NOMORE_ROWS )
{
if (ppCookie != NULL)
{
// Free the existing heap allocation
GlobalFree (*ppCookie);
}
wprintf(L"Trying to get cookie...\n");
hr = pSearch->GetColumn( hSearch, ADS_DIRSYNC_COOKIE, &col );
if ( SUCCEEDED(hr) ) {
if (col.dwADsType == ADSTYPE_PROV_SPECIFIC && col.pADsValues)
{
wprintf(L"Got cookie\n");
*pulCookieLength = col.pADsValues->ProviderSpecific.dwLength;
*ppCookie = (PUCHAR) AllocADsMem (*pulCookieLength);
memcpy(*ppCookie, col.pADsValues->ProviderSpecific.lpValue,
*pulCookieLength);
}
pSearch->FreeColumn( &col );
} else
wprintf(L"no cookie: 0x%x\n", hr);
}
cleanup:
if (pRootDSE)
pRootDSE->Release();
if (hSearch)
pSearch->CloseSearchHandle(hSearch);
if (pSearch)
pSearch->Release();
VariantClear(&var);
CoUninitialize();
delete [] szServerPath;
delete [] szDSPath;
return hr;
}
如果我仅给出2个首选项,即Scope和DIRSYNC,则该行
hr = pSearch-> SetSearchPreference(arSearchPrefs,2);
没有给出任何错误。
谁能帮助我为什么会这样。我已经检查了从msdn指定分页选项的方式:http://msdn.microsoft.com/en-us/library/windows/desktop/aa746414(v=vs.85).aspx
提前致谢!
最佳答案
从MSDN link:
ADS_SEARCHPREF_DIRSYNC
指定目录同步(DirSync)
搜索,返回自指定状态以来的所有更改。在里面
在ADSVALUE结构中,将dwType成员设置为ADS_PROV_SPECIFIC。的
ProviderSpecific成员是一个ADS_PROV_SPECIFIC结构,其结构
lpValue成员指定一个cookie,该cookie指示从中获取的状态
找回更改。第一次使用DirSync控件时,请设置
ADS_PROV_SPECIFIC结构的dwLength和lpValue成员
分别为零和NULL。读取结果集后返回
搜索,直到IDirectorySearch :: GetNextRow返回
S_ADS_NOMORE_ROWS,调用IDirectorySearch :: GetColumn来检索
ADS_DIRSYNC_COOKIE属性,其中包含要在
下一个DirSync搜索。有关更多信息,请参见轮询更改。
使用DirSync控件和LDAP_SERVER_DIRSYNC_OID。这个标志
不能与ADS_SEARCHPREF_PAGESIZE结合使用。来电者必须有
SE_SYNC_AGENT_NAME特权。