+ if ((iter = OSCollectionIterator::withCollection(properties)) == NULL ||
+ (filtered = OSDictionary::withCapacity(properties->getCapacity())) == NULL) {
+ err = kIOReturnNoMemory;
+ goto out;
+ }
+
+ while ((p = iter->getNextObject()) != NULL) {
+ if ((key = OSDynamicCast(OSSymbol, p)) == NULL ||
+ mac_iokit_check_get_property(cred, entry, key->getCStringNoCopy()) != 0)
+ continue;
+ filtered->setObject(key, properties->getObject(key));
+ }
+
+out:
+ if (iter != NULL)
+ iter->release();
+ *filteredp = filtered;
+ return err;
+}
+
+#endif
+
+/* Routine io_registry_entry_get_properties */
+kern_return_t is_io_registry_entry_get_properties(
+ io_object_t registry_entry,
+ io_buf_ptr_t *properties,
+ mach_msg_type_number_t *propertiesCnt )
+{
+ kern_return_t err = 0;
+ vm_size_t len;
+
+ CHECK( IORegistryEntry, registry_entry, entry );
+
+ OSSerialize * s = OSSerialize::withCapacity(4096);
+ if( !s)
+ return( kIOReturnNoMemory );
+
+ if (!entry->serializeProperties(s))
+ err = kIOReturnUnsupported;
+
+#if CONFIG_MACF
+ if (!err && mac_iokit_check_filter_properties(kauth_cred_get(), entry)) {
+ OSObject *propobj = OSUnserializeXML(s->text(), s->getLength());
+ OSDictionary *filteredprops = NULL;
+ err = filteredProperties(entry, OSDynamicCast(OSDictionary, propobj), &filteredprops);
+ if (propobj) propobj->release();
+
+ if (!err) {
+ s->clearText();
+ if (!filteredprops->serialize(s))
+ err = kIOReturnUnsupported;
+ }
+ if (filteredprops != NULL)
+ filteredprops->release();
+ }
+#endif /* CONFIG_MACF */
+
+ if (!err) {
+ len = s->getLength();
+ *propertiesCnt = len;
+ err = copyoutkdata( s->text(), len, properties );
+ }
+
+ s->release();
+ return( err );
+}
+
+#if CONFIG_MACF
+
+struct GetPropertiesEditorRef
+{
+ kauth_cred_t cred;
+ IORegistryEntry * entry;
+ OSCollection * root;
+};
+
+static const OSMetaClassBase *
+GetPropertiesEditor(void * reference,
+ OSSerialize * s,
+ OSCollection * container,
+ const OSSymbol * name,
+ const OSMetaClassBase * value)
+{
+ GetPropertiesEditorRef * ref = (typeof(ref)) reference;
+
+ if (!ref->root) ref->root = container;
+ if (ref->root == container)
+ {
+ if (0 != mac_iokit_check_get_property(ref->cred, ref->entry, name->getCStringNoCopy()))
+ {
+ value = 0;
+ }
+ }
+ if (value) value->retain();
+ return (value);
+}
+
+#endif /* CONFIG_MACF */
+
+/* Routine io_registry_entry_get_properties */
+kern_return_t is_io_registry_entry_get_properties_bin(
+ io_object_t registry_entry,
+ io_buf_ptr_t *properties,
+ mach_msg_type_number_t *propertiesCnt)
+{
+ kern_return_t err = kIOReturnSuccess;
+ vm_size_t len;
+ OSSerialize * s;
+ OSSerialize::Editor editor = 0;
+ void * editRef = 0;
+
+ CHECK(IORegistryEntry, registry_entry, entry);
+
+#if CONFIG_MACF
+ GetPropertiesEditorRef ref;
+ if (mac_iokit_check_filter_properties(kauth_cred_get(), entry))
+ {
+ editor = &GetPropertiesEditor;
+ editRef = &ref;
+ ref.cred = kauth_cred_get();
+ ref.entry = entry;
+ ref.root = 0;
+ }
+#endif
+
+ s = OSSerialize::binaryWithCapacity(4096, editor, editRef);
+ if (!s) return (kIOReturnNoMemory);
+
+ if (!entry->serializeProperties(s)) err = kIOReturnUnsupported;
+
+ if (kIOReturnSuccess == err)
+ {
+ len = s->getLength();
+ *propertiesCnt = len;
+ err = copyoutkdata(s->text(), len, properties);
+ }
+ s->release();
+
+ return (err);
+}
+
+/* Routine io_registry_entry_get_property_bin */
+kern_return_t is_io_registry_entry_get_property_bin(
+ io_object_t registry_entry,
+ io_name_t plane,
+ io_name_t property_name,
+ uint32_t options,
+ io_buf_ptr_t *properties,
+ mach_msg_type_number_t *propertiesCnt )
+{
+ kern_return_t err;
+ vm_size_t len;
+ OSObject * obj;
+ const OSSymbol * sym;
+
+ CHECK( IORegistryEntry, registry_entry, entry );
+
+#if CONFIG_MACF
+ if (0 != mac_iokit_check_get_property(kauth_cred_get(), entry, property_name))
+ return kIOReturnNotPermitted;
+#endif
+
+ if ((kIORegistryIterateRecursively & options) && plane[0])
+ {
+ obj = entry->copyProperty(property_name,
+ IORegistryEntry::getPlane(plane), options);
+ }
+ else
+ {
+ obj = entry->copyProperty(property_name);
+ }
+
+ if( !obj)
+ return( kIOReturnNotFound );