+/* Routine io_registry_entry_get_property */
+kern_return_t is_io_registry_entry_get_property_bytes(
+ io_object_t registry_entry,
+ io_name_t property_name,
+ io_scalar_inband_t buf,
+ mach_msg_type_number_t *dataCnt )
+{
+ OSObject * obj;
+ OSData * data;
+ OSString * str;
+ OSBoolean * boo;
+ OSNumber * off;
+ UInt64 offsetBytes;
+ unsigned int len = 0;
+ const void * bytes = 0;
+ IOReturn ret = kIOReturnSuccess;
+
+ CHECK( IORegistryEntry, registry_entry, entry );
+
+ obj = entry->copyProperty(property_name);
+ if( !obj)
+ return( kIOReturnNoResources );
+
+ // One day OSData will be a common container base class
+ // until then...
+ if( (data = OSDynamicCast( OSData, obj ))) {
+ len = data->getLength();
+ bytes = data->getBytesNoCopy();
+
+ } else if( (str = OSDynamicCast( OSString, obj ))) {
+ len = str->getLength() + 1;
+ bytes = str->getCStringNoCopy();
+
+ } else if( (boo = OSDynamicCast( OSBoolean, obj ))) {
+ len = boo->isTrue() ? sizeof("Yes") : sizeof("No");
+ bytes = boo->isTrue() ? "Yes" : "No";
+
+ } else if( (off = OSDynamicCast( OSNumber, obj ))) {
+ offsetBytes = off->unsigned64BitValue();
+ len = off->numberOfBytes();
+ bytes = &offsetBytes;
+#ifdef __BIG_ENDIAN__
+ bytes = (const void *)
+ (((UInt32) bytes) + (sizeof( UInt64) - len));
+#endif
+
+ } else
+ ret = kIOReturnBadArgument;
+
+ if( bytes) {
+ if( *dataCnt < len)
+ ret = kIOReturnIPCError;
+ else {
+ *dataCnt = len;
+ bcopy( bytes, buf, len );
+ }
+ }
+ obj->release();
+
+ return( ret );
+}
+
+/* Routine io_registry_entry_get_property */
+kern_return_t is_io_registry_entry_get_property(
+ io_object_t registry_entry,
+ io_name_t property_name,
+ io_buf_ptr_t *properties,
+ mach_msg_type_number_t *propertiesCnt )
+{
+ kern_return_t err;
+ vm_size_t len;
+ OSObject * obj;
+
+ CHECK( IORegistryEntry, registry_entry, entry );
+
+ obj = entry->copyProperty(property_name);
+ if( !obj)
+ return( kIOReturnNotFound );
+
+ OSSerialize * s = OSSerialize::withCapacity(4096);
+ if( !s) {
+ obj->release();
+ return( kIOReturnNoMemory );
+ }
+ s->clearText();
+
+ if( obj->serialize( s )) {
+ len = s->getLength();
+ *propertiesCnt = len;
+ err = copyoutkdata( s->text(), len, properties );
+
+ } else
+ err = kIOReturnUnsupported;
+
+ s->release();
+ obj->release();
+
+ return( err );
+}
+
+/* Routine io_registry_entry_get_property_recursively */
+kern_return_t is_io_registry_entry_get_property_recursively(
+ io_object_t registry_entry,
+ io_name_t plane,
+ io_name_t property_name,
+ int options,
+ io_buf_ptr_t *properties,
+ mach_msg_type_number_t *propertiesCnt )
+{
+ kern_return_t err;
+ vm_size_t len;
+ OSObject * obj;
+
+ CHECK( IORegistryEntry, registry_entry, entry );
+
+ obj = entry->copyProperty( property_name,
+ IORegistryEntry::getPlane( plane ), options);
+ if( !obj)
+ return( kIOReturnNotFound );
+
+ OSSerialize * s = OSSerialize::withCapacity(4096);
+ if( !s) {
+ obj->release();
+ return( kIOReturnNoMemory );
+ }
+
+ s->clearText();
+
+ if( obj->serialize( s )) {
+ len = s->getLength();
+ *propertiesCnt = len;
+ err = copyoutkdata( s->text(), len, properties );
+
+ } else
+ err = kIOReturnUnsupported;
+
+ s->release();
+ obj->release();
+
+ return( err );
+}