436 lines
7.9 KiB
C
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);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|