VfatOpenFile函数主要用来打开FAT的文件。具体实现代码如下:
#001 static
#002 NTSTATUS
#003 VfatOpenFile (
#004 PDEVICE_EXTENSION DeviceExt,
#005 PUNICODE_STRINGPathNameU,
#006 PFILE_OBJECT FileObject,
#007 PVFATFCB* ParentFcb )
#008 /*
#009 * FUNCTION: Opens a file
#010 */
#011 {
#012 PVFATFCB Fcb;
#013 NTSTATUS Status;
#014
#015 DPRINT ("VfatOpenFile(%p, '%wZ', %p, %p)/n", DeviceExt,PathNameU, FileObject, ParentFcb);
#016
文件是否打开,如果打开就添加文件对象的引用计数。
#017 if (FileObject->RelatedFileObject)
#018 {
#019 DPRINT ("'%wZ'/n",&FileObject->RelatedFileObject->FileName);
#020
#021 *ParentFcb = FileObject->RelatedFileObject->FsContext;
#022 (*ParentFcb)->RefCount++;
#023 }
#024 else
#025 {
#026 *ParentFcb = NULL;
#027 }
#028
如果磁盘不是固定的媒介,那么就需要检查是否还存在。
#029 if (!DeviceExt->FatInfo.FixedMedia)
#030 {
发送IOCTL_DISK_CHECK_VERIFY来检查可移动媒介是否还存在。
#031 Status = VfatBlockDeviceIoControl(DeviceExt->StorageDevice,
#032 IOCTL_DISK_CHECK_VERIFY,
#033 NULL,
#034 0,
#035 NULL,
#036 0,
#037 FALSE);
#038
#039 if (Status == STATUS_VERIFY_REQUIRED)
#040
#041 {
#042 PDEVICE_OBJECT DeviceToVerify;
#043
#044 DPRINT ("Media change detected!/n");
#045 DPRINT ("Device %p/n",DeviceExt->StorageDevice);
#046
#047 /*Find the device to verify and reset the thread field to empty value again. */
#048 DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
#049 IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
#050 Status = IoVerifyVolume (DeviceToVerify,
#051 FALSE);
#052 }
如果发现可移动媒介不存在,就返回。
#053 if (!NT_SUCCESS(Status))
#054 {
#055 DPRINT ("Status %lx/n", Status);
#056 *ParentFcb = NULL;
#057 return Status;
#058 }
#059 }
#060
增加父目录的引用计数。
#061 if (*ParentFcb)
#062 {
#063 (*ParentFcb)->RefCount++;
#064 }
#065
#066 /* try first to find anexisting FCB in memory */
#067 DPRINT ("Checking for existing FCB in memory/n");
#068
从文件路径名称获取文件控制块。
#069 Status = vfatGetFCBForFile (DeviceExt, ParentFcb, &Fcb,PathNameU);
#070 if (!NT_SUCCESS (Status))
#071 {
#072 DPRINT ("Could not make a new FCB, status: %x/n",Status);
#073 return Status;
#074 }
如果文件已经在删除过程中,就不再能访问,直接返回。
#075 if (Fcb->Flags & FCB_DELETE_PENDING)
#076 {
#077 vfatReleaseFCB (DeviceExt, Fcb);
#078 return STATUS_DELETE_PENDING;
#079 }
#080 DPRINT ("Attaching FCB to fileObject/n");
关联文件控制块到文件对象。
#081 Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
#082 if (!NT_SUCCESS(Status))
#083 {
#084 vfatReleaseFCB (DeviceExt, Fcb);
#085 }
#086 return Status;
#087 }