#ifndef IOTYPES_H
#define IOTYPES_H


#if KERNEL
#include <IOKit/system.h>
#else
#include <mach/message.h>
#include <mach/vm_types.h>
#endif

#include <IOKit/IOReturn.h>
#include <stdbool.h>
#include <libkern/OSTypes.h>
#include <device/device_types.h>


#include <HYS/IOKit/IOTypes.h>
#ifdef __cplusplus
extern "C" {
#endif

/*Listing 4-1  Object definitions in IOTypes.htypedef mach_port_t io_object_t;
 
typedef io_object_t io_connect_t;
typedef io_object_t io_iterator_t;
typedef io_object_t io_registry_entry_t;
typedef io_object_t io_service_t;
typedef io_object_t io_enumerator_t;


To understand why this is so, recall that a Mach port is the communication transport mechanism an application uses to communicate with the I/O Kit. As far as the kernel is concerned, every time your application communicates with any in-kernel object using one of the object types defined in IOTypes.h, it’s using the same generic mechanism (namely, a Mach port) to cross the user-kernel boundary. 

From the application’s point of view, however, the transport mechanism is unimportant and what matters is the type of object on the other side of the port. The fact that an io_iterator_t object, for example, encapsulates the association of a Mach port with an in-kernel IOIterator object is not as important to the application as the fact that an io_iterator_t object refers to an in-kernel object that knows how to iterate over the I/O Registry.

The io_object_t objects in user space not only refer to the in-kernel objects, they also reflect the in-kernel C++ class hierarchy. Because IOService is a subclass of IORegistryEntry, for example, you can use an io_service_t object with any IOKitLib function that expects an io_registry_entry_t object, such as IORegistryEntryGetPath.

With few exceptions (such as getting the I/O Kit master port to initiate communication with the I/O Kit and reference-counting of the io_object_t objects themselves) you should not concern yourself with the cross-boundary communication mechanism. Rather, you should focus on the specific in-kernel object you are working with, making sure you use each object type appropriately.*/

typedef io_object_t io_connect_t;
typedef io_object_t io_iterator_t;
typedef io_object_t io_registry_entry_t;
typedef io_object_t io_service_t;
typedef io_object_t io_enumerator_t;
	
#ifdef __cplusplus
}
#endif

#endif