1 /* $Id: device.c,v 1.21 2000/09/10 13:54:01 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>
19 #include <internal/id.h>
21 #include <internal/string.h>
24 #include <internal/debug.h>
27 /* FUNCTIONS ***************************************************************/
30 NTSTATUS STDCALL
NtUnloadDriver(IN PUNICODE_STRING DriverServiceName
)
36 /**********************************************************************
41 * Loads a device driver.
45 * Name of the service to load (registry key).
55 PUNICODE_STRING DriverServiceName
58 /* FIXME: this should lookup the filename from the registry and then call LdrLoadDriver */
59 return LdrLoadDriver (DriverServiceName
);
65 IoAttachDeviceByPointer (
66 IN PDEVICE_OBJECT SourceDevice
,
67 IN PDEVICE_OBJECT TargetDevice
70 PDEVICE_OBJECT AttachedDevice
;
72 DPRINT("IoAttachDeviceByPointer(SourceDevice %x, TargetDevice %x)\n",
76 AttachedDevice
= IoAttachDeviceToDeviceStack (SourceDevice
,
78 if (AttachedDevice
== NULL
)
79 return STATUS_NO_SUCH_DEVICE
;
81 return STATUS_SUCCESS
;
87 IoDeleteDevice(PDEVICE_OBJECT DeviceObject
)
89 PDEVICE_OBJECT Previous
;
91 if (DeviceObject
->Flags
& DO_SHUTDOWN_REGISTERED
)
92 IoUnregisterShutdownNotification(DeviceObject
);
94 /* remove the timer if it exists */
95 if (DeviceObject
->Timer
)
97 IoStopTimer(DeviceObject
);
98 ExFreePool(DeviceObject
->Timer
);
101 /* free device extension */
102 if (DeviceObject
->DeviceObjectExtension
)
103 ExFreePool (DeviceObject
->DeviceObjectExtension
);
105 /* remove device from driver device list */
106 Previous
= DeviceObject
->DriverObject
->DeviceObject
;
107 if (Previous
== DeviceObject
)
109 DeviceObject
->DriverObject
->DeviceObject
= DeviceObject
->NextDevice
;
113 while (Previous
->NextDevice
!= DeviceObject
)
114 Previous
= Previous
->NextDevice
;
115 Previous
->NextDevice
= DeviceObject
->NextDevice
;
118 ObDereferenceObject (DeviceObject
);
124 IoGetRelatedDeviceObject (
125 IN PFILE_OBJECT FileObject
128 return (FileObject
->DeviceObject
);
134 IoGetDeviceObjectPointer (
135 IN PUNICODE_STRING ObjectName
,
136 IN ACCESS_MASK DesiredAccess
,
137 OUT PFILE_OBJECT
* FileObject
,
138 OUT PDEVICE_OBJECT
* DeviceObject
)
140 OBJECT_ATTRIBUTES ObjectAttributes
;
141 IO_STATUS_BLOCK StatusBlock
;
142 PFILE_OBJECT LocalFileObject
;
146 DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x, FileObject %p DeviceObject %p)\n",
152 InitializeObjectAttributes (&ObjectAttributes
,
158 Status
= NtOpenFile (&FileHandle
,
163 FILE_NON_DIRECTORY_FILE
);
164 if (!NT_SUCCESS(Status
))
167 Status
= ObReferenceObjectByHandle (FileHandle
,
171 (PVOID
*)&LocalFileObject
,
173 if (NT_SUCCESS(Status
))
175 *DeviceObject
= IoGetRelatedDeviceObject (LocalFileObject
);
176 *FileObject
= LocalFileObject
;
178 NtClose (FileHandle
);
186 IoDetachDevice(PDEVICE_OBJECT TargetDevice
)
194 IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject
)
196 PDEVICE_OBJECT Current
= DeviceObject
;
198 // DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject);
200 while (Current
->AttachedDevice
!=NULL
)
202 Current
= Current
->AttachedDevice
;
203 // DPRINT("Current %x\n",Current);
206 // DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject);
212 IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice
,
213 PDEVICE_OBJECT TargetDevice
)
215 PDEVICE_OBJECT AttachedDevice
;
217 DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n",
218 SourceDevice
,TargetDevice
);
220 AttachedDevice
= IoGetAttachedDevice(TargetDevice
);
221 AttachedDevice
->AttachedDevice
= SourceDevice
;
222 SourceDevice
->AttachedDevice
= NULL
;
223 SourceDevice
->StackSize
= AttachedDevice
->StackSize
+ 1;
224 SourceDevice
->Vpb
= AttachedDevice
->Vpb
;
225 return(AttachedDevice
);
230 IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject
,
231 PDRIVER_REINITIALIZE ReinitRoutine
,
237 NTSTATUS
IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject
,
240 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
241 Irp
->IoStatus
.Information
= 0;
243 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
244 return(STATUS_NOT_IMPLEMENTED
);
247 NTSTATUS
IoInitializeDriver(PDRIVER_INITIALIZE DriverEntry
)
249 * FUNCTION: Called to initalize a loaded driver
254 PDRIVER_OBJECT DriverObject
;
257 DriverObject
= ExAllocatePool(NonPagedPool
,sizeof(DRIVER_OBJECT
));
258 if (DriverObject
== NULL
)
260 return STATUS_INSUFFICIENT_RESOURCES
;
262 memset(DriverObject
, 0, sizeof(DRIVER_OBJECT
));
264 DriverObject
->Type
= InternalDriverType
;
266 for (i
=0; i
<=IRP_MJ_MAXIMUM_FUNCTION
; i
++)
268 DriverObject
->MajorFunction
[i
] = IopDefaultDispatchFunction
;
271 DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry
);
272 Status
= DriverEntry(DriverObject
, NULL
);
273 if (!NT_SUCCESS(Status
))
275 ExFreePool(DriverObject
);
284 IoAttachDevice(PDEVICE_OBJECT SourceDevice
,
285 PUNICODE_STRING TargetDevice
,
286 PDEVICE_OBJECT
* AttachedDevice
)
288 * FUNCTION: Layers a device over the highest device in a device stack
290 * SourceDevice = Device to attached
291 * TargetDevice = Name of the target device
292 * AttachedDevice (OUT) = Caller storage for the device attached to
298 NTSTATUS
IopCreateDevice(PVOID ObjectBody
,
301 POBJECT_ATTRIBUTES ObjectAttributes
)
304 DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n",
305 ObjectBody
, Parent
, RemainingPath
);
307 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
309 return(STATUS_UNSUCCESSFUL
);
312 if (Parent
!= NULL
&& RemainingPath
!= NULL
)
314 ObAddEntryDirectory(Parent
, ObjectBody
, RemainingPath
+1);
316 return(STATUS_SUCCESS
);
322 IoCreateDevice(PDRIVER_OBJECT DriverObject
,
323 ULONG DeviceExtensionSize
,
324 PUNICODE_STRING DeviceName
,
325 DEVICE_TYPE DeviceType
,
326 ULONG DeviceCharacteristics
,
328 PDEVICE_OBJECT
* DeviceObject
)
330 * FUNCTION: Allocates memory for and intializes a device object for use for
333 * DriverObject : Driver object passed by iomgr when the driver was
335 * DeviceExtensionSize : Number of bytes for the device extension
336 * DeviceName : Unicode name of device
337 * DeviceType : Device type
338 * DeviceCharacteristics : Bit mask of device characteristics
339 * Exclusive : True if only one thread can access the device at a
343 * DeviceObject : Contains a pointer to allocated device object
344 * if the call succeeded
345 * NOTES: See the DDK documentation for more information
348 PDEVICE_OBJECT CreatedDeviceObject
;
349 OBJECT_ATTRIBUTES ObjectAttributes
;
352 assert_irql(PASSIVE_LEVEL
);
354 if (DeviceName
!= NULL
)
356 DPRINT("IoCreateDevice(DriverObject %x, DeviceName %S)\n",DriverObject
,
361 DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject
);
364 if (DeviceName
!= NULL
)
366 InitializeObjectAttributes(&ObjectAttributes
,DeviceName
,0,NULL
,NULL
);
367 CreatedDeviceObject
= ObCreateObject(&DeviceHandle
,
374 CreatedDeviceObject
= ObCreateObject(&DeviceHandle
,
380 *DeviceObject
= NULL
;
382 if (CreatedDeviceObject
== NULL
)
384 return(STATUS_INSUFFICIENT_RESOURCES
);
387 if (DriverObject
->DeviceObject
== NULL
)
389 DriverObject
->DeviceObject
= CreatedDeviceObject
;
390 CreatedDeviceObject
->NextDevice
= NULL
;
394 CreatedDeviceObject
->NextDevice
= DriverObject
->DeviceObject
;
395 DriverObject
->DeviceObject
= CreatedDeviceObject
;
398 CreatedDeviceObject
->Type
= DeviceType
;
399 CreatedDeviceObject
->DriverObject
= DriverObject
;
400 CreatedDeviceObject
->CurrentIrp
= NULL
;
401 CreatedDeviceObject
->Flags
= 0;
403 CreatedDeviceObject
->DeviceExtension
= ExAllocatePool(NonPagedPool
,
404 DeviceExtensionSize
);
405 if (DeviceExtensionSize
> 0 && CreatedDeviceObject
->DeviceExtension
== NULL
)
407 ExFreePool(CreatedDeviceObject
);
408 return(STATUS_INSUFFICIENT_RESOURCES
);
411 CreatedDeviceObject
->AttachedDevice
= NULL
;
412 CreatedDeviceObject
->DeviceType
= DeviceType
;
413 CreatedDeviceObject
->StackSize
= 1;
414 CreatedDeviceObject
->AlignmentRequirement
= 1;
415 KeInitializeDeviceQueue(&CreatedDeviceObject
->DeviceQueue
);
417 if (CreatedDeviceObject
->DeviceType
== FILE_DEVICE_DISK
)
419 IoAttachVpb(CreatedDeviceObject
);
422 *DeviceObject
= CreatedDeviceObject
;
424 return(STATUS_SUCCESS
);
430 IoOpenDeviceInstanceKey (
439 return (STATUS_NOT_IMPLEMENTED
);
445 IoQueryDeviceEnumInfo (
457 IoSetDeviceToVerify (