reactos操作系统实现(128)

时间:2021-12-06 20:20:15

 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  }