📄 iofunc.c
字号:
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IoSetInformation(IN PFILE_OBJECT FileObject,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN ULONG Length,
IN PVOID FileInformation)
{
IO_STATUS_BLOCK IoStatusBlock;
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION StackPtr;
BOOLEAN LocalEvent = FALSE;
KEVENT Event;
NTSTATUS Status;
PAGED_CODE();
IOTRACE(IO_API_DEBUG, "FileObject: %p. Class: %lx. Length: %lx \n",
FileObject, FileInformationClass, Length);
/* Reference the object */
ObReferenceObject(FileObject);
/* Check if this is a file that was opened for Synch I/O */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
/* Lock it */
IopLockFileObject(FileObject);
/* Use File Object event */
KeClearEvent(&FileObject->Event);
}
else
{
/* Use local event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
LocalEvent = TRUE;
}
/* 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->RequestorMode = KernelMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
Irp->UserIosb = &IoStatusBlock;
Irp->UserEvent = (LocalEvent) ? &Event : NULL;
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
Irp->Flags |= IRP_BUFFERED_IO;
Irp->AssociatedIrp.SystemBuffer = FileInformation;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
/* Set the Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
StackPtr->FileObject = FileObject;
/* Set Parameters */
StackPtr->Parameters.SetFile.FileInformationClass = FileInformationClass;
StackPtr->Parameters.SetFile.Length = Length;
/* Queue the IRP */
IopQueueIrpToThread(Irp);
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
/* Check if this was synch I/O */
if (!LocalEvent)
{
/* Check if the requet is pending */
if (Status == STATUS_PENDING)
{
/* Wait on the file object */
Status = KeWaitForSingleObject(&FileObject->Event,
Executive,
KernelMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status == STATUS_ALERTED)
{
/* Abort the operation */
IopAbortInterruptedIrp(&FileObject->Event, Irp);
}
/* Get the final status */
Status = FileObject->FinalStatus;
}
/* Release the file lock */
IopUnlockFileObject(FileObject);
}
else if (Status == STATUS_PENDING)
{
/* Wait on the local event and get the final status */
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = IoStatusBlock.Status;
}
/* Return the status */
return Status;
}
/* NATIVE SERVICES ***********************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
NtDeviceIoControlFile(IN HANDLE DeviceHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
IN PVOID UserApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength OPTIONAL,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength OPTIONAL)
{
/* Call the Generic Function */
return IopDeviceFsIoControl(DeviceHandle,
Event,
UserApcRoutine,
UserApcContext,
IoStatusBlock,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
TRUE);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
NtFsControlFile(IN HANDLE DeviceHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
IN PVOID UserApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength OPTIONAL,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength OPTIONAL)
{
/* Call the Generic Function */
return IopDeviceFsIoControl(DeviceHandle,
Event,
UserApcRoutine,
UserApcContext,
IoStatusBlock,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
FALSE);
}
NTSTATUS
NTAPI
NtFlushBuffersFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock)
{
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject;
PKEVENT Event = NULL;
BOOLEAN LocalEvent = FALSE;
OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
IO_STATUS_BLOCK KernelIosb;
PAGED_CODE();
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
if (PreviousMode != KernelMode)
{
/* Protect probes */
_SEH_TRY
{
/* Probe the I/O Status block */
ProbeForWriteIoStatusBlock(IoStatusBlock);
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Return exception code, if any */
if (!NT_SUCCESS(Status)) return Status;
}
/* Get the File Object */
Status = ObReferenceObjectByHandle(FileHandle,
0,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
&ObjectHandleInfo);
if (!NT_SUCCESS(Status)) return Status;
/*
* Check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
* granted. However, if this is a named pipe, make sure we don't ask for
* FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
* access right!
*/
if (!(ObjectHandleInfo.GrantedAccess &
((!(FileObject->Flags & FO_NAMED_PIPE) ? FILE_APPEND_DATA : 0) |
FILE_WRITE_DATA)))
{
/* We failed */
ObDereferenceObject(FileObject);
return STATUS_ACCESS_DENIED;
}
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
/* Lock it */
IopLockFileObject(FileObject);
}
else
{
/* Use local event */
Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
KeInitializeEvent(Event, SynchronizationEvent, FALSE);
LocalEvent = TRUE;
}
/* Get the Device Object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
/* Clear the event */
KeClearEvent(&FileObject->Event);
/* Allocate the IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, Event);
/* Set up the IRP */
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
Irp->UserEvent = (LocalEvent) ? Event : NULL;
Irp->RequestorMode = PreviousMode;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
/* Set up Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
StackPtr->FileObject = FileObject;
/* Call the Driver */
Status = IopPerformSynchronousRequest(DeviceObject,
Irp,
FileObject,
FALSE,
PreviousMode,
!LocalEvent,
IopOtherTransfer);
/* Check if this was async I/O */
if (LocalEvent)
{
/* It was, finalize this request */
Status = IopFinalizeAsynchronousIo(Status,
Event,
Irp,
PreviousMode,
&KernelIosb,
IoStatusBlock);
}
/* Return the Status */
return Status;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG BufferSize,
IN ULONG CompletionFilter,
IN BOOLEAN WatchTree)
{
PIRP Irp;
PKEVENT Event = NULL;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
PIO_STACK_LOCATION IoStack;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN LockedForSync = FALSE;
PAGED_CODE();
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
/* Check if we're called from user mode */
if (PreviousMode != KernelMode)
{
/* Enter SEH for probing */
_SEH_TRY
{
/* Probe the I/O STatus block */
ProbeForWriteIoStatusBlock(IoStatusBlock);
/* Probe the buffer */
if (BufferSize) ProbeForWrite(Buffer, BufferSize, sizeof(ULONG));
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Check if probing failed */
if (!NT_SUCCESS(Status)) return Status;
}
/* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
FILE_LIST_DIRECTORY,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status)) return Status;
/* 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);
}
/* 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);
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
/* Allocate the IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -