📄 driver.c
字号:
#include <ntddk.h>
#include "ioctl.h"
#include "wintypes.h"
//---------------------------------------------------------------------------
#ifdef _DEBUG
#define DbgPrint(_string) {DbgPrint _string;}
#else
#define DbgPrint(_string)
#endif
//---------------------------------------------------------------------------
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
DbgPrint(("IoCompletionRoutine!\n"));
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
IrpFileCreate(
IN PUNICODE_STRING FileName,
IN ACCESS_MASK DesiredAccess,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT RealDevice,
OUT PVOID *Object
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
IO_SECURITY_CONTEXT securityContext;
ACCESS_STATE accessState;
OBJECT_ATTRIBUTES objectAttributes;
PFILE_OBJECT fileObject;
AUX_ACCESS_DATA auxData;
RtlZeroMemory(&auxData, sizeof(AUX_ACCESS_DATA));
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
status = ObCreateObject(KernelMode,
*IoFileObjectType,
&objectAttributes,
KernelMode,
NULL,
sizeof(FILE_OBJECT),
0,
0,
(PVOID *)&fileObject);
if (!NT_SUCCESS(status))
{
IoFreeIrp(irp);
return status;
}
RtlZeroMemory(fileObject, sizeof(FILE_OBJECT));
fileObject->Type = IO_TYPE_FILE;
fileObject->Size = sizeof(FILE_OBJECT);
fileObject->DeviceObject = RealDevice;
// fileObject->RelatedFileObject = NULL;
fileObject->Flags = FO_SYNCHRONOUS_IO;
fileObject->FileName.MaximumLength = FileName->MaximumLength;
fileObject->FileName.Buffer = ExAllocatePool(NonPagedPool, FileName->MaximumLength);
if (fileObject->FileName.Buffer == NULL)
{
IoFreeIrp(irp);
ObDereferenceObject(fileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&fileObject->FileName, FileName);
KeInitializeEvent(&fileObject->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&fileObject->Event, NotificationEvent, FALSE);
irp->MdlAddress = NULL;
irp->Flags |= IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
irp->RequestorMode = KernelMode;
irp->UserIosb = &ioStatus;
irp->UserEvent = &event;
irp->PendingReturned = FALSE;
irp->Cancel = FALSE;
irp->CancelRoutine = NULL;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.AuxiliaryBuffer = NULL;
irp->Tail.Overlay.OriginalFileObject = fileObject;
status = SeCreateAccessState( &accessState,
&auxData,
DesiredAccess,
IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(status))
{
IoFreeIrp(irp);
ExFreePool(fileObject->FileName.Buffer);
ObDereferenceObject(fileObject);
return status;
}
securityContext.SecurityQos = NULL;
securityContext.AccessState = &accessState;
securityContext.DesiredAccess = DesiredAccess;
securityContext.FullCreateOptions = 0;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CREATE;
irpSp->DeviceObject = DeviceObject;
irpSp->FileObject = fileObject;
irpSp->Parameters.Create.SecurityContext = &securityContext;
irpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
irpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
irpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
irpSp->Parameters.Create.EaLength = 0;
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
status = ioStatus.Status;
if (!NT_SUCCESS(status))
{
ExFreePool(fileObject->FileName.Buffer);
fileObject->FileName.Length = 0;
fileObject->DeviceObject = NULL;
ObDereferenceObject(fileObject);
}
else
{
InterlockedIncrement(&fileObject->DeviceObject->ReferenceCount);
if (fileObject->Vpb)
{
InterlockedIncrement(&fileObject->Vpb->ReferenceCount);
}
*Object = fileObject;
DbgPrint(("Open file success! object = %x\n", fileObject));
}
return status;
}
NTSTATUS
IrpFileClose(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
PVPB vpb;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpSp;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->RequestorMode = KernelMode;
irp->UserEvent = &event;
irp->UserIosb = &irp->IoStatus;
irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
irp->Flags = IRP_SYNCHRONOUS_API | IRP_CLOSE_OPERATION;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLEANUP;
irpSp->FileObject = FileObject;
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event,
UserRequest,
KernelMode,
FALSE,
NULL);
}
IoReuseIrp(irp , STATUS_SUCCESS);
KeClearEvent(&event);
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLOSE;
irpSp->FileObject = FileObject;
irp->UserIosb = &ioStatusBlock;
irp->UserEvent = &event;
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->AssociatedIrp.SystemBuffer = (PVOID)NULL;
irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
vpb = FileObject->Vpb;
if (vpb && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
{
InterlockedDecrement(&vpb->ReferenceCount);
FileObject->Flags |= FO_FILE_OPEN_CANCELLED;
}
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
NULL);
}
IoFreeIrp(irp);
return status;
}
NTSTATUS
IrpFileRead(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN ULONG Length,
OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatusBlock
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
PIO_STACK_LOCATION irpSp;
PDEVICE_OBJECT deviceObject;
if (ByteOffset == NULL)
{
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);
if (irp->MdlAddress == NULL)
{
IoFreeIrp(irp);
return STATUS_INSUFFICIENT_RESOURCES;;
}
MmBuildMdlForNonPagedPool(irp->MdlAddress);
irp->Flags = IRP_READ_OPERATION;
irp->RequestorMode = KernelMode;
irp->UserIosb = IoStatusBlock;
irp->UserEvent = &event;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_READ;
irpSp->MinorFunction = IRP_MN_NORMAL;
irpSp->DeviceObject = deviceObject;
irpSp->FileObject = FileObject;
irpSp->Parameters.Read.Length = Length;
irpSp->Parameters.Read.ByteOffset = *ByteOffset;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
status = KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
return status;
}
NTSTATUS
IrpFileWrite(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN ULONG Length,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatusBlock
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
PIO_STACK_LOCATION irpSp;
PDEVICE_OBJECT deviceObject;
if (ByteOffset == NULL)
{
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);
if (irp->MdlAddress == NULL)
{
IoFreeIrp(irp);
return STATUS_INSUFFICIENT_RESOURCES;;
}
MmBuildMdlForNonPagedPool(irp->MdlAddress);
irp->Flags = IRP_WRITE_OPERATION;
irp->RequestorMode = KernelMode;
irp->UserIosb = IoStatusBlock;
irp->UserEvent = &event;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_WRITE;
irpSp->MinorFunction = IRP_MN_NORMAL;
irpSp->DeviceObject = deviceObject;
irpSp->FileObject = FileObject;
irpSp->Parameters.Write.Length = Length;
irpSp->Parameters.Write.ByteOffset = *ByteOffset;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
status = KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
return status;
}
NTSTATUS
IrpFileQuery(
IN PFILE_OBJECT FileObject,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
PDEVICE_OBJECT deviceObject;
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->Flags = IRP_BUFFERED_IO;
irp->AssociatedIrp.SystemBuffer = FileInformation;
irp->RequestorMode = KernelMode;
irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
irp->UserEvent = &event;
irp->UserIosb = &ioStatus;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
irpSp->DeviceObject = deviceObject;
irpSp->FileObject = FileObject;
irpSp->Parameters.QueryFile.Length = Length;
irpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
return ioStatus.Status;
}
NTSTATUS
IrpDirectoryQuery(
IN PFILE_OBJECT FileObject,
IN FILE_INFORMATION_CLASS FileInformationClass,
OUT PVOID Buffer,
IN ULONG Length
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
PDEVICE_OBJECT deviceObject;
PQUERY_DIRECTORY queryDirectory;
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->Flags = IRP_INPUT_OPERATION | IRP_BUFFERED_IO;
irp->RequestorMode = KernelMode;
irp->UserEvent = &event;
irp->UserIosb = &ioStatus;
irp->UserBuffer = Buffer;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
//irp->Pointer = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
irpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
irpSp->DeviceObject = deviceObject;
irpSp->FileObject = FileObject;
queryDirectory = (PQUERY_DIRECTORY)&irpSp->Parameters;
queryDirectory->Length = Length;
queryDirectory->FileName = NULL;
queryDirectory->FileInformationClass = FileInformationClass;
queryDirectory->FileIndex = 0;
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
status = ioStatus.Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -