A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #3229  by driverobject
 Tue Oct 26, 2010 7:24 pm
Hi all,

What is the difference between an IOCTL and an IRP. IOCTLs seem to be direct commands to a driver that can be sent from user mode, and have input output buffers to send back data. What about an IRP_MJ_READ for example? I can use that to send back and forth a custom data structure just as I'd do with an IOCTL. How do you choose between the two?

Thanks..
 #3231  by GamingMasteR
 Wed Oct 27, 2010 12:32 am
Hi,

IRP is the base communication method for device drivers in NT architecture, sending an IOCTL to device drivers is just translated by forming and sending an IRP with major function = IRP_MJ_DEVICE_CONTROL .
 #3665  by gglittle
 Tue Nov 23, 2010 10:44 pm
IOCTL is mnemonic for IO control code, or a 32 bit value with bit fields defined within it that provides the IO manager with buffering, and other information. An IRP, or IO request packet is a structure or defined chunk of memory created by the IO manager that has all the information that the driver needs to perform a given action on an IO request, including the IOCTL. An IOCTL is used in both kernel and user mode, but an IRP is only valid within the kernel and the targeted driver or driver stack.

Gary
 #3667  by driverobject
 Tue Nov 23, 2010 11:03 pm
So how do you differentiate between the two? Is it used as a way to easily send an arbitrary number of commands to a driver, instead of creating your own messaging mechanism that would use IRP_MJ_READ and WRITE? What is the difference in sending an IRP_MJ_WRITE and an IOCTL that would to the write as well? Is it the extra information I can provide to the IO manager about buffering that makes the IOCTL special? Can the extra information be provided in an IRP request too?

Thanks,
 #3674  by gglittle
 Wed Nov 24, 2010 3:47 am
driverobject wrote:So how do you differentiate between the two? Is it used as a way to easily send an arbitrary number of commands to a driver, instead of creating your own messaging mechanism that would use IRP_MJ_READ and WRITE? What is the difference in sending an IRP_MJ_WRITE and an IOCTL that would to the write as well? Is it the extra information I can provide to the IO manager about buffering that makes the IOCTL special? Can the extra information be provided in an IRP request too?

Thanks,
The user does NOT send IRP_MJ_READ/WRITE. Those are internal codes used by the IO manager to properly dispatch Read/Write calls from the user to the Read/Write functions registered in the driver. The user sends ReadFile or WriteFile and the IO manager builds the IRP and sets IRP_MJ_READ or IRP_MJ_WRITE. DeviceIoControl sends an IOCTL down and the IO manager moves the information provided in that call into an IRP including the IOCTL code which the driver will then use in its dispatch function. The driver typically does not need to handle IRP_MJ_READ or IRP_MJ_WRITE because it registered functions for those IRPs during it's initialization. Another driver could send IRP_MJ_READ or IRP_MJ_WRITE via IoCallDriver to another driver but the user won't.
 #3676  by driverobject
 Wed Nov 24, 2010 4:54 am
Thank you for the details, I was aware of the ReadFile translating to .._READ eventually. However I'm still not clear as to the fundemental difference in doing IO with the 2 different mechanisms.
 #3692  by gglittle
 Wed Nov 24, 2010 2:52 pm
Don't look at it as two mechanisms. It's really only one. If your driver registers READ/WRITE functions then you can use ReadFile/WriteFile, but if those functions are not registered, then you use DeviceIoControl and you will have to define the IOCTLs you need for data transfer. In nearly ALL cases there will be a combination of both to provide the full spectrum of device control and data transfer.

Gary