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