Platform SDK: Active Directory, ADSI, and Directory Services |
The following C/C++ function checks the allowedChildClassesEffective property on the schema container (IADs pointer to schema container is passed as a parameter) for the attributeSchema and classSchema classes. It returns S_OK if both classes are listed in allowedChildClassesEffective. If both are not, it returns S_FALSE.
//Function takes an IADs pointer to schema container as a parameter. HRESULT HasSchemaAdditionRights(IADs *pSchema) { if (!pSchema) return E_POINTER; HRESULT hr = E_FAIL; VARIANT var; VARIANT *pVar; //Check access rights BOOL bIsAddAttributeAllowed = FALSE; BOOL bIsAddClassAllowed = FALSE; //Get AllowedChildClassesEffective. It is constructed; //therefore, you must use GetInfoEx to explicitly get it into the cache. LPOLESTR pwszArray[] = {L"allowedChildClassesEffective"}; DWORD dwArrayItems = sizeof(pwszArray)/sizeof(LPOLESTR); VARIANT vArray; VariantInit(&vArray); // Build a Variant of array type, using the specified string array. hr = ADsBuildVarArrayStr(pwszArray, dwArrayItems, &vArray); if (SUCCEEDED(hr)) { hr = pSchema->GetInfoEx(vArray,0L); if (SUCCEEDED(hr)) { hr = pSchema->GetEx(L"allowedChildClassesEffective", &var); if (SUCCEEDED(hr)) { hr = SafeArrayAccessData((SAFEARRAY*)(var.pparray), (void HUGEP* FAR*)&pVar); long lLBound, lUBound; //One dimensional array. Get the bounds for the array. hr = SafeArrayGetLBound((SAFEARRAY*)(var.pparray), 1, &lLBound); hr = SafeArrayGetUBound((SAFEARRAY*)(var.pparray), 1, &lUBound); //Get the count of elements long cElements = lUBound-lLBound + 1; //Get the elements of the array if (SUCCEEDED(hr)) { for (int i = 0; i < cElements; i++ ) { //Check each element to see if attributeSchema or classSchema is there. if (VT_BSTR == pVar[i].vt) { if (0==_wcsicmp(L"attributeSchema", pVar[i].bstrVal)) bIsAddAttributeAllowed = TRUE; else if (0==_wcsicmp(L"classSchema", pVar[i].bstrVal)) bIsAddClassAllowed = TRUE; } } if (bIsAddAttributeAllowed && bIsAddClassAllowed) hr = S_OK; else hr = S_FALSE; } } VariantClear(&var); } } return hr; };