BOOL RecursiveIsMember(IADsGroup * pADsGroup,LPWSTR pwszMemberGUID,LPWSTR pwszMemberPath, BOOL bVerbose, LPOLESTR pwszUser, LPOLESTR pwszPassword) { HRESULT hr = S_OK; // COM Result Code IADsMembers * pADsMembers = NULL; // Ptr to Members of the IADsGroup BOOL fContinue = TRUE; // Looping Variable IEnumVARIANT * pEnumVariant = NULL; // Ptr to the Enum variant IUnknown * pUnknown = NULL; // IUnknown for getting the ENUM initially VARIANT VariantArray[FETCH_NUM]; // Variant array for temp holding returned data ULONG ulElementsFetched = NULL; // Number of elements retrieved BSTR bsGroupPath = NULL; BOOL bRet = FALSE; if(!pADsGroup || !pwszMemberGUID || !pwszMemberPath) { return FALSE; } // Get the path of the object passed in hr = pADsGroup->get_ADsPath(&bsGroupPath); if (!SUCCEEDED(hr)) return hr; if (bVerbose) { WCHAR pwszOutput[2048]; wsprintf(pwszOutput,L"Checking the Group:\n\n%s\n\n for the member:\n\n%s\n\n",bsGroupPath,pwszMemberPath); PrintBanner(pwszOutput); } // Get an interface pointer to the IADsCollection of members hr = pADsGroup->Members(&pADsMembers); if (SUCCEEDED(hr)) { // Query the IADsCollection of members for a new ENUM Interface // Be aware that the enum comes back as an IUnknown * hr = pADsMembers->get__NewEnum(&pUnknown); if (SUCCEEDED(hr)) { // QI the IUnknown * for an IEnumVARIANT interface hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void **)&pEnumVariant); if (SUCCEEDED(hr)) { // While have not hit errors or end of data.... while (fContinue) { ulElementsFetched = 0; // Get a "batch" number of group members-number of rows specified by FETCH_NUM hr = ADsEnumerateNext(pEnumVariant, FETCH_NUM, VariantArray, &ulElementsFetched); if (ulElementsFetched ) { // Loop through the current batch-printing the path for each member. for (ULONG i = 0; i < ulElementsFetched; i++ ) { IDispatch * pDispatch = NULL; // ptr for holding dispath of element BSTR bstrCurrentPath = NULL; // Holds path of object BSTR bstrGuidCurrent = NULL; // Holds path of object IDirectoryObject * pIDOCurrent = NULL;// Holds the current object // Get the dispatch ptr for the variant pDispatch = VariantArray[i].pdispVal; // assert(HAS_BIT_STYLE(VariantArray[i].vt,VT_DISPATCH)); // Get the IADs interface for the "member" of this group hr = pDispatch->QueryInterface(IID_IDirectoryObject, (VOID **) &pIDOCurrent ) ; if (SUCCEEDED(hr)) { // Get the GUID for the current object hr = GetObjectGuid(pIDOCurrent,bstrGuidCurrent); if (FAILED(hr)) return hr; IADs * pIADsCurrent = NULL; // Retrieve the IADs Interface for the current object hr = pIDOCurrent->QueryInterface(IID_IADs,(void**)&pIADsCurrent); if (FAILED(hr)) return hr; // Get the ADsPath property for this member hr = pIADsCurrent->get_ADsPath(&bstrCurrentPath); if (SUCCEEDED(hr)) { if (bVerbose) wprintf(L"Comparing:\n\n%s\nWITH:\n%s\n\n",bstrGuidCurrent,pwszMemberGUID); // Verify that the member of this group is Equal to passed. if (_wcsicmp(bstrGuidCurrent,pwszMemberGUID)==0) { if (bVerbose) wprintf(L"!!!!!Object:\n\n%s\n\nIs a member of\n\n%s\n\n",pwszMemberPath,bstrGuidCurrent); bRet = TRUE; break; } else // Otherwise, bind to this and see if it is a group. { // If is it a group then the QI to IADsGroup succeeds IADsGroup * pIADsGroupAsMember = NULL; if (pwszUser) hr = ADsOpenObject( bstrCurrentPath, pwszUser, pwszPassword, ADS_SECURE_AUTHENTICATION, IID_IADsGroup, (void**) &pIADsGroupAsMember); else hr = ADsGetObject( bstrCurrentPath, IID_IADsGroup,(void **)&pIADsGroupAsMember); // If bind was completed, then this is a group. if (SUCCEEDED(hr)) { // Recursively call this group to verify this group. BOOL bRetRecurse; bRetRecurse = RecursiveIsMember(pIADsGroupAsMember,pwszMemberGUID,pwszMemberPath,bVerbose,pwszUser ,pwszPassword ); if (bRetRecurse) { bRet = TRUE; break; } pIADsGroupAsMember->Release(); pIADsGroupAsMember = NULL; } } SysFreeString(bstrCurrentPath); bstrCurrentPath = NULL; SysFreeString(bstrGuidCurrent); bstrGuidCurrent = NULL; } // Release pIDOCurrent->Release(); pIDOCurrent = NULL; if (pIADsCurrent) { pIADsCurrent->Release(); pIADsCurrent = NULL; } } } // Clear the variant array. memset(VariantArray, 0, sizeof(VARIANT)*FETCH_NUM); } else fContinue = FALSE; } pEnumVariant->Release(); pEnumVariant = NULL; } pUnknown->Release(); pUnknown = NULL; } pADsMembers ->Release(); pADsMembers = NULL; } // Free the group path if retrieved. if (bsGroupPath) { SysFreeString(bsGroupPath); bsGroupPath = NULL; } return bRet; }
/* Note: Using the UNICODE version of main(). this removes the need for the sample to include UNICODE-ANSI conversion routines */ void wmain( int argc, wchar_t *argv[ ]) { WCHAR pwszTemp[4096]; // We have now scanned PAST whitespace- so copy the string: wcscpy_s(pwszTemp,4096,L" A String"); Trim(pwszTemp); HRESULT hr; IDirectoryObject * pDirObjectContainer = NULL; IDirectoryObject * pDirObjRet = NULL; if (!ParseCommandLine(argc,argv)) return; // Initialize COM CoInitialize(0); // Bind to the container passed // If USER and PASS passed in, use ADsOpenObject() if (bsUSER) hr = ADsOpenObject(bsLDAP, bsUSER, bsPASS, ADS_SECURE_AUTHENTICATION,IID_IDirectoryObject, (void**) &pDirObjectContainer); else hr = ADsGetObject( bsLDAP, IID_IDirectoryObject,(void **)&pDirObjectContainer); if (SUCCEEDED(hr)) { // if a file is NOT passed in- Do the simple version if (!bsFILE) { // Call the helper funtion to create the User hr = CreateUser(pDirObjectContainer, bsUNAME,bsSAMNAME, &pDirObjRet); } else // file was passed in { // Call the helper funtion to create the User hr = CreateUserFromFile(pDirObjectContainer, bsUNAME,bsSAMNAME, &pDirObjRet,bsFILE); } if (SUCCEEDED(hr)) { _putws(L"\n\n New User created with the following properties:\n"); IADs * pIADsNewGoup = NULL; // User succeeded- now get an IADs interface to it // and print some properties hr = pDirObjRet->QueryInterface(IID_IADs,(void**)&pIADsNewGoup); if (SUCCEEDED(hr)) { PrintIADSObject(pIADsNewGoup); pIADsNewGoup->Release(); pIADsNewGoup = NULL; } else CheckADHRESULT(hr,L"QueryInterface() - New User for IADs"); pDirObjRet->Release(); pDirObjRet = NULL; } else CheckADHRESULT(hr,L"CreateUser()"); pDirObjectContainer->Release(); pDirObjectContainer = NULL; } else if (bsUSER) CheckADHRESULT(hr,L"ADsOpenObject()"); else CheckADHRESULT(hr,L"ADsGetObject()"); if ( bsLDAP ) ::SysFreeString(bsLDAP); if ( bsUNAME ) ::SysFreeString(bsUNAME); if ( bsSAMNAME ) ::SysFreeString(bsSAMNAME); if ( bsFILE ) ::SysFreeString(bsFILE); if ( bsUSER ) ::SysFreeString(bsUSER); if ( bsPASS ) ::SysFreeString(bsPASS); CoUninitialize(); }