1 /* $Id: device.c,v 1.14 2000/01/12 19:02:40 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/device.c
6 * PURPOSE: Manage devices
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES ****************************************************************/
14 #include <ddk/ntddk.h>
16 #include <internal/io.h>
17 #include <internal/ob.h>
18 #include <internal/ldr.h>
20 #include <internal/string.h>
23 #include <internal/debug.h>
25 /* FUNCTIONS ***************************************************************/
28 NTSTATUS STDCALL
NtUnloadDriver(IN PUNICODE_STRING DriverServiceName
)
34 /**********************************************************************
39 * Loads a device driver.
43 * Name of the service to load (registry key).
50 NTSTATUS STDCALL
NtLoadDriver (PUNICODE_STRING DriverServiceName
)
52 /* FIXME: this should lookup the filename from the registry and then call LdrLoadDriver */
53 return LdrLoadDriver (DriverServiceName
);
57 NTSTATUS
IoAttachDeviceByPointer(PDEVICE_OBJECT SourceDevice
,
58 PDEVICE_OBJECT TargetDevice
)
64 VOID
IoDeleteDevice(PDEVICE_OBJECT DeviceObject
)
70 PDEVICE_OBJECT
IoGetRelatedDeviceObject(PFILE_OBJECT FileObject
)
72 return(FileObject
->DeviceObject
);
75 NTSTATUS
IoGetDeviceObjectPointer(PUNICODE_STRING ObjectName
,
76 ACCESS_MASK DesiredAccess
,
77 PFILE_OBJECT
* FileObject
,
78 PDEVICE_OBJECT
* DeviceObject
)
83 VOID
IoDetachDevice(PDEVICE_OBJECT TargetDevice
)
88 PDEVICE_OBJECT
IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject
)
90 PDEVICE_OBJECT Current
= DeviceObject
;
92 // DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject);
94 while (Current
->AttachedDevice
!=NULL
)
96 Current
= Current
->AttachedDevice
;
97 // DPRINT("Current %x\n",Current);
100 // DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject);
104 PDEVICE_OBJECT
IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice
,
105 PDEVICE_OBJECT TargetDevice
)
107 PDEVICE_OBJECT AttachedDevice
;
109 DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n",
110 SourceDevice
,TargetDevice
);
112 AttachedDevice
= IoGetAttachedDevice(TargetDevice
);
113 AttachedDevice
->AttachedDevice
= SourceDevice
;
114 SourceDevice
->AttachedDevice
= NULL
;
115 SourceDevice
->StackSize
= AttachedDevice
->StackSize
+ 1;
116 SourceDevice
->Vpb
= AttachedDevice
->Vpb
;
117 return(AttachedDevice
);
120 VOID
IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject
,
121 PDRIVER_REINITIALIZE ReinitRoutine
,
127 NTSTATUS
IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject
,
130 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
131 Irp
->IoStatus
.Information
= 0;
133 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
134 return(STATUS_NOT_IMPLEMENTED
);
137 NTSTATUS
IoInitializeDriver(PDRIVER_INITIALIZE DriverEntry
)
139 * FUNCTION: Called to initalize a loaded driver
144 PDRIVER_OBJECT DriverObject
;
147 DriverObject
= ExAllocatePool(NonPagedPool
,sizeof(DRIVER_OBJECT
));
148 if (DriverObject
== NULL
)
150 return STATUS_INSUFFICIENT_RESOURCES
;
152 memset(DriverObject
, 0, sizeof(DRIVER_OBJECT
));
154 DriverObject
->Type
= InternalDriverType
;
156 for (i
=0; i
<=IRP_MJ_MAXIMUM_FUNCTION
; i
++)
158 DriverObject
->MajorFunction
[i
] = IopDefaultDispatchFunction
;
161 DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry
);
162 Status
= DriverEntry(DriverObject
, NULL
);
163 if (!NT_SUCCESS(Status
))
165 ExFreePool(DriverObject
);
172 NTSTATUS
IoAttachDevice(PDEVICE_OBJECT SourceDevice
,
173 PUNICODE_STRING TargetDevice
,
174 PDEVICE_OBJECT
* AttachedDevice
)
176 * FUNCTION: Layers a device over the highest device in a device stack
178 * SourceDevice = Device to attached
179 * TargetDevice = Name of the target device
180 * AttachedDevice (OUT) = Caller storage for the device attached to
186 NTSTATUS
IopCreateDevice(PVOID ObjectBody
,
189 POBJECT_ATTRIBUTES ObjectAttributes
)
192 DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n",
193 ObjectBody
, Parent
, RemainingPath
);
195 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
197 return(STATUS_UNSUCCESSFUL
);
200 if (Parent
!= NULL
&& RemainingPath
!= NULL
)
202 ObAddEntryDirectory(Parent
, ObjectBody
, RemainingPath
+1);
204 return(STATUS_SUCCESS
);
208 NTSTATUS
IoCreateDevice(PDRIVER_OBJECT DriverObject
,
209 ULONG DeviceExtensionSize
,
210 PUNICODE_STRING DeviceName
,
211 DEVICE_TYPE DeviceType
,
212 ULONG DeviceCharacteristics
,
214 PDEVICE_OBJECT
* DeviceObject
)
216 * FUNCTION: Allocates memory for and intializes a device object for use for
219 * DriverObject : Driver object passed by iomgr when the driver was
221 * DeviceExtensionSize : Number of bytes for the device extension
222 * DeviceName : Unicode name of device
223 * DeviceType : Device type
224 * DeviceCharacteristics : Bit mask of device characteristics
225 * Exclusive : True if only one thread can access the device at a
229 * DeviceObject : Contains a pointer to allocated device object
230 * if the call succeeded
231 * NOTES: See the DDK documentation for more information
234 PDEVICE_OBJECT CreatedDeviceObject
;
235 OBJECT_ATTRIBUTES ObjectAttributes
;
238 assert_irql(PASSIVE_LEVEL
);
240 if (DeviceName
!= NULL
)
242 DPRINT("IoCreateDevice(DriverObject %x, DeviceName %S)\n",DriverObject
,
247 DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject
);
250 if (DeviceName
!= NULL
)
252 InitializeObjectAttributes(&ObjectAttributes
,DeviceName
,0,NULL
,NULL
);
253 CreatedDeviceObject
= ObCreateObject(&DeviceHandle
,
260 CreatedDeviceObject
= ObCreateObject(&DeviceHandle
,
266 *DeviceObject
= NULL
;
268 if (CreatedDeviceObject
== NULL
)
270 return(STATUS_INSUFFICIENT_RESOURCES
);
273 if (DriverObject
->DeviceObject
== NULL
)
275 DriverObject
->DeviceObject
= CreatedDeviceObject
;
276 CreatedDeviceObject
->NextDevice
= NULL
;
280 CreatedDeviceObject
->NextDevice
= DriverObject
->DeviceObject
;
281 DriverObject
->DeviceObject
= CreatedDeviceObject
;
284 CreatedDeviceObject
->Type
= DeviceType
;
285 CreatedDeviceObject
->DriverObject
= DriverObject
;
286 CreatedDeviceObject
->CurrentIrp
= NULL
;
287 CreatedDeviceObject
->Flags
= 0;
289 CreatedDeviceObject
->DeviceExtension
= ExAllocatePool(NonPagedPool
,
290 DeviceExtensionSize
);
291 if (DeviceExtensionSize
> 0 && CreatedDeviceObject
->DeviceExtension
== NULL
)
293 ExFreePool(CreatedDeviceObject
);
294 return(STATUS_INSUFFICIENT_RESOURCES
);
297 CreatedDeviceObject
->AttachedDevice
= NULL
;
298 CreatedDeviceObject
->DeviceType
= DeviceType
;
299 CreatedDeviceObject
->StackSize
= 1;
300 CreatedDeviceObject
->AlignmentRequirement
= 1;
301 KeInitializeDeviceQueue(&CreatedDeviceObject
->DeviceQueue
);
303 if (CreatedDeviceObject
->DeviceType
== FILE_DEVICE_DISK
)
305 IoAttachVpb(CreatedDeviceObject
);
308 *DeviceObject
= CreatedDeviceObject
;
310 return(STATUS_SUCCESS
);