现在的位置: 首页 > 综合 > 正文

IoCreateFile vs IoCreateFile

2011年06月18日 ⁄ 综合 ⁄ 共 3483字 ⁄ 字号 评论关闭

感觉IoCreateFile应该算是系统调用,它会调用ObCreateObject函数。

IoCreateFile和IoCreateDevice都会调用ObCreateObject函数。

在中IoCreateFile中,

   Status = ObCreateObject(FileHandle,
               DesiredAccess,
               ObjectAttributes,
               IoFileObjectType,
               (PVOID*)&FileObject);

 

在中IoCreateDevice中

   if (DeviceName != NULL)
     {
    InitializeObjectAttributes(&ObjectAttributes,DeviceName,0,NULL,NULL);
    Status = ObCreateObject(&DeviceHandle,
                0,
                &ObjectAttributes,
                IoDeviceObjectType,
                (PVOID*)&CreatedDeviceObject);
     }
   else
     {
    Status = ObCreateObject(&DeviceHandle,
                0,
                NULL,
                IoDeviceObjectType,
                (PVOID*)&CreatedDeviceObject);
     }

ObCreateObject的过程大概如下:
1.调用ObFindObject能返回Parent对象、RemainingPath。其中ObFindObject会反复parse对象名,分析出RemainingPath。
2.ObCreateObject会根据传进来的Type,即IoFileObjectType或者IoDeviceObjectType 然后调用Create函数。
如果是IoFileObjectType则调用IopCreateFile
3.调用ObCreateHandle去创建handle,handle是与进程相关的。


下面对IopCreateFile进行注解.

NTSTATUS STDCALL
IopCreateFile(PVOID			ObjectBody,
	      PVOID			Parent,
	      PWSTR			RemainingPath,
	      POBJECT_ATTRIBUTES	ObjectAttributes)
{
  PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) Parent;//Parent肯定是设备对象。
  PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
  NTSTATUS Status;

  DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
	 ObjectBody,
	 Parent,
	 RemainingPath);

  if (NULL == DeviceObject)
    {
      /* This is probably an attempt to create a meta fileobject (eg. for FAT)
         for the cache manager, so return STATUS_SUCCESS */
      DPRINT("DeviceObject was NULL\n");
      return(STATUS_SUCCESS);
    }

  if (IoDeviceObjectType != BODY_TO_HEADER(Parent)->ObjectType)//Parent肯定是设备对象。 
    {
      CPRINT("Parent is a %S which is not a device type\n",
	     BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer);
      return(STATUS_UNSUCCESSFUL);
    }

//对设备对象进行reference
  Status = ObReferenceObjectByPointer(DeviceObject,
				      STANDARD_RIGHTS_REQUIRED,
				      IoDeviceObjectType,
				      UserMode);
  if (!NT_SUCCESS(Status))
    {
      CPRINT("Failed to reference device object %x\n", DeviceObject);
      return(Status);
    }
//得到下层的设备对象
  DeviceObject = IoGetAttachedDevice(DeviceObject);
  DPRINT("DeviceObject %x\n", DeviceObject);

  if (NULL == RemainingPath)
    {
      FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
      FileObject->FileName.Buffer = 0;
      FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
    }
  else
    {
      //设备对象类型一定是下列类型之一。
      if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
	  && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
	  && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
	  && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
	  && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
	  && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
	  && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
	{
	  CPRINT("Device was wrong type\n");
	  return(STATUS_UNSUCCESSFUL);
	}

      if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
	  && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
	  && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
	{
           //如果是上述类型,并且没有被mount,则进行mount
	  if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
	    {
	      DPRINT("Mount the logical volume\n");
	      Status = IoMountVolume(DeviceObject, FALSE);
	      DPRINT("Status %x\n", Status);
	      if (!NT_SUCCESS(Status))
		{
		  CPRINT("Failed to mount logical volume (Status %x)\n",
			 Status);
		  return(Status);
		}
	    }
	  DeviceObject = DeviceObject->Vpb->DeviceObject;
	  DPRINT("FsDeviceObject %lx\n", DeviceObject);
	}
      RtlCreateUnicodeString(&(FileObject->FileName),
			     RemainingPath);
    }

  DPRINT("FileObject->FileName %wZ\n",
	 &FileObject->FileName);
  FileObject->DeviceObject = DeviceObject;
  DPRINT("FileObject %x DeviceObject %x\n",
	 FileObject,
	 DeviceObject);
  FileObject->Vpb = DeviceObject->Vpb;
  FileObject->Type = InternalFileType;

  return(STATUS_SUCCESS);
}

 

抱歉!评论已关闭.