1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: ntoskrnl/io/iomgr/controller.c 5 * PURPOSE: I/O Wrappers (called Controllers) for Kernel Device Queues 6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include <ntoskrnl.h> 12 #include <debug.h> 13 14 /* GLOBALS *******************************************************************/ 15 16 POBJECT_TYPE IoControllerObjectType; 17 18 /* FUNCTIONS *****************************************************************/ 19 20 /* 21 * @implemented 22 */ 23 VOID 24 NTAPI 25 IoAllocateController(IN PCONTROLLER_OBJECT ControllerObject, 26 IN PDEVICE_OBJECT DeviceObject, 27 IN PDRIVER_CONTROL ExecutionRoutine, 28 IN PVOID Context) 29 { 30 IO_ALLOCATION_ACTION Result; 31 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL); 32 33 /* Initialize the Wait Context Block */ 34 DeviceObject->Queue.Wcb.DeviceContext = Context; 35 DeviceObject->Queue.Wcb.DeviceRoutine = ExecutionRoutine; 36 37 /* Insert the Device Queue */ 38 if (!KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue, 39 &DeviceObject->Queue.Wcb.WaitQueueEntry)) 40 { 41 /* Call the execution routine */ 42 Result = ExecutionRoutine(DeviceObject, 43 DeviceObject->CurrentIrp, 44 NULL, 45 Context); 46 47 /* Free the controller if this was requested */ 48 if (Result == DeallocateObject) IoFreeController(ControllerObject); 49 } 50 } 51 52 /* 53 * @implemented 54 */ 55 PCONTROLLER_OBJECT 56 NTAPI 57 IoCreateController(IN ULONG Size) 58 { 59 PCONTROLLER_OBJECT Controller; 60 OBJECT_ATTRIBUTES ObjectAttributes; 61 HANDLE Handle; 62 NTSTATUS Status; 63 PAGED_CODE(); 64 65 /* Initialize an empty OBA */ 66 InitializeObjectAttributes(&ObjectAttributes, 67 NULL, 68 OBJ_KERNEL_HANDLE, 69 NULL, 70 NULL); 71 72 /* Create the Object */ 73 Status = ObCreateObject(KernelMode, 74 IoControllerObjectType, 75 &ObjectAttributes, 76 KernelMode, 77 NULL, 78 sizeof(CONTROLLER_OBJECT) + Size, 79 0, 80 0, 81 (PVOID*)&Controller); 82 if (!NT_SUCCESS(Status)) return NULL; 83 84 /* Insert it */ 85 Status = ObInsertObject(Controller, 86 NULL, 87 FILE_READ_DATA | FILE_WRITE_DATA, 88 1, 89 (PVOID*)&Controller, 90 &Handle); 91 if (!NT_SUCCESS(Status)) return NULL; 92 93 /* Close the dummy handle */ 94 ObCloseHandle(Handle, KernelMode); 95 96 /* Zero the Object and set its data */ 97 RtlZeroMemory(Controller, sizeof(CONTROLLER_OBJECT) + Size); 98 Controller->Type = IO_TYPE_CONTROLLER; 99 Controller->Size = sizeof(CONTROLLER_OBJECT) + (CSHORT)Size; 100 Controller->ControllerExtension = (Controller + 1); 101 102 /* Initialize its Queue */ 103 KeInitializeDeviceQueue(&Controller->DeviceWaitQueue); 104 105 /* Return Controller */ 106 return Controller; 107 } 108 109 /* 110 * @implemented 111 */ 112 VOID 113 NTAPI 114 IoDeleteController(IN PCONTROLLER_OBJECT ControllerObject) 115 { 116 /* Just Dereference it */ 117 ObDereferenceObject(ControllerObject); 118 } 119 120 /* 121 * @implemented 122 */ 123 VOID 124 NTAPI 125 IoFreeController(IN PCONTROLLER_OBJECT ControllerObject) 126 { 127 PKDEVICE_QUEUE_ENTRY QueueEntry; 128 PDEVICE_OBJECT DeviceObject; 129 IO_ALLOCATION_ACTION Result; 130 131 /* Remove the Queue */ 132 QueueEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue); 133 if (QueueEntry) 134 { 135 /* Get the Device Object */ 136 DeviceObject = CONTAINING_RECORD(QueueEntry, 137 DEVICE_OBJECT, 138 Queue.Wcb.WaitQueueEntry); 139 140 /* Call the routine */ 141 Result = DeviceObject->Queue.Wcb.DeviceRoutine(DeviceObject, 142 DeviceObject->CurrentIrp, 143 NULL, 144 DeviceObject-> 145 Queue.Wcb.DeviceContext); 146 /* Free the controller if this was requested */ 147 if (Result == DeallocateObject) IoFreeController(ControllerObject); 148 } 149 } 150 151 /* EOF */ 152