|
|
//=================================================================
//
// Confgmgr.cpp
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
// History:
// 10/17/97 jennymc Created
//
/////////////////////////////////////////////////////////////////////////
#define INITGUID
#include "precomp.h"
#include <cregcls.h>
#include <assertbreak.h>
#include "refptr.h"
#include "poormansresource.h"
#include "resourcedesc.h"
#include "cfgmgrdevice.h"
#include "irqdesc.h"
#include "DllUtils.h"
#include "dmadesc.h"
#include <brodcast.h>
#include <lockwrap.h>
#include "strings.h"
#include <smartptr.h>
#include <devguid.h>
static CCritSec map; STRING2GUID CConfigManager::s_ClassMap; BOOL CConfigManager::s_ClassIsValid = FALSE;
CConfigManager::CConfigManager( DWORD dwTypeToGet ) { m_dwTypeToGet = dwTypeToGet;
if (!s_ClassIsValid) { CLockWrapper t_lockMap( map ) ;
// Check again now that we have the lock
if (!s_ClassIsValid) { s_ClassMap[_T("1394")] = GUID_DEVCLASS_1394; s_ClassMap[_T("ADAPTER")] = GUID_DEVCLASS_ADAPTER; s_ClassMap[_T("APMSUPPORT")] = GUID_DEVCLASS_APMSUPPORT; s_ClassMap[_T("BATTERY")] = GUID_DEVCLASS_BATTERY; s_ClassMap[_T("CDROM")] = GUID_DEVCLASS_CDROM; s_ClassMap[_T("COMPUTER")] = GUID_DEVCLASS_COMPUTER; s_ClassMap[_T("DECODER")] = GUID_DEVCLASS_DECODER; s_ClassMap[_T("DISKDRIVE")] = GUID_DEVCLASS_DISKDRIVE; s_ClassMap[_T("DISPLAY")] = GUID_DEVCLASS_DISPLAY; s_ClassMap[_T("FDC")] = GUID_DEVCLASS_FDC; s_ClassMap[_T("FLOPPYDISK")] = GUID_DEVCLASS_FLOPPYDISK; s_ClassMap[_T("GPS")] = GUID_DEVCLASS_GPS; s_ClassMap[_T("HDC")] = GUID_DEVCLASS_HDC; s_ClassMap[_T("HIDCLASS")] = GUID_DEVCLASS_HIDCLASS; s_ClassMap[_T("IMAGE")] = GUID_DEVCLASS_IMAGE; s_ClassMap[_T("INFRARED")] = GUID_DEVCLASS_INFRARED; s_ClassMap[_T("KEYBOARD")] = GUID_DEVCLASS_KEYBOARD; s_ClassMap[_T("LEGACYDRIVER")] = GUID_DEVCLASS_LEGACYDRIVER; s_ClassMap[_T("MEDIA")] = GUID_DEVCLASS_MEDIA; s_ClassMap[_T("MODEM")] = GUID_DEVCLASS_MODEM; s_ClassMap[_T("MONITOR")] = GUID_DEVCLASS_MONITOR; s_ClassMap[_T("MOUSE")] = GUID_DEVCLASS_MOUSE; s_ClassMap[_T("MTD")] = GUID_DEVCLASS_MTD; s_ClassMap[_T("MULTIFUNCTION")] = GUID_DEVCLASS_MULTIFUNCTION; s_ClassMap[_T("MULTIPORTSERIAL")] = GUID_DEVCLASS_MULTIPORTSERIAL; s_ClassMap[_T("NET")] = GUID_DEVCLASS_NET; s_ClassMap[_T("NETCLIENT")] = GUID_DEVCLASS_NETCLIENT; s_ClassMap[_T("NETSERVICE")] = GUID_DEVCLASS_NETSERVICE; s_ClassMap[_T("NETTRANS")] = GUID_DEVCLASS_NETTRANS; s_ClassMap[_T("NODRIVER")] = GUID_DEVCLASS_NODRIVER; s_ClassMap[_T("PCMCIA")] = GUID_DEVCLASS_PCMCIA; s_ClassMap[_T("PORTS")] = GUID_DEVCLASS_PORTS; s_ClassMap[_T("PRINTER")] = GUID_DEVCLASS_PRINTER; s_ClassMap[_T("PRINTERUPGRADE")] = GUID_DEVCLASS_PRINTERUPGRADE; s_ClassMap[_T("SCSIADAPTER")] = GUID_DEVCLASS_SCSIADAPTER; s_ClassMap[_T("SMARTCARDREADER")] = GUID_DEVCLASS_SMARTCARDREADER; s_ClassMap[_T("SOUND")] = GUID_DEVCLASS_SOUND; s_ClassMap[_T("SYSTEM")] = GUID_DEVCLASS_SYSTEM; s_ClassMap[_T("TAPEDRIVE")] = GUID_DEVCLASS_TAPEDRIVE; s_ClassMap[_T("UNKNOWN")] = GUID_DEVCLASS_UNKNOWN; s_ClassMap[_T("USB")] = GUID_DEVCLASS_USB; s_ClassMap[_T("VOLUME")] = GUID_DEVCLASS_VOLUME;
s_ClassIsValid = TRUE; }
}
} ////////////////////////////////////////////////////////////////////////
//
// Reads the config manager registry keys for win98 and win95
//
////////////////////////////////////////////////////////////////////////
BOOL CConfigManager::BuildListsForThisDevice(CConfigMgrDevice *pDevice) { CResourceCollection resourceList; CHString sDeviceName, sClass, sKey(_T("Enum\\")); BOOL fRc = FALSE; CRegistry RegInfo;
// Extract the device name
sDeviceName = pDevice->GetDeviceDesc(); // Pull the resource list out and enumerate it.
pDevice->GetResourceList( resourceList );
sKey += pDevice->GetHardwareKey(); if (RegInfo.Open(HKEY_LOCAL_MACHINE, sKey, KEY_READ) == ERROR_SUCCESS) { RegInfo.GetCurrentKeyValue(L"Class", sClass); }
REFPTR_POSITION pos;
if ( resourceList.BeginEnum( pos ) ){ PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor = NULL;// Watch the scoping on this guy!
DWORD dwCount = 0;
#if NTONLY >= 5
// Go find the resource descriptor for this device
CHString sRegKeyName; CRegistry Reg; CSmartBuffer Buffer; // Watch the scoping on this guy!
if ( (Reg.Open(HKEY_LOCAL_MACHINE, L"hardware\\resourcemap\\PnP Manager\\PNPManager", KEY_QUERY_VALUE) == ERROR_SUCCESS) && pDevice->GetPhysicalDeviceObjectName(sRegKeyName) ) { sRegKeyName += L".raw";
DWORD dwValueType; DWORD dwValueDataSize = Reg.GetLongestValueData() + 2 ;
Buffer = new BYTE[dwValueDataSize];
if ((LPBYTE)Buffer == NULL) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
if(RegQueryValueEx(Reg.GethKey(), sRegKeyName, NULL, &dwValueType, (LPBYTE)Buffer, &dwValueDataSize) == ERROR_SUCCESS) { if(dwValueType == REG_FULL_RESOURCE_DESCRIPTOR) { dwCount = 1 ; pFullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) (LPBYTE)Buffer ;// Watch the scoping on this guy!
} else if(dwValueType == REG_RESOURCE_LIST) { dwCount = ((PCM_RESOURCE_LIST) (LPBYTE)Buffer)->Count ; pFullDescriptor = ((PCM_RESOURCE_LIST) (LPBYTE)Buffer)->List ;// Watch the scoping on this guy!
} } } #endif
CHString sResource; //=========================================================
// For each descriptor we find, if it's not ignored,
// we should get the string data, and place it in the
// appropriate list based on Type.
//=========================================================
CResourceDescriptorPtr pResDesc; for( pResDesc.Attach(resourceList.GetNext( pos )); NULL != pResDesc; pResDesc.Attach(resourceList.GetNext( pos )) )
{ DWORD t_dwResType = pResDesc->GetResourceType();
if ( (!pResDesc->IsIgnored()) && ((m_dwTypeToGet == ResType_All) || (m_dwTypeToGet == t_dwResType) ) ) {
switch ( t_dwResType ) {
case ResType_DMA:
DMA_INFO *pDMA_Info; DMA_DES *pTmp; pDMA_Info = new DMA_INFO; if (pDMA_Info != NULL) {
try { DWORD dwChannelWidth;
pTmp = (DMA_DES*) pResDesc->GetResource(); dwChannelWidth = (pTmp->DD_Flags) & 0x0003;
pDMA_Info->ChannelWidth = 0; if( dwChannelWidth == 0 ) { pDMA_Info->ChannelWidth = 8; } else if( dwChannelWidth == 1 ) { pDMA_Info->ChannelWidth = 16; } else if( dwChannelWidth == 2 ) { pDMA_Info->ChannelWidth = 32; }
pDMA_Info->DeviceType = sClass; pDMA_Info->Channel = pTmp->DD_Alloc_Chan; pResDesc->GetOwnerDeviceID(pDMA_Info->OwnerDeviceId); pResDesc->GetOwnerName(pDMA_Info->OwnerName); pDMA_Info->OEMNumber = pResDesc->GetOEMNumber(); pDMA_Info->Port = GetDMAPort(pFullDescriptor, dwCount, pTmp->DD_Alloc_Chan); } catch ( ... ) { delete pDMA_Info; throw ; }
// real DMA channels are in the range 0-7
// sometimes the confug mugger reports channels
// with great big numbers - we don't care
if (pDMA_Info->Channel < 8) { try { m_List.Add(pDMA_Info); } catch ( ... ) { delete pDMA_Info; throw ; } } else { delete pDMA_Info; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
break;
case ResType_IRQ: IRQ_INFO *pIRQ_Info; IRQ_DES *pTmpIrq; pIRQ_Info = new IRQ_INFO;
if (pIRQ_Info != NULL) { try { pTmpIrq = (IRQ_DES*) pResDesc->GetResource();
pIRQ_Info->Shareable = pTmpIrq->IRQD_Flags; pIRQ_Info->IRQNumber = pTmpIrq->IRQD_Alloc_Num; // Allocated IRQ number
pIRQ_Info->DeviceType = sClass; pResDesc->GetOwnerDeviceID(pIRQ_Info->OwnerDeviceId); pResDesc->GetOwnerName(pIRQ_Info->OwnerName); pIRQ_Info->OEMNumber = pResDesc->GetOEMNumber(); pIRQ_Info->Vector = GetIRQVector(pFullDescriptor, dwCount, pTmpIrq->IRQD_Alloc_Num);
m_List.Add(pIRQ_Info); } catch ( ... ) { delete pIRQ_Info; throw ; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
break;
case ResType_IO: IO_INFO *pIO_Info; IOWBEM_DES *pTmpIO; pIO_Info = new IO_INFO;
if (pIO_Info != NULL) { try {
pTmpIO = (IOWBEM_DES*) pResDesc->GetResource();
pIO_Info->DeviceType = sClass; pIO_Info->StartingAddress = pTmpIO->IOD_Alloc_Base; pIO_Info->EndingAddress = pTmpIO->IOD_Alloc_End; pIO_Info->Alias = pTmpIO->IOD_Alloc_Alias; pIO_Info->Decode = pTmpIO->IOD_Alloc_Decode; pResDesc->GetOwnerName(pIO_Info->OwnerName); m_List.Add(pIO_Info); } catch ( ... ) { delete pIO_Info; throw ; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
break;
case ResType_Mem: MEM_INFO *pMem_Info; MEM_DES *pTmpMem; pMem_Info = new MEM_INFO;
if (pMem_Info != NULL) { try { pTmpMem = (MEM_DES*) pResDesc->GetResource();
pMem_Info->DeviceType = sClass; pMem_Info->StartingAddress = pTmpMem->MD_Alloc_Base; pMem_Info->EndingAddress = pTmpMem->MD_Alloc_End; pResDesc->GetOwnerName(pMem_Info->OwnerName); pMem_Info->MemoryType = GetMemoryType(pFullDescriptor, dwCount, pTmpMem->MD_Alloc_Base);
m_List.Add(pMem_Info); } catch ( ... ) { delete pMem_Info; throw ; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
break;
} // SWITCH
} // IF !IsIgnored
} // For EnumResources
resourceList.EndEnum();
} // IF BeginEnum()
return fRc; } ////////////////////////////////////////////////////////////////////////
void CConfigManager::ResetList() { IO_INFO *pIOInfo; IRQ_INFO *pIRQInfo; DMA_INFO *pDMAInfo; MEM_INFO *pMemInfo;
int nNum = m_List.GetSize();
for( int i=0; i < nNum; i++ ){ switch (m_dwTypeToGet) {
case ResType_DMA: pDMAInfo = ( DMA_INFO *) m_List.GetAt(i); delete pDMAInfo; break;
case ResType_IRQ: pIRQInfo = ( IRQ_INFO *) m_List.GetAt(i); delete pIRQInfo; break;
case ResType_IO: pIOInfo = ( IO_INFO *) m_List.GetAt(i); delete pIOInfo; break;
case ResType_Mem: pMemInfo = ( MEM_INFO *) m_List.GetAt(i); delete pMemInfo; break;
default: ASSERT_BREAK(0); break; } } m_List.RemoveAll(); } ////////////////////////////////////////////////////////////////////////
BOOL CConfigManager::RefreshList() { BOOL bRc = FALSE; //===========================================================
// Reset lists
//===========================================================
ResetList();
// Get all the available devices and check each of them for resources used
CDeviceCollection deviceList;
if ( GetDeviceList( deviceList ) ) { REFPTR_POSITION pos;
if ( deviceList.BeginEnum( pos ) ) {
CConfigMgrDevicePtr pDevice;
for ( pDevice.Attach(deviceList.GetNext( pos )) ; pDevice != NULL; pDevice.Attach(deviceList.GetNext( pos ))) { BuildListsForThisDevice(pDevice); }
// For every begin, there is an End
deviceList.EndEnum();
} // BeginEnum
bRc = TRUE; }
return bRc;
/*
//===========================================================
// Enumerate all
//===========================================================
CRegistry Reg; CHString sDevice;
if( ERROR_SUCCESS == Reg.OpenAndEnumerateSubKeys(HKEY_DYN_DATA, "Config Manager\\Enum", KEY_READ )){
while( ERROR_SUCCESS == Reg.GetCurrentSubKeyName(sDevice) ){
//===========================================================
// Since we're keeping back pointers to the Device Object,
// new him, rather than keeping him on the stack so we're
// not dependent on the order of destruction as to how
// safe we are.
//===========================================================
CConfigMgrDevice *pDevice = new CConfigMgrDevice(sDevice,m_dwTypeToGet); if ( NULL != pDevice ){ if( !BuildListsForThisDevice(pDevice) ){ // We're done with this pointer
delete pDevice; } // otherwise ptr is deleted after device is added to list
} // IF NULL != pDevice
bRc = TRUE; if( Reg.NextSubKey() != ERROR_SUCCESS ){ break; }
} } return bRc; */ }
// valid properties for filtering
//#define CM_DRP_DEVICEDESC (0x00000001) // DeviceDesc REG_SZ property (RW)
//#define CM_DRP_SERVICE (0x00000005) // Service REG_SZ property (RW)
//#define CM_DRP_CLASS (0x00000008) // Class REG_SZ property (RW)
//#define CM_DRP_CLASSGUID (0x00000009) // ClassGUID REG_SZ property (RW)
//#define CM_DRP_DRIVER (0x0000000A) // Driver REG_SZ property (RW)
//#define CM_DRP_MFG (0x0000000C) // Mfg REG_SZ property (RW)
//#define CM_DRP_FRIENDLYNAME (0x0000000D) // FriendlyName REG_SZ property (RW)
//#define CM_DRP_LOCATION_INFORMATION (0x0000000E) // LocationInformation REG_SZ property (RW)
//#define CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME (0x0000000F) // PhysicalDeviceObjectName REG_SZ property (R)
//#define CM_DRP_MIN (0x00000001)
//#define CM_DRP_MAX (0x00000017)
BOOL CConfigManager::GetDeviceList( CDeviceCollection& deviceList, LPCWSTR pszFilter/*=NULL*/, ULONG ulProperty/*=CM_DRP_MAX*/ ) { CONFIGRET cr = CR_INVALID_POINTER;
// Dump the list first
deviceList.Empty();
DEVNODE dnRoot; CConfigMgrAPI* t_pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ; try { if ( t_pconfigmgr ) { if ( t_pconfigmgr->IsValid () ) { if ( CR_SUCCESS == ( cr = t_pconfigmgr->CM_Locate_DevNode( &dnRoot, NULL, 0 ) ) ) { DEVNODE dnFirst; if ( CR_SUCCESS == ( cr = t_pconfigmgr->CM_Get_Child( &dnFirst, dnRoot, 0 ) ) ) { // This should only fail in case we are unable to allocate a device
if ( !WalkDeviceTree( dnFirst, deviceList, pszFilter, ulProperty, t_pconfigmgr ) ) { cr = CR_OUT_OF_MEMORY; } } }
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, t_pconfigmgr ) ; t_pconfigmgr = NULL ; } else { ::SetLastError ( t_pconfigmgr->GetCreationError () ); } } } catch ( ... ) { if ( t_pconfigmgr ) { CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, t_pconfigmgr ) ; t_pconfigmgr = NULL ; } throw ; }
return ( CR_SUCCESS == cr ); }
// This device MUST be Released!
BOOL CConfigManager::LocateDevice( LPCWSTR pszDeviceID, CConfigMgrDevicePtr & pCfgMgrDevice ) { CONFIGRET cr = CR_INVALID_POINTER;
if ( (pszDeviceID != NULL) && (pszDeviceID[0] != L'\0') ) { CConfigMgrAPI* t_pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ; try { if ( t_pconfigmgr ) { if ( t_pconfigmgr->IsValid () ) { DEVNODE dnRoot;
if ( CR_SUCCESS == ( cr = t_pconfigmgr->CM_Locate_DevNode( &dnRoot, bstr_t(pszDeviceID), 0 ) ) ) { pCfgMgrDevice.Attach(new CConfigMgrDevice( dnRoot, m_dwTypeToGet )); }
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, t_pconfigmgr ) ; t_pconfigmgr = NULL ; } else { ::SetLastError ( t_pconfigmgr->GetCreationError () ); } } } catch ( ... ) { if ( t_pconfigmgr ) { CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, t_pconfigmgr ) ; t_pconfigmgr = NULL ; } throw ; } }
return ( CR_SUCCESS == cr ); }
BOOL CConfigManager::WalkDeviceTree( DEVNODE dn, CDeviceCollection& deviceList, LPCWSTR pszFilter, ULONG ulFilterProperty, CConfigMgrAPI *a_pconfigmgr ) { BOOL fReturn = TRUE;
// While it would make more sense to check the filter in WalkDeviceTree2,
// we can't. Config manager sometimes has a loop in its nodes. As a result,
// we need to be checking the entire list for a loop, so we need to apply
// the filter here.
if ( NULL == pszFilter) { // Load ALL the nodes
fReturn = WalkDeviceTree2(dn, deviceList, a_pconfigmgr ); } else { CDeviceCollection deviceList2; CConfigMgrDevicePtr pDevice; fReturn = WalkDeviceTree2(dn, deviceList2, a_pconfigmgr );
if (fReturn) { // Walk all the nodes looking for ones that match the filter. Copy the matches
// to the passed in array.
CHString strFilterValue; DWORD dwSize = deviceList2.GetSize(); for (int x=0; x < dwSize; x++) { pDevice.Attach(deviceList2.GetAt(x)); // Apply our filter, and save the device pointer to the list only
// if the device property value is the same as the filter.
if ( pDevice->GetStringProperty( ulFilterProperty, strFilterValue ) ) { if ( strFilterValue.CompareNoCase( pszFilter ) == 0 ) { fReturn = deviceList.Add( pDevice ); } } } } }
return fReturn; }
BOOL CConfigManager::WalkDeviceTree2( DEVNODE dn, CDeviceCollection& deviceList, CConfigMgrAPI *a_pconfigmgr )
{ BOOL fReturn = TRUE; // Assume TRUE, the only failure is where we
// beef allocating a device.
BOOL fIsLoop = FALSE; // Config manager has a bug that causes a loop in device lists<sigh>
CConfigMgrDevicePtr pDevice; // CHString strFilterValue;
DEVNODE dnSibling, dnChild;
// We're walking the list for siblings and children. Waliing for siblings
// is done in the context of the following loop, since siblings are at
// the same level in the tree. Walking for children is, of course, recursive.
do { // Store siblings, since we will proceed from it to the next
// sibling.
if ( CR_SUCCESS != a_pconfigmgr->CM_Get_Sibling( &dnSibling, dn, 0 ) ) { dnSibling = NULL; }
// Allocate a new device, and if it passes through our filter, or if
// there is no filter, go ahead and store the device in the device collection.
pDevice.Attach(new CConfigMgrDevice( dn, m_dwTypeToGet ));
if ( NULL != pDevice ) {
if (deviceList.GetSize() > CFGMGR_WORRY_SIZE) { fIsLoop = CheckForLoop(deviceList, pDevice); }
if (!fIsLoop) { // While it would make more sense to check the filter in WalkDeviceTree2,
// we can't. Config manager sometimes has a loop in its nodes. As a result,
// we need to be checking the entire list for a loop, so we need to apply
// the filter here.
fReturn = deviceList.Add( pDevice ); }
} // IF NULL != pszDevice
else { // We just beefed on memory, so bail out while the gettin's good
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
// If we have a child, we must walk recursively.
// Note that fReturn of FALSE supercedes all of this.
if ( fReturn && !fIsLoop && CR_SUCCESS == a_pconfigmgr->CM_Get_Child( &dnChild, dn, 0 ) ) { fReturn = WalkDeviceTree2( dnChild, deviceList, a_pconfigmgr ); }
// The new active node will be our sibling.
dn = dnSibling;
} while ( fReturn && NULL != dn && !fIsLoop );
return fReturn; }
// Check to see if pInDevice already exists in deviceList
BOOL CConfigManager::CheckForLoop(CDeviceCollection& deviceList, CConfigMgrDevice *pInDevice) { DWORD dwSize, x, y; BOOL bIsLoop = FALSE; CConfigMgrDevicePtr pDevice1; CConfigMgrDevicePtr pDevice2;
// Get the list size
dwSize = deviceList.GetSize()-1;
// If it is in here, it is probably close to the end, let's walk backward
for (x = dwSize; ((x > 0) && (!bIsLoop)); x--) { pDevice1.Attach(deviceList.GetAt(x));
// This compares the device nodes (see CConfigMgrDevice)
if (*pDevice1 == *pInDevice) { // Yup, there's a loop
bIsLoop = TRUE; } }
// If there is a loop, let's drop off the duplicated elements
if (bIsLoop) { // Remember, x get decremented one more time from the last loop
y = dwSize; do { pDevice1.Attach(deviceList.GetAt(x--)); pDevice2.Attach(deviceList.GetAt(y--)); } while ((*pDevice1 == *pDevice2) && (x > 0));
// Delete all the duplicate elements
y++; for (x = dwSize; x > y; x--) { deviceList.Remove(x); } }
return bIsLoop; }
BOOL CConfigManager::GetDeviceListFilterByClass( CDeviceCollection& deviceList, LPCWSTR pszFilter ) { #ifdef NTONLY
if (IsWinNT5()) { CHString sClassName(pszFilter); sClassName.MakeUpper(); WCHAR cGuid[128];
StringFromGUID2(s_ClassMap[sClassName], cGuid, sizeof(cGuid)/sizeof(WCHAR));
return GetDeviceList( deviceList, cGuid, CM_DRP_CLASSGUID ); } else { return GetDeviceList( deviceList, pszFilter, CM_DRP_CLASS ); }
#else
return GetDeviceList( deviceList, pszFilter, CM_DRP_CLASS ); #endif
}
// Given a FULL_RESOURCE_DESCRIPTOR, find the specified IRQ number, and return its vector
DWORD CConfigManager::GetIRQVector(PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor, DWORD dwFullCount, DWORD dwIRQNum) { if (NULL != pFullDescriptor) { PCM_PARTIAL_RESOURCE_LIST pPartialList ;
for (DWORD x=0; x < dwFullCount; x++) { pPartialList = &pFullDescriptor->PartialResourceList ;
for (DWORD y = 0; y < pPartialList->Count; y++) { PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor = &pPartialList->PartialDescriptors[y];
if ( (CmResourceTypeInterrupt == pDescriptor->Type) && ( pDescriptor->u.Interrupt.Level == dwIRQNum) ) { return pDescriptor->u.Interrupt.Vector; } }
pFullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) &pPartialList->PartialDescriptors[pPartialList->Count] ;
}
ASSERT_BREAK(0);
}
return 0xffffffff; }
// Given a FULL_RESOURCE_DESCRIPTOR, find the specified DMA channel, and return its port
DWORD CConfigManager::GetDMAPort(PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor, DWORD dwFullCount, DWORD dwChannel) { if (NULL != pFullDescriptor) { PCM_PARTIAL_RESOURCE_LIST pPartialList ;
for (DWORD x=0; x < dwFullCount; x++) { pPartialList = &pFullDescriptor->PartialResourceList ;
for (DWORD y = 0; y < pPartialList->Count; y++) { PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor = &pPartialList->PartialDescriptors[y];
if ( (CmResourceTypeDma == pDescriptor->Type) && ( pDescriptor->u.Dma.Channel == dwChannel) ) { return pDescriptor->u.Dma.Port; } }
pFullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) &pPartialList->PartialDescriptors[pPartialList->Count] ; }
ASSERT_BREAK(0);
}
return 0xffffffff; }
// Given a FULL_RESOURCE_DESCRIPTOR, find the specified startingaddress, and return its MemoryType
LPCWSTR CConfigManager::GetMemoryType(PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor, DWORD dwCount, ULONGLONG ulStartAddress) { if (NULL != pFullDescriptor) { PCM_PARTIAL_RESOURCE_LIST pPartialList ;
for (DWORD x=0; x < dwCount; x++) { pPartialList = &pFullDescriptor->PartialResourceList ;
for (DWORD y = 0; y < pPartialList->Count; y++) { PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor = &pPartialList->PartialDescriptors[y];
LARGE_INTEGER liTemp; // Used to avoid 64bit alignment problems
liTemp.HighPart = pDescriptor->u.Memory.Start.HighPart; liTemp.LowPart = pDescriptor->u.Memory.Start.LowPart;
if ( (CmResourceTypeMemory == pDescriptor->Type) && ( liTemp.QuadPart == ulStartAddress) ) { switch(pDescriptor->Flags) { case CM_RESOURCE_MEMORY_READ_WRITE : { return IDS_MTReadWrite; }
case CM_RESOURCE_MEMORY_READ_ONLY: { return IDS_MTReadOnly; }
case CM_RESOURCE_MEMORY_WRITE_ONLY: { return IDS_MTWriteOnly; }
case CM_RESOURCE_MEMORY_PREFETCHABLE: { return IDS_MTPrefetchable; } }
return L""; } }
pFullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) &pPartialList->PartialDescriptors[pPartialList->Count] ; }
ASSERT_BREAK(0);
}
return L""; }
|