From dbf90936aa2b8e4d5f3ff4f5666cf57fb334a34b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 8 May 2003 18:55:09 +0000 Subject: [PATCH] Added a little PnP-BIOS data dumper. svn path=/trunk/; revision=4659 --- reactos/apps/utils/Makefile | 2 +- reactos/apps/utils/pnpdump/.cvsignore | 5 + reactos/apps/utils/pnpdump/makefile | 23 + reactos/apps/utils/pnpdump/pnpdump.c | 643 ++++++++++++++++++++++++++ 4 files changed, 672 insertions(+), 1 deletion(-) create mode 100644 reactos/apps/utils/pnpdump/.cvsignore create mode 100644 reactos/apps/utils/pnpdump/makefile create mode 100644 reactos/apps/utils/pnpdump/pnpdump.c diff --git a/reactos/apps/utils/Makefile b/reactos/apps/utils/Makefile index 6d83f56e182..3324d935790 100644 --- a/reactos/apps/utils/Makefile +++ b/reactos/apps/utils/Makefile @@ -9,7 +9,7 @@ include $(PATH_TO_TOP)/rules.mak # Console system utilities # cabman cat net objdir partinfo pice ps sc stats -UTIL_APPS = cat objdir partinfo sc stats tickcount +UTIL_APPS = cat objdir partinfo pnpdump sc stats tickcount UTIL_NET_APPS = diff --git a/reactos/apps/utils/pnpdump/.cvsignore b/reactos/apps/utils/pnpdump/.cvsignore new file mode 100644 index 00000000000..7e878167e8e --- /dev/null +++ b/reactos/apps/utils/pnpdump/.cvsignore @@ -0,0 +1,5 @@ +*.o +*.d +*.exe +*.coff +*.sym diff --git a/reactos/apps/utils/pnpdump/makefile b/reactos/apps/utils/pnpdump/makefile new file mode 100644 index 00000000000..355a39cc2ee --- /dev/null +++ b/reactos/apps/utils/pnpdump/makefile @@ -0,0 +1,23 @@ +# $Id: makefile,v 1.1 2003/05/08 18:54:59 ekohl Exp $ + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = pnpdump + +#TARGET_CFLAGS = -fnative_struct + +TARGET_SDKLIBS = ntdll.a kernel32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/reactos/apps/utils/pnpdump/pnpdump.c b/reactos/apps/utils/pnpdump/pnpdump.c new file mode 100644 index 00000000000..2b093bd5a52 --- /dev/null +++ b/reactos/apps/utils/pnpdump/pnpdump.c @@ -0,0 +1,643 @@ +/* + * pnpdump - PnP BIOS information dumper + */ + +#include +//#include +#include +#include + +//#define DUMP_DATA +#define DUMP_SIZE_INFO + + +typedef struct _CM_PNP_BIOS_DEVICE_NODE +{ + USHORT Size; + UCHAR Node; + ULONG ProductId; + UCHAR DeviceType[3]; + USHORT DeviceAttributes; +} PACKED CM_PNP_BIOS_DEVICE_NODE,*PCM_PNP_BIOS_DEVICE_NODE; + +typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK +{ + UCHAR Signature[4]; // $PnP (ascii) + UCHAR Revision; + UCHAR Length; + USHORT ControlField; + UCHAR Checksum; + ULONG EventFlagAddress; // Physical address + USHORT RealModeEntryOffset; + USHORT RealModeEntrySegment; + USHORT ProtectedModeEntryOffset; + ULONG ProtectedModeCodeBaseAddress; + ULONG OemDeviceId; + USHORT RealModeDataBaseAddress; + ULONG ProtectedModeDataBaseAddress; +} PACKED CM_PNP_BIOS_INSTALLATION_CHECK, *PCM_PNP_BIOS_INSTALLATION_CHECK; + + +static char Hex[] = "0123456789ABCDEF"; + + +#ifdef DUMP_DATA +void HexDump(char *buffer, ULONG size) +{ + ULONG offset = 0; + unsigned char *ptr; + + while (offset < (size & ~15)) + { + ptr = (unsigned char*)((ULONG)buffer + offset); + printf("%08lx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx-%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx\n", + offset, + ptr[0], + ptr[1], + ptr[2], + ptr[3], + ptr[4], + ptr[5], + ptr[6], + ptr[7], + ptr[8], + ptr[9], + ptr[10], + ptr[11], + ptr[12], + ptr[13], + ptr[14], + ptr[15]); + offset += 16; + } + + ptr = (unsigned char*)((ULONG)buffer + offset); + printf("%08lx ", offset); + while (offset < size) + { + printf(" %02hx", *ptr); + offset++; + ptr++; + } + + printf("\n\n\n"); +} +#endif + + +LONG +GetPnpKey(PHKEY PnpKey) +{ + LONG lError; + char szBuffer[80]; + HKEY hAdapterKey; + HKEY hBusKey; + DWORD dwBus; + DWORD dwType; + DWORD dwSize; + + *PnpKey = 0; + + lError = RegOpenKey(HKEY_LOCAL_MACHINE, + "HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter", + &hAdapterKey); + if (lError != ERROR_SUCCESS) + return 0; + + /* Enumerate buses */ + for (dwBus = 0; ; dwBus++) + { + sprintf(szBuffer, "%lu", dwBus); + + lError = RegOpenKey(hAdapterKey, + szBuffer, + &hBusKey); + if (lError != ERROR_SUCCESS) + { + RegCloseKey(hAdapterKey); + return lError; + } + + dwSize = 80; + lError = RegQueryValueEx(hBusKey, + "Identifier", + NULL, + &dwType, + szBuffer, + &dwSize); + if (lError != ERROR_SUCCESS) + { + RegCloseKey(hBusKey); + RegCloseKey(hAdapterKey); + return lError; + } + + if (dwType == REG_SZ && stricmp(szBuffer, "pnp bios") == 0) + { + *PnpKey = hBusKey; + RegCloseKey(hAdapterKey); + return ERROR_SUCCESS; + } + + RegCloseKey(hBusKey); + } + + return 1; +} + + +static VOID +PnpDecodeIrq(char *Ptr) +{ + USHORT IrqMask; + int i; + + IrqMask = *Ptr; + Ptr++; + IrqMask |= (*Ptr << 8); + + printf(" IRQs:"); + + for (i = 0; i < 16; i++) + { + if (IrqMask & (1 << i)) + { + printf(" %u", i); + } + } + + printf("\n"); +} + + +static VOID +PnpDecodeDma(char *Ptr) +{ + char DmaChannel; + char DmaStatus; + int i; + + DmaChannel = *Ptr; + Ptr++; + DmaStatus = *Ptr; + + printf(" DMAs:"); + + for (i = 0; i < 8; i++) + { + if (DmaChannel & (1 << i)) + { + printf(" %u", i); + } + } + + printf("\n"); +} + + +static VOID +PnpDecodeIoPort(char *Ptr) +{ + USHORT MinBase; + USHORT MaxBase; + UCHAR Align; + UCHAR Length; + + // Info = *Ptr; + Ptr++; + MinBase = *Ptr; + Ptr++; + MinBase += (*Ptr << 8); + Ptr++; + MaxBase = *Ptr; + Ptr++; + MaxBase += (*Ptr << 8); + Ptr++; + Align = *Ptr; + Ptr++; + Length = *Ptr; + + printf(" I/O Port descriptor\n"); + printf(" MinBase 0x%x MaxBase 0x%x Align %u Length %u\n", + MinBase, MaxBase, Align, Length); +} + + +static VOID +PnpDecodeFixedIoPort(char *Ptr) +{ + USHORT IoPort; + UCHAR Length; + + IoPort = *Ptr; + Ptr++; + IoPort += (*Ptr << 8); + Ptr++; + Length = *Ptr; + + printf(" Fixed I/O Port descriptor\n"); + printf(" PortBase 0x%hx Length 0x%x\n", + IoPort, Length); + +#if 0 + if (Length == 1) + { + printf(" Fixed location I/O Port descriptor: 0x%x\n", + IoPort); + } + else + { + printf(" Fixed location I/O Port descriptor: 0x%x - 0x%x\n", + IoPort, + IoPort + Length - 1); + } +#endif +} + + +static VOID +PnpDecodeMemory16(char *Ptr) +{ + USHORT DescLength; + UCHAR Info; + USHORT MinBase; + USHORT MaxBase; + USHORT Align; + USHORT Length; + + Info = *Ptr; + Ptr++; + + MinBase = *Ptr; + Ptr++; + MinBase += (*Ptr << 8); + Ptr++; + + MaxBase = *Ptr; + Ptr++; + MaxBase += (*Ptr << 8); + Ptr++; + + Align = *Ptr; + Ptr++; + Align += (*Ptr << 8); + Ptr++; + + Length = *Ptr; + Ptr++; + Length += (*Ptr << 8); + + printf(" 16-Bit memory range descriptor\n"); + printf(" MinBase 0x%hx MaxBase 0x%hx Align 0x%hx Length 0x%hx Flags 0x%02x\n", + MinBase, MaxBase, Align,Length, Info); +} + + +static VOID +PnpDecodeMemory32(char *Ptr) +{ + USHORT DescLength; + UCHAR Info; + ULONG MinBase; + ULONG MaxBase; + ULONG Align; + ULONG Length; + + Info = *Ptr; + Ptr++; + + MinBase = *Ptr; + Ptr++; + MinBase += (*Ptr << 8); + Ptr++; + MinBase += (*Ptr << 16); + Ptr++; + MinBase += (*Ptr << 24); + Ptr++; + + MaxBase = *Ptr; + Ptr++; + MaxBase += (*Ptr << 8); + Ptr++; + MaxBase += (*Ptr << 16); + Ptr++; + MaxBase += (*Ptr << 24); + Ptr++; + + Align = *Ptr; + Ptr++; + Align += (*Ptr << 8); + Ptr++; + Align += (*Ptr << 16); + Ptr++; + Align += (*Ptr << 24); + Ptr++; + + Length = *Ptr; + Ptr++; + Length += (*Ptr << 8); + Ptr++; + Length += (*Ptr << 16); + Ptr++; + Length += (*Ptr << 24); + + printf(" 32-Bit memory range descriptor\n"); + printf(" MinBase 0x%lx MaxBase 0x%lx Align 0x%lx Length 0x%lx Flags 0x%02x\n", + MinBase, MaxBase, Align,Length, Info); +} + + +static VOID +PnpDecodeFixedMemory(char *Ptr) +{ + USHORT DescLength; + UCHAR Info; + ULONG Base; + ULONG Length; + + Info = *Ptr; + Ptr++; + + Base = *Ptr; + Ptr++; + Base += (*Ptr << 8); + Ptr++; + Base += (*Ptr << 16); + Ptr++; + Base += (*Ptr << 24); + Ptr++; + + Length = *Ptr; + Ptr++; + Length += (*Ptr << 8); + Ptr++; + Length += (*Ptr << 16); + Ptr++; + Length += (*Ptr << 24); + + printf(" 32-Bit fixed location memory range descriptor\n"); + printf(" Base 0x%lx Length 0x%lx Flags 0x%02x\n", + Base, Length, Info); +} + + +void PrintDeviceData (PCM_PNP_BIOS_DEVICE_NODE DeviceNode) +{ + char PnpId[8]; + char *Ptr; + unsigned int TagSize; + unsigned int TagType; + + char Id[4]; + + printf ("Node: %x Size %hu (0x%hx)\n", + DeviceNode->Node, + DeviceNode->Size, + DeviceNode->Size); + + memcpy(Id, &DeviceNode->ProductId, 4); + + PnpId[0] = ((Id[0] >> 2) & 0x1F) + 0x40; + PnpId[1] = ((Id[0] << 3) & 0x18) + + ((Id[1] >> 5) & 0x07) + 0x40; + PnpId[2] = (Id[1] & 0x1F) + 0x40; + + PnpId[3] = Hex[(Id[2] >> 4) & 0xF]; + PnpId[4] = Hex[Id[2] & 0x0F]; + + PnpId[5] = Hex[(Id[3] >> 4) & 0x0F]; + PnpId[6] = Hex[Id[3] & 0x0F]; + PnpId[7] = 0; + + printf(" '%s'\n", + PnpId); + + if (DeviceNode->Size > sizeof(CM_PNP_BIOS_DEVICE_NODE)) + { + Ptr = (char *)(DeviceNode + 1); + while (TRUE) + { + if (*Ptr & 0x80) + { + TagType = *Ptr & 0x7F; + Ptr++; + TagSize = *Ptr; + Ptr++; + TagSize += (*Ptr << 16); + Ptr++; + + + switch (TagType) + { + case 1: + PnpDecodeMemory16(Ptr); + break; + + case 5: + PnpDecodeMemory32(Ptr); + break; + + case 6: + PnpDecodeFixedMemory(Ptr); + break; + + default: + printf(" Large tag: type %u size %u\n", + TagType, + TagSize); + break; + } + } + else + { + TagType = (*Ptr >> 3) & 0x0F; + TagSize = *Ptr & 0x07; + Ptr++; + + switch (TagType) + { + case 2: + printf(" Logical device ID\n"); + break; + + case 3: + printf(" Compatible device ID\n"); + break; + + case 4: + PnpDecodeIrq(Ptr); + break; + + case 5: + PnpDecodeDma(Ptr); + break; + + case 8: + PnpDecodeIoPort(Ptr); + break; + + case 9: + PnpDecodeFixedIoPort(Ptr); + break; + + case 0x0F: /* end tag */ + break; + + default: + printf(" Small tag: type %u size %u\n", + TagType, + TagSize); + break; + } + + /* end tag */ + if (TagType == 0x0F) + break; + } + + Ptr = Ptr + TagSize; + } + } +} + + +int main (int argc, char *argv[]) +{ + LONG lError; + HKEY hPnpKey; + DWORD dwType; + DWORD dwSize; + DWORD i; + PCM_FULL_RESOURCE_DESCRIPTOR lpBuffer; + PCM_PNP_BIOS_INSTALLATION_CHECK lpPnpInst; + PCM_PNP_BIOS_DEVICE_NODE lpDevNode; + + DWORD dwDataSize, dwResourceSize; + + hPnpKey = 0; + + lError = GetPnpKey(&hPnpKey); + if (lError != ERROR_SUCCESS) + { + printf("Failed to get PnP-BIOS key\n"); + return 0; + } + + if (hPnpKey != 0) + { + printf("Found PnP-BIOS key\n"); + } + + /* Allocate buffer */ + dwSize = 1024; + lpBuffer = malloc(dwSize); + + lError = RegQueryValueEx(hPnpKey, + "Configuration Data", + NULL, + &dwType, + (LPSTR)lpBuffer, + &dwSize); + if (lError != ERROR_SUCCESS) + { + if (lError == ERROR_MORE_DATA) + { + printf("Need to resize buffer to %lu\n", dwSize); + + } + + printf("Failed to read 'Configuration Data' value\n"); + free (lpBuffer); + RegCloseKey(hPnpKey); + return 0; + } + +// printf ("Data size: %lu\n", dwSize); + + RegCloseKey(hPnpKey); + +// printf("Resource count %lu\n", lpBuffer->PartialResourceList.Count); + + if (lpBuffer->PartialResourceList.Count == 0) + { + printf("Invalid resource count!\n"); + free (lpBuffer); + return 0; + } + +// printf("lpBuffer %p\n", lpBuffer); + + dwResourceSize = lpBuffer->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize; +// printf("ResourceSize: %lu\n", dwResourceSize); + + lpPnpInst = (PCM_PNP_BIOS_INSTALLATION_CHECK) + ((DWORD)(&lpBuffer->PartialResourceList.PartialDescriptors[0]) + + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + +// printf("lpPnpInst %p\n", lpPnpInst); + + printf("Signature '%.4s'\n", lpPnpInst->Signature); + if (strncmp(lpPnpInst->Signature, "$PnP", 4)) + { + printf("Error: Invalid PnP signature\n"); + free(lpBuffer); + return 0; + } + +// printf("InstCheck length: %lu\n", lpPnpInst->Length); + + dwDataSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK); + lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpPnpInst + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK)); + + if (lpDevNode->Size == 0) + { + printf("Error: Device node size is zero!\n"); + return 0; + } + +#if 0 + printf ("Node: %x Size %hu (0x%hx)\n", + lpDevNode->Node, + lpDevNode->Size, + lpDevNode->Size); + + printf("Done.\n"); +return 0; +#endif + + + while (dwDataSize < dwResourceSize) + { + if (lpDevNode->Size == 0) + break; + + printf ("Node: %x Size %hu (0x%hx)\n", + lpDevNode->Node, + lpDevNode->Size, + lpDevNode->Size); + + dwDataSize += lpDevNode->Size; + lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpDevNode + lpDevNode->Size); + } + + printf ("\n Press any key...\n"); + getch(); + + dwDataSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK); + lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpPnpInst + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK)); + + while (dwDataSize < dwResourceSize) + { + PrintDeviceData (lpDevNode); + + printf ("\n Press any key...\n"); + getch(); + + dwDataSize += lpDevNode->Size; + lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpDevNode + lpDevNode->Size); + } + + free (lpBuffer); + + return 0; +}