You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3464 lines
92 KiB
3464 lines
92 KiB
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "precomp.h"
|
|
#include <assertbreak.h>
|
|
#include "poormansresource.h"
|
|
#include "resourcedesc.h"
|
|
#include "irqdesc.h"
|
|
|
|
#include <regstr.h>
|
|
#include "refptr.h"
|
|
|
|
#include "cfgmgrdevice.h"
|
|
#include "irqdesc.h"
|
|
#include "iodesc.h" // don't need this yet
|
|
#include "devdesc.h" // don't need this yet
|
|
#include "dmadesc.h"
|
|
#include <cregcls.h>
|
|
#include "nt4svctoresmap.h"
|
|
#include "chwres.h"
|
|
#include "configmgrapi.h"
|
|
#include <map>
|
|
// The Map we will use below is an STL Template, so make sure we have the std namespace
|
|
// available to us.
|
|
|
|
using namespace std;
|
|
|
|
typedef ULONG (WINAPI *CIM16GetConfigManagerStatus)(LPSTR HardwareKey);
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::CConfigMgrDevice
|
|
//
|
|
// Class Constructor.
|
|
//
|
|
// Inputs: LPCTSTR pszConfigMgrName - Name of device in config
|
|
// manager (HKEY_DYN_DATA\Config Manager\Enum
|
|
// subkey).
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CConfigMgrDevice::CConfigMgrDevice( LPCWSTR pszConfigMgrName,DWORD dwTypeToGet )
|
|
: CRefPtrLite(),
|
|
m_strConfigMgrName( pszConfigMgrName ),
|
|
m_strHardwareKey(),
|
|
m_strDeviceDesc(),
|
|
m_pbAllocationData( NULL ),
|
|
m_dwSizeAllocationData( 0 )
|
|
{
|
|
m_dwTypeToGet = dwTypeToGet;
|
|
GetConfigMgrInfo();
|
|
GetDeviceInfo();
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::CConfigMgrDevice
|
|
//
|
|
// Class Constructor.
|
|
//
|
|
// Inputs: DEVNODE m_dn - Device Node from tree
|
|
// DWORD dwResType - Resource Types to Enum
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
CConfigMgrDevice::CConfigMgrDevice( DEVNODE dn, DWORD dwResType /*=ResType_All*/ )
|
|
: CRefPtrLite(),
|
|
m_strConfigMgrName(),
|
|
m_strHardwareKey(),
|
|
m_strDeviceDesc(),
|
|
m_pbAllocationData( NULL ),
|
|
m_dwSizeAllocationData( 0 ),
|
|
m_dn( dn ),
|
|
m_dwTypeToGet( dwResType )
|
|
{
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::~CConfigMgrDevice
|
|
//
|
|
// Class Destructor.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CConfigMgrDevice::~CConfigMgrDevice( void )
|
|
{
|
|
if ( NULL != m_pbAllocationData ){
|
|
delete [] m_pbAllocationData;
|
|
m_pbAllocationData = NULL;
|
|
}
|
|
}
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This function searches for the configuration manager device name
|
|
// based on the
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
BOOL CConfigMgrDevice::MapKeyToConfigMgrDeviceName()
|
|
{
|
|
BOOL fRc = FALSE;
|
|
CRegistrySearch Search;
|
|
CHPtrArray chsaList;
|
|
CHString *pPtr;
|
|
|
|
Search.SearchAndBuildList( _T("Config Manager\\Enum"), chsaList,
|
|
m_strConfigMgrName,
|
|
_T("HardWareKey"),
|
|
VALUE_SEARCH,HKEY_DYN_DATA );
|
|
if( chsaList.GetSize() > 0 ){
|
|
|
|
pPtr = ( CHString *) chsaList.GetAt(0);
|
|
WCHAR szTmp[50];
|
|
szTmp[0] = _T('\0');
|
|
swscanf(*pPtr, L"Config Manager\\Enum\\%s", szTmp);
|
|
m_strConfigMgrName = CHString(szTmp);
|
|
fRc = TRUE;
|
|
}
|
|
Search.FreeSearchList( CSTRING_PTR, chsaList );
|
|
|
|
return fRc;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
#ifdef WIN9XONLY
|
|
DWORD CConfigMgrDevice::GetStatusFromConfigManagerDirectly(void)
|
|
{
|
|
DWORD dwStatus = 0L;
|
|
// thunk down to 16-bit to get it
|
|
CCim32NetApi *t_pCim32Api = HoldSingleCim32NetPtr::GetCim32NetApiPtr();
|
|
if( t_pCim32Api)
|
|
{
|
|
dwStatus = (t_pCim32Api->GetWin9XConfigManagerStatus)((char*)(const char*)_bstr_t(m_strHardwareKey));
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource(g_guidCim32NetApi, t_pCim32Api);
|
|
t_pCim32Api = NULL;
|
|
}
|
|
return dwStatus;
|
|
}
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This function translates the binary status code from the registry
|
|
// into the following values:
|
|
// OK, ERROR, DEGRADED, UNKNOWN
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
BOOL CConfigMgrDevice::GetStatus(CHString & chsStatus)
|
|
{
|
|
DWORD dwStatus = 0L;
|
|
BOOL fRc = FALSE;
|
|
CRegistry Reg;
|
|
CHString chsKey = CONFIGMGR_ENUM_KEY+m_strConfigMgrName;
|
|
|
|
chsStatus = IDS_STATUS_Unknown;
|
|
|
|
// Do this the old tried and true LEGACY way. Lose this code ASAP!
|
|
if ( NULL == m_dn )
|
|
{
|
|
#ifdef WIN9XONLY
|
|
{
|
|
if( !m_strHardwareKey.IsEmpty() )
|
|
{
|
|
dwStatus = GetStatusFromConfigManagerDirectly();
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef NTONLY
|
|
if( !m_strConfigMgrName.IsEmpty())
|
|
#endif
|
|
{
|
|
//===================================================
|
|
// Initialize
|
|
//===================================================
|
|
if( Reg.Open(HKEY_DYN_DATA, chsKey, KEY_READ) == ERROR_SUCCESS )
|
|
{
|
|
DWORD dwSize = 4;
|
|
Reg.GetCurrentBinaryKeyValue(CONFIGMGR_DEVICE_STATUS_VALUE, (BYTE *)&dwStatus, &dwSize);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Use the config manager to get the data for us
|
|
GetStatus( &dwStatus, NULL );
|
|
}
|
|
|
|
if( dwStatus != 0L )
|
|
{
|
|
fRc = TRUE;
|
|
//==============================================
|
|
// OK, these are wild guesses at translation,
|
|
// we may need to fiddle with these
|
|
//==============================================
|
|
if( dwStatus & DN_ROOT_ENUMERATED ||
|
|
dwStatus & DN_DRIVER_LOADED ||
|
|
dwStatus & DN_ENUM_LOADED ||
|
|
dwStatus & DN_STARTED ){
|
|
chsStatus = IDS_STATUS_OK;
|
|
}
|
|
// we don't care about these:
|
|
// DN_MANUAL,DN_NOT_FIRST_TIME,DN_HARDWARE_ENUM,DN_FILTERED
|
|
// DN_DISABLEABLE, DN_REMOVABLE,DN_MF_PARENT,DN_MF_CHILD
|
|
// DN_NEED_TO_ENUM, DN_LIAR,DN_HAS_MARK
|
|
if( dwStatus & DN_MOVED ||
|
|
dwStatus & DN_WILL_BE_REMOVED){
|
|
chsStatus = IDS_STATUS_Degraded;
|
|
}
|
|
|
|
if( dwStatus & DN_HAS_PROBLEM ||
|
|
dwStatus & DN_PRIVATE_PROBLEM){
|
|
chsStatus = IDS_STATUS_Error;
|
|
}
|
|
}
|
|
return fRc;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetConfigMgrInfo
|
|
//
|
|
// Opens the appropriate Config Manager SubKey and loads values from
|
|
// there.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: TRUE/FALSE - Did we open the subkey and get the values
|
|
// we wanted.
|
|
//
|
|
// Comments: Needs to be able to get read access to the registry.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetConfigMgrInfo( void )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
|
|
// For this to function correctly, we MUST have a value in
|
|
// m_strConfigMgrName.
|
|
|
|
|
|
if ( !m_strConfigMgrName.IsEmpty() ){
|
|
HKEY hConfigMgrKey = NULL;
|
|
|
|
CHString strKeyName( CONFIGMGR_ENUM_KEY );
|
|
|
|
// Open the config manager key
|
|
|
|
strKeyName += m_strConfigMgrName; // Don't forget to concat name Sanj, you big dummy
|
|
|
|
if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_DYN_DATA,
|
|
TOBSTRT(strKeyName),
|
|
0,
|
|
KEY_READ,
|
|
&hConfigMgrKey ) )
|
|
{
|
|
ON_BLOCK_EXIT ( RegCloseKey, hConfigMgrKey ) ;
|
|
|
|
// Get our hardware key, status and our resource allocation
|
|
if ( GetHardwareKey( hConfigMgrKey ) )
|
|
{
|
|
// Status is device status information from the registry.
|
|
if ( GetStatusInfo( hConfigMgrKey ) )
|
|
{
|
|
fReturn = GetResourceAllocation( hConfigMgrKey );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetHardwareKey
|
|
//
|
|
// Gets the Config Manager HardwareKey value.
|
|
//
|
|
// Inputs: HKEY Key - Config Manager SubKey to open.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: TRUE/FALSE - Did we get the value.
|
|
//
|
|
// Comments: Needs to be able to get read access to the registry.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetHardwareKey( HKEY hKey )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
DWORD dwSizeHardwareKeyName = 0;
|
|
|
|
|
|
// First, get the Hardware key name buffer size.
|
|
|
|
if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICE_HARDWAREKEY_VALUE,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&dwSizeHardwareKeyName ) )
|
|
{
|
|
m_strHardwareKey = L"";
|
|
|
|
// We do it this way since CHString no longer changes types with TCHAR
|
|
// LPTSTR pszBuffer = m_strHardwareKey.GetBuffer( dwSizeHardwareKeyName );
|
|
LPTSTR pszBuffer = new TCHAR[dwSizeHardwareKeyName]; //(LPTSTR) malloc(dwSizeHardwareKeyName * sizeof(TCHAR));
|
|
|
|
if ( NULL != pszBuffer )
|
|
{
|
|
|
|
try
|
|
{
|
|
// Now get the real buffer
|
|
if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICE_HARDWAREKEY_VALUE,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) pszBuffer,
|
|
&dwSizeHardwareKeyName ) )
|
|
{
|
|
fReturn = TRUE;
|
|
m_strHardwareKey = pszBuffer;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
delete [] pszBuffer;
|
|
throw ;
|
|
}
|
|
|
|
delete [] pszBuffer;
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
|
|
} // IF RegQueryValue Ex
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetResourceAllocation
|
|
//
|
|
// Gets the Config Manager Device Resource Allocation and fills
|
|
// out the resource list as appropriate.
|
|
//
|
|
// Inputs: HKEY Key - Config Manager SubKey to open.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: TRUE/FALSE - Did we get the value.
|
|
//
|
|
// Comments: Must have read access to the registry.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetResourceAllocation( HKEY hKey )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
DWORD dwSizeAllocation = 0;
|
|
|
|
|
|
// First, get the buffer size.
|
|
|
|
if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICE_ALLOCATION_VALUE,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&dwSizeAllocation ) )
|
|
{
|
|
// Initialize pbData, using a stack buffer if we can (most of the time
|
|
// this will probably suffice).
|
|
LPBYTE pbData = new BYTE[dwSizeAllocation];
|
|
// Just be safe here.
|
|
if ( NULL != pbData )
|
|
{
|
|
// Now get the real buffer
|
|
|
|
if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICE_ALLOCATION_VALUE,
|
|
0,
|
|
NULL,
|
|
pbData,
|
|
&dwSizeAllocation ) )
|
|
{
|
|
m_pbAllocationData = pbData;
|
|
m_dwSizeAllocationData = dwSizeAllocation;
|
|
fReturn = TRUE;
|
|
}
|
|
|
|
// DON'T delete the data buffer. The object destructor does it.
|
|
// delete [] pbData;
|
|
|
|
else
|
|
{
|
|
// MUST delete here though !!!
|
|
delete [] pbData;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
|
|
} // IF RegQueryValue Ex
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetStatusInfo
|
|
//
|
|
// Gets the Config Manager Device Status and Problem fields.
|
|
//
|
|
// Inputs: HKEY Key - Config Manager SubKey to open.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: TRUE/FALSE - Did we get the values.
|
|
//
|
|
// Comments: Must have read access to the registry.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetStatusInfo( HKEY hKey )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
DWORD dwBuffSize = sizeof(DWORD);
|
|
|
|
|
|
// First, get the status value, then get the problem value.
|
|
|
|
if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICE_STATUS_VALUET,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) &m_dwStatus,
|
|
&dwBuffSize ) )
|
|
{
|
|
|
|
// Now get the problem
|
|
|
|
dwBuffSize = sizeof(DWORD);
|
|
|
|
if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICE_PROBLEM_VALUE,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) &m_dwProblem,
|
|
&dwBuffSize ) ) {
|
|
fReturn = TRUE;
|
|
}
|
|
|
|
} // IF RegQueryValue Ex
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetDeviceInfo
|
|
//
|
|
// Uses the HardwareKey value to get further device information.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: TRUE/FALSE - Did we get the value(s).
|
|
//
|
|
// Comments: Needs to be able to get read access to the registry.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetDeviceInfo( void )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
|
|
// For this to function correctly, we MUST have a value in
|
|
// m_strHardwareKey
|
|
|
|
|
|
if ( !m_strHardwareKey.IsEmpty() )
|
|
{
|
|
HKEY hDeviceKey = NULL;
|
|
|
|
CHString strKeyName( LOCALMACHINE_ENUM_KEY );
|
|
|
|
// Open the config manager key
|
|
|
|
strKeyName += m_strHardwareKey; // Don't forget to concat name Sanj, you big dummy
|
|
|
|
if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
TOBSTRT(strKeyName),
|
|
0,
|
|
KEY_READ,
|
|
&hDeviceKey ) )
|
|
{
|
|
ON_BLOCK_EXIT ( RegCloseKey, hDeviceKey ) ;
|
|
|
|
fReturn = GetDeviceDesc( hDeviceKey );
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetDeviceDesc
|
|
//
|
|
// Gets the Device Description from the supplied subkey.
|
|
//
|
|
// Inputs: HKEY Key - Device SubKey to get info from.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: TRUE/FALSE - Did we get the value.
|
|
//
|
|
// Comments: If the value doesn't exist, this is not an error. We'll
|
|
// just clear the value.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetDeviceDesc( HKEY hKey )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
DWORD dwSizeDeviceName = 0;
|
|
LONG lReturn = 0L;
|
|
|
|
|
|
// First, get the DeviceDesc buffer size.
|
|
|
|
if ( ( lReturn = RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICEDESC_VALUE,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&dwSizeDeviceName ) )
|
|
== ERROR_SUCCESS )
|
|
{
|
|
//LPTSTR pszBuffer = m_strDeviceDesc.GetBuffer( dwSizeDeviceName );
|
|
LPTSTR pszBuffer = new TCHAR[dwSizeDeviceName]; //(LPTSTR) malloc(dwSizeDeviceName * sizeof(TCHAR));
|
|
|
|
m_strDeviceDesc = L"";
|
|
// Just be safe here.
|
|
|
|
if ( NULL != pszBuffer )
|
|
{
|
|
try
|
|
{
|
|
// Now get the real buffer
|
|
|
|
if ( ( lReturn = RegQueryValueEx( hKey,
|
|
CONFIGMGR_DEVICEDESC_VALUE,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) pszBuffer,
|
|
&dwSizeDeviceName ) )
|
|
== ERROR_SUCCESS )
|
|
{
|
|
fReturn = TRUE;
|
|
m_strDeviceDesc = pszBuffer;
|
|
}
|
|
else
|
|
{
|
|
fReturn = ( ERROR_FILE_NOT_FOUND == lReturn );
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
delete [] pszBuffer;
|
|
throw ;
|
|
}
|
|
|
|
//m_strDeviceDesc.ReleaseBuffer(); // Resets to string size
|
|
delete [] pszBuffer;
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
|
|
} // IF RegQueryValue Ex
|
|
else
|
|
{
|
|
fReturn = ( ERROR_FILE_NOT_FOUND == lReturn );
|
|
}
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetIRQResources
|
|
//
|
|
// Walks the device's allocated resource configuration and fills out
|
|
// an IRQ collection with IRQ Resources for this device.
|
|
//
|
|
// Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
|
|
//
|
|
// Outputs: CIRQCollection& irqList - List to populate
|
|
//
|
|
// Return: TRUE/FALSE Error occured or not (empty list
|
|
// is NOT an error).
|
|
//
|
|
// Comments: Requires READ Access to the data.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetIRQResources( CIRQCollection& irqList, CNT4ServiceToResourceMap *pResourceMap )
|
|
{
|
|
BOOL fReturn = TRUE;
|
|
CResourceCollection resourceList;
|
|
|
|
// Clear the irq list first
|
|
|
|
irqList.Empty();
|
|
|
|
// Populate the resource list first, specifying only IRQ resources, then we will
|
|
// need to Dup the data into the irq list. If we go to an AddRef/Release model, we
|
|
// will be able to copy pointers directly, saving time by not forcing us to
|
|
// alloc and realloc data.
|
|
|
|
if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_IRQ ) )
|
|
{
|
|
REFPTR_POSITION pos;
|
|
|
|
if ( resourceList.BeginEnum( pos ) )
|
|
{
|
|
|
|
CResourceDescriptorPtr pResource;
|
|
|
|
// Check each resource, validating it is an IRQ before we cast. Because
|
|
// the call to Walk should have filtered for us, these should be the
|
|
// only resources returned.
|
|
|
|
for ( pResource.Attach(resourceList.GetNext( pos )) ;
|
|
pResource != NULL && fReturn ;
|
|
pResource.Attach(resourceList.GetNext( pos )) )
|
|
{
|
|
ASSERT_BREAK( pResource->GetResourceType() == ResType_IRQ );
|
|
|
|
if ( pResource->GetResourceType() == ResType_IRQ )
|
|
{
|
|
|
|
// Cast the resource (we know the type) and add it to the
|
|
// supplied list and we're done. (Ain't AddRef/Release easy?).
|
|
|
|
CIRQDescriptor* pIRQ = (CIRQDescriptor*) pResource.GetInterfacePtr();
|
|
irqList.Add( pIRQ );
|
|
|
|
} // IF an IRQ Resource
|
|
|
|
} // WHILE retrieving descriptors
|
|
|
|
resourceList.EndEnum();
|
|
|
|
} // BeginEnum
|
|
|
|
} // IF walked list
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetIOResources
|
|
//
|
|
// Walks the device's allocated resource configuration and fills out
|
|
// an IO collection with IO Resources for this device.
|
|
//
|
|
// Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
|
|
//
|
|
// Outputs: CIOCollection& IOList - List to populate
|
|
//
|
|
// Return: TRUE/FALSE Error occured or not (empty list
|
|
// is NOT an error).
|
|
//
|
|
// Comments: Requires READ Access to the data.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetIOResources( CIOCollection& IOList, CNT4ServiceToResourceMap *pResourceMap )
|
|
{
|
|
BOOL fReturn = TRUE;
|
|
CResourceCollection resourceList;
|
|
|
|
// Clear the IO list first
|
|
|
|
IOList.Empty();
|
|
|
|
// Populate the resource list first, specifying only IO resources, then we will
|
|
// need to Dup the data into the IO list. If we go to an AddRef/Release model, we
|
|
// will be able to copy pointers directly, saving time by not forcing us to
|
|
// alloc and realloc data.
|
|
|
|
if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_IO ) )
|
|
{
|
|
REFPTR_POSITION pos;
|
|
|
|
if ( resourceList.BeginEnum( pos ) )
|
|
{
|
|
|
|
CResourceDescriptorPtr pResource;
|
|
|
|
// Check each resource, validating it is an IO before we cast. Because
|
|
// the call to Walk should have filtered for us, these should be the
|
|
// only resources returned.
|
|
|
|
for ( pResource.Attach(resourceList.GetNext( pos )) ;
|
|
pResource != NULL && fReturn ;
|
|
pResource.Attach(resourceList.GetNext( pos )) )
|
|
{
|
|
ASSERT_BREAK( pResource->GetResourceType() == ResType_IO );
|
|
|
|
if ( pResource->GetResourceType() == ResType_IO )
|
|
{
|
|
// Cast the resource (we know the type) and add it to the
|
|
// supplied list and we're done. (Ain't AddRef/Release easy?).
|
|
|
|
CIODescriptor* pIO = (CIODescriptor*) pResource.GetInterfacePtr();
|
|
IOList.Add( pIO );
|
|
|
|
} // IF an IO Resource
|
|
|
|
} // WHILE retrieving descriptors
|
|
|
|
resourceList.EndEnum();
|
|
|
|
} // BeginEnum()
|
|
|
|
} // IF walked list
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetDMAResources
|
|
//
|
|
// Walks the device's allocated resource configuration and fills out
|
|
// an DMA collection with DMA Resources for this device.
|
|
//
|
|
// Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
|
|
//
|
|
// Outputs: CDMACollection& DMAList - List to populate
|
|
//
|
|
// Return: TRUE/FALSE Error occured or not (empty list
|
|
// is NOT an error).
|
|
//
|
|
// Comments: Requires READ Access to the data.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetDMAResources( CDMACollection& DMAList, CNT4ServiceToResourceMap *pResourceMap )
|
|
{
|
|
BOOL fReturn = TRUE;
|
|
CResourceCollection resourceList;
|
|
|
|
// Clear the DMA list first
|
|
|
|
DMAList.Empty();
|
|
|
|
// Populate the resource list first, specifying only DMA resources, then we will
|
|
// need to Dup the data into the DMA list. If we go to an AddRef/Release model, we
|
|
// will be able to copy pointers directly, saving time by not forcing us to
|
|
// alloc and realloc data.
|
|
|
|
if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_DMA ) )
|
|
{
|
|
REFPTR_POSITION pos;
|
|
|
|
if ( resourceList.BeginEnum( pos ) )
|
|
{
|
|
|
|
CResourceDescriptorPtr pResource;
|
|
|
|
// Check each resource, validating it is an DMA before we cast. Because
|
|
// the call to Walk should have filtered for us, these should be the
|
|
// only resources returned.
|
|
|
|
for ( pResource.Attach(resourceList.GetNext( pos )) ;
|
|
pResource != NULL && fReturn ;
|
|
pResource.Attach(resourceList.GetNext( pos )) )
|
|
{
|
|
ASSERT_BREAK( pResource->GetResourceType() == ResType_DMA );
|
|
|
|
if ( pResource->GetResourceType() == ResType_DMA )
|
|
{
|
|
|
|
// Cast the resource (we know the type) and add it to the
|
|
// supplied list and we're done. (Ain't AddRef/Release easy?).
|
|
|
|
CDMADescriptor* pDMA = (CDMADescriptor*) pResource.GetInterfacePtr();
|
|
DMAList.Add( pDMA );
|
|
|
|
} // IF an DMA Resource
|
|
|
|
} // WHILE retrieving descriptors
|
|
|
|
resourceList.EndEnum();
|
|
|
|
} // BeginEnum
|
|
|
|
} // IF walked list
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetDeviceMemoryResources
|
|
//
|
|
// Walks the device's allocated resource configuration and fills out
|
|
// an DeviceMemory collection with DeviceMemory Resources for this device.
|
|
//
|
|
// Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
|
|
//
|
|
// Outputs: CDeviceMemoryCollection& DeviceMemoryList - List to populate
|
|
//
|
|
// Return: TRUE/FALSE Error occured or not (empty list
|
|
// is NOT an error).
|
|
//
|
|
// Comments: Requires READ Access to the data.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetDeviceMemoryResources( CDeviceMemoryCollection& DeviceMemoryList, CNT4ServiceToResourceMap *pResourceMap )
|
|
{
|
|
BOOL fReturn = TRUE;
|
|
CResourceCollection resourceList;
|
|
|
|
// Clear the DeviceMemory list first
|
|
|
|
DeviceMemoryList.Empty();
|
|
|
|
// Populate the resource list first, specifying only DeviceMemory resources, then we will
|
|
// need to Dup the data into the DeviceMemory list. If we go to an AddRef/Release model, we
|
|
// will be able to copy pointers directly, saving time by not forcing us to
|
|
// alloc and realloc data.
|
|
|
|
if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_Mem ) )
|
|
{
|
|
REFPTR_POSITION pos;
|
|
|
|
if ( resourceList.BeginEnum( pos ) )
|
|
{
|
|
|
|
CResourceDescriptorPtr pResource;
|
|
|
|
// Check each resource, validating it is an DeviceMemory before we cast. Because
|
|
// the call to Walk should have filtered for us, these should be the
|
|
// only resources returned.
|
|
|
|
for ( pResource.Attach(resourceList.GetNext( pos )) ;
|
|
pResource != NULL && fReturn ;
|
|
pResource.Attach(resourceList.GetNext( pos )) )
|
|
{
|
|
ASSERT_BREAK( pResource->GetResourceType() == ResType_Mem );
|
|
|
|
if ( pResource->GetResourceType() == ResType_Mem )
|
|
{
|
|
// Cast the resource (we know the type) and add it to the
|
|
// supplied list and we're done. (Ain't AddRef/Release easy?).
|
|
|
|
CDeviceMemoryDescriptor* pDeviceMemory = (CDeviceMemoryDescriptor*) pResource.GetInterfacePtr();;
|
|
DeviceMemoryList.Add( pDeviceMemory );
|
|
|
|
} // IF an DeviceMemory Resource
|
|
|
|
} // WHILE retrieving descriptors
|
|
|
|
resourceList.EndEnum();
|
|
|
|
} // BeginEnum
|
|
|
|
} // IF walked list
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::WalkAllocatedResources
|
|
//
|
|
// Walks the device's allocated resource configuration and fills out
|
|
// a resource collection with the appropriate data.
|
|
//
|
|
// Inputs: RESOURCEID resType - Types of resources
|
|
// to return.
|
|
// CNT4ServiceToResourceMap* pResourceMap - For NT 4.
|
|
//
|
|
// Outputs: CResourceCollection& resourceList - List to populate
|
|
//
|
|
// Return: TRUE/FALSE List found or not.
|
|
//
|
|
// Comments: Requires READ Access to the data.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::WalkAllocatedResources( CResourceCollection& resourceList, CNT4ServiceToResourceMap *pResourceMap, RESOURCEID resType )
|
|
{
|
|
LOG_CONF LogConfig;
|
|
RES_DES ResDes;
|
|
CONFIGRET cr;
|
|
BOOL fReturn = FALSE ;
|
|
|
|
// Dump the resource list first
|
|
resourceList.Empty();
|
|
|
|
// If we're on NT 4, we gotta march to the beat of a different
|
|
// drummer.
|
|
|
|
#ifdef NTONLY
|
|
if ( IsWinNT4() )
|
|
{
|
|
// Convert Resource Type from RESOURCEID to CM_RESOURCE_TYPE
|
|
|
|
fReturn = WalkAllocatedResourcesNT4( resourceList, pResourceMap, RESOURCEIDToCM_RESOURCE_TYPE( resType ) );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
#ifdef NTONLY
|
|
BOOL fIsNT5 = IsWinNT5();
|
|
#endif
|
|
|
|
// Get the allocated Logical Configuration. From there, we can iterate resource descriptors
|
|
// until we find an IRQ Descriptor.
|
|
|
|
cr = CR_NO_MORE_LOG_CONF ;
|
|
|
|
if ( (
|
|
|
|
pconfigmgr->CM_Get_First_Log_Conf( &LogConfig, m_dn, ALLOC_LOG_CONF ) == CR_SUCCESS ||
|
|
pconfigmgr->CM_Get_First_Log_Conf( &LogConfig, m_dn, BOOT_LOG_CONF ) == CR_SUCCESS
|
|
) )
|
|
{
|
|
cr = CR_SUCCESS ;
|
|
|
|
RESOURCEID resID;
|
|
|
|
// To get the first Resource Descriptor, we pass in the logical configuration.
|
|
// The config manager knows how to handle this (or at least that's what the
|
|
// ahem-"documentation" sez.
|
|
|
|
RES_DES LastResDes = LogConfig;
|
|
|
|
do
|
|
{
|
|
|
|
// Get only resources of the type we were made to retrieve
|
|
cr = pconfigmgr->CM_Get_Next_Res_Des( &ResDes, LastResDes, resType, &resID, 0 );
|
|
|
|
// Clean up the prior resource descriptor handle
|
|
if ( LastResDes != LogConfig )
|
|
{
|
|
pconfigmgr->CM_Free_Res_Des_Handle( LastResDes );
|
|
}
|
|
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
|
|
// CAUTION! On NT5, if we are doing a resource Type that is NOT ResType_All,
|
|
// the OS does not appear to fill out ResID. I guess the assumption being
|
|
// that we already know the resource type we are trying to get. HOWEVER,
|
|
// if any bits like ResType_Ignored are set, NT 5 appears to be smartly
|
|
// dropping those resources, so we'll just set resID here as if the
|
|
// call on NT 5 had done anything.
|
|
|
|
#ifdef NTONLY
|
|
if ( ResType_All != resType
|
|
&& fIsNT5 )
|
|
{
|
|
resID = resType;
|
|
}
|
|
#endif
|
|
|
|
ULONG ulDataSize = 0;
|
|
|
|
if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_Res_Des_Data_Size( &ulDataSize, ResDes, 0 ) ) )
|
|
{
|
|
ulDataSize += 10; // Pad for 10 bytes of safety
|
|
|
|
BYTE* pbData = new BYTE[ulDataSize];
|
|
|
|
if ( NULL != pbData )
|
|
{
|
|
try
|
|
{
|
|
cr = pconfigmgr->CM_Get_Res_Des_Data( ResDes, pbData, ulDataSize, 0 );
|
|
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
if ( !AddResourceToList( resID, pbData, ulDataSize, resourceList ) )
|
|
{
|
|
cr = CR_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
delete [] pbData;
|
|
throw ;
|
|
}
|
|
|
|
// We're done with the data
|
|
delete [] pbData;
|
|
|
|
} // IF NULL != pbData
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
} // IF Get Data Size
|
|
|
|
// Store the last descriptor, so we can go on to the next one.
|
|
LastResDes = ResDes;
|
|
|
|
} // If we got a descriptor
|
|
|
|
} while ( CR_SUCCESS == cr );
|
|
|
|
// If we blew out on this, we're okay, since the error means we ran out of
|
|
// resource descriptors.
|
|
|
|
if ( CR_NO_MORE_RES_DES == cr )
|
|
{
|
|
cr = CR_SUCCESS;
|
|
}
|
|
|
|
// Clean up the logical configuration handle
|
|
pconfigmgr->CM_Free_Log_Conf_Handle( LogConfig );
|
|
} // IF got alloc logconf
|
|
fReturn = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
} // else !NT 4
|
|
return fReturn;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::AddResourceToList
|
|
//
|
|
// Copies resource data as necessary, coercing from 16 to 32 bit as
|
|
// necessary, then adds the resource to the supplied list.
|
|
//
|
|
// Inputs: RESOURCEID resourceID - What resource is this?
|
|
// LPVOID pResource - The resource
|
|
// DWORD dwResourceLength - How long is it?
|
|
//
|
|
// Outputs: CResourceCollection& resourceList - List to populate
|
|
//
|
|
// Return: TRUE/FALSE Add succeeded or failed.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::AddResourceToList( RESOURCEID resourceID, LPVOID pResource, DWORD dwResourceLength, CResourceCollection& resourceList )
|
|
{
|
|
IRQ_DES irqDes;
|
|
IOWBEM_DES ioDes;
|
|
DMA_DES dmaDes;
|
|
MEM_DES memDes;
|
|
|
|
// Don't know if Config Manager will return a resource ignored value,
|
|
// so what we'll do here is check if the ignored bit is set, and for
|
|
// now, ASSERT
|
|
|
|
//ASSERT_BREAK( !(resourceID & ResType_Ignored_Bit) );
|
|
|
|
// Filter out extraneous bits
|
|
RESOURCEID resType = ( resourceID & RESOURCE_TYPE_MASK );
|
|
|
|
// Hey, I'm an optimist
|
|
BOOL fReturn = TRUE;
|
|
|
|
// Different structures for 32/16 bit CFGMGR, so if
|
|
// we ain't on WINNT, we need to coerce the data into
|
|
// a proper structure.
|
|
|
|
#ifdef WIN9XONLY
|
|
{
|
|
// We have to cheat here and coerce the data from a 16-bit
|
|
// structure into a matching 32-bit structure.
|
|
|
|
switch ( resType )
|
|
{
|
|
case ResType_IRQ:
|
|
{
|
|
IRQDes16To32( (PIRQ_DES16) pResource, &irqDes );
|
|
}
|
|
break;
|
|
|
|
case ResType_IO:
|
|
{
|
|
IODes16To32( (PIO_DES16) pResource, &ioDes );
|
|
}
|
|
break;
|
|
|
|
case ResType_DMA:
|
|
{
|
|
DMADes16To32( (PDMA_DES16) pResource, &dmaDes );
|
|
}
|
|
break;
|
|
|
|
case ResType_Mem:
|
|
{
|
|
MEMDes16To32( (PMEM_DES16) pResource, &memDes );
|
|
}
|
|
break;
|
|
|
|
} // switch ResourceID
|
|
|
|
} // IF !IsWinNT
|
|
#endif
|
|
#ifdef NTONLY
|
|
{
|
|
// Just copy the resource data into the appropriate descriptor
|
|
|
|
switch ( resType )
|
|
{
|
|
case ResType_IRQ:
|
|
{
|
|
CopyMemory( &irqDes, pResource, sizeof(IRQ_DES) );
|
|
}
|
|
break;
|
|
|
|
case ResType_IO:
|
|
{
|
|
// Because 16-bit has values 32-bit does not, we cheated and came up with our
|
|
// own structure. 32-bit values are at the top, so zero out the struct and
|
|
// trhe other values will just be ignored...yeah, that's the ticket.
|
|
|
|
ZeroMemory( &ioDes, sizeof(ioDes) );
|
|
CopyMemory( &ioDes, pResource, sizeof(IO_DES) );
|
|
}
|
|
break;
|
|
|
|
case ResType_DMA:
|
|
{
|
|
CopyMemory( &dmaDes, pResource, sizeof(DMA_DES) );
|
|
}
|
|
break;
|
|
|
|
case ResType_Mem:
|
|
{
|
|
CopyMemory( &memDes, pResource, sizeof(MEM_DES) );
|
|
}
|
|
break;
|
|
|
|
} // SWITCH ResourceId
|
|
|
|
} // else IsWinNT
|
|
#endif
|
|
|
|
CResourceDescriptorPtr pResourceDescriptor;
|
|
|
|
// Just copy the resource data into the appropriate descriptor
|
|
|
|
bool bAdd = true;
|
|
|
|
switch ( resType )
|
|
{
|
|
case ResType_IRQ:
|
|
{
|
|
pResourceDescriptor.Attach( (CResourceDescriptor*) new CIRQDescriptor( resourceID, irqDes, this ) );
|
|
}
|
|
break;
|
|
|
|
case ResType_IO:
|
|
{
|
|
bAdd = (ioDes).IOD_Alloc_End >= (ioDes).IOD_Alloc_Base;
|
|
pResourceDescriptor.Attach ( (CResourceDescriptor*) new CIODescriptor( resourceID, ioDes, this ) );
|
|
}
|
|
break;
|
|
|
|
case ResType_DMA:
|
|
{
|
|
pResourceDescriptor.Attach ( (CResourceDescriptor*) new CDMADescriptor( resourceID, dmaDes, this ) );
|
|
}
|
|
break;
|
|
|
|
case ResType_Mem:
|
|
{
|
|
pResourceDescriptor.Attach ( (CResourceDescriptor*) new CDeviceMemoryDescriptor( resourceID, memDes, this ) );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
// We don't know what it is, but make a raw one anyway
|
|
pResourceDescriptor.Attach ( new CResourceDescriptor( resourceID, pResource, dwResourceLength, this ) );
|
|
}
|
|
break;
|
|
|
|
} // SWITCH ResourceId
|
|
|
|
if (bAdd)
|
|
{
|
|
if ( NULL != pResourceDescriptor )
|
|
{
|
|
fReturn = resourceList.Add( pResourceDescriptor );
|
|
}
|
|
else
|
|
{
|
|
fReturn = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fReturn = TRUE;
|
|
}
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::WalkAllocatedResourcesNT4
|
|
//
|
|
// Because none of the logical configuration stuff in NT4 seems to
|
|
// work worth a darn, we're gonna manhandle our own data from the
|
|
// registry data under HKLM\HARDWARE\RESOURCEMAP.
|
|
//
|
|
// Inputs: CNT4ServiceToResourceMap* pResourceMap - Resource map
|
|
// to use for the walk. We create
|
|
// one if this is NULL.
|
|
// CM_RESOURCE_TYPE resType - Resource Types to return.
|
|
//
|
|
// Outputs: CResourceCollection& resourceList - List to populate
|
|
//
|
|
// Return: TRUE/FALSE List found or not.
|
|
//
|
|
// Comments: Requires READ Access to the data.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef NTONLY
|
|
BOOL CConfigMgrDevice::WalkAllocatedResourcesNT4(
|
|
CResourceCollection& resourceList,
|
|
CNT4ServiceToResourceMap *pResourceMap,
|
|
CM_RESOURCE_TYPE resType )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
CHString strServiceName;
|
|
|
|
// Allocate a map if we need one. Otherwise use the one passed in that somebody
|
|
// theoretically has cached off somewhere.
|
|
|
|
CNT4ServiceToResourceMap* pLocalMap = pResourceMap;
|
|
|
|
if ( NULL == pLocalMap )
|
|
{
|
|
pLocalMap = new CNT4ServiceToResourceMap;
|
|
}
|
|
|
|
if ( NULL != pLocalMap )
|
|
{
|
|
|
|
try
|
|
{
|
|
// Get our service name. If this succeeds, pull our resources from the reource map
|
|
if ( GetService( strServiceName ) )
|
|
{
|
|
fReturn = GetServiceResourcesNT4( strServiceName, *pLocalMap, resourceList, resType );
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( pLocalMap != pResourceMap )
|
|
{
|
|
delete pLocalMap;
|
|
}
|
|
throw ;
|
|
}
|
|
|
|
// Clean up the local map if we allocated one
|
|
if ( pLocalMap != pResourceMap )
|
|
{
|
|
delete pLocalMap;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
|
|
return fReturn;
|
|
}
|
|
#endif
|
|
|
|
#ifdef NTONLY
|
|
BOOL CConfigMgrDevice::GetServiceResourcesNT4( LPCTSTR pszServiceName, CNT4ServiceToResourceMap& resourceMap, CResourceCollection& resourceList, CM_RESOURCE_TYPE cmrtFilter/*=CmResourceTypeNull*/ )
|
|
{
|
|
BOOL fReturn = TRUE;
|
|
LPRESOURCE_DESCRIPTOR pResourceDescriptor;
|
|
|
|
// Iterate the resources, looking for matches against values we may be filtering
|
|
// for.
|
|
|
|
DWORD dwNumResources = resourceMap.NumServiceResources( pszServiceName );
|
|
|
|
for ( DWORD dwCtr = 0;
|
|
dwCtr < dwNumResources
|
|
&& fReturn;
|
|
dwCtr++ )
|
|
{
|
|
pResourceDescriptor = resourceMap.GetServiceResource( pszServiceName, dwCtr );
|
|
|
|
// Grab the resource if it's our filter, or our filter is NULL, meaning grab everything
|
|
if ( NULL != pResourceDescriptor
|
|
&& ( CmResourceTypeNull == cmrtFilter
|
|
|| cmrtFilter == pResourceDescriptor->CmResourceDescriptor.Type
|
|
)
|
|
)
|
|
{
|
|
CResourceDescriptorPtr pResource;
|
|
|
|
// Perform appropriate type coercsions, and hook the resource into the resource
|
|
/// list.
|
|
switch ( pResourceDescriptor->CmResourceDescriptor.Type )
|
|
{
|
|
case CmResourceTypeInterrupt:
|
|
{
|
|
IRQ_DES irqDes;
|
|
NT4IRQToIRQ_DES( pResourceDescriptor, &irqDes );
|
|
pResource.Attach(new CIRQDescriptor( ResType_IRQ, irqDes, this ) );
|
|
}
|
|
break;
|
|
|
|
case CmResourceTypePort:
|
|
{
|
|
IOWBEM_DES ioDes;
|
|
NT4IOToIOWBEM_DES( pResourceDescriptor, &ioDes );
|
|
pResource.Attach(new CIODescriptor( ResType_IO, ioDes, this ) );
|
|
}
|
|
break;
|
|
|
|
case CmResourceTypeMemory:
|
|
{
|
|
MEM_DES memDes;
|
|
NT4MEMToMEM_DES( pResourceDescriptor, &memDes );
|
|
pResource.Attach(new CDeviceMemoryDescriptor( ResType_Mem, memDes, this ));
|
|
}
|
|
break;
|
|
|
|
case CmResourceTypeDma:
|
|
{
|
|
DMA_DES dmaDes;
|
|
NT4DMAToDMA_DES( pResourceDescriptor, &dmaDes );
|
|
pResource.Attach(new CDMADescriptor( ResType_DMA, dmaDes, this ));
|
|
}
|
|
break;
|
|
|
|
// If it ain't one of these four, there ain't a whole heck of a
|
|
// lot we're gonna do here
|
|
}
|
|
|
|
|
|
if ( NULL != pResource )
|
|
{
|
|
fReturn = resourceList.Add( pResource );
|
|
}
|
|
else
|
|
{
|
|
// We beefed on a simple memory allocation. Get out of here.
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
} // IF resource was one we wanted to handle
|
|
|
|
} // FOR enum resources
|
|
|
|
return fReturn;
|
|
}
|
|
#endif
|
|
|
|
#ifdef NTONLY
|
|
CM_RESOURCE_TYPE CConfigMgrDevice::RESOURCEIDToCM_RESOURCE_TYPE( RESOURCEID resType )
|
|
{
|
|
CM_RESOURCE_TYPE cmResType = CmResourceTypeNull;
|
|
switch ( resType )
|
|
{
|
|
case ResType_All: cmResType = CmResourceTypeNull; break;
|
|
case ResType_IO: cmResType = CmResourceTypePort; break;
|
|
case ResType_IRQ: cmResType = CmResourceTypeInterrupt; break;
|
|
case ResType_DMA: cmResType = CmResourceTypeDma; break;
|
|
case ResType_Mem: cmResType = CmResourceTypeMemory; break;
|
|
default: cmResType = CmResourceTypeNull; break;
|
|
}
|
|
|
|
return cmResType;
|
|
}
|
|
#endif
|
|
|
|
#ifdef NTONLY
|
|
void CConfigMgrDevice::NT4IRQToIRQ_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PIRQ_DES pirqDes32 )
|
|
{
|
|
ZeroMemory( pirqDes32, sizeof(IRQ_DES) );
|
|
|
|
// 32-bit structure
|
|
//typedef struct IRQ_Des_s {
|
|
// DWORD IRQD_Count; // number of IRQ_RANGE structs in IRQ_RESOURCE
|
|
// DWORD IRQD_Type; // size (in bytes) of IRQ_RANGE (IRQType_Range)
|
|
// DWORD IRQD_Flags; // flags describing the IRQ (fIRQD flags)
|
|
// ULONG IRQD_Alloc_Num; // specifies the IRQ that was allocated
|
|
// ULONG IRQD_Affinity;
|
|
//} IRQ_DES, *PIRQ_DES;
|
|
|
|
pirqDes32->IRQD_Alloc_Num = pResourceDescriptor->CmResourceDescriptor.u.Interrupt.Level;
|
|
pirqDes32->IRQD_Affinity = pResourceDescriptor->CmResourceDescriptor.u.Interrupt.Affinity;
|
|
|
|
// We'll do our best on the flags conversion.
|
|
|
|
if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
|
|
{
|
|
pirqDes32->IRQD_Flags |= fIRQD_Share;
|
|
}
|
|
|
|
// Latched -> Edge? Have no idea, the other value in either case was Level,
|
|
// so here's a leap of faith.
|
|
|
|
if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_INTERRUPT_LATCHED )
|
|
{
|
|
pirqDes32->IRQD_Flags |= fIRQD_Edge;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef NTONLY
|
|
void CConfigMgrDevice::NT4IOToIOWBEM_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PIOWBEM_DES pioDes32 )
|
|
{
|
|
ZeroMemory( pioDes32, sizeof(IOWBEM_DES) );
|
|
|
|
// 32-bit structure
|
|
//typedef struct _IOWBEM_DES{
|
|
// DWORD IOD_Count; // number of IO_RANGE structs in IO_RESOURCE
|
|
// DWORD IOD_Type; // size (in bytes) of IO_RANGE (IOType_Range)
|
|
// DWORDLONG IOD_Alloc_Base; // base of allocated port range
|
|
// DWORDLONG IOD_Alloc_End; // end of allocated port range
|
|
// DWORD IOD_DesFlags; // flags relating to allocated port range
|
|
// BYTE IOD_Alloc_Alias; // From 16-bit-land
|
|
// BYTE IOD_Alloc_Decode; // From 16-bit-land
|
|
//} IOWBEM_DES;
|
|
|
|
LARGE_INTEGER liTemp; // Used to avoid 64bit alignment problems
|
|
|
|
liTemp.HighPart = pResourceDescriptor->CmResourceDescriptor.u.Port.Start.HighPart;
|
|
liTemp.LowPart = pResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart;
|
|
|
|
pioDes32->IOD_Alloc_Base = liTemp.QuadPart;
|
|
pioDes32->IOD_Alloc_End = pioDes32->IOD_Alloc_Base + ( pResourceDescriptor->CmResourceDescriptor.u.Port.Length - 1);
|
|
|
|
// Don't know what to do with Share disposition here, since CFGMGR32 doesn't seem to
|
|
// do it for IO Ports.
|
|
//if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
|
|
//{
|
|
// pioDes32->IOD_Flags |= fIRQD_Share;
|
|
//}
|
|
|
|
//
|
|
// Port Type flags convert straight across
|
|
//
|
|
|
|
//#define fIOD_PortType (0x1) // Bitmask,whether port is IO or memory
|
|
//#define fIOD_Memory (0x0) // Port resource really uses memory
|
|
//#define fIOD_IO (0x1) // Port resource uses IO ports
|
|
|
|
//#define CM_RESOURCE_PORT_MEMORY 0
|
|
//#define CM_RESOURCE_PORT_IO 1
|
|
|
|
pioDes32->IOD_DesFlags = pResourceDescriptor->CmResourceDescriptor.Flags;
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef NTONLY
|
|
void CConfigMgrDevice::NT4MEMToMEM_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PMEM_DES pmemDes32 )
|
|
{
|
|
ZeroMemory( pmemDes32, sizeof(MEM_DES) );
|
|
|
|
// 32-bit structure
|
|
//typedef struct Mem_Des_s {
|
|
// DWORD MD_Count; // number of MEM_RANGE structs in MEM_RESOURCE
|
|
// DWORD MD_Type; // size (in bytes) of MEM_RANGE (MType_Range)
|
|
// DWORDLONG MD_Alloc_Base; // base memory address of range allocated
|
|
// DWORDLONG MD_Alloc_End; // end of allocated range
|
|
// DWORD MD_Flags; // flags describing allocated range (fMD flags)
|
|
// DWORD MD_Reserved;
|
|
//} MEM_DES, *PMEM_DES;
|
|
|
|
LARGE_INTEGER liTemp; // Used to avoid 64bit alignment problems
|
|
|
|
liTemp.HighPart = pResourceDescriptor->CmResourceDescriptor.u.Memory.Start.HighPart;
|
|
liTemp.LowPart = pResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart;
|
|
|
|
pmemDes32->MD_Alloc_Base = liTemp.QuadPart;
|
|
pmemDes32->MD_Alloc_End = pmemDes32->MD_Alloc_Base + ( pResourceDescriptor->CmResourceDescriptor.u.Memory.Length - 1);
|
|
|
|
// Don't know what to do with Share disposition here, since CFGMGR32 doesn't seem to
|
|
// do it for IO Ports.
|
|
//if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
|
|
//{
|
|
// pioDes32->MD_Flags |= fIRQD_Share;
|
|
//}
|
|
|
|
// Flag conversions I can do
|
|
if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_READ_WRITE )
|
|
{
|
|
pmemDes32->MD_Flags |= fMD_RAM;
|
|
pmemDes32->MD_Flags |= fMD_ReadAllowed;
|
|
}
|
|
else if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_READ_ONLY )
|
|
{
|
|
pmemDes32->MD_Flags |= fMD_ROM;
|
|
pmemDes32->MD_Flags |= fMD_ReadAllowed;
|
|
}
|
|
else if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_WRITE_ONLY )
|
|
{
|
|
pmemDes32->MD_Flags |= fMD_RAM;
|
|
pmemDes32->MD_Flags |= fMD_ReadDisallowed;
|
|
}
|
|
|
|
if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_PREFETCHABLE )
|
|
{
|
|
pmemDes32->MD_Flags |= fMD_PrefetchAllowed;
|
|
}
|
|
|
|
// Don't know what to do with these flags:
|
|
|
|
//#define mMD_32_24 (0x2) // Bitmask, memory is 24 or 32-bit
|
|
//#define fMD_32_24 mMD_32_24 // compatibility
|
|
//#define fMD_24 (0x0) // Memory range is 24-bit
|
|
//#define fMD_32 (0x2) // Memory range is 32-bit
|
|
|
|
//#define mMD_CombinedWrite (0x10) // Bitmask,supports write-behind
|
|
//#define fMD_CombinedWrite mMD_CombinedWrite // compatibility
|
|
//#define fMD_CombinedWriteDisallowed (0x0) // no combined-write caching
|
|
//#define fMD_CombinedWriteAllowed (0x10) // supports combined-write caching
|
|
|
|
//#define mMD_Cacheable (0x20) // Bitmask,whether memory is cacheable
|
|
//#define fMD_NonCacheable (0x0) // Memory range is non-cacheable
|
|
//#define fMD_Cacheable (0x20) // Memory range is cacheable
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef NTONLY
|
|
void CConfigMgrDevice::NT4DMAToDMA_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PDMA_DES pdmaDes32 )
|
|
{
|
|
ZeroMemory( pdmaDes32, sizeof(DMA_DES) );
|
|
|
|
// 32-bit structure
|
|
//typedef struct DMA_Des_s {
|
|
// DWORD DD_Count; // number of DMA_RANGE structs in DMA_RESOURCE
|
|
// DWORD DD_Type; // size (in bytes) of DMA_RANGE struct (DType_Range)
|
|
// DWORD DD_Flags; // Flags describing DMA channel (fDD flags)
|
|
// ULONG DD_Alloc_Chan; // Specifies the DMA channel that was allocated
|
|
//} DMA_DES, *PDMA_DES;
|
|
|
|
pdmaDes32->DD_Alloc_Chan = pResourceDescriptor->CmResourceDescriptor.u.Dma.Channel;
|
|
|
|
// Don't know what to do with Share disposition here, since CFGMGR32 doesn't seem to
|
|
// do it for IO Ports.
|
|
//if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
|
|
//{
|
|
// pioDes32->MD_Flags |= fIRQD_Share;
|
|
//}
|
|
|
|
// These are possible flags for DMA, but I don't see any values from the
|
|
// CHWRES.H file which make a sensible conversion to these values.
|
|
|
|
//
|
|
// Define the attribute flags for a DMA resource range. Each bit flag is
|
|
// identified with a constant bitmask. Following the bitmask definition
|
|
// are the possible values.
|
|
//
|
|
//#define mDD_Width (0x3) // Bitmask, width of the DMA channel:
|
|
//#define fDD_BYTE (0x0) // 8-bit DMA channel
|
|
//#define fDD_WORD (0x1) // 16-bit DMA channel
|
|
//#define fDD_DWORD (0x2) // 32-bit DMA channel
|
|
//#define fDD_BYTE_AND_WORD (0x3) // 8-bit and 16-bit DMA channel
|
|
|
|
//#define mDD_BusMaster (0x4) // Bitmask, whether bus mastering is supported
|
|
//#define fDD_NoBusMaster (0x0) // no bus mastering
|
|
//#define fDD_BusMaster (0x4) // bus mastering
|
|
|
|
//#define mDD_Type (0x18) // Bitmask, specifies type of DMA
|
|
//#define fDD_TypeStandard (0x00) // standard DMA
|
|
//#define fDD_TypeA (0x08) // Type-A DMA
|
|
//#define fDD_TypeB (0x10) // Type-B DMA
|
|
//#define fDD_TypeF (0x18) // Type-F DMA
|
|
|
|
}
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::IRQDes16To32
|
|
//
|
|
// Coerces data from a 16-bit structure into a 32-bit structure.
|
|
//
|
|
// Inputs: PIRQ_DES16 pirqDes16 - 16-bit structure
|
|
//
|
|
// Outputs: PIRQ_DES pirqDes32 - 32-bit structure
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void CConfigMgrDevice::IRQDes16To32( PIRQ_DES16 pirqDes16, PIRQ_DES pirqDes32 )
|
|
{
|
|
ZeroMemory( pirqDes32, sizeof(IRQ_DES) );
|
|
|
|
// 16-bit Structure
|
|
//struct IRQ_Des_s {
|
|
// WORD IRQD_Flags;
|
|
// WORD IRQD_Alloc_Num; // Allocated IRQ number
|
|
// WORD IRQD_Req_Mask; // Mask of possible IRQs
|
|
// WORD IRQD_Reserved;
|
|
//};
|
|
|
|
// 32-bit structure
|
|
//typedef struct IRQ_Des_s {
|
|
// DWORD IRQD_Count; // number of IRQ_RANGE structs in IRQ_RESOURCE
|
|
// DWORD IRQD_Type; // size (in bytes) of IRQ_RANGE (IRQType_Range)
|
|
// DWORD IRQD_Flags; // flags describing the IRQ (fIRQD flags)
|
|
// ULONG IRQD_Alloc_Num; // specifies the IRQ that was allocated
|
|
// ULONG IRQD_Affinity;
|
|
//} IRQ_DES, *PIRQ_DES;
|
|
|
|
pirqDes32->IRQD_Alloc_Num = pirqDes16->IRQD_Alloc_Num;
|
|
pirqDes32->IRQD_Flags = pirqDes16->IRQD_Flags;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::IODes16To32
|
|
//
|
|
// Coerces data from a 16-bit structure into a 32-bit structure.
|
|
//
|
|
// Inputs: PIO_DES16 pioDes16 - 16-bit structure
|
|
//
|
|
// Outputs: PIOWBEM_DES pioDes32 - 32-bit structure
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void CConfigMgrDevice::IODes16To32( PIO_DES16 pioDes16, PIOWBEM_DES pioDes32 )
|
|
{
|
|
ZeroMemory( pioDes32, sizeof(IOWBEM_DES) );
|
|
|
|
// 16-bit structure
|
|
//struct IO_Des_s {
|
|
// WORD IOD_Count;
|
|
// WORD IOD_Type;
|
|
// WORD IOD_Alloc_Base;
|
|
// WORD IOD_Alloc_End;
|
|
// WORD IOD_DesFlags;
|
|
// BYTE IOD_Alloc_Alias;
|
|
// BYTE IOD_Alloc_Decode;
|
|
//};
|
|
|
|
// 32-bit Structure
|
|
//typedef struct _IOWBEM_DES{
|
|
// DWORD IOD_Count; // number of IO_RANGE structs in IO_RESOURCE
|
|
// DWORD IOD_Type; // size (in bytes) of IO_RANGE (IOType_Range)
|
|
// DWORDLONG IOD_Alloc_Base; // base of allocated port range
|
|
// DWORDLONG IOD_Alloc_End; // end of allocated port range
|
|
// DWORD IOD_DesFlags; // flags relating to allocated port range
|
|
// BYTE IOD_Alloc_Alias; // From 16-bit-land
|
|
// BYTE IOD_Alloc_Decode; // From 16-bit-land
|
|
//} IOWBEM_DES;
|
|
|
|
pioDes32->IOD_Count = pioDes16->IOD_Count;
|
|
pioDes32->IOD_Type = pioDes16->IOD_Type;
|
|
pioDes32->IOD_Alloc_Base = pioDes16->IOD_Alloc_Base;
|
|
pioDes32->IOD_Alloc_End = pioDes16->IOD_Alloc_End;
|
|
pioDes32->IOD_DesFlags = pioDes16->IOD_DesFlags;
|
|
pioDes32->IOD_Alloc_Alias = pioDes16->IOD_Alloc_Alias;
|
|
pioDes32->IOD_Alloc_Decode = pioDes16->IOD_Alloc_Decode;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::DMADes16To32
|
|
//
|
|
// Coerces data from a 16-bit structure into a 32-bit structure.
|
|
//
|
|
// Inputs: PDMA_DES16 pdmaDes16 - 16-bit structure
|
|
//
|
|
// Outputs: PDMA_DES pdmaDes32 - 32-bit structure
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void CConfigMgrDevice::DMADes16To32( PDMA_DES16 pdmaDes16, PDMA_DES pdmaDes32 )
|
|
{
|
|
ZeroMemory( pdmaDes32, sizeof(DMA_DES) );
|
|
|
|
// 16-bit structure
|
|
//struct DMA_Des_s {
|
|
// BYTE DD_Flags;
|
|
// BYTE DD_Alloc_Chan; // Channel number allocated
|
|
// BYTE DD_Req_Mask; // Mask of possible channels
|
|
// BYTE DD_Reserved;
|
|
//};
|
|
|
|
// 32-bit structure
|
|
//typedef struct DMA_Des_s {
|
|
// DWORD DD_Count; // number of DMA_RANGE structs in DMA_RESOURCE
|
|
// DWORD DD_Type; // size (in bytes) of DMA_RANGE struct (DType_Range)
|
|
// DWORD DD_Flags; // Flags describing DMA channel (fDD flags)
|
|
// ULONG DD_Alloc_Chan; // Specifies the DMA channel that was allocated
|
|
//} DMA_DES, *PDMA_DES;
|
|
|
|
pdmaDes32->DD_Flags = pdmaDes16->DD_Flags;
|
|
pdmaDes32->DD_Alloc_Chan = pdmaDes16->DD_Alloc_Chan;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::MEMDes16To32
|
|
//
|
|
// Coerces data from a 16-bit structure into a 32-bit structure.
|
|
//
|
|
// Inputs: PMEM_DES16 pmemDes16 - 16-bit structure
|
|
//
|
|
// Outputs: PMEM_DES pmemDes32 - 32-bit structure
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void CConfigMgrDevice::MEMDes16To32( PMEM_DES16 pmemDes16, PMEM_DES pmemDes32 )
|
|
{
|
|
ZeroMemory( pmemDes32, sizeof(MEM_DES) );
|
|
|
|
// 16-bit Structure
|
|
//struct Mem_Des_s {
|
|
// WORD MD_Count;
|
|
// WORD MD_Type;
|
|
// ULONG MD_Alloc_Base;
|
|
// ULONG MD_Alloc_End;
|
|
// WORD MD_Flags;
|
|
// WORD MD_Reserved;
|
|
//};
|
|
|
|
// 32-bit Structure
|
|
//typedef struct Mem_Des_s {
|
|
// DWORD MD_Count; // number of MEM_RANGE structs in MEM_RESOURCE
|
|
// DWORD MD_Type; // size (in bytes) of MEM_RANGE (MType_Range)
|
|
// DWORDLONG MD_Alloc_Base; // base memory address of range allocated
|
|
// DWORDLONG MD_Alloc_End; // end of allocated range
|
|
// DWORD MD_Flags; // flags describing allocated range (fMD flags)
|
|
// DWORD MD_Reserved;
|
|
//} MEM_DES, *PMEM_DES;
|
|
|
|
pmemDes32->MD_Count = pmemDes16->MD_Count;
|
|
pmemDes32->MD_Type = pmemDes16->MD_Type;
|
|
pmemDes32->MD_Alloc_Base = pmemDes16->MD_Alloc_Base;
|
|
pmemDes32->MD_Alloc_End = pmemDes16->MD_Alloc_End;
|
|
pmemDes32->MD_Flags = pmemDes16->MD_Flags;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::TraverseAllocationData
|
|
//
|
|
// Traverses a block of data in order to determine
|
|
// resource allocations for a particular device.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: CResourceCollection& resourceList - List to populate
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: Requires READ Access to the data.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void CConfigMgrDevice::TraverseAllocationData( CResourceCollection& resourceList )
|
|
{
|
|
const BYTE * pbTraverseData = m_pbAllocationData;
|
|
DWORD dwSizeRemainingData = m_dwSizeAllocationData,
|
|
dwResourceType = ResType_None,
|
|
dwResourceSize = 0;
|
|
|
|
// Clear the resource list first
|
|
resourceList.Empty();
|
|
|
|
// OWCH! The first hack. Near as I can tell, we need to jump eight bytes in to get
|
|
// to the first resource descriptor header (if there is one).
|
|
|
|
TraverseData( pbTraverseData, dwSizeRemainingData, FIRST_RESOURCE_OFFSET );
|
|
|
|
// From here on, we only want to deal with known resource information. Use the
|
|
// clever GetNextResource function to do all of our dirty work for us. If it
|
|
// returns TRUE, then it's located a resource. Allocate the proper type of
|
|
// descriptor based on type, place it in the list and go on to the next resource.
|
|
|
|
while ( GetNextResource( pbTraverseData, dwSizeRemainingData, dwResourceType, dwResourceSize ) )
|
|
{
|
|
if( dwResourceType == m_dwTypeToGet ){
|
|
|
|
PPOORMAN_RESDESC_HDR pResDescHdr = (PPOORMAN_RESDESC_HDR) pbTraverseData;
|
|
CResourceDescriptorPtr pResDesc;
|
|
|
|
// We have a valid type, however the actual resource descriptor will
|
|
// lie SIZEOF_RESDESC_HDR bytes past where we're at now (pointing at
|
|
// a resource header).
|
|
|
|
switch ( dwResourceType ){
|
|
case ResType_Mem:
|
|
{
|
|
CDeviceMemoryDescriptor* pMemDesc = new CDeviceMemoryDescriptor( pResDescHdr, this );
|
|
pResDesc.Attach(pMemDesc);
|
|
break;
|
|
}
|
|
|
|
case ResType_IO:
|
|
{
|
|
CIODescriptor* pIODesc = new CIODescriptor( pResDescHdr, this );
|
|
pResDesc.Attach(pIODesc);
|
|
break;
|
|
}
|
|
|
|
case ResType_DMA:
|
|
{
|
|
CDMADescriptor* pDMADesc = new CDMADescriptor( pResDescHdr, this );
|
|
pResDesc.Attach(pDMADesc);
|
|
break;
|
|
}
|
|
|
|
case ResType_IRQ:
|
|
{
|
|
CIRQDescriptor* pIRQDesc = new CIRQDescriptor( pResDescHdr, this );
|
|
pResDesc.Attach(pIRQDesc);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
pResDesc.Attach (new CResourceDescriptor( pResDescHdr, this ));
|
|
}
|
|
|
|
} // SWITCH
|
|
|
|
// Give up if we have any failures, since they are most likely memory
|
|
// related, and something really bad has happened.
|
|
|
|
if ( NULL != pResDesc )
|
|
{
|
|
if ( !resourceList.Add( pResDesc ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
}
|
|
// Move the pointer to the next resource descriptor header.
|
|
TraverseData( pbTraverseData, dwSizeRemainingData, dwResourceSize );
|
|
|
|
} // WHILE finding new resources
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::FindNextResource
|
|
//
|
|
// Iterates through a block of data, hunting for byte patterns that
|
|
// identify a resource type. In this case, as long as there are
|
|
// SIZEOF_RESDESC_HDR bytes let to work with, we extract the resource
|
|
// type and size and return those values for interpretation.
|
|
//
|
|
// Inputs: const BYTE* pbTraverseData - Data we are traversing. The
|
|
// value will change as we progress through the
|
|
// data.
|
|
// DWORD dwSizeRemainingData - How much data remains to
|
|
// be traversed.
|
|
//
|
|
// Outputs: DWORD& dwResourceType - What type of resource have we
|
|
// found.
|
|
// DWORD& dwResourceSize - How big the block of data
|
|
// describing the resource is.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CConfigMgrDevice::GetNextResource( const BYTE *pbTraverseData, DWORD dwSizeRemainingData, DWORD& dwResourceType, DWORD& dwResourceSize )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
|
|
// If we have less than SIZEOF_RESDESC_HDR bytes to work with,
|
|
// give up, we ain't goin' nowhere.
|
|
|
|
if ( dwSizeRemainingData > SIZEOF_RESDESC_HDR )
|
|
{
|
|
PPOORMAN_RESDESC_HDR pResDescHdr = (PPOORMAN_RESDESC_HDR) pbTraverseData;
|
|
DWORD dwResourceId = 0;
|
|
|
|
dwResourceSize = pResDescHdr->dwResourceSize;
|
|
|
|
// If we run into a zero byte header, the only value will be length, which
|
|
// makes no sense, so we should probably just give up.
|
|
|
|
if ( 0 != dwResourceSize )
|
|
{
|
|
// See if it's one of the four standard types. If so, be aware that this code
|
|
// ain't checking to see if it's ignored, and that an OEM can create a replacement
|
|
// for one of these standard types, in which case strange and wondrous things
|
|
// may happen.
|
|
|
|
// Strip out any unwanted data, the first 5 bits are reserved for resource type
|
|
// identification, so mask out everything else
|
|
|
|
dwResourceType = pResDescHdr->dwResourceId;
|
|
dwResourceType &= RESOURCE_TYPE_MASK;
|
|
|
|
// We got a live one!
|
|
fReturn = TRUE;
|
|
|
|
}
|
|
}
|
|
|
|
// Return whether or not we found a resource
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::GetStatus
|
|
//
|
|
// Returns the status of the device as a string. If OK, it is "OK", if
|
|
// we have a problem, it is "Error".
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: CHString& str - String to place status in.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void CConfigMgrDevice::GetProblem( CHString& str )
|
|
{
|
|
// Save the string
|
|
str = ( 0 == m_dwProblem ? IDS_CfgMgrDeviceStatus_OK : IDS_CfgMgrDeviceStatus_ERR );
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CConfigMgrDevice::TraverseData
|
|
//
|
|
// Helper function to safely bounce a pointer around our data. It will
|
|
// jump the pointer by the specified amount, or the amount remaining,
|
|
// whichever is smaller.
|
|
//
|
|
// Inputs: DWORD dwSizeTraverse - Size of upcoming jump.
|
|
//
|
|
// Outputs: const BYTE*& pbTraverseData - Data we are traversing. The
|
|
// value will change as we progress through the
|
|
// data.
|
|
// DWORD& dwSizeRemainingData - How much data remains to
|
|
// be traversed.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void CConfigMgrDevice::TraverseData( const BYTE *& pbTraverseData, DWORD& dwSizeRemainingData, DWORD dwSizeTraverse )
|
|
{
|
|
// Increment the pointer and reduce the size of remaining data, do this safely, not
|
|
// traversing beyond the end of the remaining data, if that is all that is left.
|
|
|
|
pbTraverseData += min( dwSizeRemainingData, dwSizeTraverse );
|
|
dwSizeRemainingData -= min( dwSizeRemainingData, dwSizeTraverse );
|
|
}
|
|
|
|
// New functions that converse directly with the Config Manager APIs
|
|
|
|
BOOL CConfigMgrDevice::GetDeviceID( CHString& strID )
|
|
{
|
|
BOOL bRet = FALSE ;
|
|
CONFIGRET cr = CR_SUCCESS;
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
char szDeviceId[MAX_DEVICE_ID_LEN+1];
|
|
|
|
ULONG ulBuffSize = 0;
|
|
|
|
cr = pconfigmgr->CM_Get_Device_IDA( m_dn, szDeviceId, sizeof(szDeviceId), 0 );
|
|
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
strID = szDeviceId;
|
|
}
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetStatus( LPDWORD pdwStatus, LPDWORD pdwProblem )
|
|
{
|
|
BOOL bRet = FALSE ;
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
|
|
DWORD dwStatus,
|
|
dwProblem;
|
|
|
|
CONFIGRET cr = pconfigmgr->CM_Get_DevNode_Status( &dwStatus, &dwProblem, m_dn, 0 );
|
|
|
|
// Perform pointer testing here. Ignore the man behind the curtain...
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
if ( NULL != pdwStatus )
|
|
{
|
|
*pdwStatus = dwStatus;
|
|
}
|
|
|
|
if ( NULL != pdwProblem )
|
|
{
|
|
*pdwProblem = dwProblem;
|
|
}
|
|
}
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::IsUsingForcedConfig()
|
|
{
|
|
BOOL bRet = FALSE ;
|
|
LOG_CONF conf;
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
|
|
bRet = (pconfigmgr->CM_Get_First_Log_Conf(&conf, m_dn, FORCED_LOG_CONF) ==
|
|
CR_SUCCESS);
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetParent( CConfigMgrDevicePtr & pParentDevice )
|
|
{
|
|
BOOL bRet = FALSE ;
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
DEVNODE dn;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
|
|
CONFIGRET cr = pconfigmgr->CM_Get_Parent( &dn, m_dn, 0 );
|
|
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
CConfigMgrDevice* pDevice = new CConfigMgrDevice( dn );
|
|
pParentDevice.Attach(pDevice);
|
|
}
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetChild( CConfigMgrDevicePtr & pChildDevice )
|
|
{
|
|
BOOL bRet = FALSE ;
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
DEVNODE dn;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
|
|
CONFIGRET cr = pconfigmgr->CM_Get_Child( &dn, m_dn, 0 );
|
|
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
CConfigMgrDevice* pDevice = new CConfigMgrDevice( dn );
|
|
pChildDevice.Attach(pDevice);
|
|
}
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetSibling( CConfigMgrDevicePtr & pSiblingDevice )
|
|
{
|
|
BOOL bRet = FALSE ;
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
DEVNODE dn;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
|
|
CONFIGRET cr = pconfigmgr->CM_Get_Sibling( &dn, m_dn, 0 );
|
|
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
CConfigMgrDevice* pDevice = new CConfigMgrDevice( dn );
|
|
pSiblingDevice.Attach(pDevice);
|
|
}
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetStringProperty( ULONG ulProperty, CHString& strValue )
|
|
{
|
|
TCHAR Buffer[REGSTR_VAL_MAX_HCID_LEN+1];
|
|
ULONG Type;
|
|
ULONG Size = sizeof(Buffer);
|
|
BOOL bRet = FALSE ;
|
|
CONFIGRET cr = CR_SUCCESS;
|
|
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
|
|
if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
|
|
ulProperty,
|
|
&Type,
|
|
Buffer,
|
|
&Size,
|
|
0 ) ) )
|
|
{
|
|
if ( REG_SZ == Type )
|
|
{
|
|
strValue = Buffer;
|
|
}
|
|
else
|
|
{
|
|
cr = CR_WRONG_TYPE;
|
|
}
|
|
}
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetDWORDProperty( ULONG ulProperty, DWORD *pdwVal )
|
|
{
|
|
DWORD dwVal = 0;
|
|
ULONG Type;
|
|
ULONG Size = sizeof(DWORD);
|
|
BOOL bRet = FALSE ;
|
|
CONFIGRET cr = CR_SUCCESS;
|
|
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
|
|
ulProperty,
|
|
&Type,
|
|
&dwVal,
|
|
&Size,
|
|
0 ) ) )
|
|
{
|
|
#ifdef NTONLY
|
|
{
|
|
if ( REG_DWORD == Type )
|
|
{
|
|
*pdwVal = dwVal;
|
|
}
|
|
else
|
|
{
|
|
cr = CR_WRONG_TYPE;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
#ifdef WIN9XONLY
|
|
{
|
|
if ( REG_BINARY == Type ) // Apparently Win16 doesn't do REG_DWORD
|
|
{
|
|
*pdwVal = dwVal;
|
|
}
|
|
else
|
|
{
|
|
cr = CR_WRONG_TYPE;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetMULTISZProperty( ULONG ulProperty, CHStringArray& strArray )
|
|
{
|
|
CONFIGRET cr = CR_SUCCESS;
|
|
BOOL bRet = FALSE ;
|
|
// No one is currently using this, so I'm not going to fix it now
|
|
#ifdef DOESNT_WORK_FOR_UNICODE
|
|
LPSTR pszStrings = NULL;
|
|
ULONG Type;
|
|
ULONG Size = 0;
|
|
|
|
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
|
|
ulProperty,
|
|
&Type,
|
|
pszStrings,
|
|
&Size,
|
|
0 ) )
|
|
|| CR_BUFFER_SMALL == cr )
|
|
|
|
{
|
|
// SZ or MULTI_SZ is Okay (32-bit has MULTI_SZ values that are SZ in 16-bit)
|
|
if ( REG_SZ == Type || REG_MULTI_SZ == Type )
|
|
{
|
|
// Pad the string, but be aware that on NT4 I have seen situations in which
|
|
// it reports less data than it actually returns (scary)
|
|
|
|
Size += 32;
|
|
pszStrings = new char[Size];
|
|
|
|
if ( NULL != pszStrings )
|
|
{
|
|
try
|
|
{
|
|
// Clear out the memory to be especially safe.
|
|
ZeroMemory( pszStrings, Size );
|
|
|
|
if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
|
|
ulProperty,
|
|
&Type,
|
|
pszStrings,
|
|
&Size,
|
|
0 ) ) )
|
|
{
|
|
// For REG_SZ, add a single entry to the array
|
|
if ( REG_SZ == Type )
|
|
{
|
|
strArray.Add( pszStrings );
|
|
}
|
|
else if ( REG_MULTI_SZ == Type )
|
|
{
|
|
// Add strings to the array, watching out for the double NULL
|
|
// terminator for the array
|
|
|
|
LPSTR pszTemp = pszStrings;
|
|
|
|
do
|
|
{
|
|
strArray.Add( pszTemp );
|
|
pszTemp += ( lstrlen( pszTemp ) + 1 );
|
|
} while ( NULL != *pszTemp );
|
|
}
|
|
else
|
|
{
|
|
cr = CR_WRONG_TYPE;
|
|
}
|
|
|
|
} // If Got value
|
|
}
|
|
catch ( ... )
|
|
{
|
|
delete [] pszStrings;
|
|
throw ;
|
|
}
|
|
|
|
delete [] pszStrings;
|
|
|
|
} // IF alloc pszStrings
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
} // IF REG_SZ or REG_MULTI_SZ
|
|
else
|
|
{
|
|
cr = CR_WRONG_TYPE;
|
|
}
|
|
|
|
} // IF got size of entry
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
#endif
|
|
|
|
return bRet ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetBusInfo( INTERFACE_TYPE *pitBusType, LPDWORD pdwBusNumber, CNT4ServiceToResourceMap *pResourceMap/*=NULL*/ )
|
|
{
|
|
CMBUSTYPE busType = 0;
|
|
ULONG ulSizeOfInfo = 0;
|
|
PBYTE pbData = NULL;
|
|
BOOL fReturn = FALSE;
|
|
|
|
// Farm out to the appropriate handler
|
|
#if NTONLY > 4
|
|
fReturn = GetBusInfoNT5( pitBusType, pdwBusNumber );
|
|
#endif
|
|
#if NTONLY == 4
|
|
fReturn = GetBusInfoNT4( pitBusType, pdwBusNumber, pResourceMap );
|
|
#endif
|
|
#ifdef WIN9XONLY
|
|
{
|
|
// Buffer for data. Should be big enough for any of the values we come across.
|
|
BYTE abData[255];
|
|
|
|
ulSizeOfInfo = sizeof(abData);
|
|
|
|
// Get the type and number. If the type is PCI, then get the PCI info, and this
|
|
// will return a Bus Number value. If it returns a type other than PCI, then
|
|
// we will assume a bus number of 0.
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
CONFIGRET cr = pconfigmgr->CM_Get_Bus_Info( m_dn, &busType, &ulSizeOfInfo, abData, 0 );
|
|
|
|
if ( CR_SUCCESS == cr )
|
|
{
|
|
// Make sure we can convert from a 16-bit type to a known 32-bit type.
|
|
// BusType_None will usually fail this, in which case we can call it
|
|
// quits.
|
|
|
|
if ( BusType16ToInterfaceType( busType, pitBusType ) )
|
|
{
|
|
|
|
if ( BusType_PCI == busType )
|
|
{
|
|
sPCIAccess *pPCIInfo = (sPCIAccess*) abData;
|
|
*pdwBusNumber = pPCIInfo->bBusNumber;
|
|
}
|
|
else
|
|
{
|
|
*pdwBusNumber = 0;
|
|
}
|
|
|
|
} // IF 16-32bit conversion
|
|
else
|
|
{
|
|
cr = CR_FAILURE;
|
|
}
|
|
|
|
} // CR_SUCCESS == cr
|
|
|
|
fReturn = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
} // else !IsWinNT
|
|
#endif
|
|
return fReturn;
|
|
}
|
|
|
|
#if NTONLY > 4
|
|
// This is to hack around W2K problem where Cfg Mgr devices report they're
|
|
// using Isa on boxes that have Eisa and not Isa.
|
|
BOOL CConfigMgrDevice::IsIsaReallyEisa()
|
|
{
|
|
static bRet = -1;
|
|
|
|
if (bRet == -1)
|
|
{
|
|
// FYI: This code based on code from motherboard.cpp.
|
|
|
|
CRegistry regAdapters;
|
|
CHString strPrimarySubKey;
|
|
HRESULT hRc = WBEM_E_FAILED;
|
|
DWORD dwPrimaryRc;
|
|
|
|
// If anything below fails, we'll just assume Isa really is Isa.
|
|
bRet = FALSE;
|
|
|
|
//****************************************
|
|
// Open the registry
|
|
//****************************************
|
|
if (regAdapters.OpenAndEnumerateSubKeys(
|
|
HKEY_LOCAL_MACHINE,
|
|
L"HARDWARE\\Description\\System",
|
|
KEY_READ) == ERROR_SUCCESS)
|
|
{
|
|
BOOL bDone = FALSE,
|
|
bIsaFound = FALSE,
|
|
bEisaFound = FALSE;
|
|
|
|
// Our goal is to find any subkey that has the string "Adapter" in
|
|
// it and then read the "Identifier" value.
|
|
for ( ;
|
|
(!bIsaFound || !bEisaFound) &&
|
|
((dwPrimaryRc = regAdapters.GetCurrentSubKeyName(strPrimarySubKey))
|
|
== ERROR_SUCCESS);
|
|
regAdapters.NextSubKey())
|
|
{
|
|
strPrimarySubKey.MakeUpper();
|
|
|
|
// If this is one of the keys we want since it has "Adapter" in
|
|
// it then get the "Identifier" value.
|
|
if (wcsstr(strPrimarySubKey, L"ADAPTER"))
|
|
{
|
|
WCHAR szKey[_MAX_PATH];
|
|
CRegistry reg;
|
|
|
|
swprintf(
|
|
szKey,
|
|
L"%s\\%s",
|
|
L"HARDWARE\\Description\\System",
|
|
(LPCWSTR) strPrimarySubKey);
|
|
|
|
if (reg.OpenAndEnumerateSubKeys(
|
|
HKEY_LOCAL_MACHINE,
|
|
szKey,
|
|
KEY_READ) == ERROR_SUCCESS)
|
|
{
|
|
CHString strSubKey;
|
|
|
|
// Enumerate the system components (like 0,1,...).
|
|
for ( ;
|
|
reg.GetCurrentSubKeyName(strSubKey) == ERROR_SUCCESS;
|
|
reg.NextSubKey())
|
|
{
|
|
CHString strBus;
|
|
|
|
if (reg.GetCurrentSubKeyValue(L"Identifier",
|
|
strBus) == ERROR_SUCCESS)
|
|
{
|
|
if (strBus == L"ISA")
|
|
bIsaFound = TRUE;
|
|
else if (strBus == L"EISA")
|
|
bEisaFound = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we found Eisa but not Isa, assume Cfg Mgr devices that report they're
|
|
// using Isa are actually using Eisa.
|
|
if (!bIsaFound && bEisaFound)
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
#endif
|
|
|
|
#if NTONLY > 4
|
|
INTERFACE_TYPE CConfigMgrDevice::ConvertBadIsaBusType(INTERFACE_TYPE type)
|
|
{
|
|
if (type == Isa && IsIsaReallyEisa())
|
|
type = Eisa;
|
|
|
|
return type;
|
|
}
|
|
#endif
|
|
|
|
#if NTONLY > 4
|
|
BOOL CConfigMgrDevice::GetBusInfoNT5( INTERFACE_TYPE *pitBusType, LPDWORD pdwBusNumber )
|
|
{
|
|
ULONG ulSizeOfInfo = 0;
|
|
CONFIGRET cr;
|
|
|
|
// Bus Number and Type are retrieved via the Registry function. This will only
|
|
// work on NT 5.
|
|
BOOL bRet = FALSE ;
|
|
DWORD dwType = 0;
|
|
DWORD dwBusNumber;
|
|
INTERFACE_TYPE BusType;
|
|
|
|
ulSizeOfInfo = sizeof(DWORD);
|
|
CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
|
|
if ( pconfigmgr )
|
|
{
|
|
if ( pconfigmgr->IsValid () )
|
|
{
|
|
if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
|
|
CM_DRP_BUSNUMBER,
|
|
&dwType,
|
|
&dwBusNumber,
|
|
&ulSizeOfInfo,
|
|
0 ) ) )
|
|
{
|
|
*pdwBusNumber = dwBusNumber;
|
|
|
|
ulSizeOfInfo = sizeof(BusType);
|
|
|
|
if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
|
|
CM_DRP_LEGACYBUSTYPE,
|
|
&dwType,
|
|
&BusType,
|
|
&ulSizeOfInfo,
|
|
0 ) ) )
|
|
{
|
|
*pitBusType = ConvertBadIsaBusType(BusType);
|
|
} // IF GetBusType
|
|
|
|
} // IF GetBusNumber
|
|
bRet = ( CR_SUCCESS == cr );
|
|
}
|
|
CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
|
|
}
|
|
|
|
return bRet ;
|
|
}
|
|
#endif
|
|
|
|
#if NTONLY == 4
|
|
BOOL CConfigMgrDevice::GetBusInfoNT4( INTERFACE_TYPE *pitBusType, LPDWORD pdwBusNumber, CNT4ServiceToResourceMap *pResourceMap )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
CHString strService;
|
|
|
|
if ( GetService( strService ) )
|
|
{
|
|
CNT4ServiceToResourceMap* pLocalMap = pResourceMap;
|
|
|
|
// Instantiate a resource map if we need one. Then look for
|
|
// resources for this service
|
|
|
|
if ( NULL == pLocalMap )
|
|
{
|
|
pLocalMap = new CNT4ServiceToResourceMap;
|
|
}
|
|
|
|
if ( NULL != pLocalMap )
|
|
{
|
|
try
|
|
{
|
|
if ( 0 != pLocalMap->NumServiceResources( strService ) )
|
|
{
|
|
LPRESOURCE_DESCRIPTOR pResource = pLocalMap->GetServiceResource( strService, 0 );
|
|
|
|
// If we got a resource, then use its BUS information directly to populate
|
|
// our values.
|
|
|
|
if ( NULL != pResource )
|
|
{
|
|
fReturn = TRUE;
|
|
*pitBusType = pResource->InterfaceType;
|
|
*pdwBusNumber = pResource->Bus;
|
|
}
|
|
|
|
} // If there are resources for this service
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( pLocalMap != pResourceMap )
|
|
{
|
|
delete pLocalMap;
|
|
}
|
|
throw ;
|
|
}
|
|
|
|
// Delete the local map if we allocated one.
|
|
if ( pLocalMap != pResourceMap )
|
|
{
|
|
delete pLocalMap;
|
|
}
|
|
|
|
} // if pLocalMap
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
|
|
} // If got service name
|
|
|
|
return fReturn;
|
|
}
|
|
#endif
|
|
|
|
BOOL CConfigMgrDevice::BusType16ToInterfaceType( CMBUSTYPE cmBusType16, INTERFACE_TYPE *pinterfaceType )
|
|
{
|
|
|
|
BOOL fReturn = TRUE;
|
|
|
|
// These are the enums defined for NT, so we'll standardize on these
|
|
//
|
|
// typedef enum Interface_Type {
|
|
// Internal,
|
|
// Isa,
|
|
// Eisa,
|
|
// MicroChannel,
|
|
// TurboChannel,
|
|
// PCIBus,
|
|
// VMEBus,
|
|
// NuBus,
|
|
// PCMCIABus,
|
|
// CBus,
|
|
// MPIBus,
|
|
// MPSABus,
|
|
// MaximumInterfaceType
|
|
// }INTERFACE_TYPE;
|
|
//
|
|
|
|
switch ( cmBusType16 )
|
|
{
|
|
case BusType_ISA:
|
|
{
|
|
*pinterfaceType = Isa;
|
|
}
|
|
break;
|
|
|
|
case BusType_EISA:
|
|
{
|
|
*pinterfaceType = Eisa;
|
|
}
|
|
break;
|
|
|
|
case BusType_PCI:
|
|
{
|
|
*pinterfaceType = PCIBus;
|
|
}
|
|
break;
|
|
|
|
case BusType_PCMCIA:
|
|
{
|
|
*pinterfaceType = PCMCIABus;
|
|
}
|
|
break;
|
|
|
|
case BusType_ISAPNP:
|
|
{
|
|
// Closest match I could find
|
|
*pinterfaceType = Isa;
|
|
}
|
|
break;
|
|
|
|
case BusType_MCA:
|
|
{
|
|
*pinterfaceType = MicroChannel;
|
|
}
|
|
break;
|
|
|
|
case BusType_BIOS:
|
|
{
|
|
*pinterfaceType = Internal;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
// Couldn't make the conversion (e.g. BusType_None)
|
|
fReturn = FALSE;
|
|
}
|
|
}
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
// Registry Access functions. Sometimes we want to access the registry directly because
|
|
// the device in question places private values in there that our regular functions cannot
|
|
// access.
|
|
BOOL CConfigMgrDevice::GetRegistryKeyName( CHString &strName)
|
|
{
|
|
CHString strDeviceID;
|
|
BOOL bRet = TRUE;
|
|
|
|
if ( GetDeviceID(strDeviceID) )
|
|
{
|
|
|
|
// Build the correct key
|
|
#ifdef NTONLY
|
|
strName = _T("SYSTEM\\CurrentControlSet\\Enum\\");
|
|
#endif
|
|
#ifdef WIN9XONLY
|
|
strName = _T("Enum\\");
|
|
#endif
|
|
|
|
strName += strDeviceID;
|
|
}
|
|
else
|
|
{
|
|
bRet = false;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
//
|
|
// Constructor and Destructor for the Device Collection
|
|
// object.
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CDeviceCollection::CDeviceCollection
|
|
//
|
|
// Class Constructor.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CDeviceCollection::CDeviceCollection( void )
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CDeviceCollection::~CDeviceCollection
|
|
//
|
|
// Class Destructor.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CDeviceCollection::~CDeviceCollection( void )
|
|
{
|
|
}
|
|
|
|
BOOL CDeviceCollection::GetResourceList( CResourceCollection& resourceList )
|
|
{
|
|
REFPTR_POSITION pos = NULL;
|
|
CConfigMgrDevicePtr pDevice;
|
|
CResourceCollection deviceresourceList;
|
|
BOOL fReturn = TRUE;
|
|
|
|
// Snapshot the resources on an NT 4 box. This only needs to happen once
|
|
// and then we can pass this to devices to hook themselves up to the
|
|
// appropriate resources. This keeps us from having to build this data
|
|
// for each and every device.
|
|
|
|
#ifdef NTONLY
|
|
CNT4ServiceToResourceMap* pResourceMap = NULL;
|
|
|
|
if ( IsWinNT4() )
|
|
{
|
|
pResourceMap = new CNT4ServiceToResourceMap;
|
|
}
|
|
|
|
if (pResourceMap == NULL)
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
try
|
|
{
|
|
#endif
|
|
|
|
// Empty out the Resource List first
|
|
|
|
resourceList.Empty();
|
|
|
|
if ( BeginEnum( pos ) )
|
|
{
|
|
|
|
// Get the resource list from the device, then append it
|
|
// to the list passed in to us.
|
|
|
|
for ( pDevice.Attach(GetNext( pos ) );
|
|
pDevice != NULL;
|
|
pDevice.Attach(GetNext( pos ) ) )
|
|
{
|
|
#ifdef NTONLY
|
|
pDevice->GetResourceList( deviceresourceList, pResourceMap );
|
|
#endif
|
|
#ifdef WIN9XONLY
|
|
pDevice->GetResourceList( deviceresourceList, NULL );
|
|
#endif
|
|
resourceList.Append( deviceresourceList );
|
|
|
|
} // WHILE enuming devices
|
|
|
|
EndEnum();
|
|
|
|
}
|
|
else
|
|
{
|
|
fReturn = FALSE;
|
|
}
|
|
|
|
#ifdef NTONLY
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
throw ;
|
|
}
|
|
|
|
// Clean up the resource map if we allocated one.
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
#endif
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
BOOL CDeviceCollection::GetIRQResources( CIRQCollection& IRQList )
|
|
{
|
|
REFPTR_POSITION pos = NULL;
|
|
CConfigMgrDevicePtr pDevice;
|
|
CIRQCollection deviceIRQList;
|
|
BOOL fReturn = TRUE;
|
|
|
|
// Snapshot the resources on an NT 4 box. This only needs to happen once
|
|
// and then we can pass this to devices to hook themselves up to the
|
|
// appropriate resources. This keeps us from having to build this data
|
|
// for each and every device.
|
|
|
|
CNT4ServiceToResourceMap* pResourceMap = NULL;
|
|
|
|
#ifdef NTONLY
|
|
if ( IsWinNT4() )
|
|
{
|
|
pResourceMap = new CNT4ServiceToResourceMap;
|
|
}
|
|
if (pResourceMap == NULL)
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
try
|
|
{
|
|
#endif
|
|
|
|
// Empty out the IRQ List first
|
|
|
|
IRQList.Empty();
|
|
|
|
if ( BeginEnum( pos ) )
|
|
{
|
|
|
|
// For each device, get the IRQs and append them to the
|
|
// supplied IRQ list
|
|
|
|
for ( pDevice.Attach( GetNext( pos ) );
|
|
pDevice != NULL;
|
|
pDevice.Attach( GetNext( pos ) ))
|
|
{
|
|
pDevice->GetIRQResources( deviceIRQList, pResourceMap );
|
|
IRQList.Append( deviceIRQList );
|
|
|
|
} // for all devices
|
|
|
|
EndEnum();
|
|
|
|
} // Begin Enum
|
|
else
|
|
{
|
|
fReturn = FALSE;
|
|
}
|
|
|
|
#ifdef NTONLY
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
throw ;
|
|
}
|
|
|
|
// Clean up the resource map if we allocated one.
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
#endif
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
BOOL CDeviceCollection::GetIOResources( CIOCollection& IOList )
|
|
{
|
|
REFPTR_POSITION pos = NULL;
|
|
CConfigMgrDevicePtr pDevice;
|
|
CIOCollection deviceIOList;
|
|
BOOL fReturn = TRUE;
|
|
|
|
// Snapshot the resources on an NT 4 box. This only needs to happen once
|
|
// and then we can pass this to devices to hook themselves up to the
|
|
// appropriate resources. This keeps us from having to build this data
|
|
// for each and every device.
|
|
|
|
CNT4ServiceToResourceMap* pResourceMap = NULL;
|
|
|
|
#ifdef NTONLY
|
|
if ( IsWinNT4() )
|
|
{
|
|
pResourceMap = new CNT4ServiceToResourceMap;
|
|
}
|
|
if (pResourceMap == NULL)
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
try
|
|
{
|
|
#endif
|
|
|
|
// Empty out the IO List first
|
|
|
|
IOList.Empty();
|
|
|
|
if ( BeginEnum( pos ) )
|
|
{
|
|
|
|
// For each device, get the IO Port List and append
|
|
// it to the supplied list of IO Ports.
|
|
|
|
for ( pDevice.Attach( GetNext( pos ) );
|
|
pDevice != NULL;
|
|
pDevice.Attach( GetNext( pos ) ))
|
|
{
|
|
pDevice->GetIOResources( deviceIOList, pResourceMap );
|
|
IOList.Append( deviceIOList );
|
|
|
|
} // for all devices
|
|
|
|
EndEnum();
|
|
|
|
} // BeginEnum
|
|
else
|
|
{
|
|
fReturn = FALSE;
|
|
}
|
|
|
|
#ifdef NTONLY
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
throw ;
|
|
}
|
|
|
|
// Clean up the resource map if we allocated one.
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
#endif
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
BOOL CDeviceCollection::GetDMAResources( CDMACollection& DMAList )
|
|
{
|
|
REFPTR_POSITION pos = NULL;
|
|
CConfigMgrDevicePtr pDevice;
|
|
CDMACollection deviceDMAList;
|
|
BOOL fReturn = TRUE;
|
|
|
|
// Snapshot the resources on an NT 4 box. This only needs to happen once
|
|
// and then we can pass this to devices to hook themselves up to the
|
|
// appropriate resources. This keeps us from having to build this data
|
|
// for each and every device.
|
|
|
|
CNT4ServiceToResourceMap* pResourceMap = NULL;
|
|
|
|
#ifdef NTONLY
|
|
if ( IsWinNT4() )
|
|
{
|
|
pResourceMap = new CNT4ServiceToResourceMap;
|
|
}
|
|
if (pResourceMap == NULL)
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
try
|
|
{
|
|
#endif
|
|
|
|
// Empty out the DMA List first
|
|
|
|
DMAList.Empty();
|
|
|
|
if ( BeginEnum( pos ) )
|
|
{
|
|
|
|
// For each device, get the DMA resources and append them
|
|
// to the supplied list of DMA resources
|
|
|
|
for ( pDevice.Attach( GetNext( pos ) );
|
|
pDevice != NULL;
|
|
pDevice.Attach( GetNext( pos ) ))
|
|
{
|
|
pDevice->GetDMAResources( deviceDMAList, pResourceMap );
|
|
DMAList.Append( deviceDMAList );
|
|
|
|
} // for all devices
|
|
|
|
} // BeginEnum
|
|
else
|
|
{
|
|
fReturn = FALSE;
|
|
}
|
|
|
|
#ifdef NTONLY
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
throw ;
|
|
}
|
|
|
|
// Clean up the resource map if we allocated one.
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
#endif
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
BOOL CDeviceCollection::GetDeviceMemoryResources( CDeviceMemoryCollection& DeviceMemoryList )
|
|
{
|
|
REFPTR_POSITION pos = NULL;
|
|
CConfigMgrDevicePtr pDevice;
|
|
CDeviceMemoryCollection memoryList;
|
|
BOOL fReturn = TRUE;
|
|
|
|
// Snapshot the resources on an NT 4 box. This only needs to happen once
|
|
// and then we can pass this to devices to hook themselves up to the
|
|
// appropriate resources. This keeps us from having to build this data
|
|
// for each and every device.
|
|
|
|
CNT4ServiceToResourceMap* pResourceMap = NULL;
|
|
|
|
#ifdef NTONLY
|
|
if ( IsWinNT4() )
|
|
{
|
|
pResourceMap = new CNT4ServiceToResourceMap;
|
|
}
|
|
if (pResourceMap == NULL)
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
try
|
|
{
|
|
#endif
|
|
|
|
// Empty out the DeviceMemory List first
|
|
|
|
DeviceMemoryList.Empty();
|
|
|
|
if ( BeginEnum( pos ) )
|
|
{
|
|
|
|
// For each device get the list of Memory Resources and
|
|
// append it to the list of supplied Memory Resources.
|
|
|
|
for ( pDevice.Attach( GetNext( pos ) );
|
|
pDevice != NULL;
|
|
pDevice.Attach( GetNext( pos ) ))
|
|
{
|
|
pDevice->GetDeviceMemoryResources( memoryList, pResourceMap );
|
|
DeviceMemoryList.Append( memoryList );
|
|
|
|
} // for all devices
|
|
|
|
EndEnum();
|
|
|
|
} // BeginEnum()
|
|
else
|
|
{
|
|
fReturn = FALSE;
|
|
}
|
|
|
|
#ifdef NTONLY
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
throw ;
|
|
}
|
|
|
|
// Clean up the resource map if we allocated one.
|
|
if ( NULL != pResourceMap )
|
|
{
|
|
delete pResourceMap;
|
|
}
|
|
#endif
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
#define MAX_DOS_DEVICES 8192
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : QueryDosDeviceNames
|
|
*
|
|
* DESCRIPTION : Queries for all Dos Device symbolic links
|
|
*
|
|
* INPUTS : none
|
|
*
|
|
* OUTPUTS : nichts
|
|
*
|
|
* RETURNS : nada
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL WINAPI QueryDosDeviceNames ( TCHAR *&a_DosDeviceNameList )
|
|
{
|
|
BOOL t_Status = FALSE ;
|
|
|
|
BOOL bContinue = TRUE ;
|
|
ULONG ulDosDevices = MAX_DOS_DEVICES ;
|
|
|
|
do
|
|
{
|
|
//
|
|
// let's finish loop
|
|
//
|
|
bContinue = FALSE ;
|
|
|
|
CSmartBuffer pQueryBuffer ( ( ulDosDevices * sizeof ( TCHAR ) ) );
|
|
|
|
DWORD t_QueryStatus = QueryDosDevice ( NULL , (LPTSTR)((LPBYTE)pQueryBuffer) , ulDosDevices ) ;
|
|
if ( t_QueryStatus )
|
|
{
|
|
a_DosDeviceNameList = new TCHAR [ t_QueryStatus ] ;
|
|
if (a_DosDeviceNameList == NULL)
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
memcpy ( a_DosDeviceNameList , (void*)((LPBYTE)pQueryBuffer) , t_QueryStatus * sizeof ( TCHAR ) ) ;
|
|
|
|
t_Status = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if ( STATUS_BUFFER_TOO_SMALL == (NTSTATUS)NtCurrentTeb()->LastStatusValue )
|
|
{
|
|
//
|
|
// let's continue if the reason of failure
|
|
// is just small buffer here
|
|
//
|
|
ulDosDevices = ulDosDevices * 2 ;
|
|
bContinue = TRUE ;
|
|
}
|
|
}
|
|
}
|
|
while ( bContinue ) ;
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : FindDosDeviceName
|
|
*
|
|
* DESCRIPTION : Finds the dos device symbolic link given an NT device name
|
|
*
|
|
* INPUTS : none
|
|
*
|
|
* OUTPUTS : nichts
|
|
*
|
|
* RETURNS : nada
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#define MAX_MAPPED_DEVICES 26
|
|
#define MAX_DEVICENAME_LENGTH 256
|
|
|
|
BOOL WINAPI FindDosDeviceName ( const TCHAR *a_DosDeviceNameList , const CHString a_SymbolicName , CHString &a_DosDevice , BOOL a_MappedDevice )
|
|
{
|
|
BOOL t_Status = FALSE ;
|
|
|
|
CSmartBuffer t_MappedDevices ;
|
|
|
|
if ( a_MappedDevice )
|
|
{
|
|
DWORD t_Length = GetLogicalDriveStrings ( 0 , NULL ) ;
|
|
|
|
if (t_Length)
|
|
{
|
|
LPBYTE t_buff = new BYTE[(t_Length + 1) * sizeof(TCHAR)];
|
|
|
|
if (t_buff == NULL)
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
|
|
t_MappedDevices = t_buff;
|
|
|
|
if (!GetLogicalDriveStrings ( t_Length , (LPTSTR)((LPBYTE)t_MappedDevices) ) )
|
|
{
|
|
DWORD t_Error = GetLastError () ;
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD t_Error = GetLastError () ;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
const TCHAR *t_Device = a_DosDeviceNameList ;
|
|
while ( *t_Device != NULL )
|
|
{
|
|
CSmartBuffer pQueryBuffer ((MAX_DOS_DEVICES * sizeof (TCHAR)));
|
|
|
|
DWORD t_QueryStatus = QueryDosDevice ( t_Device , (LPTSTR)((LPBYTE)pQueryBuffer) , MAX_DOS_DEVICES ) ;
|
|
if ( t_QueryStatus )
|
|
{
|
|
TCHAR *t_Symbolic = (LPTSTR)((LPBYTE)pQueryBuffer) ;
|
|
|
|
while ( *t_Symbolic != NULL )
|
|
{
|
|
if ( _wcsicmp ( a_SymbolicName , TOBSTRT(t_Symbolic) ) == 0 )
|
|
{
|
|
/*
|
|
* Atleast get a match even if there is no mapped drive
|
|
*/
|
|
t_Status = TRUE ;
|
|
a_DosDevice = t_Device ;
|
|
|
|
if ( a_MappedDevice )
|
|
{
|
|
const TCHAR *t_CurrentDevice = (const LPTSTR)((LPBYTE)t_MappedDevices) ;
|
|
while ( *t_CurrentDevice != NULL )
|
|
{
|
|
if ( _tcsnicmp ( t_Device, t_CurrentDevice , 2 ) == 0 )
|
|
{
|
|
t_Status = TRUE ;
|
|
a_DosDevice = t_Device ;
|
|
return TRUE ;
|
|
}
|
|
|
|
t_CurrentDevice = t_CurrentDevice + _tcslen ( t_CurrentDevice ) + 1 ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return TRUE ;
|
|
}
|
|
}
|
|
|
|
t_Symbolic = t_Symbolic + _tcslen ( t_Symbolic ) + 1 ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD t_Error = GetLastError () ;
|
|
}
|
|
|
|
t_Device = t_Device + _tcslen ( t_Device ) + 1 ;
|
|
}
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::IsClass(LPCWSTR pwszClassName)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
CHString sTemp;
|
|
|
|
if (GetClass(sTemp))
|
|
{
|
|
if (sTemp.CompareNoCase(pwszClassName) == 0)
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CHString sClass(pwszClassName);
|
|
sClass.MakeUpper();
|
|
|
|
WCHAR cGuid[128];
|
|
GUID gFoo = CConfigManager::s_ClassMap[sClass];
|
|
StringFromGUID2(gFoo, cGuid, sizeof(cGuid)/sizeof(WCHAR));
|
|
if (GetClassGUID(sTemp) && (sTemp.CompareNoCase(cGuid) == 0))
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CConfigMgrDevice::GetRegStringProperty(
|
|
LPCWSTR szProperty,
|
|
CHString &strValue)
|
|
{
|
|
CHString strKeyName;
|
|
DWORD dwRet;
|
|
CRegistry reg;
|
|
|
|
if (GetRegistryKeyName(strKeyName) &&
|
|
(dwRet = reg.Open(HKEY_LOCAL_MACHINE, strKeyName,
|
|
KEY_QUERY_VALUE) == ERROR_SUCCESS))
|
|
{
|
|
dwRet = reg.GetCurrentKeyValue(szProperty, strValue);
|
|
}
|
|
|
|
return dwRet == ERROR_SUCCESS;
|
|
}
|
|
|