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 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 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