Communication between a user-mode application and the driver that drives the hardware, is implemented differently for each operating system, using the custom OS Application Programming Interfaces (APIs).
On Windows, Windows CE, and Linux, the application can use the OS
file-access API to open a handle to the driver (e.g., using the Windows
CreateFile() function or using the Linux open()
function), and then read and write from/to the device by passing the handle to
the relevant OS file-access functions (e.g., the Windows
ReadFile() and WriteFile() functions, or the Linux
read() and write() functions).
The
application sends requests to the driver via I/O control (IOCTL) calls,
using the custom OS APIs provided for this purpose (e.g., the Windows
DeviceIoControl() function,
or the Linux ioctl() function).
The data passed between the driver and the application via the IOCTL calls is
encapsulated using custom OS mechanisms. For example, on Windows the data is
passed via an I/O Request Packet (IRP) structure, and is encapsulated by the
I/O Manager.