IrpCreateFile
2013年04月23日
⁄ 综合
⁄ 共 20931字 ⁄ 字号
小 中 大
- #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;
- }
-
- return status;
- }
-
- BOOLEAN GetDriveObject(
- IN ULONG DriveNumber,
- OUT PDEVICE_OBJECT *DeviceObject,
- OUT PDEVICE_OBJECT *ReadDevice
- )
- {
- WCHAR driveName[] = L"//DosDevices//A://";
- UNICODE_STRING deviceName;
- HANDLE deviceHandle;
- OBJECT_ATTRIBUTES objectAttributes;
- IO_STATUS_BLOCK ioStatus;
- PFILE_OBJECT fileObject;
- NTSTATUS status;
-
- if (DriveNumber >= 'A' && DriveNumber <= 'Z')
- {
- driveName[12] = (CHAR)DriveNumber;
- }
- else if (DriveNumber >= 'a' && DriveNumber <= 'z')
- {
- driveName[12] = (CHAR)DriveNumber - 'a' + 'A';
- }
- else
- {
- return FALSE;
- }
-
- RtlInitUnicodeString(&deviceName, driveName);
-
- InitializeObjectAttributes( &objectAttributes,
- &deviceName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- status = IoCreateFile( &deviceHandle,
- SYNCHRONIZE | FILE_ANY_ACCESS,
- &objectAttributes,
- &ioStatus,
- NULL,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE,
- NULL,
- 0,
- CreateFileTypeNone,
- NULL,
- 0x100);
-
- if (!NT_SUCCESS(status))
- {
- DbgPrint(("Could not open drive %c: %x/n", DriveNumber, status));
- return FALSE;
- }
-
- status = ObReferenceObjectByHandle( deviceHandle,
- FILE_READ_DATA,
- *IoFileObjectType,
- KernelMode,
- &fileObject,
- NULL);
-
- if (!NT_SUCCESS(status))
- {
- DbgPrint(("Could not get fileobject from handle: %c/n", DriveNumber));
- ZwClose(deviceHandle);
- return FALSE;
- }
-
- if (fileObject->Vpb == 0 || fileObject->Vpb->RealDevice == NULL)
- {
- ObDereferenceObject(fileObject);
- ZwClose(deviceHandle);
- return FALSE;
- }
-
- *DeviceObject = fileObject->Vpb->DeviceObject;
- *ReadDevice = fileObject->Vpb->RealDevice;
-
- ObDereferenceObject(fileObject);
- ZwClose(deviceHandle);
-
- return TRUE;
- }