/* * PROJECT: ReactOS Generic CPU Driver * LICENSE: GNU GPLv2 only as published by the Free Software Foundation * FILE: drivers/processor/processr/pnp.c * PURPOSE: Plug N Play routines * PROGRAMMERS: Eric Kohl */ /* INCLUDES *******************************************************************/ #include "processr.h" #include #define NDEBUG #include /* FUNCTIONS ******************************************************************/ static NTSTATUS GetDeviceId( PDEVICE_OBJECT DeviceObject, BUS_QUERY_ID_TYPE IdType, PWSTR *DeviceId) { PIO_STACK_LOCATION IrpStack; IO_STATUS_BLOCK IoStatus; PDEVICE_OBJECT TargetObject; KEVENT Event; PIRP Irp; NTSTATUS Status; PAGED_CODE(); /* Initialize the event */ KeInitializeEvent(&Event, NotificationEvent, FALSE); TargetObject = IoGetAttachedDeviceReference(DeviceObject); /* Build the IRP */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, TargetObject, NULL, 0, NULL, &Event, &IoStatus); if (Irp == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; } /* PNP IRPs all begin life as STATUS_NOT_SUPPORTED */ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; /* Get the top of stack */ IrpStack = IoGetNextIrpStackLocation(Irp); /* Set the top of stack */ RtlZeroMemory(IrpStack, sizeof(IO_STACK_LOCATION)); IrpStack->MajorFunction = IRP_MJ_PNP; IrpStack->MinorFunction = IRP_MN_QUERY_ID; IrpStack->Parameters.QueryId.IdType = IdType; /* Call the driver */ Status = IoCallDriver(TargetObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatus.Status; } if (NT_SUCCESS(Status)) { *DeviceId = (PWSTR)IoStatus.Information; } done: /* Dereference the target device object */ ObDereferenceObject(TargetObject); return Status; } static VOID ProcessorSetFriendlyName( PDEVICE_OBJECT DeviceObject) { KEY_VALUE_PARTIAL_INFORMATION *Buffer = NULL; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING HardwareKeyName, ValueName, EnumKeyName; HANDLE KeyHandle = NULL; ULONG DataLength = 0; ULONG BufferLength = 0; NTSTATUS Status; PWSTR KeyNameBuffer = NULL; PWSTR DeviceId = NULL; PWSTR InstanceId = NULL; PWSTR pszPrefix = L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum"; RtlInitUnicodeString(&HardwareKeyName, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"); InitializeObjectAttributes(&ObjectAttributes, &HardwareKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("ZwOpenKey() failed (Status 0x%08lx)\n", Status); return; } RtlInitUnicodeString(&ValueName, L"ProcessorNameString"); Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, NULL, 0, &DataLength); if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_SUCCESS) { DPRINT1("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status); goto done; } Buffer = ExAllocatePool(PagedPool, DataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION)); if (Buffer == NULL) { DPRINT1("ExAllocatePool() failed\n"); goto done; } Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, Buffer, DataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION), &DataLength); if (!NT_SUCCESS(Status)) { DPRINT1("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status); goto done; } DPRINT("ProcessorNameString: %S\n", (PWSTR)&Buffer->Data[0]); ZwClose(KeyHandle); KeyHandle = NULL; Status = GetDeviceId(DeviceObject, BusQueryDeviceID, &DeviceId); if (!NT_SUCCESS(Status)) { DPRINT1("GetDeviceId() failed (Status 0x%08lx)\n", Status); goto done; } DPRINT("DeviceId: %S\n", DeviceId); Status = GetDeviceId(DeviceObject, BusQueryInstanceID, &InstanceId); if (!NT_SUCCESS(Status)) { DPRINT1("GetDeviceId() failed (Status 0x%08lx)\n", Status); goto done; } DPRINT("InstanceId: %S\n", InstanceId); BufferLength = wcslen(pszPrefix) + 1 + wcslen(DeviceId) + 1 + wcslen(InstanceId) + 1; KeyNameBuffer = ExAllocatePool(PagedPool, BufferLength * sizeof(WCHAR)); if (KeyNameBuffer == NULL) { DPRINT1("ExAllocatePool() failed\n"); goto done; } swprintf(KeyNameBuffer, L"%s\\%s\\%s", pszPrefix, DeviceId, InstanceId); RtlInitUnicodeString(&EnumKeyName, KeyNameBuffer); InitializeObjectAttributes(&ObjectAttributes, &EnumKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("ZwOpenKey() failed (Status 0x%08lx)\n", Status); goto done; } RtlInitUnicodeString(&ValueName, L"FriendlyName"); Status = ZwSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)&Buffer->Data[0], Buffer->DataLength); if (!NT_SUCCESS(Status)) { DPRINT1("ZwSetValueKey() failed (Status 0x%08lx)\n", Status); goto done; } done: if (KeyHandle != NULL) ZwClose(KeyHandle); if (KeyNameBuffer != NULL) ExFreePool(KeyNameBuffer); if (InstanceId != NULL) ExFreePool(InstanceId); if (DeviceId != NULL) ExFreePool(DeviceId); if (Buffer != NULL) ExFreePool(Buffer); } static NTSTATUS ProcessorStartDevice( IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST ResourceList, IN PCM_RESOURCE_LIST ResourceListTranslated) { DPRINT("ProcessorStartDevice()\n"); ProcessorSetFriendlyName(DeviceObject); return STATUS_SUCCESS; } NTSTATUS NTAPI ProcessorPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpSp; ULONG_PTR Information = 0; NTSTATUS Status = STATUS_NOT_SUPPORTED; DPRINT("ProcessorPnp()\n"); IrpSp = IoGetCurrentIrpStackLocation(Irp); switch (IrpSp->MinorFunction) { case IRP_MN_START_DEVICE: DPRINT(" IRP_MN_START_DEVICE received\n"); /* Call lower driver */ Status = ForwardIrpAndWait(DeviceObject, Irp); if (NT_SUCCESS(Status)) { Status = ProcessorStartDevice(DeviceObject, IrpSp->Parameters.StartDevice.AllocatedResources, IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated); } break; case IRP_MN_QUERY_REMOVE_DEVICE: DPRINT(" IRP_MN_QUERY_REMOVE_DEVICE\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_REMOVE_DEVICE: DPRINT(" IRP_MN_REMOVE_DEVICE received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_CANCEL_REMOVE_DEVICE: DPRINT(" IRP_MN_CANCEL_REMOVE_DEVICE\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_STOP_DEVICE: DPRINT(" IRP_MN_STOP_DEVICE received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_QUERY_STOP_DEVICE: DPRINT(" IRP_MN_QUERY_STOP_DEVICE received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_CANCEL_STOP_DEVICE: DPRINT(" IRP_MN_CANCEL_STOP_DEVICE\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_QUERY_DEVICE_RELATIONS: DPRINT(" IRP_MN_QUERY_DEVICE_RELATIONS\n"); switch (IrpSp->Parameters.QueryDeviceRelations.Type) { case BusRelations: DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); break; case RemovalRelations: DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); default: DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", IrpSp->Parameters.QueryDeviceRelations.Type); return ForwardIrpAndForget(DeviceObject, Irp); } break; case IRP_MN_SURPRISE_REMOVAL: DPRINT(" IRP_MN_SURPRISE_REMOVAL received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0xd */ DPRINT(" IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); return ForwardIrpAndForget(DeviceObject, Irp); default: DPRINT(" Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction); return ForwardIrpAndForget(DeviceObject, Irp); } Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } NTSTATUS NTAPI ProcessorAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo) { PDEVICE_EXTENSION DeviceExtension = NULL; PDEVICE_OBJECT Fdo = NULL; NTSTATUS Status; DPRINT("ProcessorAddDevice()\n"); ASSERT(DriverObject); ASSERT(Pdo); /* Create functional device object */ Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &Fdo); if (NT_SUCCESS(Status)) { DeviceExtension = (PDEVICE_EXTENSION)Fdo->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(DEVICE_EXTENSION)); DeviceExtension->DeviceObject = Fdo; Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); if (!NT_SUCCESS(Status)) { DPRINT1("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status); IoDeleteDevice(Fdo); return Status; } Fdo->Flags |= DO_DIRECT_IO; Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags &= ~DO_DEVICE_INITIALIZING; } return Status; } /* EOF */