IoCreateFile vs IoCreateFile
感觉IoCreateFile应该算是系统调用,它会调用ObCreateObject函数。
IoCreateFile和IoCreateDevice都会调用ObCreateObject函数。
在中IoCreateFile中,
|
Status = ObCreateObject(FileHandle, |
在中IoCreateDevice中
|
if (DeviceName != NULL) |
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); }

浙公网安备 33010602011771号