WINDOWS9X文件读写Internal

作者:陆麟
转载请征得作者同意.
2001.3.12



在WINDOWS95/98/98SE操作系统里,一个文件的读写实际上是按照如下流程进行的.
在读写操作进行时,OS首先进行的增量MUSTCOMPLETECOUNT变量.告诉OS本操作必须完成,通过UNCODUMENTED函数EnterMustComplete函数完成. 该函数设置了KERNEL32模块里的内部变量来显示现在有个关键操作正在进行. 有句体外话, 在VMM里同样有个函数,函数名也是EnterMustComplete. 那个函数同样告诉VMM, 我们有个关键操作正在进行.防止线程被KILL或者被挂起.
接下来, WIN9x进行了一个_MapHandleWithContext(又是一个UNDOCUMENTED函数)操作.该操作本身的具体意义有待考证,但是其操作却是得到HANDLE所指对象的指针, 并且增加了应用计数.
随后,进行的乃是根本性的操作: KERNEL32发出了一个VXDCALL. 这个VXDCALL乃是通过内部例程_KInt21发出的. 该函数的名字就显示了它本身调用的是INT21H. 但是我们知道, 在WIN32下, 直接发出INT21H中断绝对会引发一个蓝屏, 所以, KERNEL32发出的乃是VWIN32的INT21H DISPATCH请求. VWIN32接到调用后, 检查一下调用是否是读写操作, 是的话, 就根据文件句柄切换一个FSD能识别的句柄. 调用IFSMgr_Ring0_FileIO. 接下来任务就转到了IFS MANAGER.
IFS MANAGER生成一个IOREQ. 跳转到Ring0ReadWrite内部例程. Ring0ReadWrite检查句柄有效性, 并且获取FSD在创建文件句柄时返回的CONTEXT, 一起PASS到CallIoFunc内部例程. CallIoFunc检查IFSHOOK的存在, 如果不存在, IFS MANAGER生成一个缺省的IFS HOOK, 并且调用相应的VFatReadFile/VFatWriteFile例程. (因为目前 MS本身仅提供了VFAT驱动),如果IFSHOOK存在,文件操作就让IFSHOOK函数继续, 而IFS MANAGER本身就脱离了文件读写处理.
然后, 调用被层层返回.KERNEL32调用UNDOCUMENTED函数LeaveMustComplete,减少MUSTCOMPLETECOUNT计数,最终回到调用者.