471 lines
13 KiB
C
471 lines
13 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 (PNP0100)",
|
||
"No Pic (PNP0000)",
|
||
"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_DEVICE_PCI) {
|
||
printf("Device is PCI enumerated\n");
|
||
}
|
||
if (pData->DeviceId) {
|
||
printf("DeviceId = %X\n", pData->DeviceId);
|
||
}
|
||
if (pData->BusData) {
|
||
printf("BusData = %06X\n", pData->BusData);
|
||
}
|
||
if (pData->LegacyBaseAddress) {
|
||
printf("LegacyBase = %X\n", pData->LegacyBaseAddress);
|
||
}
|
||
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]);
|
||
} else {
|
||
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
}
|
||
|
||
|