c7ff13f54b9e28cfe666187761fff4b5c854866a
[reactos.git] / drivers / processor / processr / pnp.c
1 /*
2 * PROJECT: ReactOS Generic CPU Driver
3 * LICENSE: GNU GPLv2 only as published by the Free Software Foundation
4 * FILE: drivers/processor/processr/pnp.c
5 * PURPOSE: Plug N Play routines
6 * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "processr.h"
12
13 #include <stdio.h>
14 #define NDEBUG
15 #include <debug.h>
16
17 /* FUNCTIONS ******************************************************************/
18
19 static
20 NTSTATUS
21 GetDeviceId(
22 PDEVICE_OBJECT DeviceObject,
23 BUS_QUERY_ID_TYPE IdType,
24 PWSTR *DeviceId)
25 {
26 PIO_STACK_LOCATION IrpStack;
27 IO_STATUS_BLOCK IoStatus;
28 PDEVICE_OBJECT TargetObject;
29 KEVENT Event;
30 PIRP Irp;
31 NTSTATUS Status;
32
33 PAGED_CODE();
34
35 /* Initialize the event */
36 KeInitializeEvent(&Event, NotificationEvent, FALSE);
37
38 TargetObject = IoGetAttachedDeviceReference(DeviceObject);
39
40 /* Build the IRP */
41 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
42 TargetObject,
43 NULL,
44 0,
45 NULL,
46 &Event,
47 &IoStatus);
48 if (Irp == NULL)
49 {
50 Status = STATUS_INSUFFICIENT_RESOURCES;
51 goto done;
52 }
53
54 /* PNP IRPs all begin life as STATUS_NOT_SUPPORTED */
55 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
56
57 /* Get the top of stack */
58 IrpStack = IoGetNextIrpStackLocation(Irp);
59
60 /* Set the top of stack */
61 RtlZeroMemory(IrpStack, sizeof(IO_STACK_LOCATION));
62 IrpStack->MajorFunction = IRP_MJ_PNP;
63 IrpStack->MinorFunction = IRP_MN_QUERY_ID;
64 IrpStack->Parameters.QueryId.IdType = IdType;
65
66 /* Call the driver */
67 Status = IoCallDriver(TargetObject, Irp);
68 if (Status == STATUS_PENDING)
69 {
70 KeWaitForSingleObject(&Event,
71 Executive,
72 KernelMode,
73 FALSE,
74 NULL);
75
76 Status = IoStatus.Status;
77 }
78
79 if (NT_SUCCESS(Status))
80 {
81 *DeviceId = (PWSTR)IoStatus.Information;
82 }
83
84 done:
85 /* Dereference the target device object */
86 ObDereferenceObject(TargetObject);
87
88 return Status;
89 }
90
91
92
93 static
94 VOID
95 ProcessorSetFriendlyName(
96 PDEVICE_OBJECT DeviceObject)
97 {
98 KEY_VALUE_PARTIAL_INFORMATION *Buffer = NULL;
99 OBJECT_ATTRIBUTES ObjectAttributes;
100 UNICODE_STRING HardwareKeyName, ValueName, EnumKeyName;
101 HANDLE KeyHandle = NULL;
102 ULONG DataLength = 0;
103 ULONG BufferLength = 0;
104 NTSTATUS Status;
105 PWSTR KeyNameBuffer = NULL;
106 PWSTR DeviceId = NULL;
107 PWSTR InstanceId = NULL;
108 PWSTR pszPrefix = L"\\Registry\\Machine\\System\\CurrentcontrolSet\\Enum";
109
110 RtlInitUnicodeString(&HardwareKeyName,
111 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
112 InitializeObjectAttributes(&ObjectAttributes,
113 &HardwareKeyName,
114 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
115 NULL,
116 NULL);
117 Status = ZwOpenKey(&KeyHandle,
118 KEY_READ,
119 &ObjectAttributes);
120 if (!NT_SUCCESS(Status))
121 {
122 DPRINT1("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
123 return;
124 }
125
126 RtlInitUnicodeString(&ValueName,
127 L"ProcessorNameString");
128 Status = ZwQueryValueKey(KeyHandle,
129 &ValueName,
130 KeyValuePartialInformation,
131 NULL,
132 0,
133 &DataLength);
134 if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_SUCCESS)
135 {
136 DPRINT1("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status);
137 goto done;
138 }
139
140 Buffer = ExAllocatePool(PagedPool,
141 DataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION));
142 if (Buffer == NULL)
143 {
144 DPRINT1("ExAllocatePool() failed\n");
145 goto done;
146 }
147
148 Status = ZwQueryValueKey(KeyHandle,
149 &ValueName,
150 KeyValuePartialInformation,
151 Buffer,
152 DataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION),
153 &DataLength);
154 if (!NT_SUCCESS(Status))
155 {
156 DPRINT1("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status);
157 goto done;
158 }
159
160 DPRINT("ProcessorNameString: %S\n", (PWSTR)&Buffer->Data[0]);
161
162 ZwClose(KeyHandle);
163 KeyHandle = NULL;
164
165 Status = GetDeviceId(DeviceObject,
166 BusQueryDeviceID,
167 &DeviceId);
168 if (!NT_SUCCESS(Status))
169 {
170 DPRINT1("GetDeviceId() failed (Status 0x%08lx)\n", Status);
171 goto done;
172 }
173
174 DPRINT("DeviceId: %S\n", DeviceId);
175
176 Status = GetDeviceId(DeviceObject,
177 BusQueryInstanceID,
178 &InstanceId);
179 if (!NT_SUCCESS(Status))
180 {
181 DPRINT1("GetDeviceId() failed (Status 0x%08lx)\n", Status);
182 goto done;
183 }
184
185 DPRINT("InstanceId: %S\n", InstanceId);
186
187 BufferLength = wcslen(pszPrefix) + 1 + wcslen(DeviceId) + 1 + wcslen(InstanceId) + 1;
188
189 KeyNameBuffer = ExAllocatePool(PagedPool, BufferLength * sizeof(WCHAR));
190 if (KeyNameBuffer == NULL)
191 {
192 DPRINT1("ExAllocatePool() failed\n");
193 goto done;
194 }
195
196 swprintf(KeyNameBuffer, L"%s\\%s\\%s", pszPrefix, DeviceId, InstanceId);
197
198 RtlInitUnicodeString(&EnumKeyName, KeyNameBuffer);
199 InitializeObjectAttributes(&ObjectAttributes,
200 &EnumKeyName,
201 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
202 NULL,
203 NULL);
204 Status = ZwOpenKey(&KeyHandle,
205 KEY_WRITE,
206 &ObjectAttributes);
207 if (!NT_SUCCESS(Status))
208 {
209 DPRINT1("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
210 goto done;
211 }
212
213 RtlInitUnicodeString(&ValueName,
214 L"FriendlyName");
215 Status = ZwSetValueKey(KeyHandle,
216 &ValueName,
217 0,
218 REG_SZ,
219 (PVOID)&Buffer->Data[0],
220 Buffer->DataLength);
221 if (!NT_SUCCESS(Status))
222 {
223 DPRINT1("ZwSetValueKey() failed (Status 0x%08lx)\n", Status);
224 goto done;
225 }
226
227 done:
228 if (KeyHandle != NULL)
229 ZwClose(KeyHandle);
230
231 if (KeyNameBuffer != NULL)
232 ExFreePool(KeyNameBuffer);
233
234 if (InstanceId != NULL)
235 ExFreePool(InstanceId);
236
237 if (DeviceId != NULL)
238 ExFreePool(DeviceId);
239
240 if (Buffer != NULL)
241 ExFreePool(Buffer);
242 }
243
244
245 static
246 NTSTATUS
247 ProcessorStartDevice(
248 IN PDEVICE_OBJECT DeviceObject,
249 IN PCM_RESOURCE_LIST ResourceList,
250 IN PCM_RESOURCE_LIST ResourceListTranslated)
251 {
252 DPRINT("ProcessorStartDevice()\n");
253
254 ProcessorSetFriendlyName(DeviceObject);
255
256 return STATUS_SUCCESS;
257 }
258
259
260 NTSTATUS
261 NTAPI
262 ProcessorPnp(
263 IN PDEVICE_OBJECT DeviceObject,
264 IN PIRP Irp)
265 {
266 PIO_STACK_LOCATION IrpSp;
267 ULONG_PTR Information = 0;
268 NTSTATUS Status = STATUS_NOT_SUPPORTED;
269
270 DPRINT("ProcessorPnp()\n");
271
272 IrpSp = IoGetCurrentIrpStackLocation(Irp);
273
274 switch (IrpSp->MinorFunction)
275 {
276 case IRP_MN_START_DEVICE:
277 DPRINT(" IRP_MN_START_DEVICE received\n");
278
279 /* Call lower driver */
280 Status = ForwardIrpAndWait(DeviceObject, Irp);
281 if (NT_SUCCESS(Status))
282 {
283 Status = ProcessorStartDevice(DeviceObject,
284 IrpSp->Parameters.StartDevice.AllocatedResources,
285 IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated);
286 }
287 break;
288
289 case IRP_MN_QUERY_REMOVE_DEVICE:
290 DPRINT(" IRP_MN_QUERY_REMOVE_DEVICE\n");
291 return ForwardIrpAndForget(DeviceObject, Irp);
292
293 case IRP_MN_REMOVE_DEVICE:
294 DPRINT(" IRP_MN_REMOVE_DEVICE received\n");
295 return ForwardIrpAndForget(DeviceObject, Irp);
296
297 case IRP_MN_CANCEL_REMOVE_DEVICE:
298 DPRINT(" IRP_MN_CANCEL_REMOVE_DEVICE\n");
299 return ForwardIrpAndForget(DeviceObject, Irp);
300
301 case IRP_MN_STOP_DEVICE:
302 DPRINT(" IRP_MN_STOP_DEVICE received\n");
303 return ForwardIrpAndForget(DeviceObject, Irp);
304
305 case IRP_MN_QUERY_STOP_DEVICE:
306 DPRINT(" IRP_MN_QUERY_STOP_DEVICE received\n");
307 return ForwardIrpAndForget(DeviceObject, Irp);
308
309 case IRP_MN_CANCEL_STOP_DEVICE:
310 DPRINT(" IRP_MN_CANCEL_STOP_DEVICE\n");
311 return ForwardIrpAndForget(DeviceObject, Irp);
312
313 case IRP_MN_QUERY_DEVICE_RELATIONS:
314 DPRINT(" IRP_MN_QUERY_DEVICE_RELATIONS\n");
315
316 switch (IrpSp->Parameters.QueryDeviceRelations.Type)
317 {
318 case BusRelations:
319 DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
320 return ForwardIrpAndForget(DeviceObject, Irp);
321 break;
322
323 case RemovalRelations:
324 DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
325 return ForwardIrpAndForget(DeviceObject, Irp);
326
327 default:
328 DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
329 IrpSp->Parameters.QueryDeviceRelations.Type);
330 return ForwardIrpAndForget(DeviceObject, Irp);
331 }
332 break;
333
334 case IRP_MN_SURPRISE_REMOVAL:
335 DPRINT(" IRP_MN_SURPRISE_REMOVAL received\n");
336 return ForwardIrpAndForget(DeviceObject, Irp);
337
338 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0xd */
339 DPRINT(" IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
340 return ForwardIrpAndForget(DeviceObject, Irp);
341
342 default:
343 DPRINT(" Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
344 return ForwardIrpAndForget(DeviceObject, Irp);
345 }
346
347 Irp->IoStatus.Information = Information;
348 Irp->IoStatus.Status = Status;
349 IoCompleteRequest(Irp, IO_NO_INCREMENT);
350
351 return Status;
352 }
353
354
355 NTSTATUS
356 NTAPI
357 ProcessorAddDevice(
358 IN PDRIVER_OBJECT DriverObject,
359 IN PDEVICE_OBJECT Pdo)
360 {
361 PDEVICE_EXTENSION DeviceExtension = NULL;
362 PDEVICE_OBJECT Fdo = NULL;
363 NTSTATUS Status;
364
365 DPRINT("ProcessorAddDevice()\n");
366
367 ASSERT(DriverObject);
368 ASSERT(Pdo);
369
370 /* Create functional device object */
371 Status = IoCreateDevice(DriverObject,
372 sizeof(DEVICE_EXTENSION),
373 NULL,
374 FILE_DEVICE_UNKNOWN,
375 FILE_DEVICE_SECURE_OPEN,
376 FALSE,
377 &Fdo);
378 if (NT_SUCCESS(Status))
379 {
380 DeviceExtension = (PDEVICE_EXTENSION)Fdo->DeviceExtension;
381 RtlZeroMemory(DeviceExtension, sizeof(DEVICE_EXTENSION));
382
383 DeviceExtension->DeviceObject = Fdo;
384
385 Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
386 if (!NT_SUCCESS(Status))
387 {
388 DPRINT1("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
389 IoDeleteDevice(Fdo);
390 return Status;
391 }
392
393 Fdo->Flags |= DO_DIRECT_IO;
394 Fdo->Flags |= DO_POWER_PAGABLE;
395
396 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
397 }
398
399 return Status;
400 }
401
402 /* EOF */