bunch of w32api fixes. ascii.h is gonecd ..! coff.h was unused and quite a few others...
[reactos.git] / reactos / apps / utils / pnpdump / pnpdump.c
1 /*
2 * pnpdump - PnP BIOS information dumper
3 */
4
5 #include <windows.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <conio.h>
10
11 #include <ddk/ntddk.h>
12
13 #include <pshpack1.h>
14
15 typedef struct _CM_PNP_BIOS_DEVICE_NODE
16 {
17 USHORT Size;
18 UCHAR Node;
19 ULONG ProductId;
20 UCHAR DeviceType[3];
21 USHORT DeviceAttributes;
22 } CM_PNP_BIOS_DEVICE_NODE,*PCM_PNP_BIOS_DEVICE_NODE;
23
24 typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK
25 {
26 UCHAR Signature[4]; // $PnP (ascii)
27 UCHAR Revision;
28 UCHAR Length;
29 USHORT ControlField;
30 UCHAR Checksum;
31 ULONG EventFlagAddress; // Physical address
32 USHORT RealModeEntryOffset;
33 USHORT RealModeEntrySegment;
34 USHORT ProtectedModeEntryOffset;
35 ULONG ProtectedModeCodeBaseAddress;
36 ULONG OemDeviceId;
37 USHORT RealModeDataBaseAddress;
38 ULONG ProtectedModeDataBaseAddress;
39 } CM_PNP_BIOS_INSTALLATION_CHECK, *PCM_PNP_BIOS_INSTALLATION_CHECK;
40
41 #include <poppack.h>
42
43 typedef struct _PNP_ID_NAME_
44 {
45 char *PnpId;
46 char *DeviceName;
47 } PNP_ID_NAME, *PPNP_ID_NAME;
48
49
50 static char Hex[] = "0123456789ABCDEF";
51
52 static PNP_ID_NAME PnpName[] =
53 {
54 /* Interrupt Controllers */
55 {"PNP0000", "AT Interrupt Controller"},
56 {"PNP0001", "EISA Interrupt Controller"},
57 {"PNP0002", "MCA Interrupt Controller"},
58 {"PNP0003", "APIC"},
59 {"PNP0004", "Cyrix SLiC MP Interrupt Controller"},
60
61 /* Timers */
62 {"PNP0100", "AT Timer"},
63 {"PNP0101", "EISA Timer"},
64 {"PNP0102", "MCA Timer"},
65
66 /* DMA Controllers */
67 {"PNP0200", "AT DMA Controller"},
68 {"PNP0201", "EISA DMA Controller"},
69 {"PNP0202", "MCA DMA Controller"},
70
71 /* Keyboards */
72 {"PNP0300", "IBM PC/XT Keyboard (83 keys)"},
73 {"PNP0301", "IBM PC/AT Keyboard (86 keys)"},
74 {"PNP0302", "IBM PC/XT Keyboard (84 keys)"},
75 {"PNP0303", "IBM Enhanced (101/102 keys)"},
76 {"PNP0304", "Olivetti Keyboard (83 keys)"},
77 {"PNP0305", "Olivetti Keyboard (102 keys)"},
78 {"PNP0306", "Olivetti Keyboard (86 keys)"},
79 {"PNP0307", "Microsoft Windows(R) Keyboard"},
80 {"PNP0308", "General Input Device Emulation Interface (GIDEI) legacy"},
81 {"PNP0309", "Olivetti Keyboard (A101/102 key)"},
82 {"PNP030A", "AT&T 302 keyboard"},
83 {"PNP030B", "Reserved by Microsoft"},
84 {"PNP0320", "Japanese 101-key keyboard"},
85 {"PNP0321", "Japanese AX keyboard"},
86 {"PNP0322", "Japanese 106-key keyboard A01"},
87 {"PNP0323", "Japanese 106-key keyboard 002/003"},
88 {"PNP0324", "Japanese 106-key keyboard 001"},
89 {"PNP0325", "Japanese Toshiba Desktop keyboard"},
90 {"PNP0326", "Japanese Toshiba Laptop keyboard"},
91 {"PNP0327", "Japanese Toshiba Notebook keyboard"},
92 {"PNP0340", "Korean 84-key keyboard"},
93 {"PNP0341", "Korean 86-key keyboard"},
94 {"PNP0342", "Korean Enhanced keyboard"},
95 {"PNP0343", "Korean Enhanced keyboard 101b"},
96 {"PNP0343", "Korean Enhanced keyboard 101c"},
97 {"PNP0344", "Korean Enhanced keyboard 103"},
98
99 /* Parallel Ports */
100 {"PNP0400", "Standard LPT printer port"},
101 {"PNP0401", "ECP printer port"},
102
103 /* Serial Ports */
104 {"PNP0500", "Standard PC COM port"},
105 {"PNP0501", "16550A-compatible COM port"},
106 {"PNP0510", "Generic IRDA-compatible port"},
107
108 /* Harddisk Controllers */
109 {"PNP0600", "Generic ESDI/ATA/IDE harddisk controller"},
110 {"PNP0601", "Plus Hardcard II"},
111 {"PNP0602", "Plus Hardcard IIXL/EZ"},
112 {"PNP0603", "Generic IDE supporting Microsoft Device Bay Specification"},
113
114 /* Floppy Controllers */
115 {"PNP0700", "PC standard floppy disk controller"},
116 {"PNP0701", "Standard floppy controller supporting MS Device Bay Specification"},
117
118 /* obsolete devices */
119 {"PNP0800", "Microsoft Sound System compatible device"},
120
121 /* Display Adapters */
122 {"PNP0900", "VGA Compatible"},
123 {"PNP0901", "Video Seven VRAM/VRAM II/1024i"},
124 {"PNP0902", "8514/A Compatible"},
125 {"PNP0903", "Trident VGA"},
126 {"PNP0904", "Cirrus Logic Laptop VGA"},
127 {"PNP0905", "Cirrus Logic VGA"},
128 {"PNP0906", "Tseng ET4000"},
129 {"PNP0907", "Western Digital VGA"},
130 {"PNP0908", "Western Digital Laptop VGA"},
131 {"PNP0909", "S3 Inc. 911/924"},
132 {"PNP090A", "ATI Ultra Pro/Plus (Mach 32)"},
133 {"PNP090B", "ATI Ultra (Mach 8)"},
134 {"PNP090C", "XGA Compatible"},
135 {"PNP090D", "ATI VGA Wonder"},
136 {"PNP090E", "Weitek P9000 Graphics Adapter"},
137 {"PNP090F", "Oak Technology VGA"},
138 {"PNP0910", "Compaq QVision"},
139 {"PNP0911", "XGA/2"},
140 {"PNP0912", "Tseng Labs W32/W32i/W32p"},
141 {"PNP0913", "S3 Inc. 801/928/964"},
142 {"PNP0914", "Cirrus Logic 5429/5434 (memory mapped)"},
143 {"PNP0915", "Compaq Advanced VGA (AVGA)"},
144 {"PNP0916", "ATI Ultra Pro Turbo (Mach64)"},
145 {"PNP0917", "Reserved by Microsoft"},
146 {"PNP0918", "Matrox MGA"},
147 {"PNP0919", "Compaq QVision 2000"},
148 {"PNP091A", "Tseng W128"},
149 {"PNP0930", "Chips & Technologies Super VGA"},
150 {"PNP0931", "Chips & Technologies Accelerator"},
151 {"PNP0940", "NCR 77c22e Super VGA"},
152 {"PNP0941", "NCR 77c32blt"},
153 {"PNP09FF", "Plug and Play Monitors (VESA DDC)"},
154
155 /* Peripheral Buses */
156 {"PNP0A00", "ISA Bus"},
157 {"PNP0A01", "EISA Bus"},
158 {"PNP0A02", "MCA Bus"},
159 {"PNP0A03", "PCI Bus"},
160 {"PNP0A04", "VESA/VL Bus"},
161 {"PNP0A05", "Generic ACPI Bus"},
162 {"PNP0A06", "Generic ACPI Extended-IO Bus (EIO bus)"},
163
164 /* System devices */
165 {"PNP0800", "AT-style speaker sound"},
166 {"PNP0B00", "AT Real-Time Clock"},
167 {"PNP0C00", "Plug and Play BIOS (only created by the root enumerator)"},
168 {"PNP0C01", "System Board"},
169 {"PNP0C02", "General Plug and Play motherboard registers."},
170 {"PNP0C03", "Plug and Play BIOS Event Notification Interrupt"},
171 {"PNP0C04", "Math Coprocessor"},
172 {"PNP0C05", "APM BIOS (Version independent)"},
173 {"PNP0C06", "Reserved for identification of early Plug and Play BIOS implementation"},
174 {"PNP0C07", "Reserved for identification of early Plug and Play BIOS implementation"},
175 {"PNP0C08", "ACPI system board hardware"},
176 {"PNP0C09", "ACPI Embedded Controller"},
177 {"PNP0C0A", "ACPI Control Method Battery"},
178 {"PNP0C0B", "ACPI Fan"},
179 {"PNP0C0C", "ACPI power button device"},
180 {"PNP0C0D", "ACPI lid device"},
181 {"PNP0C0E", "ACPI sleep button device"},
182 {"PNP0C0F", "PCI interrupt link device"},
183 {"PNP0C10", "ACPI system indicator device"},
184 {"PNP0C11", "ACPI thermal zone"},
185 {"PNP0C12", "Device Bay Controller"},
186
187 /* PCMCIA Controllers */
188 {"PNP0E00", "Intel 82365-Compatible PCMCIA Controller"},
189 {"PNP0E01", "Cirrus Logic CL-PD6720 PCMCIA Controller"},
190 {"PNP0E02", "VLSI VL82C146 PCMCIA Controller"},
191 {"PNP0E03", "Intel 82365-compatible CardBus controller"},
192
193 /* Mice */
194 {"PNP0F00", "Microsoft Bus Mouse"},
195 {"PNP0F01", "Microsoft Serial Mouse"},
196 {"PNP0F02", "Microsoft InPort Mouse"},
197 {"PNP0F03", "Microsoft PS/2-style Mouse"},
198 {"PNP0F04", "Mouse Systems Mouse"},
199 {"PNP0F05", "Mouse Systems 3-Button Mouse (COM2)"},
200 {"PNP0F06", "Genius Mouse (COM1)"},
201 {"PNP0F07", "Genius Mouse (COM2)"},
202 {"PNP0F08", "Logitech Serial Mouse"},
203 {"PNP0F09", "Microsoft BallPoint Serial Mouse"},
204 {"PNP0F0A", "Microsoft Plug and Play Mouse"},
205 {"PNP0F0B", "Microsoft Plug and Play BallPoint Mouse"},
206 {"PNP0F0C", "Microsoft-compatible Serial Mouse"},
207 {"PNP0F0D", "Microsoft-compatible InPort-compatible Mouse"},
208 {"PNP0F0E", "Microsoft-compatible PS/2-style Mouse"},
209 {"PNP0F0F", "Microsoft-compatible Serial BallPoint-compatible Mouse"},
210 {"PNP0F10", "Texas Instruments QuickPort Mouse"},
211 {"PNP0F11", "Microsoft-compatible Bus Mouse"},
212 {"PNP0F12", "Logitech PS/2-style Mouse"},
213 {"PNP0F13", "PS/2 Port for PS/2-style Mice"},
214 {"PNP0F14", "Microsoft Kids Mouse"},
215 {"PNP0F15", "Logitech bus mouse"},
216 {"PNP0F16", "Logitech SWIFT device"},
217 {"PNP0F17", "Logitech-compatible serial mouse"},
218 {"PNP0F18", "Logitech-compatible bus mouse"},
219 {"PNP0F19", "Logitech-compatible PS/2-style Mouse"},
220 {"PNP0F1A", "Logitech-compatible SWIFT Device"},
221 {"PNP0F1B", "HP Omnibook Mouse"},
222 {"PNP0F1C", "Compaq LTE Trackball PS/2-style Mouse"},
223 {"PNP0F1D", "Compaq LTE Trackball Serial Mouse"},
224 {"PNP0F1E", "Microsoft Kids Trackball Mouse"},
225 {"PNP0F1F", "Reserved by Microsoft Input Device Group"},
226 {"PNP0F20", "Reserved by Microsoft Input Device Group"},
227 {"PNP0F21", "Reserved by Microsoft Input Device Group"},
228 {"PNP0F22", "Reserved by Microsoft Input Device Group"},
229 {"PNP0F23", "Reserved by Microsoft Input Device Group"},
230 {"PNP0FFF", "Reserved by Microsoft Systems"},
231
232 /* List Terminator */
233 {NULL, NULL}
234 };
235
236
237 /* FUNCTIONS ****************************************************************/
238
239 static char *
240 GetDeviceName(char *PnpId)
241 {
242 PPNP_ID_NAME IdName;
243
244 IdName = PnpName;
245 while (IdName->PnpId != NULL)
246 {
247 if (!strcmp(IdName->PnpId, PnpId))
248 return IdName->DeviceName;
249
250 IdName++;
251 }
252
253 return "Unknown Device";
254 }
255
256
257 LONG
258 GetPnpKey(PHKEY PnpKey)
259 {
260 LONG lError;
261 char szBuffer[80];
262 HKEY hAdapterKey;
263 HKEY hBusKey;
264 DWORD dwBus;
265 DWORD dwType;
266 DWORD dwSize;
267
268 *PnpKey = 0;
269
270 lError = RegOpenKey(HKEY_LOCAL_MACHINE,
271 "HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter",
272 &hAdapterKey);
273 if (lError != ERROR_SUCCESS)
274 return 0;
275
276 /* Enumerate buses */
277 for (dwBus = 0; ; dwBus++)
278 {
279 sprintf(szBuffer, "%lu", dwBus);
280
281 lError = RegOpenKey(hAdapterKey,
282 szBuffer,
283 &hBusKey);
284 if (lError != ERROR_SUCCESS)
285 {
286 RegCloseKey(hAdapterKey);
287 return lError;
288 }
289
290 dwSize = 80;
291 lError = RegQueryValueEx(hBusKey,
292 "Identifier",
293 NULL,
294 &dwType,
295 (LPBYTE)szBuffer,
296 &dwSize);
297 if (lError != ERROR_SUCCESS)
298 {
299 RegCloseKey(hBusKey);
300 RegCloseKey(hAdapterKey);
301 return lError;
302 }
303
304 if (dwType == REG_SZ && stricmp(szBuffer, "pnp bios") == 0)
305 {
306 *PnpKey = hBusKey;
307 RegCloseKey(hAdapterKey);
308 return ERROR_SUCCESS;
309 }
310
311 RegCloseKey(hBusKey);
312 }
313
314 return 1;
315 }
316
317
318 static VOID
319 PnpDecodeIrq(unsigned char *Ptr)
320 {
321 USHORT IrqMask;
322 int i;
323
324 IrqMask = *Ptr;
325 Ptr++;
326 IrqMask |= (*Ptr << 8);
327
328 printf(" IRQs:");
329
330 for (i = 0; i < 16; i++)
331 {
332 if (IrqMask & (1 << i))
333 {
334 printf(" %u", i);
335 }
336 }
337
338 printf("\n");
339 }
340
341
342 static VOID
343 PnpDecodeDma(unsigned char *Ptr)
344 {
345 unsigned char DmaChannel;
346 unsigned char DmaStatus;
347 int i;
348
349 DmaChannel = *Ptr;
350 Ptr++;
351 DmaStatus = *Ptr;
352
353 printf(" DMAs:");
354
355 for (i = 0; i < 8; i++)
356 {
357 if (DmaChannel & (1 << i))
358 {
359 printf(" %u", i);
360 }
361 }
362
363 printf("\n");
364 }
365
366
367 static VOID
368 PnpDecodeIoPort(unsigned char *Ptr)
369 {
370 USHORT MinBase;
371 USHORT MaxBase;
372 UCHAR Align;
373 UCHAR Length;
374
375 // Info = *Ptr;
376 Ptr++;
377 MinBase = *Ptr;
378 Ptr++;
379 MinBase += (*Ptr << 8);
380 Ptr++;
381 MaxBase = *Ptr;
382 Ptr++;
383 MaxBase += (*Ptr << 8);
384 Ptr++;
385 Align = *Ptr;
386 Ptr++;
387 Length = *Ptr;
388
389 printf(" I/O Port descriptor\n");
390 printf(" MinBase 0x%x MaxBase 0x%x Align %u Length %u\n",
391 MinBase, MaxBase, Align, Length);
392 }
393
394
395 static VOID
396 PnpDecodeFixedIoPort(unsigned char *Ptr)
397 {
398 USHORT IoPort;
399 UCHAR Length;
400
401 IoPort = *Ptr;
402 Ptr++;
403 IoPort += (*Ptr << 8);
404 Ptr++;
405 Length = *Ptr;
406
407 printf(" Fixed I/O Port descriptor\n");
408 printf(" PortBase 0x%hx Length 0x%x\n",
409 IoPort, Length);
410
411 #if 0
412 if (Length == 1)
413 {
414 printf(" Fixed location I/O Port descriptor: 0x%x\n",
415 IoPort);
416 }
417 else
418 {
419 printf(" Fixed location I/O Port descriptor: 0x%x - 0x%x\n",
420 IoPort,
421 IoPort + Length - 1);
422 }
423 #endif
424 }
425
426
427 static VOID
428 PnpDecodeMemory16(unsigned char *Ptr)
429 {
430 UCHAR Info;
431 USHORT MinBase;
432 USHORT MaxBase;
433 USHORT Align;
434 USHORT Length;
435
436 Info = *Ptr;
437 Ptr++;
438
439 MinBase = *Ptr;
440 Ptr++;
441 MinBase += (*Ptr << 8);
442 Ptr++;
443
444 MaxBase = *Ptr;
445 Ptr++;
446 MaxBase += (*Ptr << 8);
447 Ptr++;
448
449 Align = *Ptr;
450 Ptr++;
451 Align += (*Ptr << 8);
452 Ptr++;
453
454 Length = *Ptr;
455 Ptr++;
456 Length += (*Ptr << 8);
457
458 printf(" 16-Bit memory range descriptor\n");
459 printf(" MinBase 0x%hx MaxBase 0x%hx Align 0x%hx Length 0x%hx Flags 0x%02x\n",
460 MinBase, MaxBase, Align,Length, Info);
461 }
462
463
464 static VOID
465 PnpDecodeMemory32(unsigned char *Ptr)
466 {
467 UCHAR Info;
468 ULONG MinBase;
469 ULONG MaxBase;
470 ULONG Align;
471 ULONG Length;
472
473 Info = *Ptr;
474 Ptr++;
475
476 MinBase = *Ptr;
477 Ptr++;
478 MinBase += (*Ptr << 8);
479 Ptr++;
480 MinBase += (*Ptr << 16);
481 Ptr++;
482 MinBase += (*Ptr << 24);
483 Ptr++;
484
485 MaxBase = *Ptr;
486 Ptr++;
487 MaxBase += (*Ptr << 8);
488 Ptr++;
489 MaxBase += (*Ptr << 16);
490 Ptr++;
491 MaxBase += (*Ptr << 24);
492 Ptr++;
493
494 Align = *Ptr;
495 Ptr++;
496 Align += (*Ptr << 8);
497 Ptr++;
498 Align += (*Ptr << 16);
499 Ptr++;
500 Align += (*Ptr << 24);
501 Ptr++;
502
503 Length = *Ptr;
504 Ptr++;
505 Length += (*Ptr << 8);
506 Ptr++;
507 Length += (*Ptr << 16);
508 Ptr++;
509 Length += (*Ptr << 24);
510
511 printf(" 32-Bit memory range descriptor\n");
512 printf(" MinBase 0x%lx MaxBase 0x%lx Align 0x%lx Length 0x%lx Flags 0x%02x\n",
513 MinBase, MaxBase, Align,Length, Info);
514 }
515
516
517 static VOID
518 PnpDecodeFixedMemory(unsigned char *Ptr)
519 {
520 UCHAR Info;
521 ULONG Base;
522 ULONG Length;
523
524 Info = *Ptr;
525 Ptr++;
526
527 Base = *Ptr;
528 Ptr++;
529 Base += (*Ptr << 8);
530 Ptr++;
531 Base += (*Ptr << 16);
532 Ptr++;
533 Base += (*Ptr << 24);
534 Ptr++;
535
536 Length = *Ptr;
537 Ptr++;
538 Length += (*Ptr << 8);
539 Ptr++;
540 Length += (*Ptr << 16);
541 Ptr++;
542 Length += (*Ptr << 24);
543
544 printf(" 32-Bit fixed location memory range descriptor\n");
545 printf(" Base 0x%lx Length 0x%lx Flags 0x%02x\n",
546 Base, Length, Info);
547 }
548
549
550 void PrintDeviceData (PCM_PNP_BIOS_DEVICE_NODE DeviceNode)
551 {
552 char PnpId[8];
553 unsigned char *Ptr;
554 unsigned int TagSize;
555 unsigned int TagType;
556
557 unsigned char Id[4];
558
559 printf ("Node: %x Size %hu (0x%hx)\n",
560 DeviceNode->Node,
561 DeviceNode->Size,
562 DeviceNode->Size);
563
564 memcpy(Id, &DeviceNode->ProductId, 4);
565
566 PnpId[0] = ((Id[0] >> 2) & 0x1F) + 0x40;
567 PnpId[1] = ((Id[0] << 3) & 0x18) +
568 ((Id[1] >> 5) & 0x07) + 0x40;
569 PnpId[2] = (Id[1] & 0x1F) + 0x40;
570
571 PnpId[3] = Hex[(Id[2] >> 4) & 0xF];
572 PnpId[4] = Hex[Id[2] & 0x0F];
573
574 PnpId[5] = Hex[(Id[3] >> 4) & 0x0F];
575 PnpId[6] = Hex[Id[3] & 0x0F];
576 PnpId[7] = 0;
577
578 printf(" '%s' (%s)\n",
579 PnpId, GetDeviceName(PnpId));
580
581 if (DeviceNode->Size > sizeof(CM_PNP_BIOS_DEVICE_NODE))
582 {
583 Ptr = (unsigned char *)(DeviceNode + 1);
584 while (TRUE)
585 {
586 if (*Ptr & 0x80)
587 {
588 TagType = *Ptr & 0x7F;
589 Ptr++;
590 TagSize = *Ptr;
591 Ptr++;
592 TagSize += (*Ptr << 16);
593 Ptr++;
594
595
596 switch (TagType)
597 {
598 case 1:
599 PnpDecodeMemory16(Ptr);
600 break;
601
602 case 5:
603 PnpDecodeMemory32(Ptr);
604 break;
605
606 case 6:
607 PnpDecodeFixedMemory(Ptr);
608 break;
609
610 default:
611 printf(" Large tag: type %u size %u\n",
612 TagType,
613 TagSize);
614 break;
615 }
616 }
617 else
618 {
619 TagType = (*Ptr >> 3) & 0x0F;
620 TagSize = *Ptr & 0x07;
621 Ptr++;
622
623 switch (TagType)
624 {
625 case 2:
626 printf(" Logical device ID\n");
627 break;
628
629 case 3:
630 printf(" Compatible device ID\n");
631 break;
632
633 case 4:
634 PnpDecodeIrq(Ptr);
635 break;
636
637 case 5:
638 PnpDecodeDma(Ptr);
639 break;
640
641 case 8:
642 PnpDecodeIoPort(Ptr);
643 break;
644
645 case 9:
646 PnpDecodeFixedIoPort(Ptr);
647 break;
648
649 case 0x0F: /* end tag */
650 break;
651
652 default:
653 printf(" Small tag: type %u size %u\n",
654 TagType,
655 TagSize);
656 break;
657 }
658
659 /* end tag */
660 if (TagType == 0x0F)
661 break;
662 }
663
664 Ptr = Ptr + TagSize;
665 }
666 }
667 }
668
669
670 int main (int argc, char *argv[])
671 {
672 LONG lError;
673 HKEY hPnpKey;
674 DWORD dwType;
675 DWORD dwSize;
676 BOOL Ask;
677 PCM_FULL_RESOURCE_DESCRIPTOR lpBuffer;
678 PCM_PNP_BIOS_INSTALLATION_CHECK lpPnpInst;
679 PCM_PNP_BIOS_DEVICE_NODE lpDevNode;
680 DWORD dwDataSize;
681 DWORD dwResourceSize;
682
683 hPnpKey = 0;
684
685 Ask = TRUE;
686 if (argc >1 && (!strcmp(argv[1],"/S") || !strcmp(argv[1],"/s")))
687 {
688 Ask = FALSE;
689 }
690
691 if (argc >1 && !strcmp(argv[1],"/?"))
692 {
693 printf("This utility prints the PnP-nodes from the registry\n");
694 printf("\"/s\" prevents the \"Press any key\"\n\n");
695 return 0;
696 }
697
698 lError = GetPnpKey(&hPnpKey);
699 if (lError != ERROR_SUCCESS)
700 {
701 printf("Failed to get PnP-BIOS key\n");
702 return 0;
703 }
704
705 if (hPnpKey != 0)
706 {
707 printf("Found PnP-BIOS key\n");
708 }
709
710 /* Allocate buffer */
711 dwSize = 2048;
712 lpBuffer = malloc(dwSize);
713 if (lpBuffer == NULL)
714 {
715 printf("Error: malloc() failed\n");
716 RegCloseKey(hPnpKey);
717 return 0;
718 }
719
720 do
721 {
722 lError = RegQueryValueEx(hPnpKey,
723 "Configuration Data",
724 NULL,
725 &dwType,
726 (LPBYTE)lpBuffer,
727 &dwSize);
728 if (lError == ERROR_MORE_DATA)
729 {
730 lpBuffer = realloc(lpBuffer, dwSize);
731 if (lpBuffer == NULL)
732 {
733 printf("Error: realloc() of %u bytes failed\n", (unsigned) dwSize);
734 RegCloseKey(hPnpKey);
735 return 0;
736 }
737 }
738 }
739 while (lError == ERROR_MORE_DATA);
740 if (lError != ERROR_SUCCESS)
741 {
742 printf("Failed to read 'Configuration Data' value\n");
743 free(lpBuffer);
744 RegCloseKey(hPnpKey);
745 return 0;
746 }
747
748 // printf ("Data size: %lu\n", dwSize);
749
750 RegCloseKey(hPnpKey);
751
752 // printf("Resource count %lu\n", lpBuffer->PartialResourceList.Count);
753
754 if (lpBuffer->PartialResourceList.Count == 0)
755 {
756 printf("Invalid resource count!\n");
757 free(lpBuffer);
758 return 0;
759 }
760
761 // printf("lpBuffer %p\n", lpBuffer);
762
763 dwResourceSize = lpBuffer->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize;
764 // printf("ResourceSize: %lu\n", dwResourceSize);
765
766 lpPnpInst = (PCM_PNP_BIOS_INSTALLATION_CHECK)
767 ((ULONG_PTR)(&lpBuffer->PartialResourceList.PartialDescriptors[0]) +
768 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
769
770 // printf("lpPnpInst %p\n", lpPnpInst);
771
772 printf("Signature '%.4s'\n", lpPnpInst->Signature);
773 if (strncmp((PCHAR)lpPnpInst->Signature, "$PnP", 4))
774 {
775 printf("Error: Invalid PnP signature\n");
776 free(lpBuffer);
777 return 0;
778 }
779
780 // printf("InstCheck length: %lu\n", lpPnpInst->Length);
781
782 dwDataSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
783 lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpPnpInst + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
784
785 if (lpDevNode->Size == 0)
786 {
787 printf("Error: Device node size is zero!\n");
788 return 0;
789 }
790
791 #if 0
792 printf("Node: %x Size %hu (0x%hx)\n",
793 lpDevNode->Node,
794 lpDevNode->Size,
795 lpDevNode->Size);
796
797 printf("Done.\n");
798 return 0;
799 #endif
800
801
802 while (dwDataSize < dwResourceSize)
803 {
804 if (lpDevNode->Size == 0)
805 break;
806
807 printf("Node: %x Size %hu (0x%hx)\n",
808 lpDevNode->Node,
809 lpDevNode->Size,
810 lpDevNode->Size);
811
812 dwDataSize += lpDevNode->Size;
813 lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpDevNode + lpDevNode->Size);
814 }
815
816 if (Ask)
817 {
818 printf("\n Press any key...\n");
819 getch();
820 }
821 else
822 {
823 printf("\n");
824 }
825
826 dwDataSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
827 lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpPnpInst + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
828
829 while (dwDataSize < dwResourceSize)
830 {
831 if (lpDevNode->Size == 0)
832 break;
833
834 PrintDeviceData(lpDevNode);
835
836 if (Ask)
837 {
838 printf("\n Press any key...\n");
839 getch();
840 }
841 else
842 {
843 printf("\n");
844 }
845
846 dwDataSize += lpDevNode->Size;
847 lpDevNode = (PCM_PNP_BIOS_DEVICE_NODE)((DWORD)lpDevNode + lpDevNode->Size);
848 }
849
850 free(lpBuffer);
851
852 return 0;
853 }
854
855 /* EOF */