462 lines
11 KiB
C
462 lines
11 KiB
C
|
|
|||
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1994 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
registry.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the code that dumps pccard info from the registry
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Neil Sandlin (neilsa) 11 Feb 1999
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
User mode
|
|||
|
|
|||
|
Revision History :
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "pch.h"
|
|||
|
|
|||
|
#define PCMCIA_REGISTRY_CONTROLLER_TYPE "OtherController"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DumpIrqMap(
|
|||
|
PUCHAR IRQMap
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
ULONG i;
|
|||
|
ULONG usable = 0, crossed = 0;
|
|||
|
|
|||
|
for (i = 1; i < 16; i++) {
|
|||
|
if (IRQMap[i] == i) {
|
|||
|
usable++;
|
|||
|
} else if (IRQMap[i] != 0) {
|
|||
|
crossed++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (usable == 0) {
|
|||
|
printf("NO usable IRQs found!\n");
|
|||
|
} else {
|
|||
|
if (usable == 1) {
|
|||
|
printf("1 usable IRQ found: ");
|
|||
|
} else {
|
|||
|
printf("%d usable IRQs found: ", usable);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
for (i = 1; (i < 16) && usable; i++) {
|
|||
|
if (IRQMap[i] == i) {
|
|||
|
printf("%X", i);
|
|||
|
if (--usable != 0) {
|
|||
|
printf(",");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
|
|||
|
if (crossed) {
|
|||
|
printf("Crosswired IRQs found!\n");
|
|||
|
|
|||
|
for (i = 1; (i < 16) && crossed; i++) {
|
|||
|
if (IRQMap[i] && (IRQMap[i] != i)) {
|
|||
|
printf(" %X ==> %X\n", i, IRQMap[i]);
|
|||
|
crossed--;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DumpDetectedIrqMaskData(
|
|||
|
PVOID pArgData,
|
|||
|
ULONG DataSize
|
|||
|
)
|
|||
|
{
|
|||
|
static PUCHAR ErrorStrings[] = {
|
|||
|
"Unknown",
|
|||
|
"Scan Disabled",
|
|||
|
"Map Zero",
|
|||
|
"No Timer",
|
|||
|
"No Pic",
|
|||
|
"No Legacy Base",
|
|||
|
"Dup Legacy Base",
|
|||
|
"No Controllers"
|
|||
|
};
|
|||
|
#define MAX_ERROR_CODE 7
|
|||
|
|
|||
|
|
|||
|
if (DataSize == sizeof(CM_PCCARD_DEVICE_DATA)) {
|
|||
|
PCM_PCCARD_DEVICE_DATA pData = (PCM_PCCARD_DEVICE_DATA) pArgData;
|
|||
|
printf("Version 1.0 Data\n");
|
|||
|
if (pData->Flags & PCCARD_MAP_ERROR) {
|
|||
|
UCHAR ec = pData->ErrorCode;
|
|||
|
|
|||
|
if (ec > MAX_ERROR_CODE) {
|
|||
|
ec = 0;
|
|||
|
}
|
|||
|
printf("\n*** Detection error: %s\n\n", ErrorStrings[ec]);
|
|||
|
}
|
|||
|
|
|||
|
if (pData->Flags & PCCARD_DEVICE_PCI) {
|
|||
|
printf("Device is PCI enumerated\n");
|
|||
|
} else {
|
|||
|
printf("Device is legacy detected\n");
|
|||
|
}
|
|||
|
printf("DeviceId = %X\n", pData->DeviceId);
|
|||
|
printf("LegacyBase = %X\n", pData->LegacyBaseAddress);
|
|||
|
DumpIrqMap(pData->IRQMap);
|
|||
|
|
|||
|
} else if (DataSize == sizeof(OLD_PCCARD_DEVICE_DATA)) {
|
|||
|
POLD_PCCARD_DEVICE_DATA pData = (POLD_PCCARD_DEVICE_DATA) pArgData;
|
|||
|
printf("Version 0.9 Data\n");
|
|||
|
printf("DeviceId = %X\n", pData->DeviceId);
|
|||
|
printf("LegacyBase = %X\n", pData->LegacyBaseAddress);
|
|||
|
DumpIrqMap(pData->IRQMap);
|
|||
|
|
|||
|
} else {
|
|||
|
printf("Error: unrecognized data size\n");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DumpPcCardKey(
|
|||
|
HKEY handlePcCard
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine looks through the OtherController key for pccard entries
|
|||
|
created by NTDETECT. For each entry, the IRQ scan data is read in and
|
|||
|
saved for later.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
handlePcCard - open handle to "OtherController" key in registry at
|
|||
|
HARDWARE\Description\System\MultifunctionAdapter\<ISA>
|
|||
|
|
|||
|
Return value:
|
|||
|
|
|||
|
status
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
#define VALUE2_BUFFER_SIZE sizeof(CM_PCCARD_DEVICE_DATA) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR)
|
|||
|
UCHAR valueInfo[VALUE2_BUFFER_SIZE];
|
|||
|
ULONG valueInfoSize;
|
|||
|
ULONG DataType;
|
|||
|
|
|||
|
LONG status;
|
|||
|
LPTSTR subKeyInfo;
|
|||
|
HKEY handleSubKey = NULL;
|
|||
|
ULONG subKeyInfoSize;
|
|||
|
ULONG index;
|
|||
|
ULONG resultLength;
|
|||
|
DWORD SubKeys;
|
|||
|
BOOLEAN FoundPcCard = FALSE;
|
|||
|
|
|||
|
status = RegQueryInfoKey(handlePcCard,
|
|||
|
NULL, NULL, 0,
|
|||
|
&SubKeys,
|
|||
|
&subKeyInfoSize,
|
|||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
|||
|
|
|||
|
if ((status != ERROR_SUCCESS) &&
|
|||
|
(status != ERROR_MORE_DATA) &&
|
|||
|
(status != ERROR_INSUFFICIENT_BUFFER)) {
|
|||
|
printf("Error: unable to query info on PcCardKey\n");
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
subKeyInfo = malloc(subKeyInfoSize+1);
|
|||
|
|
|||
|
if (!subKeyInfo) {
|
|||
|
printf("Error: unable to malloc subKeyInfo (%d)\n", subKeyInfoSize+1);
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
for (index=0; index < SubKeys; index++) {
|
|||
|
|
|||
|
//
|
|||
|
// Loop through the children of the PcCardController key
|
|||
|
//
|
|||
|
status = RegEnumKey(handlePcCard,
|
|||
|
index,
|
|||
|
subKeyInfo,
|
|||
|
subKeyInfoSize+1);
|
|||
|
|
|||
|
if (status != NO_ERROR) {
|
|||
|
if (!FoundPcCard) {
|
|||
|
printf("\nError: unable to find pccard detection key\n\n");
|
|||
|
}
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
if (handleSubKey) {
|
|||
|
// close handle from previous iteration
|
|||
|
RegCloseKey(handleSubKey);
|
|||
|
handleSubKey = NULL;
|
|||
|
}
|
|||
|
|
|||
|
status = RegOpenKeyEx(handlePcCard,
|
|||
|
subKeyInfo,
|
|||
|
0,
|
|||
|
KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
|
|||
|
&handleSubKey);
|
|||
|
|
|||
|
if (status != NO_ERROR) {
|
|||
|
printf("Error: unable to open enumerated key %s (%d)\n", subKeyInfo, status);
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get the value of "Identifier"
|
|||
|
//
|
|||
|
|
|||
|
valueInfoSize = VALUE2_BUFFER_SIZE;
|
|||
|
status = RegQueryValueEx(handleSubKey,
|
|||
|
"Identifier",
|
|||
|
0,
|
|||
|
&DataType,
|
|||
|
valueInfo,
|
|||
|
&valueInfoSize
|
|||
|
);
|
|||
|
|
|||
|
if (status == NO_ERROR) {
|
|||
|
|
|||
|
if ((valueInfoSize == 17) &&
|
|||
|
(valueInfo[0] == 'P') &&
|
|||
|
(valueInfo[1] == 'c') &&
|
|||
|
(valueInfo[2] == 'C') &&
|
|||
|
(valueInfo[3] == 'a') &&
|
|||
|
(valueInfo[4] == 'r') &&
|
|||
|
(valueInfo[5] == 'd')) {
|
|||
|
|
|||
|
FoundPcCard = TRUE;
|
|||
|
//
|
|||
|
// Get the IRQ detection data
|
|||
|
//
|
|||
|
valueInfoSize = VALUE2_BUFFER_SIZE;
|
|||
|
status = RegQueryValueEx(handleSubKey,
|
|||
|
"Configuration Data",
|
|||
|
0,
|
|||
|
&DataType,
|
|||
|
valueInfo,
|
|||
|
&valueInfoSize
|
|||
|
);
|
|||
|
|
|||
|
if (status == NO_ERROR) {
|
|||
|
PCM_FULL_RESOURCE_DESCRIPTOR pFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) valueInfo;
|
|||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) pFullDesc->PartialResourceList.PartialDescriptors;
|
|||
|
|
|||
|
|
|||
|
if (pPartialDesc->Type == CmResourceTypeDeviceSpecific) {
|
|||
|
printf("\n*** PcCard Irq Detection Data:%s ***\n\n", subKeyInfo);
|
|||
|
|
|||
|
DumpDetectedIrqMaskData((PVOID)((ULONG_PTR)&pPartialDesc->u.DeviceSpecificData + 3*sizeof(ULONG)),
|
|||
|
pPartialDesc->u.DeviceSpecificData.DataSize);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
cleanup:
|
|||
|
if (handleSubKey) {
|
|||
|
RegCloseKey(handleSubKey);
|
|||
|
}
|
|||
|
|
|||
|
if (subKeyInfo) {
|
|||
|
free(subKeyInfo);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DumpIrqScanInfo(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine finds the "OtherController" entry in
|
|||
|
HARDWARE\Description\System\MultifunctionAdapter\<ISA>. This is
|
|||
|
where NTDETECT stores irq scan results.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Return value:
|
|||
|
|
|||
|
status
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
#define VALUE_BUFFER_SIZE 4
|
|||
|
|
|||
|
UCHAR valueInfo[VALUE_BUFFER_SIZE];
|
|||
|
ULONG valueInfoSize;
|
|||
|
|
|||
|
HKEY handleRoot = NULL;
|
|||
|
HKEY handleSubKey = NULL;
|
|||
|
HKEY handlePcCard = NULL;
|
|||
|
LPTSTR subKeyInfo = NULL;
|
|||
|
ULONG subKeyInfoSize;
|
|||
|
LONG status;
|
|||
|
ULONG resultLength;
|
|||
|
ULONG index;
|
|||
|
ULONG DataType;
|
|||
|
DWORD SubKeys;
|
|||
|
BOOLEAN FoundIsa = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Get a handle to the MultifunctionAdapter key
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|||
|
"HARDWARE\\DESCRIPTION\\System\\MultiFunctionAdapter",
|
|||
|
0,
|
|||
|
KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
|
|||
|
&handleRoot);
|
|||
|
|
|||
|
if (status != NO_ERROR) {
|
|||
|
printf("Error: unable to open MultiFunctionAdapter key (%d)\n", status);
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
status = RegQueryInfoKey(handleRoot,
|
|||
|
NULL, NULL, 0,
|
|||
|
&SubKeys,
|
|||
|
&subKeyInfoSize,
|
|||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
|||
|
|
|||
|
if ((status != ERROR_SUCCESS) &&
|
|||
|
(status != ERROR_MORE_DATA) &&
|
|||
|
(status != ERROR_INSUFFICIENT_BUFFER)) {
|
|||
|
printf("Error: unable to query info on MultiFunctionAdapter key (%d)\n", status);
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
subKeyInfo = malloc(subKeyInfoSize+1);
|
|||
|
|
|||
|
if (!subKeyInfo) {
|
|||
|
printf("Error: unable to malloc subKeyInfo (%d)\n", subKeyInfoSize+1);
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
for (index=0; index < SubKeys; index++) {
|
|||
|
|
|||
|
//
|
|||
|
// Loop through the children of "MultifunctionAdapter"
|
|||
|
//
|
|||
|
status = RegEnumKey(handleRoot,
|
|||
|
index,
|
|||
|
subKeyInfo,
|
|||
|
subKeyInfoSize+1);
|
|||
|
|
|||
|
if (status != NO_ERROR) {
|
|||
|
if (!FoundIsa) {
|
|||
|
printf("Error: ISA key not found (%d)\n", status);
|
|||
|
}
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (handleSubKey) {
|
|||
|
// close handle from previous iteration
|
|||
|
RegCloseKey(handleSubKey);
|
|||
|
handleSubKey = NULL;
|
|||
|
}
|
|||
|
|
|||
|
status = RegOpenKeyEx(handleRoot,
|
|||
|
subKeyInfo,
|
|||
|
0,
|
|||
|
KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
|
|||
|
&handleSubKey);
|
|||
|
|
|||
|
if (status != NO_ERROR) {
|
|||
|
printf("Error: unable to open enumerated key %s (%d)\n", subKeyInfo, status);
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Get the value of "Identifier"
|
|||
|
//
|
|||
|
valueInfoSize = VALUE_BUFFER_SIZE;
|
|||
|
status = RegQueryValueEx(handleSubKey,
|
|||
|
"Identifier",
|
|||
|
0,
|
|||
|
&DataType,
|
|||
|
valueInfo,
|
|||
|
&valueInfoSize
|
|||
|
);
|
|||
|
|
|||
|
if (status == NO_ERROR) {
|
|||
|
|
|||
|
if ((valueInfoSize == 4) &&
|
|||
|
(valueInfo[0] == 'I') &&
|
|||
|
(valueInfo[1] == 'S') &&
|
|||
|
(valueInfo[2] == 'A') &&
|
|||
|
(valueInfo[3] == 0)) {
|
|||
|
|
|||
|
FoundIsa = TRUE;
|
|||
|
status = RegOpenKeyEx(handleSubKey,
|
|||
|
PCMCIA_REGISTRY_CONTROLLER_TYPE,
|
|||
|
0,
|
|||
|
KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
|
|||
|
&handlePcCard);
|
|||
|
|
|||
|
if (status == NO_ERROR) {
|
|||
|
|
|||
|
DumpPcCardKey(handlePcCard);
|
|||
|
RegCloseKey(handlePcCard);
|
|||
|
} else {
|
|||
|
printf("\nError: unable to find pccard detection data\n\n");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
cleanup:
|
|||
|
if (handleRoot) {
|
|||
|
RegCloseKey(handleRoot);
|
|||
|
}
|
|||
|
|
|||
|
if (handleSubKey) {
|
|||
|
RegCloseKey(handleSubKey);
|
|||
|
}
|
|||
|
|
|||
|
if (subKeyInfo) {
|
|||
|
free(subKeyInfo);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|