Pradeepa Senanayake wrote:

Recently I have been going through the Libusbk.sys driver source to check the IOCTLs it uses. I realized that the User-Mode dll files are using DeviceIoControl for all the communications with the device. 

But there are two callbacks registered, namely EvtIoRead and EvtIoWrite, which according to my understanding will get called if the application/dll calls ReadFile or WriteFile functions. 

I was just wandering why we are using IOCTLS for Bulk IN/OUT transactions instead of using ReadFile and WriteFile functions?

Two reasons.

First, they aren't flexible enough.  A USB device can have many pipes.  With ReadFile and WriteFile, there's no way to tell the driver which pipe you want to read or write.  An ioctl has two buffers, so you have a way to send that metadata.  In addition, individual ioctls can use different buffering schemes ("buffered" vs "direct"), whereas ReadFile and WriteFile always have to use the buffering type declared when the driver was created.

Second, there is no advantage.  There's nothing that ReadFile and WriteFile can do that DeviceIoControl cannot do better.  ReadFile, WriteFile and DeviceIoControl all get immediately converted to I/O Request Packets (IRPs), and from that point on they are virtually indistinguishable in the I/O system.
Tim Roberts,
Providenza & Boekelheide, Inc.