📄 file.c
字号:
/* Make absolutely sure this is a device object */
if (!(FileObject) || !(FileObject->Flags & FO_STREAM_FILE))
{
/* Assign the Security Descriptor */
DeviceObject->SecurityDescriptor = SecurityDescriptor;
}
/* Return success */
return STATUS_SUCCESS;
}
else
{
DPRINT1("FIXME: Set SD unimplemented for Devices\n");
return STATUS_SUCCESS;
}
}
else if (OperationCode == DeleteSecurityDescriptor)
{
/* Same as for devices, do nothing */
return STATUS_SUCCESS;
}
/* At this point, we know we're a file. Reference it */
ObReferenceObject(FileObject);
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
/* Lock the file object */
IopLockFileObject(FileObject);
}
else
{
/* Use local event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
LocalEvent = TRUE;
}
/* Clear the File Object event */
KeClearEvent(&FileObject->Event);
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
/* Allocate the IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, NULL);
/* Set the IRP */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->RequestorMode = ExGetPreviousMode();
Irp->UserIosb = &IoStatusBlock;
Irp->UserEvent = (LocalEvent) ? &Event : NULL;
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
/* Set Stack Parameters */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
/* Check if this is a query or set */
if (OperationCode == QuerySecurityDescriptor)
{
/* Set the major function and parameters */
StackPtr->MajorFunction = IRP_MJ_QUERY_SECURITY;
StackPtr->Parameters.QuerySecurity.SecurityInformation =
*SecurityInformation;
StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
Irp->UserBuffer = SecurityDescriptor;
}
else
{
/* Set the major function and parameters for a set */
StackPtr->MajorFunction = IRP_MJ_SET_SECURITY;
StackPtr->Parameters.SetSecurity.SecurityInformation =
*SecurityInformation;
StackPtr->Parameters.SetSecurity.SecurityDescriptor =
SecurityDescriptor;
}
/* Queue the IRP */
IopQueueIrpToThread(Irp);
/* Update operation counts */
IopUpdateOperationCount(IopOtherTransfer);
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
/* Check if this was async I/O */
if (LocalEvent)
{
/* Check if the IRP is pending completion */
if (Status == STATUS_PENDING)
{
/* Wait on the local event */
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = IoStatusBlock.Status;
}
}
else
{
/* Check if the IRP is pending completion */
if (Status == STATUS_PENDING)
{
/* Wait on the file object */
KeWaitForSingleObject(&FileObject->Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = FileObject->FinalStatus;
}
/* Release the lock */
IopUnlockFileObject(FileObject);
}
/* This Driver doesn't implement Security, so try to give it a default */
if (Status == STATUS_INVALID_DEVICE_REQUEST)
{
/* Was this a query? */
if (OperationCode == QuerySecurityDescriptor)
{
/* Set a World Security Descriptor */
Status = SeSetWorldSecurityDescriptor(*SecurityInformation,
SecurityDescriptor,
BufferLength);
}
else
{
/* It wasn't a query, so just fake success */
Status = STATUS_SUCCESS;
}
}
else if (OperationCode == QuerySecurityDescriptor)
{
/* Callers usually expect the normalized form */
if (Status == STATUS_BUFFER_OVERFLOW) Status = STATUS_BUFFER_TOO_SMALL;
/* Return length */
*BufferLength = IoStatusBlock.Information;
}
/* Return Status */
return Status;
}
NTSTATUS
NTAPI
IopQueryNameFile(IN PVOID ObjectBody,
IN BOOLEAN HasName,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength,
IN KPROCESSOR_MODE PreviousMode)
{
POBJECT_NAME_INFORMATION LocalInfo;
PFILE_NAME_INFORMATION LocalFileInfo;
PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
ULONG LocalReturnLength, FileLength;
NTSTATUS Status;
PWCHAR p;
IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
/* Validate length */
if (Length < sizeof(OBJECT_NAME_INFORMATION))
{
/* Wrong length, fail */
return STATUS_INFO_LENGTH_MISMATCH;
}
/* Allocate Buffer */
LocalInfo = ExAllocatePoolWithTag(PagedPool, Length, TAG_IO);
if (!LocalInfo) return STATUS_INSUFFICIENT_RESOURCES;
/* Query the name */
Status = ObQueryNameString(FileObject->DeviceObject,
LocalInfo,
Length,
&LocalReturnLength);
if (!NT_SUCCESS(Status))
{
/* Free the buffer and fail */
ExFreePool(LocalInfo);
return Status;
}
/* Copy the information */
RtlCopyMemory(ObjectNameInfo,
LocalInfo,
(LocalReturnLength > Length) ?
Length : LocalReturnLength);
/* Set buffer pointer */
p = (PWCHAR)(ObjectNameInfo + 1);
ObjectNameInfo->Name.Buffer = p;
/* Advance in buffer */
p += (LocalInfo->Name.Length / sizeof(WCHAR));
/* Check if this already filled our buffer */
if (LocalReturnLength > Length)
{
/* Free the buffer and fail */
ExFreePool(LocalInfo);
return STATUS_BUFFER_OVERFLOW;
}
/* Now get the file name buffer and check the length needed */
LocalFileInfo = (PFILE_NAME_INFORMATION)LocalInfo;
FileLength = Length -
LocalReturnLength +
FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
/* Query the File name */
Status = IoQueryFileInformation(FileObject,
FileNameInformation,
FileLength,
LocalFileInfo,
&LocalReturnLength);
if (NT_ERROR(Status))
{
/* Fail on errors only, allow warnings */
ExFreePool(LocalInfo);
return Status;
}
/* ROS HACK. VFAT SUCKS */
if (NT_WARNING(Status)) LocalReturnLength = FileLength;
/* Now calculate the new lengths left */
FileLength = LocalReturnLength -
FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
LocalReturnLength = (ULONG_PTR)p -
(ULONG_PTR)ObjectNameInfo +
LocalFileInfo->FileNameLength;
/* Write the Name and null-terminate it */
RtlCopyMemory(p, LocalFileInfo->FileName, FileLength);
p += (FileLength / sizeof(WCHAR));
*p = UNICODE_NULL;
LocalReturnLength += sizeof(UNICODE_NULL);
/* Return the length needed */
*ReturnLength = LocalReturnLength;
/* Setup the length and maximum length */
FileLength = (ULONG_PTR)p - (ULONG_PTR)ObjectNameInfo;
ObjectNameInfo->Name.Length = (USHORT)FileLength -
sizeof(OBJECT_NAME_INFORMATION);
ObjectNameInfo->Name.MaximumLength = (USHORT)ObjectNameInfo->Name.Length +
sizeof(UNICODE_NULL);
/* Free buffer and return */
ExFreePool(LocalInfo);
return Status;
}
VOID
NTAPI
IopCloseFile(IN PEPROCESS Process OPTIONAL,
IN PVOID ObjectBody,
IN ACCESS_MASK GrantedAccess,
IN ULONG HandleCount,
IN ULONG SystemHandleCount)
{
PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
KEVENT Event;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
KIRQL OldIrql;
IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
/* If this isn't the last handle for the current process, quit */
if (HandleCount != 1) return;
/* Check if the file is locked and has more then one handle opened */
if ((FileObject->LockOperation) && (SystemHandleCount != 1))
{
DPRINT1("We need to unlock this file!\n");
KEBUGCHECK(0);
}
/* Make sure this is the last handle */
if (SystemHandleCount != 1) return;
/* 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
{
/* Get the FO's device */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
/* Set the handle created flag */
FileObject->Flags |= FO_HANDLE_CREATED;
/* Check if this is a sync FO and lock it */
if (FileObject->Flags & FO_SYNCHRONOUS_IO) IopLockFileObject(FileObject);
/* 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->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
/* Set up Stack Pointer Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_CLEANUP;
StackPtr->FileObject = FileObject;
/* Queue the IRP */
IopQueueIrpToThread(Irp);
/* Update operation counts */
IopUpdateOperationCount(IopOtherTransfer);
/* Call the FS Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
/* Wait for completion */
KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, NULL);
}
/* Unqueue the IRP */
KeRaiseIrql(APC_LEVEL, &OldIrql);
IopUnQueueIrpFromThread(Irp);
KeLowerIrql(OldIrql);
/* Free the IRP */
IoFreeIrp(Irp);
/* Release the lock if we were holding it */
if (FileObject->Flags & FO_SYNCHRONOUS_IO) IopUnlockFileObject(FileObject);
}
NTSTATUS
NTAPI
IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN ULONG FileInformationSize,
OUT PVOID FileInformation)
{
NTSTATUS Status = STATUS_SUCCESS;
KPROCESSOR_MODE AccessMode = ExGetPreviousMode();
DUMMY_FILE_OBJECT DummyFileObject;
FILE_NETWORK_OPEN_INFORMATION NetworkOpenInfo;
HANDLE Handle;
OPEN_PACKET OpenPacket;
BOOLEAN IsBasic;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -