xref: /reactos/drivers/processor/processr/pnp.c (revision 7ed1883c)
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