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