USB开发—自上而下(四)

来源:互联网 发布:ij scan utility 软件 编辑:程序博客网 时间:2024/06/02 11:40

聊完了CreateFile的调用过程,我们再来看一看三个非常重要的API函数DeviceIoControl、ReadFile、WriteFile

BOOL WINAPI DeviceIoControl(_In_ HANDLE hDevice,_In_ DWORD dwIoControlCode,_In_opt_ LPVOID lpInBuffer,_In_ DWORD nInBufferSize,_Out_opt_ LPVOID lpOutBuffer,_In_ DWORD nOutBufferSize,_Out_opt_ LPDWORD lpBytesReturned,_Inout_opt_ LPOVERLAPPED lpOverlapped);
hDevice—通过CreateFile打开的设备句柄

dwIoControlCode—应用程序调用驱动程序的控制命令

lpInBuffer—应用程序传递到驱动程序数据的缓冲区地址

nInBufferSize—缓冲区长度

nOutBuffer—驱动程序返回数据到应用程序的缓冲区地址

nOutBufferSize—缓冲区长度

lpBytesReturned—驱动程序实际返回的数据长度

lpOverlapped—重叠结构,异步调用函数时使用

DeviceIoControl的调用过程比较简单,API通过系统调用进入内核,内核中两次调用ObReferenceObjectByHandle,一次为了获取句柄对应的设备对象(实际上是文件对象),另一次是为了获取Event句柄对应的事件对象,该对象用于处理用户模式下的同步问题;顺着设备对象的堆叠往上爬,获得了顶层设备对象,之后就准备了一个IRP,通过IoCallDriver调用了驱动程序中的OnMajorDeviceIoControl函数,这些函数前一章已经分析过,理解起来应该不成问题。


BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer,  DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
hFile—通过CreateFile打开的设备句柄

lpBuffer—应用程序传递到驱动程序数据的缓冲区地址

nNumberOfBytesToWrite—缓冲区长度

lpNumberOfBytesWriten—实际写操作的长度

lpOverlapped—重叠结构,异步调用函数时使用



BOOL ReadFile(    HANDLE hFile,    LPVOID lpBuffer,    DWORD nNumberOfBytesToRead,    LPDWORD lpNumberOfBytesRead,    LPOVERLAPPED lpOverlapped    );
hFile—通过CreateFile打开的设备句柄

lpBuffer—驱动程序返回数据到应用程序的缓冲区地址

nNumberOfBytesToRead—缓冲区长度

lpNumberOfBytesRead—驱动程序实际返回的数据长度

lpOverlapped—重叠结构,异步调用函数时使用



从上面的函数调用图可以看出:

1, WriteFile、ReadFile、DeviceIoControl三个函数异曲同工,走的路线很相近

2, 在windows内核层,WriteFile生成一个MajorFunction为IRP_MJ_WRITE的IRP

        ReadFile生成一个MajorFunction为IRP_MJ_READ的IRP

        DeviceIoControl生成一个MajorFunction为IRP_MJ_DEVICE_CONTROL的IRP

3, 在windows内核层,WriteFile函数生成的IO_STACK_LOCATION消息参数联合体需要转换成Write结构体

       ReadFile函数生成的IO_STACK_LOCATION消息参数联合体需要转换成Read结构体

       DeviceIoControl函数生成的IO_STACK_LOCATION消息参数联合体需要转换成DeviceIoControl结构体

4, 只要驱动支持,WriteFile,ReadFile完全可以由DeviceIoControl替代


参考资料: 

1, <<Windows内核情景分析>>






0 0