Advertisement
yorath

asd2fsm

Dec 4th, 2013
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 24.66 KB | None | 0 0
  1. #include "irp.h"
  2. #include "ntdata.h"
  3. #include "util.h"
  4.  
  5.  
  6. NTSTATUS
  7.     IoCompletionRoutine(
  8.     __in PDEVICE_OBJECT DeviceObject,
  9.     __in PIRP Irp,
  10.     __in PVOID Context)
  11. {
  12.     *Irp->UserIosb = Irp->IoStatus;
  13.     if (Irp->UserEvent != NULL) {
  14.         KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);
  15.     }
  16.     if (Irp->MdlAddress != NULL) {
  17.         IoFreeMdl(Irp->MdlAddress);
  18.         Irp->MdlAddress = NULL;
  19.     }
  20.     IoFreeIrp(Irp);
  21.     return STATUS_MORE_PROCESSING_REQUIRED;
  22. }
  23.  
  24.  
  25. VOID
  26.     IoCancelRoutine(
  27.     __inout PDEVICE_OBJECT DeviceObject,
  28.     __in PIRP Irp
  29.     )
  30. {
  31.     Irp->IoStatus.Status = STATUS_CANCELLED;
  32.     Irp->IoStatus.Information = 0;
  33.     IoCompleteRequest(Irp, 0);
  34.     IoReleaseCancelSpinLock(Irp->CancelIrql);
  35. }
  36.  
  37.  
  38. NTSTATUS
  39.     GetDriveObject(
  40.     __in PUNICODE_STRING FileName,
  41.     __out PDEVICE_OBJECT *DeviceObject,
  42.     __out PDEVICE_OBJECT *RealDevice)
  43. {
  44.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  45.     HANDLE FileHandle = NULL;
  46.     IO_STATUS_BLOCK IoStatusBlock = { 0 };
  47.     UNICODE_STRING DeviceName = { 0 };
  48.     OBJECT_ATTRIBUTES oa = { 0 };
  49.     PFILE_OBJECT FileObject = NULL;
  50.     WCHAR WcDeviceName[] = L"\\DosDevices\\*:\\";
  51.  
  52.     if (FileName->Length < 2 * sizeof(WCHAR)) {
  53.         return STATUS_INVALID_PARAMETER;
  54.     }
  55.  
  56.     WcDeviceName[12] = FileName->Buffer[0];
  57.     RtlInitUnicodeString(&DeviceName, WcDeviceName);
  58.     InitializeObjectAttributes(&oa, &DeviceName,
  59.         OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
  60.  
  61.     Status = IoCreateFile(
  62.         &FileHandle,
  63.         FILE_READ_ATTRIBUTES | SYNCHRONIZE,
  64.         &oa,
  65.         &IoStatusBlock,
  66.         NULL,
  67.         FILE_ATTRIBUTE_NORMAL,
  68.         FILE_SHARE_READ | FILE_SHARE_WRITE,
  69.         FILE_OPEN,
  70.         FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE,
  71.         NULL,
  72.         0,
  73.         CreateFileTypeNone,
  74.         NULL,
  75.         IO_NO_PARAMETER_CHECKING);
  76.     if(!NT_SUCCESS(Status)) {
  77.         YyPrint("Failed to open %C drive: 0x%08x\n", FileName->Buffer[0], Status);
  78.         return Status;
  79.     }
  80.  
  81.     Status = ObReferenceObjectByHandle(FileHandle, FILE_READ_ACCESS,
  82.         *IoFileObjectType, KernelMode, (PVOID *)&FileObject, NULL);
  83.     if(!NT_SUCCESS(Status)) {
  84.         YyPrint("Failed to get PFILE_OBJECT: 0x%08x\n", Status);
  85.         ZwClose(FileHandle);
  86.         return Status;
  87.     }
  88.  
  89.     // If FileObject has a mounted Vpb, use its DeviceObject.
  90.     if (FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL) {
  91.         *DeviceObject = FileObject->Vpb->DeviceObject;
  92.         *RealDevice = FileObject->Vpb->RealDevice;
  93. #pragma prefast(suppress:28175, "Safe to use the 'Vpb' member of _DEVICE_OBJECT")
  94.     } else if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) &&
  95.         FileObject->DeviceObject->Vpb != NULL &&
  96.         FileObject->DeviceObject->Vpb->DeviceObject != NULL) {
  97.             // Otherwise, if the real device has a VPB that indicates that it
  98.             // is mounted, then use the file system device object associated
  99.             // with the VPB.
  100. #pragma prefast(suppress:28175, "Safe to use the 'Vpb' member of _DEVICE_OBJECT")
  101.             *DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
  102. #pragma prefast(suppress:28175, "Safe to use the 'Vpb' member of _DEVICE_OBJECT")
  103.             *RealDevice = FileObject->DeviceObject->Vpb->RealDevice;
  104.     } else {
  105.         Status = STATUS_UNSUCCESSFUL;
  106.     }
  107.  
  108.     ObDereferenceObject(FileObject);
  109.     ZwClose(FileHandle);
  110.  
  111.     return Status;
  112. }
  113.  
  114.  
  115. NTSTATUS
  116.     IrpCreateFile(
  117.     __out PHANDLE Handle,
  118.     __in PUNICODE_STRING FileName,
  119.     __in ACCESS_MASK DesiredAccess,
  120.     __out PIO_STATUS_BLOCK IoStatusBlock,
  121.     __in ULONG FileAttributes,
  122.     __in ULONG ShareAccess,
  123.     __in ULONG CreateDisposition,
  124.     __in ULONG CreateOptions)
  125. {
  126.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  127.     OBJECT_ATTRIBUTES oa = { 0 };
  128.     PDEVICE_OBJECT DeviceObject = NULL, RealDevice = NULL;
  129.     PFILE_OBJECT FileObject = NULL;
  130.     PIRP Irp = NULL;
  131.     KEVENT SyncEvent = { 0 };
  132.     PIO_STACK_LOCATION IrpSp = NULL;
  133.     ACCESS_STATE AccessState = { 0 };
  134.     AUX_ACCESS_DATA AuxData = { 0 };
  135.     IO_SECURITY_CONTEXT SecurityContext = { 0 };
  136.  
  137.     Status = GetDriveObject(FileName, &DeviceObject, &RealDevice);
  138.     if (!NT_SUCCESS(Status)) {
  139.         YyPrint("Failed to get DeviceObject: 0x%08x\n", Status);
  140.         return Status;
  141.     }
  142.  
  143.     Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
  144.     if(Irp == NULL) {
  145.         YyPrint("Failed to allocate IRP\n");
  146.         return STATUS_INSUFFICIENT_RESOURCES;
  147.     }
  148.  
  149.     Status = SeCreateAccessState(&AccessState, &AuxData, DesiredAccess,
  150.         IoGetFileObjectGenericMapping());
  151.     if (!NT_SUCCESS(Status)) {
  152.         YyPrint("SeCreateAccessState failed: 0x%08x\n", Status);
  153.         IoFreeIrp(Irp);
  154.         return Status;
  155.     }
  156.  
  157.     InitializeObjectAttributes(&oa, NULL, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
  158.     Status = ObCreateObject(KernelMode, *IoFileObjectType, &oa, KernelMode,
  159.         NULL, sizeof(FILE_OBJECT), 0, 0, (PVOID *)&FileObject);
  160.     if (!NT_SUCCESS(Status)) {
  161.         YyPrint("Failed to create object: 0x%08x\n", Status);
  162.         IoFreeIrp(Irp);
  163.         return Status;
  164.     }
  165.  
  166.     RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
  167.     // FileName format: C:\Windows\system32
  168.     // FileObject->FileName format: \Windows\system32
  169.     FileName->Buffer += 2;
  170.     FileName->Length -= 2 * sizeof(WCHAR);
  171.     FileName->MaximumLength -= 2 * sizeof(WCHAR);
  172.     if (FileName->Length > 0) {
  173.         FileObject->FileName.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool,
  174.             FileName->MaximumLength, 'fobj');
  175.         if (FileObject->FileName.Buffer == NULL) {
  176.             YyPrint("Failed to allocate space for FileObject->FileName.Buffer\n");
  177.             IoFreeIrp(Irp);
  178.             ObDereferenceObject(FileObject);
  179.             return STATUS_INSUFFICIENT_RESOURCES;
  180.         }
  181.     } else {
  182.         FileObject->FileName.MaximumLength = 0;
  183.         FileObject->FileName.Buffer = NULL;
  184.     }
  185.  
  186.     RtlCopyMemory(FileObject->FileName.Buffer, FileName->Buffer, FileName->Length);
  187.     FileObject->FileName.Length = FileName->Length;
  188.     FileObject->FileName.MaximumLength = FileName->MaximumLength;
  189.     FileObject->Type = IO_TYPE_FILE;
  190.     FileObject->Size = sizeof(FILE_OBJECT);
  191.     // DeviceObject: C/D/E... drive
  192.     FileObject->DeviceObject = RealDevice;
  193.     FileObject->Flags = FO_SYNCHRONOUS_IO;
  194.     KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, FALSE);
  195.     KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
  196.  
  197.     KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  198.  
  199.     SecurityContext.SecurityQos = NULL;
  200.     SecurityContext.AccessState = &AccessState;
  201.     SecurityContext.DesiredAccess = DesiredAccess;
  202.     SecurityContext.FullCreateOptions = 0;
  203.  
  204.     Irp->MdlAddress = NULL;
  205.     Irp->AssociatedIrp.SystemBuffer = NULL;
  206.     Irp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
  207.     Irp->RequestorMode = KernelMode;
  208.     Irp->UserIosb = IoStatusBlock;
  209.     Irp->UserEvent = &SyncEvent;
  210.     Irp->PendingReturned = FALSE;
  211.     Irp->Cancel = FALSE;
  212.     Irp->CancelRoutine = NULL;
  213.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  214.     Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
  215.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  216.  
  217.     IrpSp = IoGetNextIrpStackLocation(Irp);
  218.     IrpSp->MajorFunction = IRP_MJ_CREATE;
  219.     IrpSp->DeviceObject = DeviceObject;
  220.     IrpSp->FileObject = FileObject;
  221.     IrpSp->Parameters.Create.SecurityContext = &SecurityContext;
  222.     IrpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
  223.     IrpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
  224.     IrpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
  225.     IrpSp->Parameters.Create.EaLength = 0;
  226.  
  227.     IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
  228.     IoSetCancelRoutine(Irp, IoCancelRoutine);
  229.     Status = IoCallDriver(DeviceObject, Irp);
  230.     if(Status == STATUS_PENDING) {
  231.         KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, 0);
  232.     }
  233.  
  234.     Status = IoStatusBlock->Status;
  235.  
  236.     if(!NT_SUCCESS(Status)) {
  237.         YyPrint("Failed: 0x%08x\n", Status);
  238.         // FileObject->DeviceObject can't be set to NULL before ObDereferenceObject
  239.         // otherwise it won't call ExFreePoolWithTag to free FileObject->FileName.Buffer
  240.         // which will lead to memory leak
  241.         ObDereferenceObject(FileObject);
  242.     } else {
  243. #pragma prefast(suppress:28175, "Safe to use the 'ReferenceCount' member of _DEVICE_OBJECT")
  244.         InterlockedIncrement((volatile LONG *)&FileObject->DeviceObject->ReferenceCount);
  245.         if (FileObject->Vpb) {
  246.             InterlockedIncrement((volatile LONG *)&FileObject->Vpb->ReferenceCount);
  247.         }
  248.         Status = ObInsertObject(FileObject, NULL, DesiredAccess, 0, NULL, Handle);
  249.         if (!NT_SUCCESS(Status)) {
  250.             YyPrintAPI("ObInsertObject");
  251.             ObDereferenceObject(FileObject);
  252.         }
  253.     }
  254.  
  255.     return Status;
  256. }
  257.  
  258.  
  259. NTSTATUS
  260.     IrpClose(
  261.     __in PFILE_OBJECT FileObject)
  262. {
  263.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  264.     IO_STATUS_BLOCK IoStatusBlock = { 0 };
  265.     PIRP Irp = NULL;
  266.     KEVENT SyncEvent = { 0 };
  267.     PIO_STACK_LOCATION IrpSp = NULL;
  268.  
  269.     if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL) {
  270.         return STATUS_UNSUCCESSFUL;
  271.     }
  272.  
  273.     Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
  274.     if(Irp == NULL) {
  275.         YyPrint("Failed to allocate IRP\n");
  276.         return STATUS_INSUFFICIENT_RESOURCES;
  277.     }
  278.  
  279.     KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  280.  
  281.     Irp->UserEvent = &SyncEvent;
  282.     Irp->UserIosb = &IoStatusBlock;
  283.     Irp->RequestorMode = KernelMode;
  284.     Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
  285.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  286.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  287.  
  288.     IrpSp = IoGetNextIrpStackLocation(Irp);
  289.     IrpSp->MajorFunction = IRP_MJ_CLEANUP;
  290.     IrpSp->FileObject = FileObject;
  291.  
  292.     Status = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
  293.     if (Status == STATUS_PENDING) {
  294.         KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, NULL);
  295.     }
  296.  
  297.     Status = IoStatusBlock.Status;
  298.     if(!NT_SUCCESS(Status)) {
  299.         YyPrint("Failed: 0x%08x\n", Status);
  300.         IoFreeIrp(Irp);
  301.         return Status;
  302.     }
  303.  
  304.     KeClearEvent(&SyncEvent);
  305.     IoReuseIrp(Irp , STATUS_SUCCESS);
  306.  
  307.     Irp->UserEvent = &SyncEvent;
  308.     Irp->UserIosb = &IoStatusBlock;
  309.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  310.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  311.     Irp->AssociatedIrp.SystemBuffer = NULL;
  312.     Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
  313.  
  314.     IrpSp = IoGetNextIrpStackLocation(Irp);
  315.     IrpSp->MajorFunction = IRP_MJ_CLOSE;
  316.     IrpSp->FileObject = FileObject;
  317.  
  318.     if (FileObject->Vpb && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
  319.         InterlockedDecrement((volatile LONG *)&FileObject->Vpb->ReferenceCount);
  320.         FileObject->Flags |= FO_FILE_OPEN_CANCELLED;
  321.     }
  322.  
  323.     Status = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
  324.     if (Status == STATUS_PENDING) {
  325.         KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, NULL);
  326.     }
  327.  
  328.     IoFreeIrp(Irp);
  329.  
  330.     return IoStatusBlock.Status;
  331. }
  332.  
  333.  
  334. NTSTATUS
  335.     IrpQueryDirectoryFile(
  336.     __in PFILE_OBJECT FileObject,
  337.     __out PIO_STATUS_BLOCK IoStatusBlock,
  338.     __out PVOID FileInformation,
  339.     __in ULONG Length,
  340.     __in FILE_INFORMATION_CLASS FileInformationClass,
  341.     __in BOOLEAN ReturnSingleEntry,
  342.     __in_opt PUNICODE_STRING FileName,
  343.     __in BOOLEAN RestartScan)
  344. {
  345.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  346.     PIRP Irp = NULL;
  347.     KEVENT SyncEvent = { 0 };
  348.     PIO_STACK_LOCATION IrpSp = NULL;
  349.     MODE Mode = KernelMode;
  350.     PVOID KernelBuffer = NULL;
  351.  
  352.     if (FileObject->Vpb == NULL || FileObject->Vpb->DeviceObject == NULL) {
  353.         return STATUS_UNSUCCESSFUL;
  354.     }
  355.  
  356.     Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
  357.     if(Irp == NULL) {
  358.         YyPrint("Failed to allocate IRP\n");
  359.         return STATUS_INSUFFICIENT_RESOURCES;
  360.     }
  361.  
  362.     if ((ULONG)FileInformation < MmUserProbeAddress) {
  363.         Mode = UserMode;
  364.     }
  365.     RtlZeroMemory(FileInformation, Length);
  366.  
  367.     if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO) {
  368.         if (Mode == UserMode) {
  369.             KernelBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, 'kmbf');
  370.             if (KernelBuffer == NULL) {
  371.                 YyPrint("Failed to allocate memory for kernel mode buffer\n");
  372.                 IoFreeIrp(Irp);
  373.                 return STATUS_INSUFFICIENT_RESOURCES;
  374.             }
  375.             Irp->AssociatedIrp.SystemBuffer = KernelBuffer;
  376.         } else {
  377.             Irp->AssociatedIrp.SystemBuffer = FileInformation;
  378.         }
  379.     } else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO) {
  380.         Irp->MdlAddress = IoAllocateMdl(FileInformation, Length, FALSE, FALSE, NULL);
  381.         if (Irp->MdlAddress == NULL) {
  382.             YyPrint("Failed to allocate Mdl\n");
  383.             IoFreeIrp(Irp);
  384.             return STATUS_INSUFFICIENT_RESOURCES;
  385.         }
  386.         MmBuildMdlForNonPagedPool(Irp->MdlAddress);
  387.     } else {
  388.         Irp->UserBuffer = FileInformation;
  389.     }
  390.  
  391.     KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  392.  
  393.     Irp->UserEvent = &SyncEvent;
  394.     Irp->UserIosb = IoStatusBlock;
  395.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  396.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  397.     Irp->RequestorMode = Mode;
  398.  
  399.     IrpSp = IoGetNextIrpStackLocation(Irp);
  400.     IrpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
  401.     IrpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
  402.     IrpSp->FileObject = FileObject;
  403.     if (ReturnSingleEntry) {
  404.         SetFlag(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
  405.     }
  406.     if (RestartScan) {
  407.         SetFlag(IrpSp->Flags, SL_RESTART_SCAN);
  408.     }
  409.     IrpSp->Parameters.QueryDirectory.Length = Length;
  410.     IrpSp->Parameters.QueryDirectory.FileName = FileName;
  411.     IrpSp->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
  412.  
  413.     IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
  414.     IoSetCancelRoutine(Irp, IoCancelRoutine);
  415.     Status = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
  416.     if (Status == STATUS_PENDING) {
  417.         // if the alertable is TRUE, it will cause BSOD
  418.         Status = KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, NULL);
  419.         if (Status != STATUS_SUCCESS) {
  420.             YyPrint("KeWaitForSingleObject: 0x%08x\n", Status);
  421.         }
  422.     }
  423.  
  424.     if (KernelBuffer != NULL) {
  425.         if (NT_SUCCESS(IoStatusBlock->Status)) {
  426.             RtlCopyMemory(FileInformation, KernelBuffer, Length);
  427.         }
  428.         ExFreePoolWithTag(KernelBuffer, 'kmbf');
  429.     }
  430.  
  431.     return IoStatusBlock->Status;
  432. }
  433.  
  434.  
  435. NTSTATUS
  436.     IrpQueryInformationFile(
  437.     __in PFILE_OBJECT FileObject,
  438.     __out PIO_STATUS_BLOCK IoStatusBlock,
  439.     __out PVOID FileInformation,
  440.     __in ULONG Length,
  441.     __in FILE_INFORMATION_CLASS FileInformationClass)
  442. {
  443.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  444.     PIRP Irp = NULL;
  445.     KEVENT SyncEvent = { 0 };
  446.     PIO_STACK_LOCATION IrpSp = NULL;
  447.  
  448.     if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL) {
  449.         return STATUS_UNSUCCESSFUL;
  450.     }
  451.  
  452.     Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
  453.     if(Irp == NULL) {
  454.         YyPrint("Failed to allocate IRP\n");
  455.         return STATUS_INSUFFICIENT_RESOURCES;
  456.     }
  457.  
  458.     KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  459.  
  460.     RtlZeroMemory(FileInformation, Length);
  461.     Irp->AssociatedIrp.SystemBuffer = FileInformation;
  462.     Irp->UserEvent = &SyncEvent;
  463.     Irp->UserIosb = IoStatusBlock;
  464.     Irp->RequestorMode = KernelMode;
  465.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  466.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  467.  
  468.     IrpSp = IoGetNextIrpStackLocation(Irp);
  469.     IrpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
  470.     IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
  471.     IrpSp->FileObject = FileObject;
  472.     IrpSp->Parameters.QueryFile.Length = Length;
  473.     IrpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;
  474.  
  475.     IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
  476.     IoSetCancelRoutine(Irp, IoCancelRoutine);
  477.     Status = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
  478.     if (Status == STATUS_PENDING) {
  479.         KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, 0);
  480.     }
  481.  
  482.     return IoStatusBlock->Status;
  483. }
  484.  
  485.  
  486. NTSTATUS
  487.     IrpSetInformationFile(
  488.     __in PFILE_OBJECT FileObject,
  489.     __out PIO_STATUS_BLOCK IoStatusBlock,
  490.     __in PVOID FileInformation,
  491.     __in ULONG Length,
  492.     __in FILE_INFORMATION_CLASS FileInformationClass,
  493.     __in BOOLEAN ReplaceIfExists)
  494. {
  495.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  496.     PIRP Irp = NULL;
  497.     KEVENT SyncEvent = { 0 };
  498.     PIO_STACK_LOCATION IrpSp = NULL;
  499.  
  500.     if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL) {
  501.         return STATUS_UNSUCCESSFUL;
  502.     }
  503.  
  504.     Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
  505.     if(Irp == NULL) {
  506.         YyPrint("Failed to allocate IRP\n");
  507.         return STATUS_INSUFFICIENT_RESOURCES;
  508.     }
  509.  
  510.     KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  511.  
  512.     Irp->AssociatedIrp.SystemBuffer = FileInformation;
  513.     Irp->UserEvent = &SyncEvent;
  514.     Irp->UserIosb = IoStatusBlock;
  515.     Irp->RequestorMode = KernelMode;
  516.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  517.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  518.  
  519.     IrpSp = IoGetNextIrpStackLocation(Irp);
  520.     IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
  521.     IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
  522.     IrpSp->FileObject = FileObject;
  523.     IrpSp->Parameters.SetFile.ReplaceIfExists = ReplaceIfExists;
  524.     IrpSp->Parameters.SetFile.FileObject = FileObject;
  525.     IrpSp->Parameters.SetFile.AdvanceOnly = FALSE;
  526.     IrpSp->Parameters.SetFile.Length = Length;
  527.     IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
  528.  
  529.     IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
  530.     IoSetCancelRoutine(Irp, IoCancelRoutine);
  531.     Status = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
  532.     if (Status == STATUS_PENDING) {
  533.         KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, 0);
  534.     }
  535.  
  536.     return IoStatusBlock->Status;
  537. }
  538.  
  539.  
  540. NTSTATUS
  541.     IrpReadFile(
  542.     __in PFILE_OBJECT FileObject,
  543.     __out PIO_STATUS_BLOCK IoStatusBlock,
  544.     __out PVOID Buffer,
  545.     __in ULONG Length,
  546.     __in_opt PLARGE_INTEGER ByteOffset)
  547. {
  548.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  549.     PIRP Irp = NULL;
  550.     KEVENT SyncEvent = { 0 };
  551.     PIO_STACK_LOCATION IrpSp = NULL;
  552.     MODE Mode = KernelMode;
  553.     PVOID KernelBuffer = NULL;
  554.  
  555.     if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL) {
  556.         return STATUS_UNSUCCESSFUL;
  557.     }
  558.  
  559.     if(ByteOffset == NULL) {
  560.         if(!(FileObject->Flags & FO_SYNCHRONOUS_IO)) {
  561.             return STATUS_INVALID_PARAMETER;
  562.         }
  563.         ByteOffset = &FileObject->CurrentByteOffset;
  564.     }
  565.  
  566.     Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
  567.     if(Irp == NULL) {
  568.         YyPrint("Failed to allocate IRP\n");
  569.         return STATUS_INSUFFICIENT_RESOURCES;
  570.     }
  571.  
  572.     if ((ULONG)Buffer < MmUserProbeAddress) {
  573.         Mode = UserMode;
  574.     }
  575.     RtlZeroMemory(Buffer, Length);
  576.  
  577.     if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO) {
  578.         if (Mode == UserMode) {
  579.             KernelBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, 'kmbf');
  580.             if (KernelBuffer == NULL) {
  581.                 YyPrint("Failed to allocate memory for kernel mode buffer\n");
  582.                 IoFreeIrp(Irp);
  583.                 return STATUS_INSUFFICIENT_RESOURCES;
  584.             }
  585.             Irp->AssociatedIrp.SystemBuffer = KernelBuffer;
  586.         } else {
  587.             Irp->AssociatedIrp.SystemBuffer = Buffer;
  588.         }
  589.     } else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO) {
  590.         Irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
  591.         if (Irp->MdlAddress == NULL) {
  592.             YyPrint("Failed to allocate Mdl\n");
  593.             IoFreeIrp(Irp);
  594.             return STATUS_INSUFFICIENT_RESOURCES;
  595.         }
  596.         MmBuildMdlForNonPagedPool(Irp->MdlAddress);
  597.     } else {
  598.         Irp->UserBuffer = Buffer;
  599.     }
  600.  
  601.     KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  602.  
  603.     Irp->UserEvent = &SyncEvent;
  604.     Irp->UserIosb = IoStatusBlock;
  605.     Irp->RequestorMode = Mode;
  606.     Irp->Flags = IRP_READ_OPERATION;
  607.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  608.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  609.  
  610.     IrpSp = IoGetNextIrpStackLocation(Irp);
  611.     IrpSp->MajorFunction = IRP_MJ_READ;
  612.     IrpSp->MinorFunction = IRP_MN_NORMAL;
  613.     IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
  614.     IrpSp->FileObject = FileObject;
  615.     IrpSp->Parameters.Read.Length = Length;
  616.     IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
  617.  
  618.     IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
  619.     IoSetCancelRoutine(Irp, IoCancelRoutine);
  620.     Status = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
  621.     if (Status == STATUS_PENDING) {
  622.         KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, 0);
  623.     }
  624.  
  625.     if (KernelBuffer != NULL) {
  626.         if (NT_SUCCESS(IoStatusBlock->Status)) {
  627.             RtlCopyMemory(Buffer, KernelBuffer, Length);
  628.         }
  629.         ExFreePoolWithTag(KernelBuffer, 'kmbf');
  630.     }
  631.  
  632.     return IoStatusBlock->Status;
  633. }
  634.  
  635.  
  636. NTSTATUS
  637.     IrpWriteFile(
  638.     __in PFILE_OBJECT FileObject,
  639.     __out PIO_STATUS_BLOCK IoStatusBlock,
  640.     __in PVOID Buffer,
  641.     __in ULONG Length,
  642.     __in_opt PLARGE_INTEGER ByteOffset)
  643. {
  644.     NTSTATUS Status = STATUS_UNSUCCESSFUL;
  645.     PIRP Irp = NULL;
  646.     KEVENT SyncEvent = { 0 };
  647.     PIO_STACK_LOCATION IrpSp = NULL;
  648.     MODE Mode = KernelMode;
  649.     PVOID KernelBuffer = NULL;
  650.  
  651.     if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL) {
  652.         return STATUS_UNSUCCESSFUL;
  653.     }
  654.  
  655.     if (ByteOffset == NULL) {
  656.         if (!(FileObject->Flags & FO_SYNCHRONOUS_IO)) {
  657.             return STATUS_INVALID_PARAMETER;
  658.         }
  659.         ByteOffset = &FileObject->CurrentByteOffset;
  660.     }
  661.  
  662.     Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
  663.     if(Irp == NULL) {
  664.         YyPrint("Failed to allocate IRP\n");
  665.         return STATUS_INSUFFICIENT_RESOURCES;
  666.     }
  667.  
  668.     if ((ULONG)Buffer < MmUserProbeAddress) {
  669.         Mode = UserMode;
  670.     }
  671.  
  672.     if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO) {
  673.         if (Mode == UserMode) {
  674.             KernelBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, 'kmbf');
  675.             if (KernelBuffer == NULL) {
  676.                 YyPrint("Failed to allocate memory for kernel mode buffer\n");
  677.                 IoFreeIrp(Irp);
  678.                 return STATUS_INSUFFICIENT_RESOURCES;
  679.             }
  680.             Irp->AssociatedIrp.SystemBuffer = KernelBuffer;
  681.         } else {
  682.             Irp->AssociatedIrp.SystemBuffer = Buffer;
  683.         }
  684.     } else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO) {
  685.         Irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
  686.         if (Irp->MdlAddress == NULL) {
  687.             YyPrint("Failed to allocate Mdl\n");
  688.             IoFreeIrp(Irp);
  689.             return STATUS_INSUFFICIENT_RESOURCES;
  690.         }
  691.         MmBuildMdlForNonPagedPool(Irp->MdlAddress);
  692.     } else {
  693.         Irp->UserBuffer = Buffer;
  694.     }
  695.  
  696.     KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  697.  
  698.     Irp->UserEvent = &SyncEvent;
  699.     Irp->UserIosb = IoStatusBlock;
  700.     Irp->RequestorMode = Mode;
  701.     Irp->Flags = IRP_WRITE_OPERATION;
  702.     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
  703.     Irp->Tail.Overlay.OriginalFileObject = FileObject;
  704.  
  705.     IrpSp = IoGetNextIrpStackLocation(Irp);
  706.     IrpSp->MajorFunction = IRP_MJ_WRITE;
  707.     IrpSp->MinorFunction = IRP_MN_NORMAL;
  708.     IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
  709.     IrpSp->FileObject = FileObject;
  710.     IrpSp->Parameters.Write.Length = Length;
  711.     IrpSp->Parameters.Write.ByteOffset = *ByteOffset;
  712.  
  713.     IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
  714.     IoSetCancelRoutine(Irp, IoCancelRoutine);
  715.     Status = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
  716.     if (Status == STATUS_PENDING) {
  717.         KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, NULL);
  718.     }
  719.  
  720.     if (KernelBuffer != NULL) {
  721.         if (NT_SUCCESS(IoStatusBlock->Status)) {
  722.             RtlCopyMemory(Buffer, KernelBuffer, Length);
  723.         }
  724.         ExFreePoolWithTag(KernelBuffer, 'kmbf');
  725.     }
  726.  
  727.     return IoStatusBlock->Status;
  728. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement