1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| NTSTATUS IrpOpenFile( IN PUNICODE_STRING FilePath, IN ACCESS_MASK DesiredAccess, OUT PDEVICE_OBJECT* RootDevice, OUT PFILE_OBJECT* FileObject, OUT PIO_STATUS_BLOCK IoStatus) { PDEVICE_OBJECT RealDevice = NULL; PDEVICE_OBJECT DeviceObject = NULL; PFILE_OBJECT TempObject = NULL; NTSTATUS Status = STATUS_SUCCESS; OBJECT_ATTRIBUTES ObjAttrib = { 0 }; UNICODE_STRING TempName = { 0 };
PIRP Irp = NULL; KEVENT LocalKEvent = { 0 }; IO_STATUS_BLOCK LocalIoStatus = { 0 }; PIO_STACK_LOCATION IrpSp = NULL; AUX_ACCESS_DATA AuxData = { 0 }; ACCESS_STATE AccessState = { 0 }; IO_SECURITY_CONTEXT IoSecCtx = { 0 };
if (!FileObject || !RootDevice || !IoStatus || !FilePath || !FilePath->Buffer || !FilePath->Length) return STATUS_INVALID_PARAMETER;
TempName.Length = FilePath->Length - sizeof(WCHAR) * 6; TempName.MaximumLength = TempName.Length; TempName.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPoolNx, TempName.Length, 'test'); if (!TempName.Buffer) return STATUS_INSUFFICIENT_RESOURCES; RtlCopyMemory(TempName.Buffer, &FilePath->Buffer[6], TempName.Length);
Status = GetRootRealDevice(FilePath->Buffer[4], &DeviceObject, &RealDevice); if (!NT_SUCCESS(Status)) { ExFreePool(TempName.Buffer); return Status; }
InitializeObjectAttributes(&ObjAttrib, FilePath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ObCreateObject( KernelMode, *IoFileObjectType, &ObjAttrib, KernelMode, NULL, sizeof(FILE_OBJECT), 0, 0, &TempObject); if (!NT_SUCCESS(Status)) { ExFreePool(TempName.Buffer); return Status; }
RtlZeroMemory(TempObject, sizeof(FILE_OBJECT)); TempObject->Type = IO_TYPE_FILE; TempObject->Size = sizeof(FILE_OBJECT); TempObject->DeviceObject = RealDevice; TempObject->Flags = FO_SYNCHRONOUS_IO | FO_WRITE_THROUGH; KeInitializeEvent(&TempObject->Lock, SynchronizationEvent, FALSE); KeInitializeEvent(&TempObject->Event, NotificationEvent, FALSE); TempObject->FileName = TempName;
Status = SeCreateAccessState( &AccessState, &AuxData, FILE_ALL_ACCESS, IoGetFileObjectGenericMapping()); if (!NT_SUCCESS(Status)) { ObDereferenceObject(TempObject); return Status; }
KeInitializeEvent(&LocalKEvent, NotificationEvent, FALSE); Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!Irp) { ObDereferenceObject(TempObject); return STATUS_INSUFFICIENT_RESOURCES; } Irp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API; Irp->RequestorMode = KernelMode; Irp->UserEvent = &LocalKEvent; Irp->UserIosb = &LocalIoStatus; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.OriginalFileObject = TempObject;
IoSecCtx.AccessState = &AccessState; IoSecCtx.DesiredAccess = DesiredAccess; IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->MajorFunction = IRP_MJ_CREATE; IrpSp->DeviceObject = DeviceObject; IrpSp->FileObject = TempObject; IrpSp->Parameters.Create.SecurityContext = &IoSecCtx; IrpSp->Parameters.Create.Options = (FILE_OPEN << 24) | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_WRITE_THROUGH; IrpSp->Parameters.Create.FileAttributes = FILE_ATTRIBUTE_NORMAL; IrpSp->Parameters.Create.ShareAccess = 0; IrpSp->Parameters.Create.EaLength = 0;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&LocalKEvent, Executive, KernelMode, TRUE, NULL); Status = LocalIoStatus.Status; } *IoStatus = LocalIoStatus;
if (!NT_SUCCESS(Status)) { ObDereferenceObject(TempObject); return Status; }
InterlockedIncrement(&TempObject->DeviceObject->ReferenceCount); if (TempObject->Vpb) InterlockedIncrement(&(LONG)TempObject->Vpb->ReferenceCount); *FileObject = TempObject; *RootDevice = DeviceObject;
return Status; }
|