ebe99f43286dc2ed318d52b99e8795d6ead771c5
[reactos.git] / reactos / ntoskrnl / io / device.c
1 /* $Id: device.c,v 1.14 2000/01/12 19:02:40 ekohl Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * 15/05/98: Created
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <ddk/ntddk.h>
15
16 #include <internal/io.h>
17 #include <internal/ob.h>
18 #include <internal/ldr.h>
19 #include <string.h>
20 #include <internal/string.h>
21
22 #define NDEBUG
23 #include <internal/debug.h>
24
25 /* FUNCTIONS ***************************************************************/
26
27
28 NTSTATUS STDCALL NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
29 {
30 UNIMPLEMENTED;
31 }
32
33
34 /**********************************************************************
35 * NAME EXPORTED
36 * NtLoadDriver
37 *
38 * DESCRIPTION
39 * Loads a device driver.
40 *
41 * ARGUMENTS
42 * DriverServiceName
43 * Name of the service to load (registry key).
44 *
45 * RETURN VALUE
46 * Status.
47 *
48 * REVISIONS
49 */
50 NTSTATUS STDCALL NtLoadDriver (PUNICODE_STRING DriverServiceName)
51 {
52 /* FIXME: this should lookup the filename from the registry and then call LdrLoadDriver */
53 return LdrLoadDriver (DriverServiceName);
54 }
55
56
57 NTSTATUS IoAttachDeviceByPointer(PDEVICE_OBJECT SourceDevice,
58 PDEVICE_OBJECT TargetDevice)
59 {
60 UNIMPLEMENTED;
61 }
62
63
64 VOID IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
65 {
66 UNIMPLEMENTED;
67 }
68
69
70 PDEVICE_OBJECT IoGetRelatedDeviceObject(PFILE_OBJECT FileObject)
71 {
72 return(FileObject->DeviceObject);
73 }
74
75 NTSTATUS IoGetDeviceObjectPointer(PUNICODE_STRING ObjectName,
76 ACCESS_MASK DesiredAccess,
77 PFILE_OBJECT* FileObject,
78 PDEVICE_OBJECT* DeviceObject)
79 {
80 UNIMPLEMENTED;
81 }
82
83 VOID IoDetachDevice(PDEVICE_OBJECT TargetDevice)
84 {
85 UNIMPLEMENTED;
86 }
87
88 PDEVICE_OBJECT IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
89 {
90 PDEVICE_OBJECT Current = DeviceObject;
91
92 // DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject);
93
94 while (Current->AttachedDevice!=NULL)
95 {
96 Current = Current->AttachedDevice;
97 // DPRINT("Current %x\n",Current);
98 }
99
100 // DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject);
101 return(Current);
102 }
103
104 PDEVICE_OBJECT IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
105 PDEVICE_OBJECT TargetDevice)
106 {
107 PDEVICE_OBJECT AttachedDevice;
108
109 DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n",
110 SourceDevice,TargetDevice);
111
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);
118 }
119
120 VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,
121 PDRIVER_REINITIALIZE ReinitRoutine,
122 PVOID Context)
123 {
124 UNIMPLEMENTED;
125 }
126
127 NTSTATUS IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject,
128 PIRP Irp)
129 {
130 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
131 Irp->IoStatus.Information = 0;
132
133 IoCompleteRequest(Irp, IO_NO_INCREMENT);
134 return(STATUS_NOT_IMPLEMENTED);
135 }
136
137 NTSTATUS IoInitializeDriver(PDRIVER_INITIALIZE DriverEntry)
138 /*
139 * FUNCTION: Called to initalize a loaded driver
140 * ARGUMENTS:
141 */
142 {
143 NTSTATUS Status;
144 PDRIVER_OBJECT DriverObject;
145 ULONG i;
146
147 DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
148 if (DriverObject == NULL)
149 {
150 return STATUS_INSUFFICIENT_RESOURCES;
151 }
152 memset(DriverObject, 0, sizeof(DRIVER_OBJECT));
153
154 DriverObject->Type = InternalDriverType;
155
156 for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)
157 {
158 DriverObject->MajorFunction[i] = IopDefaultDispatchFunction;
159 }
160
161 DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry);
162 Status = DriverEntry(DriverObject, NULL);
163 if (!NT_SUCCESS(Status))
164 {
165 ExFreePool(DriverObject);
166 return(Status);
167 }
168
169 return(Status);
170 }
171
172 NTSTATUS IoAttachDevice(PDEVICE_OBJECT SourceDevice,
173 PUNICODE_STRING TargetDevice,
174 PDEVICE_OBJECT* AttachedDevice)
175 /*
176 * FUNCTION: Layers a device over the highest device in a device stack
177 * ARGUMENTS:
178 * SourceDevice = Device to attached
179 * TargetDevice = Name of the target device
180 * AttachedDevice (OUT) = Caller storage for the device attached to
181 */
182 {
183 UNIMPLEMENTED;
184 }
185
186 NTSTATUS IopCreateDevice(PVOID ObjectBody,
187 PVOID Parent,
188 PWSTR RemainingPath,
189 POBJECT_ATTRIBUTES ObjectAttributes)
190 {
191
192 DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n",
193 ObjectBody, Parent, RemainingPath);
194
195 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
196 {
197 return(STATUS_UNSUCCESSFUL);
198 }
199
200 if (Parent != NULL && RemainingPath != NULL)
201 {
202 ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1);
203 }
204 return(STATUS_SUCCESS);
205 }
206
207
208 NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject,
209 ULONG DeviceExtensionSize,
210 PUNICODE_STRING DeviceName,
211 DEVICE_TYPE DeviceType,
212 ULONG DeviceCharacteristics,
213 BOOLEAN Exclusive,
214 PDEVICE_OBJECT* DeviceObject)
215 /*
216 * FUNCTION: Allocates memory for and intializes a device object for use for
217 * a driver
218 * ARGUMENTS:
219 * DriverObject : Driver object passed by iomgr when the driver was
220 * loaded
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
226 * time
227 * RETURNS:
228 * Success or failure
229 * DeviceObject : Contains a pointer to allocated device object
230 * if the call succeeded
231 * NOTES: See the DDK documentation for more information
232 */
233 {
234 PDEVICE_OBJECT CreatedDeviceObject;
235 OBJECT_ATTRIBUTES ObjectAttributes;
236 HANDLE DeviceHandle;
237
238 assert_irql(PASSIVE_LEVEL);
239
240 if (DeviceName != NULL)
241 {
242 DPRINT("IoCreateDevice(DriverObject %x, DeviceName %S)\n",DriverObject,
243 DeviceName->Buffer);
244 }
245 else
246 {
247 DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject);
248 }
249
250 if (DeviceName != NULL)
251 {
252 InitializeObjectAttributes(&ObjectAttributes,DeviceName,0,NULL,NULL);
253 CreatedDeviceObject = ObCreateObject(&DeviceHandle,
254 0,
255 &ObjectAttributes,
256 IoDeviceType);
257 }
258 else
259 {
260 CreatedDeviceObject = ObCreateObject(&DeviceHandle,
261 0,
262 NULL,
263 IoDeviceType);
264 }
265
266 *DeviceObject = NULL;
267
268 if (CreatedDeviceObject == NULL)
269 {
270 return(STATUS_INSUFFICIENT_RESOURCES);
271 }
272
273 if (DriverObject->DeviceObject == NULL)
274 {
275 DriverObject->DeviceObject = CreatedDeviceObject;
276 CreatedDeviceObject->NextDevice = NULL;
277 }
278 else
279 {
280 CreatedDeviceObject->NextDevice = DriverObject->DeviceObject;
281 DriverObject->DeviceObject = CreatedDeviceObject;
282 }
283
284 CreatedDeviceObject->Type = DeviceType;
285 CreatedDeviceObject->DriverObject = DriverObject;
286 CreatedDeviceObject->CurrentIrp = NULL;
287 CreatedDeviceObject->Flags = 0;
288
289 CreatedDeviceObject->DeviceExtension = ExAllocatePool(NonPagedPool,
290 DeviceExtensionSize);
291 if (DeviceExtensionSize > 0 && CreatedDeviceObject->DeviceExtension == NULL)
292 {
293 ExFreePool(CreatedDeviceObject);
294 return(STATUS_INSUFFICIENT_RESOURCES);
295 }
296
297 CreatedDeviceObject->AttachedDevice = NULL;
298 CreatedDeviceObject->DeviceType = DeviceType;
299 CreatedDeviceObject->StackSize = 1;
300 CreatedDeviceObject->AlignmentRequirement = 1;
301 KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue);
302
303 if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK)
304 {
305 IoAttachVpb(CreatedDeviceObject);
306 }
307
308 *DeviceObject = CreatedDeviceObject;
309
310 return(STATUS_SUCCESS);
311 }
312
313
314 /* EOF */