#include #include #define LOCAL static #define EXPORT /* */ typedef unsigned char UB; typedef signed char B; typedef unsigned short UH; typedef signed short H; typedef unsigned long UW; typedef signed long W; typedef unsigned int UINT; typedef signed int INT; typedef _Packed struct _pnpheader { UW signature; // +0x00 UB version; // +0x04 UB length; // +0x05 UH control_field; // +0x06 UB checksum; // +0x08 UW event_notification_flag; // +0x09 UH realmode_code_offset; // +0x0d UH realmode_code_segment; // +0x0f UH protectedmode_code_offset; // +0x11 UW protectedmode_code_segment; // +0x13 UW oem_device_identifier; // +0x17 UH realmode_data_segment; // +0x1b UW protectedmode_data_segment; // +0x1d } PnPHeader; #define PnPBIOSEntry(ptr) \ (void far *)(((UW)ptr->realmode_code_segment << 16) | \ (ptr->realmode_code_offset)); LOCAL void far *find_pnpbios(void) { UW adr; UB sum; UB far *ptr; INT i, len; for (adr = 0x000f0000; adr < 0x00100000; adr += 0x10) { ptr = (UB far *)((adr & 0x0000ffff) | ((adr & 0x000f0000) << 12)); /* check "$PnP" header */ if (*(UW far *)ptr != 0x506e5024) continue; /* check length */ len = *(ptr + 5); if (adr + len >= 0x00100000) continue; /* calc checksum */ sum = 0; for (i = 0; i < len; i++) sum += *(ptr + i); if (sum) continue; return ptr; } return NULL; } LOCAL void dump_pnpheader(PnPHeader far *ptr) { printf("[$PnP: 0x%08lx]\n", ptr); printf("Signature 0x%08lx\n", ptr->signature); printf("Version 0x%02x\n", ptr->version); printf("Length 0x%02x\n", ptr->length); printf("Control Field 0x%04x\n", ptr->control_field); printf("Checksum 0x%02x\n", ptr->checksum); printf("Event notification flag address 0x%08lx\n", ptr->event_notification_flag); printf("Real Mode 16-bit offset to entry point 0x%04x\n", ptr->realmode_code_offset); printf("Read Mode 16-bit code segment address 0x%04x\n", ptr->realmode_code_segment); printf("16-Bit Protected Mode offset to entry point 0x%04x\n", ptr->protectedmode_code_offset); printf("16-Bit Protected Mode code segment base 0x%08lx\n", ptr->protectedmode_code_segment); printf("OEM Device Identifier 0x%08lx\n", ptr->oem_device_identifier); printf("Real Mode 16-bit data segment address 0x%04x\n", ptr->realmode_data_segment); printf("16-Bit Protected Mode data segment base address 0x%08lx\n", ptr->protectedmode_data_segment); return; } /* Function 0h - Get Number of System Device Nodes */ LOCAL UH pnp00h(PnPHeader far *ptr, UB *NumNodes, UH *NodeSize) { H (__cdecl far *entry)(H Function, UB far *NumNodes, UH far *NodeSize, UH BiosSelector); UH result; entry = PnPBIOSEntry(ptr); result = (*entry)(0x00, NumNodes, NodeSize, ptr->realmode_data_segment); return result; } /* Function 40h - Get PnP ISA Configuration Structure */ LOCAL UH pnp40h(PnPHeader far *ptr, UB *Configuration) { H (__cdecl far *entry)(H Function, UB far *Configuration, UH BiosSelector); UH result; entry = PnPBIOSEntry(ptr); result = (*entry)(0x40, Configuration, ptr->realmode_data_segment); return result; } /* Function 41h - Get ESCD Info */ LOCAL UH pnp41h(PnPHeader far *ptr, UH *MinESCDWriteSize, UH *ESCDSize, UW *NVStorageBase) { H (__cdecl far *entry)(H Function, UH far *MinESCDWriteSize, UH far *ESCDSize, UW far *NVStorageBase, UH BiosSelector); UH result; entry = PnPBIOSEntry(ptr); result = (*entry)(0x41, MinESCDWriteSize, ESCDSize, NVStorageBase, ptr->realmode_data_segment); return result; } EXPORT INT main(int argc, char *argv[]) { PnPHeader far *ptr; ptr = find_pnpbios(); if (ptr == NULL) { printf("PnP Header not found\n"); goto fin0; } dump_pnpheader(ptr); { UB z; UH r, y; r = pnp00h(ptr, &z, &y); printf("%x %x %x\n", r, z, y); } fin0: return 0; }