/*** 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 //#define _X86_ #include #include #include #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\" // if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL) { // // hkey2 is now "Hardware\ACPI\\" // RegCloseKey(hkey1); if ((hkey1 = EnumSubKey(hkey2, 0)) != NULL) { // // hkey1 is now "Hardware\ACPI\\\" // RegCloseKey(hkey2); if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL) { // // hkey2 is now // "Hardware\ACPI\\\\" // 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