文件读取流程:
打开目标文件并获取句柄之后,通过系统调用NtReadFile()从目标文件读出。其基本流程如下:
(1) 先通过句柄找到相应的FILE_OBJECT数据结构
(2) 找到文件对象之后,由于文件对象代表着的是个磁盘文件,所以其指针Vpb指向一个VPB,而VPB中的指针DeviceObject则指向目标文件所属文件卷的设备对象,这个设备对象属于某种文件系统的FSD,例如FAT的FSD。另一方面,FILE_OBJECT数据结构中的指针FsContext则指向目标文件FCB。
(3) 创建主功能码为IRP_MJ_READ的IRP,然后以此IRP为参数调用相应FSD的IRP_MJ_READ主功能函数。
(4) 依据主功能函数实现文件读取
文件读出的方式有两种,其一是通过(文件内容)缓存机制的读出,其二是直接从文件读出。如果IRP中的标志字段Flags的IRP_NOCACHE标志字段为1,就会直接从文件中读出,从而绕过缓存机制。IRP的IRP_NOCACHE标志从哪里来?一般而言,这最终来自系统调用NtCreateFile创建打开文件时参数Flags中的标志位FILE_NO_INTERMEDIATE_BUFFERING。
说明:系统调用NtReadFile和NtWriteFile并非读写文件的唯一途径,另一个办法是将目标文件映射到用户内存空间,然后可以像访问内存一样地读写文件了。但是文件映射机制最后还是要通过文件系统驱动和磁盘驱动才能落实到物理存储着的文件上。