|
|
/*** tables.c - Dump various ACPI tables
* * This module provides the functions to dump various ACPI tables. * * Copyright (c) 1999 Microsoft Corporation * Author: Michael Tsang (MikeTs) * Created 04/08/99 * * MODIFICATION HISTORY */
#ifdef __UNASM
#pragma warning (disable: 4201 4214 4514)
typedef unsigned __int64 ULONGLONG; #define LOCAL __cdecl
#define EXPORT __cdecl
#include <stdarg.h>
//#define _X86_
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#define ULONG_PTR ULONG
#define EXCL_BASEDEF
#include "pch.h"
#include "fmtdata.h"
#define BYTEOF(d,i) (((BYTE *)&(d))[i])
/***LP IsWinNT - check if OS is NT
* * ENTRY * None * * EXIT-SUCCESS * returns TRUE - OS is NT * EXIT-FAILURE * returns FALSE - OS is not NT */
BOOL LOCAL IsWinNT(VOID) { BOOL rc = FALSE; OSVERSIONINFO osinfo;
ENTER((2, "IsWinNT()\n"));
osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&osinfo) && (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)) { rc = TRUE; }
EXIT((2, "IsWinNT=%x\n", rc)); return rc; } //IsWinNT
#ifndef WINNT
/***LP OpenVxD - Open ACPITAB.VXD
* * ENTRY * None * * EXIT-SUCCESS * returns VxD handle * EXIT-FAILURE * returns NULL */
HANDLE LOCAL OpenVxD(VOID) { HANDLE hVxD; DWORD dwVersion;
ENTER((2, "OpenVxD()\n"));
if ((hVxD = CreateFile(ACPITAB_VXD_NAME, 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) { ERROR(("OpenVxD: failed to open VxD %s (rc=%x)", ACPITAB_VXD_NAME, GetLastError())); hVxD = NULL; } else if (!DeviceIoControl(hVxD, ACPITAB_DIOC_GETVERSION, NULL, 0, &dwVersion, sizeof(dwVersion), NULL, NULL)) { ERROR(("OpenVxD: failed to get VxD version. (rc=%x)", GetLastError())); CloseVxD(hVxD); hVxD = NULL; } else if (dwVersion != ((ACPITAB_MAJOR_VER << 8) | ACPITAB_MINOR_VER)) { ERROR(("OpenVxD: version error (Ver=%x)", dwVersion)); CloseVxD(hVxD); hVxD = NULL; }
EXIT((2, "OpenVxD=%x\n", hVxD)); return hVxD; } //OpenVxD
/***LP CloseVxD - Close the VxD
* * ENTRY * hVxD - VxD handle * * EXIT * None */
VOID LOCAL CloseVxD(HANDLE hVxD) { ENTER((2, "CloseVxD(hVxD=%x)\n", hVxD));
CloseHandle(hVxD);
EXIT((2, "CloseVxD!\n")); } //CloseVxD
/***LP VxDGetTableBySig - Get table by its signature
* * ENTRY * dwTabSig - table signature * pdwTableAddr -> to hold physical address of table (can be NULL) * * EXIT-SUCCESS * returns pointer to table * EXIT-FAILURE * returns NULL */
PBYTE LOCAL VxDGetTableBySig(DWORD dwTabSig, PDWORD pdwTableAddr) { PBYTE pb = NULL; TABINFO TabInfo;
ENTER((2, "VxDGetTableBySig(TabSig=%x,pdwAddr=%p)\n", dwTabSig, pdwTableAddr));
TabInfo.dwTabSig = dwTabSig; if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABINFO, NULL, 0, &TabInfo, sizeof(TabInfo), NULL, NULL)) { if (dwTabSig == SIG_RSDP) { //
// We are getting RSD PTR
//
if ((pb = MEMALLOC(sizeof(RSDP))) != NULL) { memcpy(pb, &TabInfo.rsdp, sizeof(RSDP)); if (pdwTableAddr != NULL) { *pdwTableAddr = TabInfo.dwPhyAddr; } } else { ERROR(("VxDGetTableBySig: failed to allocate RSDP buffer")); } } else if (dwTabSig == FACS_SIGNATURE) { if ((pb = MEMALLOC(sizeof(FACS))) != NULL) { memcpy(pb, &TabInfo.facs, sizeof(FACS)); if (pdwTableAddr != NULL) { *pdwTableAddr = TabInfo.dwPhyAddr; } } else { ERROR(("VxDGetTableBySig: failed to allocate FACS buffer")); } } else if ((pb = MEMALLOC(TabInfo.dh.Length)) != NULL) { if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE, (PVOID)TabInfo.dwPhyAddr, 0, pb, TabInfo.dh.Length, NULL, NULL) == 0) { ERROR(("VxDGetTableBySig: failed to get table %s. (rc=%x)", GetTableSigStr(dwTabSig), GetLastError())); MEMFREE(pb); pb = NULL; } else { if (pdwTableAddr != NULL) { *pdwTableAddr = TabInfo.dwPhyAddr; }
ValidateTable(pb, TabInfo.dh.Length); } } else { ERROR(("VxDGetTableBySig: failed to allocate table buffer (len=%d)", TabInfo.dh.Length)); } } else { ERROR(("VxDGetTableBySig: failed to get table info %s. (rc=%x)", GetTableSigStr(dwTabSig), GetLastError())); }
EXIT((2, "VxDGetTableBySig=%x\n", pb)); return pb; } //VxDGetTableBySig
/***LP VxDGetTableByAddr - Get table by its physical address
* * ENTRY * dwTableAddr - physical address of table * pdwTableSig -> to hold signature of table (can be NULL) * * EXIT-SUCCESS * returns pointer to table * EXIT-FAILURE * returns NULL */
PBYTE LOCAL VxDGetTableByAddr(DWORD dwTableAddr, PDWORD pdwTableSig) { PBYTE pb = NULL; DESCRIPTION_HEADER dh;
ENTER((2, "VxDGetTableByAddr(TabAddr=%x,pdwSig=%p)\n", dwTableAddr, pdwTableSig));
if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE, (PVOID)dwTableAddr, 0, &dh, sizeof(dh), NULL, NULL)) { DWORD dwLen = (dh.Signature == SIG_LOW_RSDP)? sizeof(RSDP): dh.Length;
if ((pb = MEMALLOC(dwLen)) != NULL) { if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE, (PVOID)dwTableAddr, 0, pb, dwLen, NULL, NULL) == 0) { ERROR(("VxDGetTableByAddr: failed to get table %s at %x. (rc=%x)", GetTableSigStr(dh.Signature), dwTableAddr, GetLastError())); MEMFREE(pb); pb = NULL; } else if (pdwTableSig != NULL) { if (pdwTableSig != NULL) { *pdwTableSig = (dh.Signature == SIG_LOW_RSDP)? SIG_RSDP: dh.Signature; }
ValidateTable(pb, dwLen); } } else { ERROR(("VxDGetTableByAddr: failed to allocate table buffer (len=%d)", dh.Length)); } } else { ERROR(("VxDGetTableByAddr: failed to get table %s header (rc=%x)", GetTableSigStr(dh.Signature), GetLastError())); }
EXIT((2, "VxDGetTableByAddr=%x\n", pb)); return pb; } //VxDGetTableByAddr
#endif //ifndef WINNT
/***LP EnumSubKey - enumerate subkey
* * ENTRY * hkey - key to enumerate * dwIndex - subkey index * * EXIT-SUCCESS * returns subkey * EXIT-FAILURE * returns NULL */
HKEY LOCAL EnumSubKey(HKEY hkey, DWORD dwIndex) { HKEY hkeySub = NULL; char szSubKey[32]; DWORD dwSubKeySize = sizeof(szSubKey);
ENTER((2, "EnumSubKey(hkey=%x,Index=%d)\n", hkey, dwIndex));
if ((RegEnumKeyEx(hkey, dwIndex, szSubKey, &dwSubKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) && (RegOpenKeyEx(hkey, szSubKey, 0, KEY_READ, &hkeySub) != ERROR_SUCCESS)) { hkeySub = NULL; }
EXIT((2, "EnumSubKey=%x\n", hkeySub)); return hkeySub; } //EnumSubKey
/***LP OpenNTTable - Open ACPI table in NT registry
* * ENTRY * dwTabSig - table signature * * EXIT-SUCCESS * returns table registry handle * EXIT-FAILURE * returns NULL */
HKEY LOCAL OpenNTTable(DWORD dwTabSig) { HKEY hkeyTab = NULL, hkey1 = NULL, hkey2 = NULL; static char szTabKey[] = "Hardware\\ACPI\\xxxx";
ENTER((2, "OpenNTTable(TabSig=%s)\n", GetTableSigStr(dwTabSig)));
if (dwTabSig == FADT_SIGNATURE) { memcpy(&szTabKey[strlen(szTabKey) - 4], "FADT", sizeof(ULONG)); } else { memcpy(&szTabKey[strlen(szTabKey) - 4], &dwTabSig, sizeof(ULONG)); }
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTabKey, 0, KEY_READ, &hkey1) == ERROR_SUCCESS) { //
// hkey1 is now "Hardware\ACPI\<TabSig>"
//
if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL) { //
// hkey2 is now "Hardware\ACPI\<TabSig>\<OEMID>"
//
RegCloseKey(hkey1); if ((hkey1 = EnumSubKey(hkey2, 0)) != NULL) { //
// hkey1 is now "Hardware\ACPI\<TabSig>\<OEMID>\<OEMTabID>"
//
RegCloseKey(hkey2); if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL) { //
// hkey2 is now
// "Hardware\ACPI\<TabSig>\<OEMID>\<OEMTabID>\<OEMRev>"
//
hkeyTab = hkey2; } } } }
if (hkey1 != NULL) { RegCloseKey(hkey1); }
if ((hkey2 != NULL) && (hkeyTab != hkey2)) { RegCloseKey(hkey2); }
EXIT((2, "OpenNTTable=%x\n", hkeyTab)); return hkeyTab; } //OpenNTTable
/***LP GetNTTable - Get ACPI table from NT registry
* * ENTRY * dwTabSig - table signature * * EXIT-SUCCESS * returns pointer to table * EXIT-FAILURE * returns NULL */
PBYTE LOCAL GetNTTable(DWORD dwTabSig) { PBYTE pb = NULL; HKEY hkeyTab;
ENTER((2, "GetNTTable(TabSig=%s)\n", GetTableSigStr(dwTabSig)));
if ((hkeyTab = OpenNTTable(dwTabSig)) != NULL) { DWORD dwLen = 0; PSZ pszTabKey = "00000000";
if (RegQueryValueEx(hkeyTab, pszTabKey, NULL, NULL, NULL, &dwLen) == ERROR_SUCCESS) { if ((pb = MEMALLOC(dwLen)) != NULL) { if (RegQueryValueEx(hkeyTab, pszTabKey, NULL, NULL, pb, &dwLen) != ERROR_SUCCESS) { ERROR(("GetNTTable: failed to read table")); } } else { ERROR(("GetNTTable: failed to allocate table buffer")); } } else { ERROR(("GetNTTable: failed to read table key")); } RegCloseKey(hkeyTab); } else { ERROR(("GetNTTable: failed to get table %s", GetTableSigStr(dwTabSig))); }
EXIT((2, "GetNTTable=%x\n", pb)); return pb; } //GetNTTable
/***LP GetTableBySig - Get table by its signature
* * ENTRY * dwTabSig - table signature * pdwTableAddr -> to hold physical address of table (can be NULL) * * EXIT-SUCCESS * returns pointer to table * EXIT-FAILURE * returns NULL */
PBYTE LOCAL GetTableBySig(DWORD dwTabSig, PDWORD pdwTableAddr) { PBYTE pb = NULL;
ENTER((2, "GetTableBySig(TabSig=%x,pdwAddr=%p)\n", dwTabSig, pdwTableAddr));
if (gdwfASL & ASLF_NT) { if (((pb = GetNTTable(dwTabSig)) != NULL) && (pdwTableAddr != NULL)) { *pdwTableAddr = 0; } } #ifndef WINNT
else { pb = VxDGetTableBySig(dwTabSig, pdwTableAddr); } #endif
EXIT((2, "GetTableBySig=%x\n", pb)); return pb; } //GetTableBySig
/***LP GetTableByAddr - Get table by its physical address
* * ENTRY * dwTableAddr - physical address of table * pdwTableSig -> to hold signature of table (can be NULL) * * EXIT-SUCCESS * returns pointer to table * EXIT-FAILURE * returns NULL */
PBYTE LOCAL GetTableByAddr(DWORD dwTableAddr, PDWORD pdwTableSig) { PBYTE pb = NULL;
ENTER((2, "GetTableByAddr(TabAddr=%x,pdwSig=%p)\n", dwTableAddr, pdwTableSig));
if (gdwfASL & ASLF_NT) { ERROR(("GetTableByAddr: not supported by NT")); } #ifndef WINNT
else { pb = VxDGetTableByAddr(dwTableAddr, pdwTableSig); } #endif
EXIT((2, "GetTableByAddr=%x\n", pb)); return pb; } //GetTableByAddr
/***LP DumpAllTables - Dump all ACPI tables
* * ENTRY * pfileOut -> output file * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL DumpAllTables(FILE *pfileOut) { int rc = ASLERR_NONE; PBYTE pb; DWORD dwAddr;
ENTER((1, "DumpAllTables(pfileOut=%p)\n", pfileOut));
if (gdwfASL & ASLF_NT) { DumpTableBySig(pfileOut, RSDT_SIGNATURE); DumpTableBySig(pfileOut, FADT_SIGNATURE); DumpTableBySig(pfileOut, FACS_SIGNATURE); DumpTableBySig(pfileOut, SBST_SIGNATURE); DumpTableBySig(pfileOut, APIC_SIGNATURE); DumpTableBySig(pfileOut, SIG_BOOT); DumpTableBySig(pfileOut, SIG_DBGP); DumpTableBySig(pfileOut, DSDT_SIGNATURE); DumpTableBySig(pfileOut, SSDT_SIGNATURE); DumpTableBySig(pfileOut, PSDT_SIGNATURE); } else if ((pb = GetTableBySig(SIG_RSDP, &dwAddr)) != NULL) { if ((rc = DumpRSDP(pfileOut, pb, dwAddr)) == ASLERR_NONE) { DWORD dwRSDTAddr = ((PRSDP)pb)->RsdtAddress; DWORD dwTableSig;
MEMFREE(pb); if ((pb = GetTableByAddr(dwRSDTAddr, &dwTableSig)) != NULL) { if ((rc = DumpTable(pfileOut, pb, dwRSDTAddr, dwTableSig)) == ASLERR_NONE) { PRSDT pRSDT = (PRSDT)pb; DWORD i, dwcEntries;
dwcEntries = (pRSDT->Header.Length - sizeof(DESCRIPTION_HEADER))/sizeof(ULONG);
for (i = 0; i < dwcEntries; ++i) { if ((rc = DumpTableByAddr(pfileOut, pRSDT->Tables[i])) != ASLERR_NONE) { break; } } }
if ((rc == ASLERR_NONE) && ((rc = DumpTableBySig(pfileOut, FACS_SIGNATURE)) == ASLERR_NONE)) { rc = DumpTableBySig(pfileOut, DSDT_SIGNATURE); } } else { rc = ASLERR_GET_TABLE; } }
if (pb != NULL) { MEMFREE(pb); } } else { rc = ASLERR_GET_TABLE; }
EXIT((1, "DumpAllTables=%d\n", rc)); return rc; } //DumpAllTables
/***LP DumpTableBySig - Dump an ACPI table by its Table Signature
* * ENTRY * pfileOut -> output file * dwTableSig - table signature * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL DumpTableBySig(FILE *pfileOut, DWORD dwTableSig) { int rc = ASLERR_NONE; PBYTE pb; DWORD dwTableAddr;
ENTER((1, "DumpTableBySig(pfileOut=%p,TableSig=%s)\n", pfileOut, GetTableSigStr(dwTableSig)));
if (((PSZ)&dwTableSig)[0] == '*') { rc = DumpAllTables(pfileOut); } else if ((pb = GetTableBySig(dwTableSig, &dwTableAddr)) != NULL) { rc = DumpTable(pfileOut, pb, dwTableAddr, dwTableSig); MEMFREE(pb); } else { rc = ASLERR_GET_TABLE; }
EXIT((1, "DumpTableBySig=%d\n", rc)); return rc; } //DumpTableBySig
/***LP DumpTableByAddr - Dump an ACPI table by its address
* * ENTRY * pfileOut -> output file * dwTableAddr - physical address of the table * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL DumpTableByAddr(FILE *pfileOut, DWORD dwTableAddr) { int rc = ASLERR_NONE; PBYTE pb; DWORD dwTableSig;
ENTER((1, "DumpTableByAddr(pfileOut=%p,TableAddr=%x)\n", pfileOut, dwTableAddr));
if ((pb = GetTableByAddr(dwTableAddr, &dwTableSig)) != NULL) { rc = DumpTable(pfileOut, pb, dwTableAddr, dwTableSig); MEMFREE(pb); } else { rc = ASLERR_GET_TABLE; }
EXIT((1, "DumpTableByAddr=%d\n", rc)); return rc; } //DumpTableByAddr
/***LP DumpRSDP - Dump the RSD PTR table
* * ENTRY * pfileOut -> output file * pb -> RSDP structure * dwAddr - physical address of RSDP * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL DumpRSDP(FILE *pfileOut, PBYTE pb, DWORD dwAddr) { int rc = ASLERR_NONE;
ENTER((1, "DumpRSDP(pfileOut=%p,Addr=%x,pRSDP=%p)\n", pfileOut, dwAddr, pb));
if (pfileOut != NULL) { DWORD dwOffset = 0;
fprintf(pfileOut, szSectFmt, dwAddr, "RSD PTR"); if (BinFPrintf(pfileOut, NULL, afmtRSDPTR, pb, &dwOffset, szOffsetFmt) != FERR_NONE) { ERROR(("DumpRSDP: failed to dump RSD PTR structure")); rc = ASLERR_INTERNAL_ERROR; } } else { rc = DumpTableBin(SIG_RSDP, dwAddr, pb, sizeof(RSDP)); }
EXIT((1, "DumpRSDP=%d\n", rc)); return rc; } //DumpRSDP
/***LP DumpTable - Dump an ACPI table
* * ENTRY * pfileOut -> output file * pb -> ACPI table * dwTableAddr - physical address of table * dwTableSig - signature of table * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL DumpTable(FILE *pfileOut, PBYTE pb, DWORD dwTableAddr, DWORD dwTableSig) { int rc = ASLERR_NONE;
ENTER((1, "DumpTable(pfileOut=%p,pb=%p,TableAddr=%x,TableSig=%s)\n", pfileOut, pb, dwTableAddr, GetTableSigStr(dwTableSig)));
if (dwTableSig == SIG_RSDP) { rc = DumpRSDP(pfileOut, pb, dwTableAddr); } else if (pfileOut != NULL) { rc = DumpTableTxt(pfileOut, pb, dwTableAddr, dwTableSig); } else { rc = DumpTableBin(dwTableSig, dwTableAddr, pb, (dwTableSig == FACS_SIGNATURE)? sizeof(FACS): ((PDESCRIPTION_HEADER)pb)->Length); }
EXIT((1, "DumpTable=%d\n", rc)); return rc; } //DumpTable
/***LP DumpTableTxt - Dump an ACPI table to a text file
* * ENTRY * pfileOut -> output file * pb -> ACPI table * dwTableAddr - physical address of table * dwTableSig - signature of table * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL DumpTableTxt(FILE *pfileOut, PBYTE pb, DWORD dwTableAddr, DWORD dwTableSig) { int rc = ASLERR_NONE; PFMT pfmt; DWORD dwFlags;
ENTER((1, "DumpTableTxt(pfileOut=%p,pb=%p,TableAddr=%x,TableSig=%s)\n", pfileOut, pb, dwTableAddr, GetTableSigStr(dwTableSig)));
if ((rc = FindTableFmt(dwTableSig, &pfmt, &dwFlags)) == ASLERR_SIG_NOT_FOUND) { rc = ASLERR_NONE; }
if (rc == ASLERR_NONE) { DWORD dwOffset = 0;
fprintf(pfileOut, szSectFmt, dwTableAddr, GetTableSigStr(dwTableSig)); if (!(dwFlags & TF_NOHDR) && (BinFPrintf(pfileOut, NULL, afmtTableHdr, pb, &dwOffset, szOffsetFmt) != FERR_NONE)) { ERROR(("DumpTableTxt: failed to dump %s structure header", GetTableSigStr(dwTableSig))); rc = ASLERR_INTERNAL_ERROR; } else if (pfmt != NULL) { if (BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset, szOffsetFmt) != FERR_NONE) { ERROR(("DumpTableTxt: failed to dump %s structure", GetTableSigStr(dwTableSig))); rc = ASLERR_INTERNAL_ERROR; } else if ((dwTableSig == FADT_SIGNATURE) && (((PDESCRIPTION_HEADER)pb)->Revision > 1)) { /*
pfmt = (((PGRAS)pb)->id == REGSPACE_PCICFG)? afmtGRASPCICS: afmtGRASRegAddr;*/ fprintf(pfileOut, "; Reset Register\n"); if ((BinFPrintf(pfileOut, NULL, afmtGRASCommon, pb, &dwOffset, szOffsetFmt) != FERR_NONE) || (BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset, szOffsetFmt) != FERR_NONE) || (BinFPrintf(pfileOut, NULL, afmtFACP2, pb, &dwOffset, szOffsetFmt) != FERR_NONE)) { ERROR(("DumpTableTxt: failed to dump extended %s structure", GetTableSigStr(dwTableSig))); rc = ASLERR_INTERNAL_ERROR; } } else if (dwTableSig == SIG_DBGP) {
/*
pfmt = (((PGRAS)pb)->id == REGSPACE_PCICFG)? afmtGRASPCICS: afmtGRASRegAddr;*/
fprintf(pfileOut, "; Debug Port Base Address\n"); if ((BinFPrintf(pfileOut, NULL, afmtGRASCommon, pb, &dwOffset, szOffsetFmt) != FERR_NONE) || (BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset, szOffsetFmt) != FERR_NONE)) { ERROR(("DumpTableTxt: failed to dump extended %s structure", GetTableSigStr(dwTableSig))); rc = ASLERR_INTERNAL_ERROR; } } } else { #define NUM_COLS 16
PRSDT pRSDT; DWORD i, dwcEntries; PBYTE pbEnd; char szAMLName[_MAX_FNAME]; char szBytes[NUM_COLS + 1];
switch (dwTableSig) { case RSDT_SIGNATURE: pRSDT = (PRSDT)pb; dwcEntries = (pRSDT->Header.Length - sizeof(DESCRIPTION_HEADER))/sizeof(ULONG); for (i = 0; i < dwcEntries; ++i) { fprintf(pfileOut, szOffsetFmt, dwOffset); fprintf(pfileOut, "[%02d] %08lx\n", i, pRSDT->Tables[i]); dwOffset += sizeof(ULONG); } break;
case DSDT_SIGNATURE: case SSDT_SIGNATURE: case PSDT_SIGNATURE: strncpy(szAMLName, (PSZ)&dwTableSig, sizeof(DWORD)); strcpy(&szAMLName[sizeof(DWORD)], ".AML"); rc = UnAsmAML(szAMLName, dwTableAddr, pb, (PFNPRINT)fprintf, pfileOut); break;
default: //
// Don't return error because we want to continue.
//
WARN(("DumpTableTxt: unexpected table signature %s", GetTableSigStr(dwTableSig)));
pbEnd = pb + ((PDESCRIPTION_HEADER)pb)->Length; pb += sizeof(DESCRIPTION_HEADER); i = 0; while (pb < pbEnd) { szBytes[i] = (char)(isprint(*pb)? *pb: '.'); if (i == 0) { fprintf(pfileOut, szOffsetFmt, dwOffset); fprintf(pfileOut, "%02x", *pb); } else if (i == NUM_COLS/2) { fprintf(pfileOut, "-%02x", *pb); } else { fprintf(pfileOut, ",%02x", *pb); } i++; if (i == NUM_COLS) { szBytes[i] = '\0'; fprintf(pfileOut, " ;%s\n", szBytes); i = 0; } dwOffset += sizeof(BYTE); pb += sizeof(BYTE); }
if (i < NUM_COLS) { szBytes[i] = '\0'; while (i < NUM_COLS) { fprintf(pfileOut, " "); i++; } fprintf(pfileOut, " ;%s\n", szBytes); } } } }
EXIT((1, "DumpTableTxt=%d\n", rc)); return rc; } //DumpTableTxt
/***LP DumpTableBin - Dump an ACPI table to a binary file
* * ENTRY * dwTableSig - table signature * dwAddr - physical address of table * pb -> ACPI table * dwLen - length of table * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL DumpTableBin(DWORD dwTableSig, DWORD dwAddr, PBYTE pb, DWORD dwLen) { int rc = ASLERR_NONE; char szBinFile[_MAX_FNAME]; FILE *pfile;
ENTER((1, "DumpTableBin(TableSig=%s,Addr=%x,pb=%p,Len=%d)\n", GetTableSigStr(dwTableSig), dwAddr, pb, dwLen));
strncpy(szBinFile, (PSZ)&dwTableSig, sizeof(DWORD)); sprintf(&szBinFile[sizeof(DWORD)], "%04x", (WORD)dwAddr); strcpy(&szBinFile[sizeof(DWORD) + 4], ".BIN"); if ((pfile = fopen(szBinFile, "wb")) == NULL) { ERROR(("DumpTableBin: failed to create file %s", szBinFile)); rc = ASLERR_CREATE_FILE; } else { if (fwrite(pb, dwLen, 1, pfile) != 1) { ERROR(("DumpTableBin: failed to write to file %s", szBinFile)); rc = ASLERR_WRITE_FILE; } fclose(pfile); }
EXIT((1, "DumpTableBin=%d\n", rc)); return rc; } //DumpTableBin
/***LP FindTableFmt - Find the appropriate table format structure
* * ENTRY * dwTableSig - table signature * ppfmt -> to hold pfmt found * pdwFlags -> to hold table flags * * EXIT-SUCCESS * returns ASLERR_NONE * EXIT-FAILURE * returns negative error code */
int LOCAL FindTableFmt(DWORD dwTableSig, PFMT *ppfmt, PDWORD pdwFlags) { int rc = ASLERR_NONE; int i;
ENTER((1, "FindTableFmt(TableSig=%s,ppfmt=%p,pdwFlags=%p)\n", GetTableSigStr(dwTableSig), ppfmt, pdwFlags));
for (i = 0; FmtTable[i].dwTableSig != 0; ++i) { if (dwTableSig == FmtTable[i].dwTableSig) { *ppfmt = FmtTable[i].pfmt; *pdwFlags = FmtTable[i].dwFlags; break; } }
if (FmtTable[i].dwTableSig == 0) { *ppfmt = NULL; *pdwFlags = 0; rc = ASLERR_SIG_NOT_FOUND; }
EXIT((1, "FindTableFmt=%d (pfmt=%p,Flags=%x)\n", rc, *ppfmt, *pdwFlags)); return rc; } //FindTableFmt
/***LP GetTableSigStr - Get table signature string
* * ENTRY * dwTableSig - table signature * * EXIT * returns the table signature string */
PSZ LOCAL GetTableSigStr(DWORD dwTableSig) { static char szTableSig[5] = {0};
ENTER((2, "GetTableSigStr(TableSig=%08x)\n", dwTableSig));
strncpy(szTableSig, (PSZ)&dwTableSig, sizeof(DWORD));
EXIT((2, "GetTableSigStr=%s\n", szTableSig)); return szTableSig; } //GetTableSigStr
/***LP ValidateTable - Validate the given table
* * ENTRY * pbTable -> Table * dwLen - Table length * * EXIT-SUCCESS * returns TRUE * EXIT-FAILURE * returns FALSE */
BOOL LOCAL ValidateTable(PBYTE pbTable, DWORD dwLen) { BOOL rc = TRUE; DWORD dwTableSig, dwTableLen = 0; BOOL fNeedChkSum = FALSE;
ENTER((2, "ValidateTable(pbTable=%x,Len=%d)\n", pbTable, dwLen));
dwTableSig = ((PDESCRIPTION_HEADER)pbTable)->Signature; switch (dwTableSig) { case SIG_LOW_RSDP: dwTableLen = sizeof(RSDP); fNeedChkSum = TRUE; break;
case RSDT_SIGNATURE: case FADT_SIGNATURE: case DSDT_SIGNATURE: case SSDT_SIGNATURE: case PSDT_SIGNATURE: case APIC_SIGNATURE: case SBST_SIGNATURE: case SIG_BOOT: case SIG_DBGP: dwTableLen = ((PDESCRIPTION_HEADER)pbTable)->Length; fNeedChkSum = TRUE; break;
case FACS_SIGNATURE: dwTableLen = ((PFACS)pbTable)->Length; break;
default: if (IsALikelySig(dwTableSig) && (((PDESCRIPTION_HEADER)pbTable)->Length < 256)) { dwTableLen = ((PDESCRIPTION_HEADER)pbTable)->Length; fNeedChkSum = TRUE; } else { WARN(("ValidateTable: invalid table signature %s", GetTableSigStr(dwTableSig))); rc = FALSE; } }
if (dwTableLen > dwLen) { WARN(("ValidateTable: invalid length %d in table %s", dwTableLen, GetTableSigStr(dwTableSig))); rc = FALSE; }
if ((rc == TRUE) && fNeedChkSum && (ComputeDataChkSum(pbTable, dwTableLen) != 0)) { WARN(("ValidateTable: invalid checksum in table %s", GetTableSigStr(dwTableSig))); rc = FALSE; }
EXIT((2, "ValidateTable=%x\n", rc)); return rc; } //ValidateTable
/***LP IsALikelySig - Check if a table signature is possibly valid
* * ENTRY * dwTableSig - table signature * * EXIT-SUCCESS * returns TRUE * EXIT-FAILURE * returns FALSE */
BOOL LOCAL IsALikelySig(DWORD dwTableSig) { BOOL rc = TRUE; int i, ch;
ENTER((2, "IsALikelySig(dwTableSig=%x)\n", dwTableSig));
for (i = 0; i < sizeof(DWORD); ++i) { ch = BYTEOF(dwTableSig, i); if ((ch < 'A') || (ch > 'Z')) { rc = FALSE; break; } }
EXIT((2, "IsALikelySig=%x\n", rc)); return rc; } //IsALikelySig
#endif //ifdef __UNASM
|