HRESULT CpiFindCollectionObject( ICatalogCollection* piColl, LPCWSTR pwzID, LPCWSTR pwzName, ICatalogObject** ppiObj ) { HRESULT hr = S_OK; IDispatch* piDisp = NULL; ICatalogObject* piObj = NULL; VARIANT vtVal; ::VariantInit(&vtVal); long lCnt; hr = piColl->get_Count(&lCnt); ExitOnFailure(hr, "Failed to get to number of items in collection"); for (long i = 0; i < lCnt; i++) { // get ICatalogObject interface hr = piColl->get_Item(i, &piDisp); ExitOnFailure(hr, "Failed to get object from collection"); hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj); ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface"); // compare id if (pwzID && *pwzID) { hr = piObj->get_Key(&vtVal); ExitOnFailure(hr, "Failed to get key"); hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR); ExitOnFailure(hr, "Failed to change variant type"); if (0 == lstrcmpiW(vtVal.bstrVal, pwzID)) { if (ppiObj) { *ppiObj = piObj; piObj = NULL; } ExitFunction1(hr = S_OK); } ::VariantClear(&vtVal); } // compare name if (pwzName && *pwzName) { hr = piObj->get_Name(&vtVal); ExitOnFailure(hr, "Failed to get name"); hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR); ExitOnFailure(hr, "Failed to change variant type"); if (0 == lstrcmpW(vtVal.bstrVal, pwzName)) { if (ppiObj) { *ppiObj = piObj; piObj = NULL; } ExitFunction1(hr = S_OK); } ::VariantClear(&vtVal); } // release interface pointers ReleaseNullObject(piDisp); ReleaseNullObject(piObj); } hr = S_FALSE; LExit: // clean up ReleaseObject(piDisp); ReleaseObject(piObj); ::VariantClear(&vtVal); return hr; }
HRESULT CpiRemoveCollectionObject( ICatalogCollection* piColl, LPCWSTR pwzID, LPCWSTR pwzName, BOOL fResetDeleteable ) { HRESULT hr = S_OK; IDispatch* piDisp = NULL; ICatalogObject* piObj = NULL; BOOL fMatch = FALSE; VARIANT vtVal; ::VariantInit(&vtVal); long lCnt; hr = piColl->get_Count(&lCnt); ExitOnFailure(hr, "Failed to get to number of items in collection"); for (long i = 0; i < lCnt; i++) { // get ICatalogObject interface hr = piColl->get_Item(i, &piDisp); ExitOnFailure(hr, "Failed to get object from collection"); hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj); ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface"); // compare id if (pwzID && *pwzID) { hr = piObj->get_Key(&vtVal); ExitOnFailure(hr, "Failed to get key"); hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR); ExitOnFailure(hr, "Failed to change variant type"); if (0 == lstrcmpiW(vtVal.bstrVal, pwzID)) fMatch = TRUE; ::VariantClear(&vtVal); } // compare name if (pwzName && *pwzName) { hr = piObj->get_Name(&vtVal); ExitOnFailure(hr, "Failed to get name"); hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR); ExitOnFailure(hr, "Failed to change variant type"); if (0 == lstrcmpW(vtVal.bstrVal, pwzName)) fMatch = TRUE; ::VariantClear(&vtVal); } // if it's a match, remove it if (fMatch) { if (fResetDeleteable) { // reset deleteable property, if set hr = CpiResetObjectProperty(piColl, piObj, L"Deleteable"); ExitOnFailure(hr, "Failed to reset deleteable property"); } hr = piColl->Remove(i); ExitOnFailure(hr, "Failed to remove item from collection"); break; } // release interface pointers ReleaseNullObject(piDisp); ReleaseNullObject(piObj); } hr = S_OK; LExit: // clean up ReleaseObject(piDisp); ReleaseObject(piObj); ::VariantClear(&vtVal); return hr; }
HRESULT CpiFindCollectionObjectByIntegerKey( ICatalogCollection* piColl, long lKey, ICatalogObject** ppiObj ) { HRESULT hr = S_OK; IDispatch* piDisp = NULL; ICatalogObject* piObj = NULL; VARIANT vtVal; ::VariantInit(&vtVal); long lCnt; hr = piColl->get_Count(&lCnt); ExitOnFailure(hr, "Failed to get to number of items in collection"); for (long i = 0; i < lCnt; i++) { // get ICatalogObject interface hr = piColl->get_Item(i, &piDisp); ExitOnFailure(hr, "Failed to get object from collection"); hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj); ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface"); // compare key hr = piObj->get_Key(&vtVal); ExitOnFailure(hr, "Failed to get key"); hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_I4); ExitOnFailure(hr, "Failed to change variant type"); if (vtVal.lVal == lKey) { if (ppiObj) { *ppiObj = piObj; piObj = NULL; } ExitFunction1(hr = S_OK); } // clean up ReleaseNullObject(piDisp); ReleaseNullObject(piObj); ::VariantClear(&vtVal); } hr = S_FALSE; LExit: // clean up ReleaseObject(piDisp); ReleaseObject(piObj); ::VariantClear(&vtVal); return hr; }
static HRESULT FindUserCollectionObjectIndex( ICatalogCollection* piColl, PSID pSid, int* pi ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; NTSTATUS st = 0; long i = 0; long lCollCnt = 0; LSA_OBJECT_ATTRIBUTES loaAttributes; LSA_HANDLE lsahPolicy = NULL; PLSA_UNICODE_STRING plusNames = NULL; PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL; PLSA_TRANSLATED_SID pltsSids = NULL; IDispatch* piDisp = NULL; ICatalogObject* piObj = NULL; VARIANT vtVal; PSID pTmpSid = NULL; PLSA_TRANSLATED_SID pltsSid; ::VariantInit(&vtVal); ::ZeroMemory(&loaAttributes, sizeof(loaAttributes)); // open policy handle st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy); er = ::LsaNtStatusToWinError(st); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle"); // get number of elements in collection hr = piColl->get_Count(&lCollCnt); ExitOnFailure(hr, "Failed to get to number of objects in collection"); if (0 == lCollCnt) ExitFunction1(hr = S_FALSE); // not found // allocate name buffer plusNames = (PLSA_UNICODE_STRING)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LSA_UNICODE_STRING) * lCollCnt); ExitOnNull(plusNames, hr, E_OUTOFMEMORY, "Failed to allocate names buffer"); // get accounts in collection for (i = 0; i < lCollCnt; i++) { // get ICatalogObject interface hr = piColl->get_Item(i, &piDisp); ExitOnFailure(hr, "Failed to get object from collection"); hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj); ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface"); // get value hr = piObj->get_Key(&vtVal); ExitOnFailure(hr, "Failed to get key"); hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR); ExitOnFailure(hr, "Failed to change variant type"); // copy account name string hr = InitLsaUnicodeString(&plusNames[i], vtVal.bstrVal, ::SysStringLen(vtVal.bstrVal)); ExitOnFailure(hr, "Failed to initialize account name string"); // clean up ReleaseNullObject(piDisp); ReleaseNullObject(piObj); ::VariantClear(&vtVal); } // lookup names st = ::LsaLookupNames(lsahPolicy, lCollCnt, plusNames, &plrdsDomains, &pltsSids); er = ::LsaNtStatusToWinError(st); if (ERROR_NONE_MAPPED != er && ERROR_SOME_NOT_MAPPED != er) ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup account names"); // compare SIDs for (i = 0; i < lCollCnt; i++) { // get SID pltsSid = &pltsSids[i]; if (SidTypeDomain == pltsSid->Use || SidTypeInvalid == pltsSid->Use || SidTypeUnknown == pltsSid->Use) continue; // ignore... hr = CreateSidFromDomainRidPair(plrdsDomains->Domains[pltsSid->DomainIndex].Sid, pltsSid->RelativeId, &pTmpSid); ExitOnFailure(hr, "Failed to convert SID"); // compare SIDs if (::EqualSid(pSid, pTmpSid)) { *pi = i; ExitFunction1(hr = S_OK); } } if (ERROR_NONE_MAPPED == er && ERROR_SOME_NOT_MAPPED == er) hr = HRESULT_FROM_WIN32(er); else hr = S_FALSE; // not found LExit: // clean up ReleaseObject(piDisp); ReleaseObject(piObj); ::VariantClear(&vtVal); if (plusNames) { for (i = 0; i < lCollCnt; i++) FreeLsaUnicodeString(&plusNames[i]); ::HeapFree(::GetProcessHeap(), 0, plusNames); } if (lsahPolicy) ::LsaClose(lsahPolicy); if (plrdsDomains) ::LsaFreeMemory(plrdsDomains); if (pltsSids) ::LsaFreeMemory(pltsSids); if (pTmpSid) ::HeapFree(::GetProcessHeap(), 0, pTmpSid); return hr; }