📄 iofunc.c
字号:
/* Enter SEH for allocations */
_SEH_TRY
{
/* Select the right Buffer Length */
BufferLength = (InputBufferLength > OutputBufferLength) ?
InputBufferLength : OutputBufferLength;
/* Make sure there is one */
if (BufferLength)
{
/* Allocate the System Buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
BufferLength,
TAG_SYS_BUF);
/* Check if we got a buffer */
if (InputBuffer)
{
/* Copy into the System Buffer */
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
InputBuffer,
InputBufferLength);
}
/* Write the flags */
Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
if (OutputBuffer) Irp->Flags |= IRP_INPUT_OPERATION;
/* Save the Buffer */
Irp->UserBuffer = OutputBuffer;
}
else
{
/* Clear the Flags and Buffer */
Irp->UserBuffer = NULL;
}
}
_SEH_HANDLE
{
/* Cleanup after exception */
IopCleanupAfterException(FileObject, Irp, Event, NULL);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) return Status;
break;
/* Direct I/O */
case METHOD_IN_DIRECT:
case METHOD_OUT_DIRECT:
/* Enter SEH */
_SEH_TRY
{
/* Check if we got an input buffer */
if ((InputBufferLength) && (InputBuffer))
{
/* Allocate the System Buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
InputBufferLength,
TAG_SYS_BUF);
/* Copy into the System Buffer */
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
InputBuffer,
InputBufferLength);
/* Write the flags */
Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
}
/* Check if we got an output buffer */
if (OutputBuffer)
{
/* Allocate the System Buffer */
Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
OutputBufferLength,
FALSE,
FALSE,
Irp);
if (!Irp->MdlAddress)
{
/* Raise exception we'll catch */
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
}
/* Do the probe */
MmProbeAndLockPages(Irp->MdlAddress,
PreviousMode,
(AccessType == METHOD_IN_DIRECT) ?
IoReadAccess : IoWriteAccess);
}
}
_SEH_HANDLE
{
/* Cleanup after exception */
IopCleanupAfterException(FileObject, Irp, Event, NULL);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) return Status;
break;
case METHOD_NEITHER:
/* Just save the Buffer */
Irp->UserBuffer = OutputBuffer;
StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
}
/* Use deferred completion for FS I/O */
Irp->Flags |= (!IsDevIoCtl) ? IRP_DEFER_IO_COMPLETION : 0;
/* Perform the call */
return IopPerformSynchronousRequest(DeviceObject,
Irp,
FileObject,
!IsDevIoCtl,
PreviousMode,
LockedForSynch,
IopOtherTransfer);
}
NTSTATUS
NTAPI
IopQueryDeviceInformation(IN PFILE_OBJECT FileObject,
IN ULONG InformationClass,
IN ULONG Length,
OUT PVOID Information,
OUT PULONG ReturnedLength,
IN BOOLEAN File)
{
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, "Handle: %p. CTL: %lx. Type: %lx \n",
FileObject, InformationClass, File);
/* 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 = Information;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
/* Set the Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = File ? IRP_MJ_QUERY_INFORMATION:
IRP_MJ_QUERY_VOLUME_INFORMATION;
StackPtr->FileObject = FileObject;
/* Check which type this is */
if (File)
{
/* Set Parameters */
StackPtr->Parameters.QueryFile.FileInformationClass = InformationClass;
StackPtr->Parameters.QueryFile.Length = Length;
}
else
{
/* Set Parameters */
StackPtr->Parameters.QueryVolume.FsInformationClass = InformationClass;
StackPtr->Parameters.QueryVolume.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 Length and Status. ReturnedLength is NOT optional */
*ReturnedLength = IoStatusBlock.Information;
return Status;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
IoSynchronousPageWrite(IN PFILE_OBJECT FileObject,
IN PMDL Mdl,
IN PLARGE_INTEGER Offset,
IN PKEVENT Event,
IN PIO_STATUS_BLOCK StatusBlock)
{
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
IOTRACE(IO_API_DEBUG, "FileObject: %p. Mdl: %p. Offset: %p \n",
FileObject, Mdl, Offset);
/* Get the Device Object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
/* Allocate IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the Stack */
StackPtr = IoGetNextIrpStackLocation(Irp);
/* Create the IRP Settings */
Irp->MdlAddress = Mdl;
Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
Irp->UserIosb = StatusBlock;
Irp->UserEvent = Event;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_PAGING_IO;
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
/* Set the Stack Settings */
StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
StackPtr->Parameters.Write.ByteOffset = *Offset;
StackPtr->MajorFunction = IRP_MJ_WRITE;
StackPtr->FileObject = FileObject;
/* Call the Driver */
return IofCallDriver(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IoPageRead(IN PFILE_OBJECT FileObject,
IN PMDL Mdl,
IN PLARGE_INTEGER Offset,
IN PKEVENT Event,
IN PIO_STATUS_BLOCK StatusBlock)
{
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
IOTRACE(IO_API_DEBUG, "FileObject: %p. Mdl: %p. Offset: %p \n",
FileObject, Mdl, Offset);
/* Get the Device Object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
/* Allocate IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the Stack */
StackPtr = IoGetNextIrpStackLocation(Irp);
/* Create the IRP Settings */
Irp->MdlAddress = Mdl;
Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
Irp->UserIosb = StatusBlock;
Irp->UserEvent = Event;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_PAGING_IO |
IRP_NOCACHE |
IRP_SYNCHRONOUS_PAGING_IO |
IRP_INPUT_OPERATION;
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
/* Set the Stack Settings */
StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
StackPtr->Parameters.Read.ByteOffset = *Offset;
StackPtr->MajorFunction = IRP_MJ_READ;
StackPtr->FileObject = FileObject;
/* Call the Driver */
return IofCallDriver(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IoQueryFileInformation(IN PFILE_OBJECT FileObject,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN ULONG Length,
OUT PVOID FileInformation,
OUT PULONG ReturnedLength)
{
/* Call the shared routine */
return IopQueryDeviceInformation(FileObject,
FileInformationClass,
Length,
FileInformation,
ReturnedLength,
TRUE);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
IN FS_INFORMATION_CLASS FsInformationClass,
IN ULONG Length,
OUT PVOID FsInformation,
OUT PULONG ReturnedLength)
{
/* Call the shared routine */
return IopQueryDeviceInformation(FileObject,
FsInformationClass,
Length,
FsInformation,
ReturnedLength,
FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -