ADSI过滤使用c ++的OU中的所有计算机

时间:2015-06-18 07:19:03

标签: c++ ldap-query adsi

我是c ++的新手。使用MSDN article iam的帮助尝试使用ADSI获取域中OU下的所有计算机。但我得到8254L(FILTER_UNKNOWN)错误。我不知道我在这里做错了什么。我尝试更新过滤器但没有更改错误。请在这里建议我做错了什么。

以下是用于获取列表的代码。

// ConsoleApplication3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <objbase.h>
#include <wchar.h>
#include <activeds.h>
#include <sddl.h>
#include <comutil.h>
#include <string.h>
#include <stdio.h>


HRESULT FindComputers(IDirectorySearch *pContainerToSearch,  //  IDirectorySearch pointer to the container to search.
    LPOLESTR szFilter, //  Filter to find specific users.
    //  NULL returns all user objects.
    LPOLESTR *pszPropertiesToReturn, //  Properties to return for user objects found.
    //  NULL returns all set properties.
    BOOL bIsVerbose //  TRUE indicates that display all properties for the found objects.
    //  FALSE indicates that only the RDN.
    );


//  Entry point for the application.
void wmain(int argc, wchar_t *argv[])
{
    //  Initialize COM.
    CoInitialize(NULL);
    HRESULT hr = S_OK;
    //  Get rootDSE and the current user domain container distinguished name.
    IADs *pObject = NULL;
    IDirectorySearch *pContainerToSearch = NULL;
    LPOLESTR szPath = new OLECHAR[MAX_PATH];
    BOOL bReturnVerbose = FALSE;
    DWORD dwLength = MAX_PATH * 2;
    LPOLESTR pszBuffer = new OLECHAR[dwLength];
    VARIANT var;

    hr = ADsOpenObject(L"LDAP://rootDSE",
        NULL,
        NULL,
        ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
        IID_IADs,
        (void**)&pObject);
    if (FAILED(hr))
    {
        wprintf(L"Cannot execute query. Cannot bind to LDAP://rootDSE.\n");
        if (pObject)
            pObject->Release();
        return;
    }
    if (SUCCEEDED(hr))
    {
        hr = pObject->Get(_bstr_t("defaultNamingContext"), &var);
        if (SUCCEEDED(hr))
        {
            wprintf(L"bstrVal: %s\n", var.bstrVal);
            //  Build path to the domain container.

          // wcsncpy_s(szPath, L"LDAP://", MAX_PATH);
          // wcsncat_s(szPath, var.bstrVal, MAX_PATH - wcslen(szPath));


           //hr = ADsOpenObject(szPath,
           hr = ADsOpenObject(L"LDAP://OU=IA Computers,OU=Infosys,DC=iaseries,Dc=local",
                NULL,
                NULL,
                ADS_SECURE_AUTHENTICATION, //  Use Secure Authentication.
                IID_IDirectorySearch,
                (void**)&pContainerToSearch);

            if (SUCCEEDED(hr))
            {
                hr = FindComputers(pContainerToSearch, //  IDirectorySearch pointer to domainDNS container.
                    pszBuffer,
                    NULL, //  Return all properties.
                    bReturnVerbose
                    );
                if (SUCCEEDED(hr))
                {
                    if (S_FALSE == hr)
                        wprintf(L"Computer object cannot be found.\n");
                }
                else if (E_ADS_INVALID_FILTER == hr)
                    wprintf(L"Cannot execute query. Invalid filter was specified.\n");
                else
                    wprintf(L"Query failed to run. HRESULT: %x\n", hr);

            }
            else
            {
                wprintf(L"Cannot execute query. Cannot bind to the container.\n");
            }
            if (pContainerToSearch)
                pContainerToSearch->Release();

        }
        VariantClear(&var);

    }

    if (pObject)
        pObject->Release();

    //  Uninitialize COM.
    CoUninitialize();
    delete[] szPath;
    delete[] pszBuffer;

    getchar();

}


HRESULT FindComputers(IDirectorySearch *pContainerToSearch,  //  IDirectorySearch pointer to the container to search.
    LPOLESTR szFilter, //  Filter for finding specific users.
    //  NULL returns all user objects.
    LPOLESTR *pszPropertiesToReturn, //  Properties to return for user objects found.
    //  NULL returns all set properties.
    BOOL bIsVerbose    //  TRUE indicates that all properties for the found objects are displayed.
    //  FALSE indicates only the RDN.
    )
{
    if (!pContainerToSearch)
        return E_POINTER;
    DWORD dwLength = (MAX_PATH * 2)+100;
    // Create search filter.
    LPOLESTR pszSearchFilter = new OLECHAR[dwLength];

    //  Add the filter.
    //swprintf_s(pszSearchFilter, dwLength, L"((objectClass=Computer)%s)", szFilter);
    swprintf_s(pszSearchFilter, dwLength, L"(&(objectClass=*)(objectCategory=Computer)%s)", szFilter);


    //  Specify subtree search.
    ADS_SEARCHPREF_INFO SearchPrefs;
    SearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
    SearchPrefs.vValue.dwType = ADSTYPE_INTEGER;
    SearchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE;
    DWORD dwNumPrefs = 1;

    //  COL for iterations.
    LPOLESTR pszColumn = NULL;
    ADS_SEARCH_COLUMN col;
    HRESULT hr = S_OK;

    //  Interface Pointers
    IADs  *pObj = NULL;
    IADs  * pIADs = NULL;

    //  Search handle.
    ADS_SEARCH_HANDLE hSearch = NULL;

    //  Set search preference.
    hr = pContainerToSearch->SetSearchPreference(&SearchPrefs, dwNumPrefs);
    if (FAILED(hr))
        return hr;

    LPOLESTR pszBool = NULL;
    DWORD dwBool = 0;
    PSID pObjectSID = NULL;
    LPOLESTR szSID = NULL;
    LPOLESTR szDSGUID = new WCHAR[39];
    LPGUID pObjectGUID = NULL;
    SYSTEMTIME systemtime;
    DATE date;
    VARIANT varDate;
    LPOLESTR *pszPropertyList = NULL;
    LPOLESTR pszNonVerboseList[] = { L"name", L"distinguishedName" };

    LPOLESTR szName = new OLECHAR[MAX_PATH];
    LPOLESTR szDN = new OLECHAR[MAX_PATH];

    VariantInit(&varDate);

    int iCount = 0;
    DWORD x = 0L;



    if (!bIsVerbose)
    {
        //  Return non-verbose list properties only.
        hr = pContainerToSearch->ExecuteSearch(pszSearchFilter,
            pszNonVerboseList,
            sizeof(pszNonVerboseList) / sizeof(LPOLESTR),
            &hSearch
            );
    }
    else
    {
        if (!pszPropertiesToReturn)
        {
            //  Return all properties.
            hr = pContainerToSearch->ExecuteSearch(pszSearchFilter,
                NULL,
                (DWORD)-1,
                &hSearch
                );
        }
        else
        {
            //  Specified subset.
            pszPropertyList = pszPropertiesToReturn;
            //  Return specified properties.
            hr = pContainerToSearch->ExecuteSearch(pszSearchFilter,
                pszPropertyList,
                sizeof(pszPropertyList) / sizeof(LPOLESTR),
                &hSearch
                );
        }
    }
    if (SUCCEEDED(hr))
    {
        //  Call IDirectorySearch::GetNextRow() to retrieve the next data row.
        hr = pContainerToSearch->GetFirstRow(hSearch);
        if (SUCCEEDED(hr))
        {
            while (hr != S_ADS_NOMORE_ROWS)
            {
                //  Keep track of count.
                iCount++;
                if (bIsVerbose)
                    wprintf(L"----------------------------------\n");
                //  Loop through the array of passed column names,
                //  print the data for each column.

                while (pContainerToSearch->GetNextColumnName(hSearch, &pszColumn) != S_ADS_NOMORE_COLUMNS)
                {
                    hr = pContainerToSearch->GetColumn(hSearch, pszColumn, &col);
                    if (SUCCEEDED(hr))
                    {
                        //  Print the data for the column and free the column.
                        if (bIsVerbose)
                        {
                            //  Get the data for this column.
                            wprintf(L"%s\n", col.pszAttrName);
                            switch (col.dwADsType)
                            {
                            case ADSTYPE_DN_STRING:
                                for (x = 0; x< col.dwNumValues; x++)
                                {
                                    wprintf(L"  %s\r\n", col.pADsValues[x].DNString);
                                }
                                break;
                            case ADSTYPE_CASE_EXACT_STRING:
                            case ADSTYPE_CASE_IGNORE_STRING:
                            case ADSTYPE_PRINTABLE_STRING:
                            case ADSTYPE_NUMERIC_STRING:
                            case ADSTYPE_TYPEDNAME:
                            case ADSTYPE_FAXNUMBER:
                            case ADSTYPE_PATH:
                                for (x = 0; x< col.dwNumValues; x++)
                                {
                                    wprintf(L"  %s\r\n", col.pADsValues[x].CaseIgnoreString);
                                }
                                break;
                            case ADSTYPE_BOOLEAN:
                                for (x = 0; x< col.dwNumValues; x++)
                                {
                                    dwBool = col.pADsValues[x].Boolean;
                                    pszBool = dwBool ? L"TRUE" : L"FALSE";
                                    wprintf(L"  %s\r\n", pszBool);
                                }
                                break;
                            case ADSTYPE_INTEGER:
                                for (x = 0; x< col.dwNumValues; x++)
                                {
                                    wprintf(L"  %d\r\n", col.pADsValues[x].Integer);
                                }
                                break;
                            case ADSTYPE_OCTET_STRING:
                                if (_wcsicmp(col.pszAttrName, L"objectSID") == 0)
                                {
                                    for (x = 0; x< col.dwNumValues; x++)
                                    {
                                        pObjectSID = (PSID)(col.pADsValues[x].OctetString.lpValue);
                                        //  Convert SID to string.
                                        ConvertSidToStringSid(pObjectSID, &szSID);
                                        wprintf(L"  %s\r\n", szSID);
                                        LocalFree(szSID);
                                    }
                                }
                                else if ((_wcsicmp(col.pszAttrName, L"objectGUID") == 0))
                                {
                                    for (x = 0; x< col.dwNumValues; x++)
                                    {
                                        //  Cast to LPGUID.
                                        pObjectGUID = (LPGUID)(col.pADsValues[x].OctetString.lpValue);
                                        //  Convert GUID to string.
                                        ::StringFromGUID2(*pObjectGUID, szDSGUID, 39);
                                        //  Print the GUID.
                                        wprintf(L"  %s\r\n", szDSGUID);
                                    }
                                }
                                else
                                    wprintf(L"  Value of type Octet String. No Conversion.");
                                break;
                            case ADSTYPE_UTC_TIME:
                                for (x = 0; x< col.dwNumValues; x++)
                                {
                                    systemtime = col.pADsValues[x].UTCTime;
                                    if (SystemTimeToVariantTime(&systemtime,
                                        &date) != 0)
                                    {
                                        //  Pack in variant.vt.
                                        varDate.vt = VT_DATE;
                                        varDate.date = date;
                                        VariantChangeType(&varDate, &varDate, VARIANT_NOVALUEPROP, VT_BSTR);
                                        wprintf(L"  %s\r\n", varDate.bstrVal);
                                        VariantClear(&varDate);
                                    }
                                    else
                                        wprintf(L"  Could not convert UTC-Time.\n", pszColumn);
                                }
                                break;
                            case ADSTYPE_NT_SECURITY_DESCRIPTOR:
                                for (x = 0; x< col.dwNumValues; x++)
                                {
                                    wprintf(L"  Security descriptor.\n");
                                }
                                break;
                            default:
                                wprintf(L"Unknown type %d.\n", col.dwADsType);
                            }
                        }
                        else
                        {
#ifdef _MBCS
                            //  Verbose handles only the two single-valued attributes: cn and ldapdisplayname,
                            //  so this is a special case.
                            if (0 == wcscmp(L"name", pszColumn))
                            {
                                //wcscpy_s(szName, col.pADsValues->CaseIgnoreString);
                                szName = col.pADsValues->CaseIgnoreString;
                            }
                            if (0 == wcscmp(L"distinguishedName", pszColumn))
                            {
                                //wcscpy_s(szDN, col.pADsValues->CaseIgnoreString);
                                szDN = col.pADsValues->CaseIgnoreString;
                            }
#endif _MBCS
                        }
                        pContainerToSearch->FreeColumn(&col);
                    }
                    FreeADsMem(pszColumn);
                }
                if (!bIsVerbose)
                    wprintf(L"%s\n  DN: %s\n\n", szName, szDN);
                //  Get the next row.
                hr = pContainerToSearch->GetNextRow(hSearch);
            }

        }
        //  Close the search handle to cleanup.
        pContainerToSearch->CloseSearchHandle(hSearch);
    }
    if (SUCCEEDED(hr) && 0 == iCount)
        hr = S_FALSE;

    delete[] szName;
    delete[] szDN;
    delete[] szDSGUID;
    delete[] pszSearchFilter;
    return hr;
}

1 个答案:

答案 0 :(得分:0)

我能够找出问题所在。下面是工作样本的代码。 我没有多清理代码。如果您打算使用,请更新。

// ConsoleApplication3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <objbase.h>
#include <wchar.h>
#include <activeds.h>
#include <sddl.h>
#include <comutil.h>
#include <string.h>
#include <stdio.h>


HRESULT FindComputers(IDirectorySearch *pContainerToSearch);  //  IDirectorySearch pointer to the container to search.
	


//  Entry point for the application.
void wmain(int argc, wchar_t *argv[])
{
	//  Initialize COM.
	CoInitialize(NULL);
	HRESULT hr = S_OK;
	//  Get rootDSE and the current user domain container distinguished name.
	IADs *pObject = NULL;
	IDirectorySearch *pContainerToSearch = NULL;
	LPOLESTR szPath = new OLECHAR[MAX_PATH];
	BOOL bReturnVerbose = FALSE;
	DWORD dwLength = MAX_PATH * 2;
	VARIANT var;
	
	hr = ADsOpenObject(L"LDAP://rootDSE",
		NULL,
		NULL,
		ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
		IID_IADs,
		(void**)&pObject);
	if (FAILED(hr))
	{
		wprintf(L"Cannot execute query. Cannot bind to LDAP://rootDSE.\n");
		if (pObject)
			pObject->Release();
		return;
	}
	if (SUCCEEDED(hr))
	{
		hr = pObject->Get(_bstr_t("defaultNamingContext"), &var);
		if (SUCCEEDED(hr))
		{
			//wprintf(L"bstrVal: %s\n", var.bstrVal);
			
			//  Build path to the domain container.
		   // wcsncpy_s(szPath, L"LDAP://", MAX_PATH);
		  // wcsncat_s(szPath, var.bstrVal, MAX_PATH - wcslen(szPath));
			
		   
		   //hr = ADsOpenObject(szPath,
		   hr = ADsOpenObject(L"LDAP://OU=IA Computers,OU=MyDept,DC=Test,Dc=com",
				NULL,
				NULL,
				ADS_SECURE_AUTHENTICATION, //  Use Secure Authentication.
				IID_IDirectorySearch,
				(void**)&pContainerToSearch);

			if (SUCCEEDED(hr))
			{
				hr = FindComputers(pContainerToSearch); //  IDirectorySearch pointer to domainDNS container.
					
				if (SUCCEEDED(hr))
				{
					if (S_FALSE == hr)
						wprintf(L"Computer object cannot be found.\n");
				}
				else if (E_ADS_INVALID_FILTER == hr)
					wprintf(L"Cannot execute query. Invalid filter was specified.\n");
				else
					wprintf(L"Query failed to run. HRESULT: %x\n", hr);

			}
			else
			{
				wprintf(L"Cannot execute query. Cannot bind to the container.\n");
			}
			if (pContainerToSearch)
				pContainerToSearch->Release();

		}
		VariantClear(&var);

	}

	if (pObject)
		pObject->Release();

	//  Uninitialize COM.
	CoUninitialize();
	delete[] szPath;

	getchar();
	
}


HRESULT FindComputers(IDirectorySearch *pContainerToSearch)  //  IDirectorySearch pointer to the container to search.
{
	if (!pContainerToSearch)
		return E_POINTER;
	DWORD dwLength = (MAX_PATH * 2);
	// Create search filter.
	LPOLESTR pszSearchFilter = new OLECHAR[dwLength];

	//  Add the filter.
	pszSearchFilter = L"((objectCategory=computer))";
	
	//  Specify subtree search.
	ADS_SEARCHPREF_INFO SearchPrefs;
	SearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
	SearchPrefs.vValue.dwType = ADSTYPE_INTEGER;
	SearchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE;
	DWORD dwNumPrefs = 1;

	//  COL for iterations.
	LPOLESTR pszColumn = NULL;
	ADS_SEARCH_COLUMN col;
	HRESULT hr = S_OK;

	//  Interface Pointers
	IADs  *pObj = NULL;
	IADs  * pIADs = NULL;

	//  Search handle.
	ADS_SEARCH_HANDLE hSearch = NULL;

	//  Set search preference.
	hr = pContainerToSearch->SetSearchPreference(&SearchPrefs, dwNumPrefs);
	if (FAILED(hr))
		return hr;

	LPOLESTR pszNonVerboseList[] = { L"name", L"distinguishedName" };

	LPOLESTR szName = new OLECHAR[MAX_PATH];
	LPOLESTR szDN = new OLECHAR[MAX_PATH];
		
	int iCount = 0;
	DWORD x = 0L;
	

	//  Return non-verbose list properties only.
	hr = pContainerToSearch->ExecuteSearch(pszSearchFilter,
		pszNonVerboseList,
		sizeof(pszNonVerboseList) / sizeof(LPOLESTR),
		&hSearch
		);

	if (SUCCEEDED(hr))
	{
		//  Call IDirectorySearch::GetNextRow() to retrieve the next data row.
		hr = pContainerToSearch->GetFirstRow(hSearch);
		if (SUCCEEDED(hr))
		{
			while (hr != S_ADS_NOMORE_ROWS)
			{
				//  Keep track of count.
				iCount++;
				
				//  Loop through the array of passed column names,
				//  print the data for each column.

				while (pContainerToSearch->GetNextColumnName(hSearch, &pszColumn) != S_ADS_NOMORE_COLUMNS)
				{
					hr = pContainerToSearch->GetColumn(hSearch, pszColumn, &col);
					if (SUCCEEDED(hr))
					{
						//  Verbose handles only the two single-valued attributes: cn and ldapdisplayname,
						//  so this is a special case.
						if (0 == wcscmp(L"name", pszColumn))
						{
							//wcscpy_s(szName, col.pADsValues->CaseIgnoreString);
							szName = col.pADsValues->CaseIgnoreString;
						}
						if (0 == wcscmp(L"distinguishedName", pszColumn))
						{
							//wcscpy_s(szDN, col.pADsValues->CaseIgnoreString);
							szDN = col.pADsValues->CaseIgnoreString;
						}
			
						pContainerToSearch->FreeColumn(&col);
					}
					FreeADsMem(pszColumn);
				}
				
				wprintf(L"%s\n  DN: %s\n\n", szName, szDN);

				//  Get the next row.
				hr = pContainerToSearch->GetNextRow(hSearch);
			}

		}
		//  Close the search handle to cleanup.
		pContainerToSearch->CloseSearchHandle(hSearch);
	}
	if (SUCCEEDED(hr) && 0 == iCount)
		hr = S_FALSE;

	delete[] szName;
	delete[] szDN;
	delete[] pszSearchFilter;
	return hr;
}

谢谢, 维杰