Index: drivers/bus/acpi/acpica/tables/tbutils.c =================================================================== --- drivers/bus/acpi/acpica/tables/tbutils.c (revision 74167) +++ drivers/bus/acpi/acpica/tables/tbutils.c (working copy) @@ -330,7 +330,14 @@ * so unmap the RSDP here before mapping other tables */ AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP)); - +#ifdef __REACTOS__ + /* + * ReactOS hack to add RSDT/XSDT as a regular table, so we can dump it + * later in registry without actually reparsing RSDP + */ + Status = AcpiTbInstallStandardTable(Address, + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE, &TableIndex); +#endif /* Map the RSDT/XSDT table header to get the full table length */ Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); Index: drivers/bus/acpi/busmgr/utils.c =================================================================== --- drivers/bus/acpi/busmgr/utils.c (revision 74167) +++ drivers/bus/acpi/busmgr/utils.c (working copy) @@ -24,6 +24,7 @@ */ #include +#include #define NDEBUG #include @@ -369,4 +370,233 @@ return_ACPI_STATUS(status); } +NTSTATUS +acpi_dump_table_to_registry(ACPI_STRING Signature, PCSTR KeyName) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING HardwareKeyName, ValueName; + ANSI_STRING HardwareKeyNameA; + HANDLE KeyHandle = NULL; + NTSTATUS Status; + ACPI_STATUS AcpiStatus; + ACPI_TABLE_HEADER OutTableHeader; + ACPI_TABLE_HEADER *OutTable; + char OemId[7]; + char OemTableId[9]; + char key[64]; + AcpiStatus = AcpiGetTableHeader(Signature, 0, &OutTableHeader); + if (ACPI_FAILURE(AcpiStatus)) + { + DPRINT1("AcpiGetTable() for %ws failed (Status 0x%08lx)\n", KeyName, AcpiStatus); + return STATUS_UNSUCCESSFUL; + } + + AcpiStatus = AcpiGetTable(Signature, 0, &OutTable); + if (ACPI_FAILURE(AcpiStatus)) + { + DPRINT1("AcpiGetTable() for %ws failed (Status 0x%08lx)\n", KeyName, AcpiStatus); + return STATUS_UNSUCCESSFUL; + } + + RtlZeroMemory(OemId, sizeof(OemId)); + RtlZeroMemory(OemTableId, sizeof(OemTableId)); + RtlCopyMemory(OemId, OutTableHeader.OemId, sizeof(OutTableHeader.OemId)); + RtlCopyMemory(OemTableId, OutTableHeader.OemTableId, sizeof(OutTableHeader.OemTableId)); + RtlStringCbPrintfA(key, + sizeof(key), + "\\Registry\\Machine\\HARDWARE\\ACPI\\%s", + KeyName); + RtlInitAnsiString(&HardwareKeyNameA, key); + RtlAnsiStringToUnicodeString(&HardwareKeyName, &HardwareKeyNameA, TRUE); + + InitializeObjectAttributes(&ObjectAttributes, + &HardwareKeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwCreateKey() for %ws failed (Status 0x%08lx)\n", KeyName, Status); + return Status; + } + + if (OutTableHeader.OemRevision != 0) + { + ZwClose(KeyHandle); + RtlStringCbPrintfA(key, + sizeof(key), + "\\Registry\\Machine\\HARDWARE\\ACPI\\%s\\%s", + KeyName, + OemId); + RtlInitAnsiString(&HardwareKeyNameA, key); + RtlAnsiStringToUnicodeString(&HardwareKeyName, &HardwareKeyNameA, TRUE); + + InitializeObjectAttributes(&ObjectAttributes, + &HardwareKeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwCreateKey() for %ws failed (Status 0x%08lx)\n", KeyName, Status); + return Status; + } + ZwClose(KeyHandle); + + RtlStringCbPrintfA(key, + sizeof(key), + "\\Registry\\Machine\\HARDWARE\\ACPI\\%s\\%s\\%s", + KeyName, + OemId, + OemTableId); + RtlInitAnsiString(&HardwareKeyNameA, key); + RtlAnsiStringToUnicodeString(&HardwareKeyName, &HardwareKeyNameA, TRUE); + + InitializeObjectAttributes(&ObjectAttributes, + &HardwareKeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwCreateKey() for %ws failed (Status 0x%08lx)\n", KeyName, Status); + return Status; + } + ZwClose(KeyHandle); + + RtlStringCbPrintfA(key, + sizeof(key), + "\\Registry\\Machine\\HARDWARE\\ACPI\\%s\\%s\\%s\\%8.8X", + KeyName, + OemId, + OemTableId, + OutTableHeader.OemRevision); + RtlInitAnsiString(&HardwareKeyNameA, key); + RtlAnsiStringToUnicodeString(&HardwareKeyName, &HardwareKeyNameA, TRUE); + + InitializeObjectAttributes(&ObjectAttributes, + &HardwareKeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwCreateKey() for %ws failed (Status 0x%08lx)\n", KeyName, Status); + return Status; + } + } + + RtlInitUnicodeString(&ValueName, + L"00000000"); + Status = ZwSetValueKey(KeyHandle, + &ValueName, + 0, + REG_BINARY, + OutTable, + OutTable->Length); + ZwClose(KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwSetValueKey() failed (Status 0x%08lx)\n", Status); + return Status; + } + + return STATUS_SUCCESS; +} + +NTSTATUS +acpi_dump_registry() +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING HardwareKeyName; + HANDLE KeyHandle = NULL; + NTSTATUS Status; + + RtlInitUnicodeString(&HardwareKeyName, + L"\\Registry\\Machine\\HARDWARE\\ACPI"); + InitializeObjectAttributes(&ObjectAttributes, + &HardwareKeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwCreateKey() for ACPI failed (Status 0x%08lx)\n", Status); + return Status; + } + ZwClose(KeyHandle); + + Status = acpi_dump_table_to_registry(ACPI_SIG_DSDT, "DSDT"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("acpi_dump_table_to_registry() for DSDT failed (Status 0x%08lx)\n", Status); + return Status; + } + + Status = acpi_dump_table_to_registry(ACPI_SIG_FACS, "FACS"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("acpi_dump_table_to_registry() for FACS failed (Status 0x%08lx)\n", Status); + return Status; + } + + Status = acpi_dump_table_to_registry(ACPI_SIG_FADT, "FADT"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("acpi_dump_table_to_registry() for FADT failed (Status 0x%08lx)\n", Status); + return Status; + } + + Status = acpi_dump_table_to_registry(ACPI_SIG_RSDT, "RSDT"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("acpi_dump_table_to_registry() for RSDT failed (Status 0x%08lx)\n", Status); + + Status = acpi_dump_table_to_registry(ACPI_SIG_XSDT, "RSDT"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("acpi_dump_table_to_registry() for XSDT failed (Status 0x%08lx)\n", Status); + return Status; + } + + return Status; + } + + return STATUS_SUCCESS; +} Index: drivers/bus/acpi/include/acpi_bus.h =================================================================== --- drivers/bus/acpi/include/acpi_bus.h (revision 74167) +++ drivers/bus/acpi/include/acpi_bus.h (working copy) @@ -57,6 +57,8 @@ ACPI_STRING pathname, struct acpi_object_list *arguments, struct acpi_handle_list *list); +NTSTATUS +acpi_dump_registry(); enum acpi_bus_removal_type { ACPI_BUS_REMOVAL_NORMAL = 0, Index: drivers/bus/acpi/pnp.c =================================================================== --- drivers/bus/acpi/pnp.c (revision 74167) +++ drivers/bus/acpi/pnp.c (working copy) @@ -299,6 +299,12 @@ return STATUS_UNSUCCESSFUL; } + status = acpi_dump_registry(); + if (!NT_SUCCESS(status)) + { + DPRINT1("Unable to dump ACPI tables in registry\n"); + } + DPRINT("Acpi subsystem init\n"); /* Initialize ACPI bus manager */ AcpiStatus = acpi_init();