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
GetDeviceId(PDEVICE_OBJECT DeviceObject,BUS_QUERY_ID_TYPE IdType,PWSTR * DeviceId)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
ProcessorSetFriendlyName(PDEVICE_OBJECT DeviceObject)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
ProcessorStartDevice(IN PDEVICE_OBJECT DeviceObject,IN PCM_RESOURCE_LIST ResourceList,IN PCM_RESOURCE_LIST ResourceListTranslated)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
ProcessorPnp(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)262 ProcessorPnp(
263 IN PDEVICE_OBJECT DeviceObject,
264 IN PIRP Irp)
265 {
266 PDEVICE_EXTENSION DeviceExtension;
267 PIO_STACK_LOCATION IrpSp;
268 ULONG_PTR Information = 0;
269 NTSTATUS Status = STATUS_NOT_SUPPORTED;
270
271 DPRINT("ProcessorPnp()\n");
272
273 IrpSp = IoGetCurrentIrpStackLocation(Irp);
274
275 switch (IrpSp->MinorFunction)
276 {
277 case IRP_MN_START_DEVICE:
278 DPRINT(" IRP_MN_START_DEVICE received\n");
279
280 /* Call lower driver */
281 DeviceExtension = DeviceObject->DeviceExtension;
282 Status = STATUS_UNSUCCESSFUL;
283
284 if (IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp))
285 {
286 Status = Irp->IoStatus.Status;
287 if (NT_SUCCESS(Status))
288 {
289 Status = ProcessorStartDevice(DeviceObject,
290 IrpSp->Parameters.StartDevice.AllocatedResources,
291 IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated);
292 }
293 }
294 break;
295
296 case IRP_MN_QUERY_REMOVE_DEVICE:
297 DPRINT(" IRP_MN_QUERY_REMOVE_DEVICE\n");
298 return ForwardIrpAndForget(DeviceObject, Irp);
299
300 case IRP_MN_REMOVE_DEVICE:
301 DPRINT(" IRP_MN_REMOVE_DEVICE received\n");
302 return ForwardIrpAndForget(DeviceObject, Irp);
303
304 case IRP_MN_CANCEL_REMOVE_DEVICE:
305 DPRINT(" IRP_MN_CANCEL_REMOVE_DEVICE\n");
306 return ForwardIrpAndForget(DeviceObject, Irp);
307
308 case IRP_MN_STOP_DEVICE:
309 DPRINT(" IRP_MN_STOP_DEVICE received\n");
310 return ForwardIrpAndForget(DeviceObject, Irp);
311
312 case IRP_MN_QUERY_STOP_DEVICE:
313 DPRINT(" IRP_MN_QUERY_STOP_DEVICE received\n");
314 return ForwardIrpAndForget(DeviceObject, Irp);
315
316 case IRP_MN_CANCEL_STOP_DEVICE:
317 DPRINT(" IRP_MN_CANCEL_STOP_DEVICE\n");
318 return ForwardIrpAndForget(DeviceObject, Irp);
319
320 case IRP_MN_QUERY_DEVICE_RELATIONS:
321 DPRINT(" IRP_MN_QUERY_DEVICE_RELATIONS\n");
322
323 switch (IrpSp->Parameters.QueryDeviceRelations.Type)
324 {
325 case BusRelations:
326 DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
327 return ForwardIrpAndForget(DeviceObject, Irp);
328 break;
329
330 case RemovalRelations:
331 DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
332 return ForwardIrpAndForget(DeviceObject, Irp);
333
334 default:
335 DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
336 IrpSp->Parameters.QueryDeviceRelations.Type);
337 return ForwardIrpAndForget(DeviceObject, Irp);
338 }
339 break;
340
341 case IRP_MN_SURPRISE_REMOVAL:
342 DPRINT(" IRP_MN_SURPRISE_REMOVAL received\n");
343 return ForwardIrpAndForget(DeviceObject, Irp);
344
345 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0xd */
346 DPRINT(" IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
347 return ForwardIrpAndForget(DeviceObject, Irp);
348
349 default:
350 DPRINT(" Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
351 return ForwardIrpAndForget(DeviceObject, Irp);
352 }
353
354 Irp->IoStatus.Information = Information;
355 Irp->IoStatus.Status = Status;
356 IoCompleteRequest(Irp, IO_NO_INCREMENT);
357
358 return Status;
359 }
360
361
362 NTSTATUS
363 NTAPI
ProcessorAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT Pdo)364 ProcessorAddDevice(
365 IN PDRIVER_OBJECT DriverObject,
366 IN PDEVICE_OBJECT Pdo)
367 {
368 PDEVICE_EXTENSION DeviceExtension = NULL;
369 PDEVICE_OBJECT Fdo = NULL;
370 NTSTATUS Status;
371
372 DPRINT("ProcessorAddDevice()\n");
373
374 ASSERT(DriverObject);
375 ASSERT(Pdo);
376
377 /* Create functional device object */
378 Status = IoCreateDevice(DriverObject,
379 sizeof(DEVICE_EXTENSION),
380 NULL,
381 FILE_DEVICE_UNKNOWN,
382 FILE_DEVICE_SECURE_OPEN,
383 FALSE,
384 &Fdo);
385 if (NT_SUCCESS(Status))
386 {
387 DeviceExtension = (PDEVICE_EXTENSION)Fdo->DeviceExtension;
388 RtlZeroMemory(DeviceExtension, sizeof(DEVICE_EXTENSION));
389
390 DeviceExtension->DeviceObject = Fdo;
391
392 Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
393 if (!NT_SUCCESS(Status))
394 {
395 DPRINT1("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
396 IoDeleteDevice(Fdo);
397 return Status;
398 }
399
400 Fdo->Flags |= DO_DIRECT_IO;
401 Fdo->Flags |= DO_POWER_PAGABLE;
402
403 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
404 }
405
406 return Status;
407 }
408
409 /* EOF */
410