📄 file.c
字号:
}
/* Copy the I/O Status */
OpenPacket->Information = IoStatusBlock.Information;
/* The driver failed to create the file */
if (!NT_SUCCESS(Status))
{
/* Check if we have a name */
if (FileObject->FileName.Length)
{
/* Free it */
ExFreePool(FileObject->FileName.Buffer);
FileObject->FileName.Length = 0;
}
/* Clear its device object */
FileObject->DeviceObject = NULL;
/* Save this now because the FO might go away */
OpenCancelled = FileObject->Flags & FO_FILE_OPEN_CANCELLED ?
TRUE : FALSE;
/* Clear the file object in the open packet */
OpenPacket->FileObject = NULL;
/* Dereference the file object */
if (!UseDummyFile) ObDereferenceObject(FileObject);
/* Dereference the device object */
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
/* Unless the driver cancelled the open, dereference the VPB */
if (!(OpenCancelled) && (Vpb)) IopDereferenceVpb(Vpb);
/* Set the status and return */
OpenPacket->FinalStatus = Status;
return Status;
}
else if (Status == STATUS_REPARSE)
{
/* FIXME: We don't handle this at all! */
KEBUGCHECK(0);
}
/* Get the owner of the File Object */
OwnerDevice = IoGetRelatedDeviceObject(FileObject);
/*
* It's possible that the device to whom we sent the IRP to
* isn't actually the device that ended opening the file object
* internally.
*/
if (OwnerDevice != DeviceObject)
{
/* We have to de-reference the VPB we had associated */
if (Vpb) IopDereferenceVpb(Vpb);
/* And re-associate with the actual one */
Vpb = FileObject->Vpb;
if (Vpb) InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
}
/* Make sure we are not using a dummy */
if (!UseDummyFile)
{
/* Check if this was a volume open */
if ((!(FileObject->RelatedFileObject) ||
(FileObject->RelatedFileObject->Flags & FO_VOLUME_OPEN)) &&
!(FileObject->FileName.Length))
{
/* All signs point to it, but make sure it was actually an FSD */
if ((OwnerDevice->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
(OwnerDevice->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) ||
(OwnerDevice->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM) ||
(OwnerDevice->DeviceType == FILE_DEVICE_FILE_SYSTEM))
{
/* The owner device is an FSD, so this is a volume open for real */
FileObject->Flags |= FO_VOLUME_OPEN;
}
}
/* Reference the object and set the parse check */
ObReferenceObject(FileObject);
*Object = FileObject;
OpenPacket->FinalStatus = IoStatusBlock.Status;
OpenPacket->ParseCheck = TRUE;
return OpenPacket->FinalStatus;
}
else
{
/* Check if this was a query */
if (OpenPacket->QueryOnly)
{
/* Check if the caller wants basic info only */
if (!OpenPacket->FullAttributes)
{
/* Allocate the buffer */
FileBasicInfo = ExAllocatePoolWithTag(NonPagedPool,
sizeof(*FileBasicInfo),
TAG_IO);
if (FileBasicInfo)
{
/* Do the query */
Status = IoQueryFileInformation(FileObject,
FileBasicInformation,
sizeof(*FileBasicInfo),
FileBasicInfo,
&ReturnLength);
if (NT_SUCCESS(Status))
{
/* Copy the data */
RtlCopyMemory(OpenPacket->BasicInformation,
FileBasicInfo,
ReturnLength);
}
/* Free our buffer */
ExFreePool(FileBasicInfo);
}
else
{
/* Fail */
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
/* This is a full query */
Status = IoQueryFileInformation(
FileObject,
FileNetworkOpenInformation,
sizeof(FILE_NETWORK_OPEN_INFORMATION),
OpenPacket->NetworkInformation,
&ReturnLength);
if (!NT_SUCCESS(Status)) ASSERT(Status != STATUS_NOT_IMPLEMENTED);
}
}
/* Delete the file object */
IopDeleteFile(FileObject);
/* Clear out the file */
OpenPacket->FileObject = NULL;
/* Set and return status */
OpenPacket->FinalStatus = Status;
OpenPacket->ParseCheck = TRUE;
return Status;
}
}
NTSTATUS
NTAPI
IopParseFile(IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object)
{
PVOID DeviceObject;
POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
/* Validate the open packet */
if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(ParseObject);
OpenPacket->RelatedFileObject = ParseObject;
/* Call the main routine */
return IopParseDevice(DeviceObject,
ObjectType,
AccessState,
AccessMode,
Attributes,
CompleteName,
RemainingName,
OpenPacket,
SecurityQos,
Object);
}
VOID
NTAPI
IopDeleteFile(IN PVOID ObjectBody)
{
PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
KEVENT Event;
PDEVICE_OBJECT DeviceObject;
BOOLEAN DereferenceDone = FALSE;
PVPB Vpb;
KIRQL OldIrql;
IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
/* Check if the file has a device object */
if (FileObject->DeviceObject)
{
/* Check if this is a direct open or not */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
{
/* Get the attached device */
DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
}
else
{
/* Use the file object's device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
/* Sanity check */
ASSERT(!(FileObject->Flags & FO_SYNCHRONOUS_IO) ||
(InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE));
/* Check if the handle wasn't created yet */
if (!(FileObject->Flags & FO_HANDLE_CREATED))
{
/* Send the cleanup IRP */
IopCloseFile(NULL, ObjectBody, 0, 1, 1);
}
/* Clear and set up Events */
KeClearEvent(&FileObject->Event);
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
/* Allocate an IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) return;
/* Set it up */
Irp->UserEvent = &Event;
Irp->UserIosb = &Irp->IoStatus;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
/* Set up Stack Pointer Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_CLOSE;
StackPtr->FileObject = FileObject;
/* Queue the IRP */
IopQueueIrpToThread(Irp);
/* Get the VPB and check if this isn't a direct open */
Vpb = FileObject->Vpb;
if ((Vpb) && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
{
/* Dereference the VPB before the close */
InterlockedDecrement((PLONG)&Vpb->ReferenceCount);
}
/* Check if the FS will never disappear by itself */
if (FileObject->DeviceObject->Flags & DO_NEVER_LAST_DEVICE)
{
/* Dereference it */
InterlockedDecrement(&FileObject->DeviceObject->ReferenceCount);
DereferenceDone = TRUE;
}
/* Call the FS Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
/* Wait for completion */
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
}
/* De-queue the IRP */
KeRaiseIrql(APC_LEVEL, &OldIrql);
IopUnQueueIrpFromThread(Irp);
KeLowerIrql(OldIrql);
/* Free the IRP */
IoFreeIrp(Irp);
/* Clear the file name */
if (FileObject->FileName.Buffer)
{
ExFreePool(FileObject->FileName.Buffer);
FileObject->FileName.Buffer = NULL;
}
/* Check if the FO had a completion port */
if (FileObject->CompletionContext)
{
/* Free it */
ObDereferenceObject(FileObject->CompletionContext->Port);
ExFreePool(FileObject->CompletionContext);
}
/* Check if dereference has been done yet */
if (!DereferenceDone)
{
/* Dereference device object */
IopDereferenceDeviceObject(FileObject->DeviceObject, FALSE);
}
}
}
NTSTATUS
NTAPI
IopSecurityFile(IN PVOID ObjectBody,
IN SECURITY_OPERATION_CODE OperationCode,
IN PSECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PULONG BufferLength,
IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
IN POOL_TYPE PoolType,
IN OUT PGENERIC_MAPPING GenericMapping)
{
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION StackPtr;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
BOOLEAN LocalEvent = FALSE;
KEVENT Event;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
/* Check if this is a device or file */
if (((PFILE_OBJECT)ObjectBody)->Type == IO_TYPE_DEVICE)
{
/* It's a device */
DeviceObject = (PDEVICE_OBJECT)ObjectBody;
FileObject = NULL;
}
else
{
/* It's a file */
FileObject = (PFILE_OBJECT)ObjectBody;
/* Check if this is a direct open */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
{
/* Get the Device Object */
DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
}
else
{
/* Otherwise, use the direct device*/
DeviceObject = FileObject->DeviceObject;
}
}
/* Check if the request was for a device object */
if (!(FileObject) ||
(!(FileObject->FileName.Length) && !(FileObject->RelatedFileObject)) ||
(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
{
/* Check what kind of request this was */
if (OperationCode == QuerySecurityDescriptor)
{
DPRINT1("FIXME: Device Query security descriptor UNHANDLED\n");
return STATUS_SUCCESS;
}
else if (OperationCode == DeleteSecurityDescriptor)
{
/* Simply return success */
return STATUS_SUCCESS;
}
else if (OperationCode == AssignSecurityDescriptor)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -