windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/w95upg/hwcomp/resenum.c
2020-09-26 16:20:57 +08:00

436 lines
7.9 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
resenum.c
Abstract:
Win95 hardware resource enumeration routines.
Author:
Jim Schmidt (jimschm) 28-Jul-1998
Revision History:
jimschm 28-Sep-1998 Auto DMA added to resource enum
--*/
#include "pch.h"
#include <cfgmgr32.h>
BOOL
pFindDynamicValue (
IN PCTSTR DevNode,
OUT PTSTR DynamicKey
);
PBYTE
GetDevNodeResources (
IN PCTSTR DevNodeKey
)
{
PBYTE Data = NULL;
TCHAR DynDataKey[MAX_REGISTRY_KEY];
HKEY Key;
//
// Given a dev node, locate the dynamic entry
//
if (!pFindDynamicValue (DevNodeKey, DynDataKey)) {
return NULL;
}
//
// Get resource binary blob from HKEY_DYN_DATA\Config Manager\Enum\*\Allocation.
//
Key = OpenRegKeyStr (DynDataKey);
if (!Key) {
DEBUGMSG ((DBG_WHOOPS, "Can't open key: %s", DynDataKey));
return NULL;
}
Data = GetRegValueBinary (Key, S_ALLOCATION);
CloseRegKey (Key);
return Data;
}
VOID
FreeDevNodeResources (
IN PBYTE ResourceData
)
{
if (ResourceData) {
MemFree (g_hHeap, 0, ResourceData);
}
}
BOOL
pFindDynamicValue (
IN PCTSTR DevNode,
OUT PTSTR DynamicKey
)
{
REGKEY_ENUM e;
PCTSTR HardwareKey;
HKEY SubKey;
BOOL Found = FALSE;
TCHAR BaseCfgMgrKey[MAX_REGISTRY_KEY];
StringCopy (BaseCfgMgrKey, TEXT("HKDD\\"));
StringCat (BaseCfgMgrKey, S_CONFIG_MANAGER);
if (StringIMatchCharCount (TEXT("HKLM\\Enum\\"), DevNode, 10)) {
DevNode = CharCountToPointer (DevNode, 10);
} else if (StringIMatchCharCount (TEXT("HKEY_LOCAL_MACHINE\\Enum\\"), DevNode, 24)) {
DevNode = CharCountToPointer (DevNode, 24);
}
if (EnumFirstRegKeyStr (&e, BaseCfgMgrKey)) {
do {
SubKey = OpenRegKey (e.KeyHandle, e.SubKeyName);
if (!SubKey) {
DEBUGMSG ((DBG_ERROR, "Can't open subkey %s in HKDD\\Config Manager\\Enum", e.SubKeyName));
continue;
}
HardwareKey = GetRegValueString (SubKey, S_HARDWAREKEY_VALUENAME);
if (HardwareKey) {
if (StringIMatch (DevNode, HardwareKey)) {
Found = TRUE;
AbortRegKeyEnum (&e);
StringCopy (DynamicKey, BaseCfgMgrKey);
StringCopy (AppendWack (DynamicKey), e.SubKeyName);
}
MemFree (g_hHeap, 0, HardwareKey);
}
CloseRegKey (SubKey);
} while (!Found && EnumNextRegKey (&e));
}
return Found;
}
BOOL
EnumFirstDevNodeResourceEx (
OUT PDEVNODERESOURCE_ENUM EnumPtr,
IN PBYTE DevNodeResources
)
{
ZeroMemory (EnumPtr, sizeof (DEVNODERESOURCE_ENUM));
EnumPtr->Resources = DevNodeResources;
if (!DevNodeResources) {
return FALSE;
}
if (*((PDWORD) EnumPtr->Resources) != 0x0400) {
DEBUGMSG ((DBG_ERROR, "Enumeration of dev node resources, cfg mgr != v4"));
return FALSE;
}
EnumPtr->NextResource = DevNodeResources + sizeof (DWORD) * 2;
return EnumNextDevNodeResourceEx (EnumPtr);
}
BOOL
EnumNextDevNodeResourceEx (
IN OUT PDEVNODERESOURCE_ENUM EnumPtr
)
{
DWORD Len;
Len = *((PDWORD) EnumPtr->NextResource);
if (!Len) {
return FALSE;
}
EnumPtr->Resource = EnumPtr->NextResource;
EnumPtr->ResourceData = EnumPtr->Resource + sizeof (DWORD) * 2;
EnumPtr->Type = *((PDWORD) (EnumPtr->Resource + sizeof (DWORD)));
EnumPtr->NextResource += Len;
return TRUE;
}
BOOL
EnumFirstDevNodeResource (
OUT PDEVNODERESOURCE_ENUM EnumPtr,
IN PCTSTR DevNode
)
{
if (!EnumFirstDevNodeResourceEx (
EnumPtr,
GetDevNodeResources (DevNode)
)) {
FreeDevNodeResources (EnumPtr->Resources);
return FALSE;
}
return TRUE;
}
BOOL
EnumNextDevNodeResource (
IN OUT PDEVNODERESOURCE_ENUM EnumPtr
)
{
if (!EnumNextDevNodeResourceEx (EnumPtr)) {
FreeDevNodeResources (EnumPtr->Resources);
return FALSE;
}
return TRUE;
}
BOOL
pIsDisplayableType (
IN PDEVNODESTRING_ENUM EnumPtr
)
{
BOOL b = TRUE;
switch (EnumPtr->Enum.Type) {
case ResType_Mem:
break;
case ResType_IO:
break;
case ResType_DMA:
break;
case ResType_IRQ:
break;
default:
b = FALSE;
break;
}
return b;
}
VOID
pFormatMemoryResource (
IN OUT PDEVNODESTRING_ENUM EnumPtr
)
{
PMEM_RESOURCE_9X MemRes;
MemRes = (PMEM_RESOURCE_9X) EnumPtr->Enum.ResourceData;
wsprintf (
EnumPtr->Value,
TEXT("%08X - %08X"),
MemRes->MEM_Header.MD_Alloc_Base,
MemRes->MEM_Header.MD_Alloc_End
);
}
VOID
pFormatIoResource (
IN OUT PDEVNODESTRING_ENUM EnumPtr
)
{
PIO_RESOURCE_9X IoRes;
IoRes = (PIO_RESOURCE_9X) EnumPtr->Enum.ResourceData;
wsprintf (
EnumPtr->Value,
TEXT("%04X - %04X"),
IoRes->IO_Header.IOD_Alloc_Base,
IoRes->IO_Header.IOD_Alloc_End
);
}
VOID
pAddChannel (
IN OUT PTSTR String,
IN UINT Channel
)
{
if (String[0]) {
StringCat (String, TEXT(" "));
}
wsprintf (
GetEndOfString (String),
TEXT("%02X"),
Channel
);
}
VOID
pFormatDmaResource (
IN OUT PDEVNODESTRING_ENUM EnumPtr
)
{
PDMA_RESOURCE_9X DmaRes;
DWORD Bit, Channel;
PCTSTR ResText;
DmaRes = (PDMA_RESOURCE_9X) EnumPtr->Enum.ResourceData;
EnumPtr->Value[0] = 0;
Channel = 0;
for (Bit = 1 ; Bit ; Bit <<= 1) {
if (DmaRes->DMA_Bits & Bit) {
pAddChannel (EnumPtr->Value, Channel);
}
Channel++;
}
if (EnumPtr->Value[0] == 0) {
ResText = GetStringResource (MSG_AUTO_DMA);
if (ResText) { // otherwise... do nothing, I guess, since this function
// doesn't return a status value right now.
StringCopy (EnumPtr->Value, ResText);
FreeStringResource (ResText);
}
}
}
VOID
pFormatIrqResource (
IN OUT PDEVNODESTRING_ENUM EnumPtr
)
{
PIRQ_RESOURCE_9X IrqRes;
IrqRes = (PIRQ_RESOURCE_9X) EnumPtr->Enum.ResourceData;
wsprintf (
EnumPtr->Value,
TEXT("%02X"),
IrqRes->AllocNum
);
}
BOOL
pEnumDevNodeStringWorker (
IN OUT PDEVNODESTRING_ENUM EnumPtr
)
{
UINT Id = 0;
PCTSTR Name;
//
// Format each type of resource for display
//
switch (EnumPtr->Enum.Type) {
case ResType_Mem:
Id = MSG_RESTYPE_MEMORY;
pFormatMemoryResource (EnumPtr);
break;
case ResType_IO:
Id = MSG_RESTYPE_IO;
pFormatIoResource (EnumPtr);
break;
case ResType_DMA:
Id = MSG_RESTYPE_DMA;
pFormatDmaResource (EnumPtr);
break;
case ResType_IRQ:
Id = MSG_RESTYPE_IRQ;
pFormatIrqResource (EnumPtr);
break;
}
if (Id) {
Name = GetStringResource (Id);
if (Name) {
StringCopy (
EnumPtr->ResourceName,
Name
);
FreeStringResource (Name);
return TRUE;
}
}
return FALSE;
}
BOOL
EnumFirstDevNodeString (
OUT PDEVNODESTRING_ENUM EnumPtr,
IN PCTSTR DevNodeKeyStr
)
{
if (!EnumFirstDevNodeResource (&EnumPtr->Enum, DevNodeKeyStr)) {
return FALSE;
}
if (pIsDisplayableType (EnumPtr)) {
return pEnumDevNodeStringWorker (EnumPtr);
}
return EnumNextDevNodeString (EnumPtr);
}
BOOL
EnumNextDevNodeString (
IN OUT PDEVNODESTRING_ENUM EnumPtr
)
{
do {
if (!EnumNextDevNodeResource (&EnumPtr->Enum)) {
return FALSE;
}
} while (!pIsDisplayableType (EnumPtr));
return pEnumDevNodeStringWorker (EnumPtr);
}