CreateFile打开文件执行流程浅析

CreateFile打开文件的执行流程浅析

    分析CreateFile这个函数打开文件的执行流程有助于我们理解windows操作系统在接收到用户打开文件请求后都会做哪些工作、它是如何找到驱动程序的、以及有哪些windows核心部件参与了打开文件的操作,这对我们开发windows驱动程序十分有益。下面我们以CreateFile打开文件C:/MYFILE.CPP来浅析这一过程,系统对象参考图例见下图。

 

1、              用户程序通常通过给win32子系统例程CreateFile()指定文件名、访问权限以及其它一些参数来打开文件,本例当中文件名是C:/MYFILE.CPP;随后win32子系统将收到的文件名前面加上前缀//./,即文件名变为//./C:/MYFILE.CPP,处理完后win32子系统会代表用户程序调用NtCreateFile()系统调用,此时,CPU将会由用户态转换为内核态。NtCreateFile()系统调用是由I/O管理器实现的,它必须在内核态执行。

2、              NtCreateFile()内部,I/O管理器将接收到的文件名前缀//./转化为/??/,即/??/C:/MYFILE.CPP,转化后的名字被I/O管理器发送给对象管理器(Object Manager)来解析。

3、              对象管理器会对文件名前缀“??”进行特殊处理,在对象管理器看来,文件名前缀“??”是指当前会话的DosDevices目录,因此对象管理器就在当前会话的DosDevices目录下查找“C:”,如果找不到,则它根据DosDevices目录下的符号连接“Global”到达“/Globall??”目录。

4、              现在对象管理器会在“/Globall??”目录下查找“C:,在这个目录下它找到了“C:”,并且“C:”是指向“/Device/HarddiskVolume1,因此它将生成新的内核路径/Device/HarddiskVolume1/MYFILE.CPP,并且重新解析这个新生成的路径。

5、              取得了新路径,对象管理器会在根目录下查找Device目录,找到后它会在/Device目录中寻找HarddiskVolume1,通过这个名字它将会找到一个设备对象。这个设备对象是一个存储设备对象(storage device object)。

6、              找到设备对象后对象管理器将把这个设备对象以及未解析完的文件名/MYFILE.CPP返回给I/O管理器处理。I/O管理器会检验这个设备对象是否被文件系统挂载过(通过查看与它关联的VPB中的VPB_MOUNTED标志),若未挂载,则I/O管理器会发送一个卷挂载请求给每一个可能挂载这个设备的文件系统进行卷挂载操作。若已挂载,则I/O管理器就能找到该设备对象对应的文件系统驱动程序,然后向该驱动程序对应的函数入口发送用户请求。请注意,发送给驱动文件系统驱动程序的文件名是未解析的部分,本例中是/MYFILE.CPP

7、              最后,文件系统驱动程序进行相应的处理并将处理结果返回给I/O管理器,I/O管理器将结果给win32子系统,最终win32子系统把结果返回给用户程序。

 

至此,CreateFile函数的执行流程大概分析完毕,从中我们可以了解windows在打开一个文件时会经历CPU状态的切换、文件名的转变等操作,并且我们也会了解windows是如何找到驱动程序并把用户请求发送诶给动程序的。

 

本文只是个人总结,其中不乏错误之处,欢迎大家指正。

 

你可能感兴趣的:(CreateFile打开文件执行流程浅析)