当从IO管理器里调用函数IopParseDevice来分析设备时,就可以找到相应的磁盘设备,并在这个函数里调用函数IopCheckVpbMounted来检查这个文件系统是否加载,如果没有加载,就会调用函数IopMountVolume来加载文件卷,那么在这个函数里就会构造一个IRP发送给文件系统驱动程序,驱动程序就收到主功能码为IRP_MJ_FILE_SYSTEM_CONTROL和次功能码为IRP_MN_MOUNT_VOLUME的IRP处理请求。在FAT文件系统里是通过函数VfatFileSystemControl来处理相应的功能码,具体实现如下:
#001 NTSTATUSVfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
#002 /*
#003 * FUNCTION: File systemcontrol
#004 */
#005 {
#006
#007 NTSTATUS Status;
#008
#009 DPRINT("VfatFileSystemControl(IrpContext %p)/n", IrpContext);
#010
#011 ASSERT(IrpContext);
#012 ASSERT(IrpContext->Irp);
#013 ASSERT(IrpContext->Stack);
#014
#015 IrpContext->Irp->IoStatus.Information = 0;
#016
这里区分次功能码,并分派给不同的函数处理。
#017 switch(IrpContext->MinorFunction)
#018 {
#019 caseIRP_MN_USER_FS_REQUEST:
#020 switch(IrpContext->Stack->Parameters.DeviceIoControl.IoControlCode)
#021 {
#022 caseFSCTL_GET_VOLUME_BITMAP:
#023 Status =VfatGetVolumeBitmap(IrpContext);
#024 break;
#025 caseFSCTL_GET_RETRIEVAL_POINTERS:
#026 Status =VfatGetRetrievalPointers(IrpContext);
#027 break;
#028 case FSCTL_MOVE_FILE:
#029 Status =VfatMoveFile(IrpContext);
#030 break;
#031 #ifdef USE_ROS_CC_AND_FS
#032 caseFSCTL_ROS_QUERY_LCN_MAPPING:
#033 Status =VfatRosQueryLcnMapping(IrpContext);
#034 break;
#035 #endif
#036 caseFSCTL_IS_VOLUME_DIRTY:
#037 Status =VfatIsVolumeDirty(IrpContext);
#038 break;
#039 caseFSCTL_MARK_VOLUME_DIRTY:
#040 Status =VfatMarkVolumeDirty(IrpContext);
#041 break;
#042 default:
#043 Status =STATUS_INVALID_DEVICE_REQUEST;
#044 }
#045 break;
#046
这里就是实现加载文件卷的功能码处理。
#047 caseIRP_MN_MOUNT_VOLUME:
#048 Status = VfatMount(IrpContext);
#049 break;
#050
#051 caseIRP_MN_VERIFY_VOLUME:
#052 DPRINT("VFATFS:IRP_MN_VERIFY_VOLUME/n");
#053 Status = VfatVerify(IrpContext);
#054 break;
#055
#056 default:
#057 DPRINT("VFATFSC: MinorFunction %d/n", IrpContext->MinorFunction);
#058 Status =STATUS_INVALID_DEVICE_REQUEST;
#059 break;
#060 }
#061
#062 IrpContext->Irp->IoStatus.Status = Status;
#063
#064 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
#065 VfatFreeIrpContext(IrpContext);
#066 return (Status);
#067 }
#068