xref: /reactos/drivers/storage/partmgr/utils.c (revision b09b5584)
1 #include "partmgr.h"
2 
3 NTSTATUS
4 NTAPI
5 ForwardIrpAndForget(
6     _In_ PDEVICE_OBJECT DeviceObject,
7     _In_ PIRP Irp)
8 {
9     // this part of a structure is identical in both FDO and PDO
10     PDEVICE_OBJECT LowerDevice = ((PFDO_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
11 
12     ASSERT(LowerDevice);
13 
14     IoSkipCurrentIrpStackLocation(Irp);
15     return IoCallDriver(LowerDevice, Irp);
16 }
17 
18 NTSTATUS
19 IssueSyncIoControlRequest(
20     _In_ UINT32 IoControlCode,
21     _In_ PDEVICE_OBJECT DeviceObject,
22     _In_ PVOID InputBuffer,
23     _In_ ULONG InputBufferLength,
24     _In_ PVOID OutputBuffer,
25     _In_ ULONG OutputBufferLength,
26     _In_ BOOLEAN InternalDeviceIoControl)
27 {
28     PIRP Irp;
29     IO_STATUS_BLOCK IoStatusBlock;
30     PKEVENT Event;
31     NTSTATUS Status;
32     PAGED_CODE();
33 
34     /* Allocate a non-paged event */
35     Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Event), TAG_PARTMGR);
36     if (!Event)
37     {
38         return STATUS_INSUFFICIENT_RESOURCES;
39     }
40 
41     /* Initialize it */
42     KeInitializeEvent(Event, NotificationEvent, FALSE);
43 
44     /* Build the IRP */
45     Irp = IoBuildDeviceIoControlRequest(IoControlCode,
46                                         DeviceObject,
47                                         InputBuffer,
48                                         InputBufferLength,
49                                         OutputBuffer,
50                                         OutputBufferLength,
51                                         InternalDeviceIoControl,
52                                         Event,
53                                         &IoStatusBlock);
54     if (!Irp)
55     {
56         /* Fail, free the event */
57         ExFreePoolWithTag(Event, TAG_PARTMGR);
58         return STATUS_INSUFFICIENT_RESOURCES;
59     }
60 
61     /* Call the driver and check if it's pending */
62     Status = IoCallDriver(DeviceObject, Irp);
63     if (Status == STATUS_PENDING)
64     {
65         /* Wait on the driver */
66         KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL);
67         Status = IoStatusBlock.Status;
68     }
69 
70     /* Free the event and return the Status */
71     ExFreePoolWithTag(Event, TAG_PARTMGR);
72     return Status;
73 }
74