/*++ 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\ 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\. 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); } }