📄 iofunc.c
字号:
if (!Irp) return IopCleanupFailedIrp(FileObject, Event, NULL);
/* Set up the IRP */
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = Event;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
/* Set up Stack Data */
IoStack = IoGetNextIrpStackLocation(Irp);
IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
IoStack->FileObject = FileObject;
/* Set parameters */
IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
IoStack->Parameters.NotifyDirectory.Length = BufferSize;
if (WatchTree) IoStack->Flags = SL_WATCH_TREE;
/* Perform the call */
return IopPerformSynchronousRequest(DeviceObject,
Irp,
FileObject,
FALSE,
PreviousMode,
LockedForSync,
IopOtherTransfer);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
NtLockFile(IN HANDLE FileHandle,
IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length,
IN ULONG Key,
IN BOOLEAN FailImmediately,
IN BOOLEAN ExclusiveLock)
{
PFILE_OBJECT FileObject;
PLARGE_INTEGER LocalLength = NULL;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
PKEVENT Event = NULL;
BOOLEAN LockedForSync = FALSE;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
LARGE_INTEGER CapturedByteOffset, CapturedLength;
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_HANDLE_INFORMATION HandleInformation;
PAGED_CODE();
CapturedByteOffset.QuadPart = 0;
CapturedLength.QuadPart = 0;
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
/* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
0,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
&HandleInformation);
if (!NT_SUCCESS(Status)) return Status;
/* Check if we're called from user mode */
if (PreviousMode != KernelMode)
{
/* Must have either FILE_READ_DATA or FILE_WRITE_DATA access */
if (!(HandleInformation.GrantedAccess &
(FILE_WRITE_DATA | FILE_READ_DATA)))
{
ObDereferenceObject(FileObject);
return STATUS_ACCESS_DENIED;
}
/* Enter SEH for probing */
_SEH_TRY
{
/* Probe the I/O STatus block */
ProbeForWriteIoStatusBlock(IoStatusBlock);
/* Probe and capture the large integers */
CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
CapturedLength = ProbeForReadLargeInteger(Length);
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Check if probing failed */
if (!NT_SUCCESS(Status))
{
/* Dereference the object and return exception code */
ObDereferenceObject(FileObject);
return Status;
}
}
else
{
/* Otherwise, capture them directly */
CapturedByteOffset = *ByteOffset;
CapturedLength = *Length;
}
/* Check if we have an event handle */
if (EventHandle)
{
/* Reference it */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE,
ExEventObjectType,
PreviousMode,
(PVOID *)&Event,
NULL);
if (Status != STATUS_SUCCESS) return Status;
KeClearEvent(Event);
}
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
/* Lock it */
IopLockFileObject(FileObject);
LockedForSync = TRUE;
}
/* Clear File Object event */
KeClearEvent(&FileObject->Event);
FileObject->LockOperation = TRUE;
/* Allocate the IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) return IopCleanupFailedIrp(FileObject, Event, NULL);
/* Set up the IRP */
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = Event;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
/* Set up Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
StackPtr->MinorFunction = IRP_MN_LOCK;
StackPtr->FileObject = FileObject;
/* Enter SEH */
_SEH_TRY
{
/* Allocate local buffer */
LocalLength = ExAllocatePoolWithTag(NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK);
/* Set the length */
*LocalLength = CapturedLength;
Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID)LocalLength;
StackPtr->Parameters.LockControl.Length = LocalLength;
}
_SEH_HANDLE
{
/* Allocating failed, clean up */
IopCleanupAfterException(FileObject, Irp, Event, NULL);
if (LocalLength) ExFreePool(LocalLength);
/* Get status */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) return Status;
/* Set Parameters */
StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
StackPtr->Parameters.LockControl.Key = Key;
/* Set Flags */
if (FailImmediately) StackPtr->Flags = SL_FAIL_IMMEDIATELY;
if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
/* Perform the call */
return IopPerformSynchronousRequest(DeviceObject,
Irp,
FileObject,
FALSE,
PreviousMode,
LockedForSync,
IopOtherTransfer);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
NtQueryDirectoryFile(IN HANDLE FileHandle,
IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan)
{
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN LockedForSynch = FALSE;
PKEVENT Event = NULL;
PVOID AuxBuffer = NULL;
PMDL Mdl;
UNICODE_STRING CapturedFileName;
PUNICODE_STRING SearchPattern;
PAGED_CODE();
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
/* Check if we came from user mode */
if (PreviousMode != KernelMode)
{
/* Enter SEH for probing */
_SEH_TRY
{
/* Probe the I/O Status Block */
ProbeForWriteIoStatusBlock(IoStatusBlock);
/* Probe the file information */
ProbeForWrite(FileInformation, Length, sizeof(ULONG));
/* Check if we have a file name */
if (FileName)
{
/* Capture it */
CapturedFileName = ProbeForReadUnicodeString(FileName);
if (CapturedFileName.Length)
{
/* Probe its buffer */
ProbeForRead(CapturedFileName.Buffer,
CapturedFileName.Length,
1);
}
/* Allocate the auxiliary buffer */
AuxBuffer = ExAllocatePoolWithTag(NonPagedPool,
CapturedFileName.Length +
sizeof(UNICODE_STRING),
TAG_SYSB);
RtlCopyMemory((PVOID)((ULONG_PTR)AuxBuffer +
sizeof(UNICODE_STRING)),
CapturedFileName.Buffer,
CapturedFileName.Length);
/* Setup the search pattern */
SearchPattern = (PUNICODE_STRING)AuxBuffer;
SearchPattern->Buffer = (PWCHAR)((ULONG_PTR)AuxBuffer +
sizeof(UNICODE_STRING));
SearchPattern->Length = CapturedFileName.Length;
SearchPattern->MaximumLength = CapturedFileName.Length;
}
}
_SEH_HANDLE
{
/* Get exception code and free the buffer */
if (AuxBuffer) ExFreePool(AuxBuffer);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Return status on failure */
if (!NT_SUCCESS(Status)) return Status;
}
/* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
FILE_LIST_DIRECTORY,
IoFileObjectType,
PreviousMode,
(PVOID *)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
/* Fail */
if (AuxBuffer) ExFreePool(AuxBuffer);
return Status;
}
/* Check if we have an even handle */
if (EventHandle)
{
/* Get its pointer */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE,
ExEventObjectType,
PreviousMode,
(PVOID *)&Event,
NULL);
if (!NT_SUCCESS(Status))
{
/* Fail */
ObDereferenceObject(FileObject);
return Status;
}
/* Clear it */
KeClearEvent(Event);
}
/* Check if this is a file that was opened for Synch I/O */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
/* Lock it */
IopLockFileObject(FileObject);
/* Remember to unlock later */
LockedForSynch = TRUE;
}
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
/* Clear the File Object's event */
KeClearEvent(&FileObject->Event);
/* Allocate the IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (!Irp) return IopCleanupFailedIrp(FileObject, EventHandle, AuxBuffer);
/* Set up the IRP */
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = Event;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
Irp->MdlAddress = NULL;
Irp->Tail.Overlay.AuxiliaryBuffer = AuxBuffer;
Irp->AssociatedIrp.SystemBuffer = NULL;
/* Check if this is buffered I/O */
if (DeviceObject->Flags & DO_BUFFERED_IO)
{
/* Enter SEH */
_SEH_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
}
_SEH_HANDLE
{
/* Allocating failed, clean up */
IopCleanupAfterException(FileObject, Irp, Event, NULL);
if (AuxBuffer) ExFreePool(AuxBuffer);
/* Get status */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) return Status;
/* Set the buffer and flags */
Irp->UserBuffer = FileInformation;
Irp->Flags = (IRP_BUFFERED_IO |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -