📄 iofunc.c
字号:
IRP_DEALLOCATE_BUFFER |
IRP_INPUT_OPERATION);
}
else if (DeviceObject->Flags & DO_DIRECT_IO)
{
/* Allocate an MDL */
Mdl = IoAllocateMdl(FileInformation, Length, FALSE, TRUE, Irp);
MmProbeAndLockPages(Mdl, PreviousMode, IoWriteAccess);
}
else
{
/* No allocation flags, and use the buffer directly */
Irp->UserBuffer = FileInformation;
}
/* Set up Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
StackPtr->MinorFunction = IRP_MN_QUERY_DIRECTORY;
/* Set Parameters */
StackPtr->Parameters.QueryDirectory.FileInformationClass =
FileInformationClass;
StackPtr->Parameters.QueryDirectory.FileName = AuxBuffer;
StackPtr->Parameters.QueryDirectory.FileIndex = 0;
StackPtr->Parameters.QueryDirectory.Length = Length;
StackPtr->Flags = 0;
if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
/* Set deferred I/O */
Irp->Flags |= IRP_DEFER_IO_COMPLETION;
/* Perform the call */
return IopPerformSynchronousRequest(DeviceObject,
Irp,
FileObject,
TRUE,
PreviousMode,
LockedForSynch,
IopOtherTransfer);
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
NtQueryEaFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN BOOLEAN ReturnSingleEntry,
IN PVOID EaList OPTIONAL,
IN ULONG EaListLength,
IN PULONG EaIndex OPTIONAL,
IN BOOLEAN RestartScan)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
NtQueryInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
OBJECT_HANDLE_INFORMATION HandleInformation;
PFILE_OBJECT FileObject;
NTSTATUS Status = STATUS_SUCCESS;
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PKEVENT Event = NULL;
BOOLEAN LocalEvent = FALSE;
PKNORMAL_ROUTINE NormalRoutine;
PVOID NormalContext;
KIRQL OldIrql;
IO_STATUS_BLOCK KernelIosb;
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
/* Check if we're called from user mode */
if (PreviousMode != KernelMode)
{
/* Validate the information class */
if ((FileInformationClass >= FileMaximumInformation) ||
!(IopQueryOperationLength[FileInformationClass]))
{
/* Invalid class */
return STATUS_INVALID_INFO_CLASS;
}
/* Validate the length */
if (Length < IopQueryOperationLength[FileInformationClass])
{
/* Invalid length */
return STATUS_INFO_LENGTH_MISMATCH;
}
/* Enter SEH for probing */
_SEH_TRY
{
/* Probe the I/O Status block */
ProbeForWriteIoStatusBlock(IoStatusBlock);
/* Probe the information */
ProbeForWrite(FileInformation, Length, sizeof(ULONG));
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) return Status;
}
else
{
/* Validate the information class */
if ((FileInformationClass >= FileMaximumInformation) ||
!(IopQueryOperationLength[FileInformationClass]))
{
/* Invalid class */
return STATUS_INVALID_INFO_CLASS;
}
/* Validate the length */
if (Length < IopQueryOperationLength[FileInformationClass])
{
/* Invalid length */
return STATUS_INFO_LENGTH_MISMATCH;
}
}
/* Reference the Handle */
Status = ObReferenceObjectByHandle(FileHandle,
IopQueryOperationAccess
[FileInformationClass],
IoFileObjectType,
PreviousMode,
(PVOID *)&FileObject,
&HandleInformation);
if (!NT_SUCCESS(Status)) return Status;
/* Check if this is a direct open or not */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
{
/* Get the device object */
DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
}
else
{
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
/* Check if this is a file that was opened for Synch I/O */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
/* Lock it */
IopLockFileObject(FileObject);
/* Check if the caller just wants the position */
if (FileInformationClass == FilePositionInformation)
{
/* Protect write in SEH */
_SEH_TRY
{
/* Write the offset */
((PFILE_POSITION_INFORMATION)FileInformation)->
CurrentByteOffset = FileObject->CurrentByteOffset;
/* Fill out the I/O Status Block */
IoStatusBlock->Information = sizeof(FILE_POSITION_INFORMATION);
Status = IoStatusBlock->Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Release the file lock, dereference the file and return */
IopUnlockFileObject(FileObject);
ObDereferenceObject(FileObject);
return Status;
}
}
else
{
/* Use local event */
Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
KeInitializeEvent(Event, SynchronizationEvent, FALSE);
LocalEvent = TRUE;
}
/* Clear the File Object event */
KeClearEvent(&FileObject->Event);
/* Allocate the IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, Event);
/* Set the IRP */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
Irp->UserEvent = (LocalEvent) ? Event : NULL;
Irp->AssociatedIrp.SystemBuffer = NULL;
Irp->MdlAddress = NULL;
Irp->UserBuffer = FileInformation;
/* Set the Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
StackPtr->FileObject = FileObject;
/* Enter SEH */
_SEH_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
}
_SEH_HANDLE
{
/* Allocating failed, clean up */
IopCleanupAfterException(FileObject, Irp, NULL, Event);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) return Status;
/* Set the flags */
Irp->Flags = (IRP_BUFFERED_IO |
IRP_DEALLOCATE_BUFFER |
IRP_INPUT_OPERATION |
IRP_DEFER_IO_COMPLETION);
/* Set the Parameters */
StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass;
StackPtr->Parameters.QueryFile.Length = Length;
/* Queue the IRP */
IopQueueIrpToThread(Irp);
/* Update operation counts */
IopUpdateOperationCount(IopOtherTransfer);
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
/* Check if this was async I/O */
if (LocalEvent)
{
/* Then to a non-alertable wait */
Status = KeWaitForSingleObject(Event,
Executive,
PreviousMode,
FALSE,
NULL);
if (Status == STATUS_USER_APC)
{
/* Abort the request */
IopAbortInterruptedIrp(Event, Irp);
}
/* Set the final status */
Status = KernelIosb.Status;
/* Enter SEH to write the IOSB back */
_SEH_TRY
{
/* Write it back to the caller */
*IoStatusBlock = KernelIosb;
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Free the event */
ExFreePool(Event);
}
else
{
/* Wait for the IRP */
Status = KeWaitForSingleObject(&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if ((Status == STATUS_USER_APC) || (Status == STATUS_ALERTED))
{
/* Abort the request */
IopAbortInterruptedIrp(&FileObject->Event, Irp);
}
/* Set the final status */
Status = FileObject->FinalStatus;
/* Release the file lock */
IopUnlockFileObject(FileObject);
}
}
else
{
/* Free the event if we had one */
if (LocalEvent)
{
/* Clear it in the IRP for completion */
Irp->UserEvent = NULL;
ExFreePool(Event);
}
/* Set the caller IOSB */
Irp->UserIosb = IoStatusBlock;
/* The IRP wasn't completed, complete it ourselves */
KeRaiseIrql(APC_LEVEL, &OldIrql);
IopCompleteRequest(&Irp->Tail.Apc,
&NormalRoutine,
&NormalContext,
(PVOID*)&FileObject,
&NormalContext);
KeLowerIrql(OldIrql);
/* Release the file object if we had locked it*/
if (!LocalEvent) IopUnlockFileObject(FileObject);
}
/* Return the Status */
return Status;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
NtQueryQuotaInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN BOOLEAN ReturnSingleEntry,
IN PVOID SidList OPTIONAL,
IN ULONG SidListLength,
IN PSID StartSid OPTIONAL,
IN BOOLEAN RestartScan)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
NtReadFile(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -