Leaked source code of windows server 2003
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

  1. /////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. /////////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include <assertbreak.h>
  8. #include "poormansresource.h"
  9. #include "resourcedesc.h"
  10. #include "irqdesc.h"
  11. #include <regstr.h>
  12. #include "refptr.h"
  13. #include "cfgmgrdevice.h"
  14. #include "irqdesc.h"
  15. #include "iodesc.h" // don't need this yet
  16. #include "devdesc.h" // don't need this yet
  17. #include "dmadesc.h"
  18. #include <cregcls.h>
  19. #include "nt4svctoresmap.h"
  20. #include "chwres.h"
  21. #include "configmgrapi.h"
  22. #include <map>
  23. // The Map we will use below is an STL Template, so make sure we have the std namespace
  24. // available to us.
  25. using namespace std;
  26. typedef ULONG (WINAPI *CIM16GetConfigManagerStatus)(LPSTR HardwareKey);
  27. ////////////////////////////////////////////////////////////////////////
  28. //
  29. // Function: CConfigMgrDevice::CConfigMgrDevice
  30. //
  31. // Class Constructor.
  32. //
  33. // Inputs: LPCTSTR pszConfigMgrName - Name of device in config
  34. // manager (HKEY_DYN_DATA\Config Manager\Enum
  35. // subkey).
  36. //
  37. // Outputs: None.
  38. //
  39. // Return: None.
  40. //
  41. // Comments: None.
  42. //
  43. ////////////////////////////////////////////////////////////////////////
  44. CConfigMgrDevice::CConfigMgrDevice( LPCWSTR pszConfigMgrName,DWORD dwTypeToGet )
  45. : CRefPtrLite(),
  46. m_strConfigMgrName( pszConfigMgrName ),
  47. m_strHardwareKey(),
  48. m_strDeviceDesc(),
  49. m_pbAllocationData( NULL ),
  50. m_dwSizeAllocationData( 0 )
  51. {
  52. m_dwTypeToGet = dwTypeToGet;
  53. GetConfigMgrInfo();
  54. GetDeviceInfo();
  55. }
  56. ////////////////////////////////////////////////////////////////////////
  57. //
  58. // Function: CConfigMgrDevice::CConfigMgrDevice
  59. //
  60. // Class Constructor.
  61. //
  62. // Inputs: DEVNODE m_dn - Device Node from tree
  63. // DWORD dwResType - Resource Types to Enum
  64. //
  65. // Outputs: None.
  66. //
  67. // Return: None.
  68. //
  69. // Comments: None.
  70. //
  71. ////////////////////////////////////////////////////////////////////////
  72. CConfigMgrDevice::CConfigMgrDevice( DEVNODE dn, DWORD dwResType /*=ResType_All*/ )
  73. : CRefPtrLite(),
  74. m_strConfigMgrName(),
  75. m_strHardwareKey(),
  76. m_strDeviceDesc(),
  77. m_pbAllocationData( NULL ),
  78. m_dwSizeAllocationData( 0 ),
  79. m_dn( dn ),
  80. m_dwTypeToGet( dwResType )
  81. {
  82. }
  83. ////////////////////////////////////////////////////////////////////////
  84. //
  85. // Function: CConfigMgrDevice::~CConfigMgrDevice
  86. //
  87. // Class Destructor.
  88. //
  89. // Inputs: None.
  90. //
  91. // Outputs: None.
  92. //
  93. // Return: None.
  94. //
  95. // Comments: None.
  96. //
  97. ////////////////////////////////////////////////////////////////////////
  98. CConfigMgrDevice::~CConfigMgrDevice( void )
  99. {
  100. if ( NULL != m_pbAllocationData ){
  101. delete [] m_pbAllocationData;
  102. m_pbAllocationData = NULL;
  103. }
  104. }
  105. ////////////////////////////////////////////////////////////////////////
  106. //
  107. // This function searches for the configuration manager device name
  108. // based on the
  109. //
  110. ////////////////////////////////////////////////////////////////////////
  111. BOOL CConfigMgrDevice::MapKeyToConfigMgrDeviceName()
  112. {
  113. BOOL fRc = FALSE;
  114. CRegistrySearch Search;
  115. CHPtrArray chsaList;
  116. CHString *pPtr;
  117. Search.SearchAndBuildList( _T("Config Manager\\Enum"), chsaList,
  118. m_strConfigMgrName,
  119. _T("HardWareKey"),
  120. VALUE_SEARCH,HKEY_DYN_DATA );
  121. if( chsaList.GetSize() > 0 ){
  122. pPtr = ( CHString *) chsaList.GetAt(0);
  123. WCHAR szTmp[50];
  124. szTmp[0] = _T('\0');
  125. swscanf(*pPtr, L"Config Manager\\Enum\\%s", szTmp);
  126. m_strConfigMgrName = CHString(szTmp);
  127. fRc = TRUE;
  128. }
  129. Search.FreeSearchList( CSTRING_PTR, chsaList );
  130. return fRc;
  131. }
  132. ////////////////////////////////////////////////////////////////////////
  133. #ifdef WIN9XONLY
  134. DWORD CConfigMgrDevice::GetStatusFromConfigManagerDirectly(void)
  135. {
  136. DWORD dwStatus = 0L;
  137. // thunk down to 16-bit to get it
  138. CCim32NetApi *t_pCim32Api = HoldSingleCim32NetPtr::GetCim32NetApiPtr();
  139. if( t_pCim32Api)
  140. {
  141. dwStatus = (t_pCim32Api->GetWin9XConfigManagerStatus)((char*)(const char*)_bstr_t(m_strHardwareKey));
  142. CResourceManager::sm_TheResourceManager.ReleaseResource(g_guidCim32NetApi, t_pCim32Api);
  143. t_pCim32Api = NULL;
  144. }
  145. return dwStatus;
  146. }
  147. #endif
  148. ////////////////////////////////////////////////////////////////////////
  149. //
  150. // This function translates the binary status code from the registry
  151. // into the following values:
  152. // OK, ERROR, DEGRADED, UNKNOWN
  153. //
  154. ////////////////////////////////////////////////////////////////////////
  155. BOOL CConfigMgrDevice::GetStatus(CHString & chsStatus)
  156. {
  157. DWORD dwStatus = 0L;
  158. BOOL fRc = FALSE;
  159. CRegistry Reg;
  160. CHString chsKey = CONFIGMGR_ENUM_KEY+m_strConfigMgrName;
  161. chsStatus = IDS_STATUS_Unknown;
  162. // Do this the old tried and true LEGACY way. Lose this code ASAP!
  163. if ( NULL == m_dn )
  164. {
  165. #ifdef WIN9XONLY
  166. {
  167. if( !m_strHardwareKey.IsEmpty() )
  168. {
  169. dwStatus = GetStatusFromConfigManagerDirectly();
  170. }
  171. }
  172. #endif
  173. #ifdef NTONLY
  174. if( !m_strConfigMgrName.IsEmpty())
  175. #endif
  176. {
  177. //===================================================
  178. // Initialize
  179. //===================================================
  180. if( Reg.Open(HKEY_DYN_DATA, chsKey, KEY_READ) == ERROR_SUCCESS )
  181. {
  182. DWORD dwSize = 4;
  183. Reg.GetCurrentBinaryKeyValue(CONFIGMGR_DEVICE_STATUS_VALUE, (BYTE *)&dwStatus, &dwSize);
  184. }
  185. }
  186. }
  187. else
  188. {
  189. // Use the config manager to get the data for us
  190. GetStatus( &dwStatus, NULL );
  191. }
  192. if( dwStatus != 0L )
  193. {
  194. fRc = TRUE;
  195. //==============================================
  196. // OK, these are wild guesses at translation,
  197. // we may need to fiddle with these
  198. //==============================================
  199. if( dwStatus & DN_ROOT_ENUMERATED ||
  200. dwStatus & DN_DRIVER_LOADED ||
  201. dwStatus & DN_ENUM_LOADED ||
  202. dwStatus & DN_STARTED ){
  203. chsStatus = IDS_STATUS_OK;
  204. }
  205. // we don't care about these:
  206. // DN_MANUAL,DN_NOT_FIRST_TIME,DN_HARDWARE_ENUM,DN_FILTERED
  207. // DN_DISABLEABLE, DN_REMOVABLE,DN_MF_PARENT,DN_MF_CHILD
  208. // DN_NEED_TO_ENUM, DN_LIAR,DN_HAS_MARK
  209. if( dwStatus & DN_MOVED ||
  210. dwStatus & DN_WILL_BE_REMOVED){
  211. chsStatus = IDS_STATUS_Degraded;
  212. }
  213. if( dwStatus & DN_HAS_PROBLEM ||
  214. dwStatus & DN_PRIVATE_PROBLEM){
  215. chsStatus = IDS_STATUS_Error;
  216. }
  217. }
  218. return fRc;
  219. }
  220. ////////////////////////////////////////////////////////////////////////
  221. //
  222. // Function: CConfigMgrDevice::GetConfigMgrInfo
  223. //
  224. // Opens the appropriate Config Manager SubKey and loads values from
  225. // there.
  226. //
  227. // Inputs: None.
  228. //
  229. // Outputs: None.
  230. //
  231. // Return: TRUE/FALSE - Did we open the subkey and get the values
  232. // we wanted.
  233. //
  234. // Comments: Needs to be able to get read access to the registry.
  235. //
  236. ////////////////////////////////////////////////////////////////////////
  237. BOOL CConfigMgrDevice::GetConfigMgrInfo( void )
  238. {
  239. BOOL fReturn = FALSE;
  240. // For this to function correctly, we MUST have a value in
  241. // m_strConfigMgrName.
  242. if ( !m_strConfigMgrName.IsEmpty() ){
  243. HKEY hConfigMgrKey = NULL;
  244. CHString strKeyName( CONFIGMGR_ENUM_KEY );
  245. // Open the config manager key
  246. strKeyName += m_strConfigMgrName; // Don't forget to concat name Sanj, you big dummy
  247. if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_DYN_DATA,
  248. TOBSTRT(strKeyName),
  249. 0,
  250. KEY_READ,
  251. &hConfigMgrKey ) )
  252. {
  253. ON_BLOCK_EXIT ( RegCloseKey, hConfigMgrKey ) ;
  254. // Get our hardware key, status and our resource allocation
  255. if ( GetHardwareKey( hConfigMgrKey ) )
  256. {
  257. // Status is device status information from the registry.
  258. if ( GetStatusInfo( hConfigMgrKey ) )
  259. {
  260. fReturn = GetResourceAllocation( hConfigMgrKey );
  261. }
  262. }
  263. }
  264. }
  265. return FALSE;
  266. }
  267. ////////////////////////////////////////////////////////////////////////
  268. //
  269. // Function: CConfigMgrDevice::GetHardwareKey
  270. //
  271. // Gets the Config Manager HardwareKey value.
  272. //
  273. // Inputs: HKEY Key - Config Manager SubKey to open.
  274. //
  275. // Outputs: None.
  276. //
  277. // Return: TRUE/FALSE - Did we get the value.
  278. //
  279. // Comments: Needs to be able to get read access to the registry.
  280. //
  281. ////////////////////////////////////////////////////////////////////////
  282. BOOL CConfigMgrDevice::GetHardwareKey( HKEY hKey )
  283. {
  284. BOOL fReturn = FALSE;
  285. DWORD dwSizeHardwareKeyName = 0;
  286. // First, get the Hardware key name buffer size.
  287. if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
  288. CONFIGMGR_DEVICE_HARDWAREKEY_VALUE,
  289. 0,
  290. NULL,
  291. NULL,
  292. &dwSizeHardwareKeyName ) )
  293. {
  294. m_strHardwareKey = L"";
  295. // We do it this way since CHString no longer changes types with TCHAR
  296. // LPTSTR pszBuffer = m_strHardwareKey.GetBuffer( dwSizeHardwareKeyName );
  297. LPTSTR pszBuffer = new TCHAR[dwSizeHardwareKeyName]; //(LPTSTR) malloc(dwSizeHardwareKeyName * sizeof(TCHAR));
  298. if ( NULL != pszBuffer )
  299. {
  300. try
  301. {
  302. // Now get the real buffer
  303. if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
  304. CONFIGMGR_DEVICE_HARDWAREKEY_VALUE,
  305. 0,
  306. NULL,
  307. (LPBYTE) pszBuffer,
  308. &dwSizeHardwareKeyName ) )
  309. {
  310. fReturn = TRUE;
  311. m_strHardwareKey = pszBuffer;
  312. }
  313. }
  314. catch ( ... )
  315. {
  316. delete [] pszBuffer;
  317. throw ;
  318. }
  319. delete [] pszBuffer;
  320. }
  321. else
  322. {
  323. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  324. }
  325. } // IF RegQueryValue Ex
  326. return fReturn;
  327. }
  328. ////////////////////////////////////////////////////////////////////////
  329. //
  330. // Function: CConfigMgrDevice::GetResourceAllocation
  331. //
  332. // Gets the Config Manager Device Resource Allocation and fills
  333. // out the resource list as appropriate.
  334. //
  335. // Inputs: HKEY Key - Config Manager SubKey to open.
  336. //
  337. // Outputs: None.
  338. //
  339. // Return: TRUE/FALSE - Did we get the value.
  340. //
  341. // Comments: Must have read access to the registry.
  342. //
  343. ////////////////////////////////////////////////////////////////////////
  344. BOOL CConfigMgrDevice::GetResourceAllocation( HKEY hKey )
  345. {
  346. BOOL fReturn = FALSE;
  347. DWORD dwSizeAllocation = 0;
  348. // First, get the buffer size.
  349. if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
  350. CONFIGMGR_DEVICE_ALLOCATION_VALUE,
  351. 0,
  352. NULL,
  353. NULL,
  354. &dwSizeAllocation ) )
  355. {
  356. // Initialize pbData, using a stack buffer if we can (most of the time
  357. // this will probably suffice).
  358. LPBYTE pbData = new BYTE[dwSizeAllocation];
  359. // Just be safe here.
  360. if ( NULL != pbData )
  361. {
  362. // Now get the real buffer
  363. if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
  364. CONFIGMGR_DEVICE_ALLOCATION_VALUE,
  365. 0,
  366. NULL,
  367. pbData,
  368. &dwSizeAllocation ) )
  369. {
  370. m_pbAllocationData = pbData;
  371. m_dwSizeAllocationData = dwSizeAllocation;
  372. fReturn = TRUE;
  373. }
  374. // DON'T delete the data buffer. The object destructor does it.
  375. // delete [] pbData;
  376. else
  377. {
  378. // MUST delete here though !!!
  379. delete [] pbData;
  380. }
  381. }
  382. else
  383. {
  384. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  385. }
  386. } // IF RegQueryValue Ex
  387. return fReturn;
  388. }
  389. ////////////////////////////////////////////////////////////////////////
  390. //
  391. // Function: CConfigMgrDevice::GetStatusInfo
  392. //
  393. // Gets the Config Manager Device Status and Problem fields.
  394. //
  395. // Inputs: HKEY Key - Config Manager SubKey to open.
  396. //
  397. // Outputs: None.
  398. //
  399. // Return: TRUE/FALSE - Did we get the values.
  400. //
  401. // Comments: Must have read access to the registry.
  402. //
  403. ////////////////////////////////////////////////////////////////////////
  404. BOOL CConfigMgrDevice::GetStatusInfo( HKEY hKey )
  405. {
  406. BOOL fReturn = FALSE;
  407. DWORD dwBuffSize = sizeof(DWORD);
  408. // First, get the status value, then get the problem value.
  409. if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
  410. CONFIGMGR_DEVICE_STATUS_VALUET,
  411. 0,
  412. NULL,
  413. (LPBYTE) &m_dwStatus,
  414. &dwBuffSize ) )
  415. {
  416. // Now get the problem
  417. dwBuffSize = sizeof(DWORD);
  418. if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
  419. CONFIGMGR_DEVICE_PROBLEM_VALUE,
  420. 0,
  421. NULL,
  422. (LPBYTE) &m_dwProblem,
  423. &dwBuffSize ) ) {
  424. fReturn = TRUE;
  425. }
  426. } // IF RegQueryValue Ex
  427. return fReturn;
  428. }
  429. ////////////////////////////////////////////////////////////////////////
  430. //
  431. // Function: CConfigMgrDevice::GetDeviceInfo
  432. //
  433. // Uses the HardwareKey value to get further device information.
  434. //
  435. // Inputs: None.
  436. //
  437. // Outputs: None.
  438. //
  439. // Return: TRUE/FALSE - Did we get the value(s).
  440. //
  441. // Comments: Needs to be able to get read access to the registry.
  442. //
  443. ////////////////////////////////////////////////////////////////////////
  444. BOOL CConfigMgrDevice::GetDeviceInfo( void )
  445. {
  446. BOOL fReturn = FALSE;
  447. // For this to function correctly, we MUST have a value in
  448. // m_strHardwareKey
  449. if ( !m_strHardwareKey.IsEmpty() )
  450. {
  451. HKEY hDeviceKey = NULL;
  452. CHString strKeyName( LOCALMACHINE_ENUM_KEY );
  453. // Open the config manager key
  454. strKeyName += m_strHardwareKey; // Don't forget to concat name Sanj, you big dummy
  455. if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  456. TOBSTRT(strKeyName),
  457. 0,
  458. KEY_READ,
  459. &hDeviceKey ) )
  460. {
  461. ON_BLOCK_EXIT ( RegCloseKey, hDeviceKey ) ;
  462. fReturn = GetDeviceDesc( hDeviceKey );
  463. }
  464. }
  465. return FALSE;
  466. }
  467. ////////////////////////////////////////////////////////////////////////
  468. //
  469. // Function: CConfigMgrDevice::GetDeviceDesc
  470. //
  471. // Gets the Device Description from the supplied subkey.
  472. //
  473. // Inputs: HKEY Key - Device SubKey to get info from.
  474. //
  475. // Outputs: None.
  476. //
  477. // Return: TRUE/FALSE - Did we get the value.
  478. //
  479. // Comments: If the value doesn't exist, this is not an error. We'll
  480. // just clear the value.
  481. //
  482. ////////////////////////////////////////////////////////////////////////
  483. BOOL CConfigMgrDevice::GetDeviceDesc( HKEY hKey )
  484. {
  485. BOOL fReturn = FALSE;
  486. DWORD dwSizeDeviceName = 0;
  487. LONG lReturn = 0L;
  488. // First, get the DeviceDesc buffer size.
  489. if ( ( lReturn = RegQueryValueEx( hKey,
  490. CONFIGMGR_DEVICEDESC_VALUE,
  491. 0,
  492. NULL,
  493. NULL,
  494. &dwSizeDeviceName ) )
  495. == ERROR_SUCCESS )
  496. {
  497. //LPTSTR pszBuffer = m_strDeviceDesc.GetBuffer( dwSizeDeviceName );
  498. LPTSTR pszBuffer = new TCHAR[dwSizeDeviceName]; //(LPTSTR) malloc(dwSizeDeviceName * sizeof(TCHAR));
  499. m_strDeviceDesc = L"";
  500. // Just be safe here.
  501. if ( NULL != pszBuffer )
  502. {
  503. try
  504. {
  505. // Now get the real buffer
  506. if ( ( lReturn = RegQueryValueEx( hKey,
  507. CONFIGMGR_DEVICEDESC_VALUE,
  508. 0,
  509. NULL,
  510. (LPBYTE) pszBuffer,
  511. &dwSizeDeviceName ) )
  512. == ERROR_SUCCESS )
  513. {
  514. fReturn = TRUE;
  515. m_strDeviceDesc = pszBuffer;
  516. }
  517. else
  518. {
  519. fReturn = ( ERROR_FILE_NOT_FOUND == lReturn );
  520. }
  521. }
  522. catch ( ... )
  523. {
  524. delete [] pszBuffer;
  525. throw ;
  526. }
  527. //m_strDeviceDesc.ReleaseBuffer(); // Resets to string size
  528. delete [] pszBuffer;
  529. }
  530. else
  531. {
  532. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  533. }
  534. } // IF RegQueryValue Ex
  535. else
  536. {
  537. fReturn = ( ERROR_FILE_NOT_FOUND == lReturn );
  538. }
  539. return fReturn;
  540. }
  541. ////////////////////////////////////////////////////////////////////////
  542. //
  543. // Function: CConfigMgrDevice::GetIRQResources
  544. //
  545. // Walks the device's allocated resource configuration and fills out
  546. // an IRQ collection with IRQ Resources for this device.
  547. //
  548. // Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
  549. //
  550. // Outputs: CIRQCollection& irqList - List to populate
  551. //
  552. // Return: TRUE/FALSE Error occured or not (empty list
  553. // is NOT an error).
  554. //
  555. // Comments: Requires READ Access to the data.
  556. //
  557. ////////////////////////////////////////////////////////////////////////
  558. BOOL CConfigMgrDevice::GetIRQResources( CIRQCollection& irqList, CNT4ServiceToResourceMap *pResourceMap )
  559. {
  560. BOOL fReturn = TRUE;
  561. CResourceCollection resourceList;
  562. // Clear the irq list first
  563. irqList.Empty();
  564. // Populate the resource list first, specifying only IRQ resources, then we will
  565. // need to Dup the data into the irq list. If we go to an AddRef/Release model, we
  566. // will be able to copy pointers directly, saving time by not forcing us to
  567. // alloc and realloc data.
  568. if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_IRQ ) )
  569. {
  570. REFPTR_POSITION pos;
  571. if ( resourceList.BeginEnum( pos ) )
  572. {
  573. CResourceDescriptorPtr pResource;
  574. // Check each resource, validating it is an IRQ before we cast. Because
  575. // the call to Walk should have filtered for us, these should be the
  576. // only resources returned.
  577. for ( pResource.Attach(resourceList.GetNext( pos )) ;
  578. pResource != NULL && fReturn ;
  579. pResource.Attach(resourceList.GetNext( pos )) )
  580. {
  581. ASSERT_BREAK( pResource->GetResourceType() == ResType_IRQ );
  582. if ( pResource->GetResourceType() == ResType_IRQ )
  583. {
  584. // Cast the resource (we know the type) and add it to the
  585. // supplied list and we're done. (Ain't AddRef/Release easy?).
  586. CIRQDescriptor* pIRQ = (CIRQDescriptor*) pResource.GetInterfacePtr();
  587. irqList.Add( pIRQ );
  588. } // IF an IRQ Resource
  589. } // WHILE retrieving descriptors
  590. resourceList.EndEnum();
  591. } // BeginEnum
  592. } // IF walked list
  593. return fReturn;
  594. }
  595. ////////////////////////////////////////////////////////////////////////
  596. //
  597. // Function: CConfigMgrDevice::GetIOResources
  598. //
  599. // Walks the device's allocated resource configuration and fills out
  600. // an IO collection with IO Resources for this device.
  601. //
  602. // Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
  603. //
  604. // Outputs: CIOCollection& IOList - List to populate
  605. //
  606. // Return: TRUE/FALSE Error occured or not (empty list
  607. // is NOT an error).
  608. //
  609. // Comments: Requires READ Access to the data.
  610. //
  611. ////////////////////////////////////////////////////////////////////////
  612. BOOL CConfigMgrDevice::GetIOResources( CIOCollection& IOList, CNT4ServiceToResourceMap *pResourceMap )
  613. {
  614. BOOL fReturn = TRUE;
  615. CResourceCollection resourceList;
  616. // Clear the IO list first
  617. IOList.Empty();
  618. // Populate the resource list first, specifying only IO resources, then we will
  619. // need to Dup the data into the IO list. If we go to an AddRef/Release model, we
  620. // will be able to copy pointers directly, saving time by not forcing us to
  621. // alloc and realloc data.
  622. if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_IO ) )
  623. {
  624. REFPTR_POSITION pos;
  625. if ( resourceList.BeginEnum( pos ) )
  626. {
  627. CResourceDescriptorPtr pResource;
  628. // Check each resource, validating it is an IO before we cast. Because
  629. // the call to Walk should have filtered for us, these should be the
  630. // only resources returned.
  631. for ( pResource.Attach(resourceList.GetNext( pos )) ;
  632. pResource != NULL && fReturn ;
  633. pResource.Attach(resourceList.GetNext( pos )) )
  634. {
  635. ASSERT_BREAK( pResource->GetResourceType() == ResType_IO );
  636. if ( pResource->GetResourceType() == ResType_IO )
  637. {
  638. // Cast the resource (we know the type) and add it to the
  639. // supplied list and we're done. (Ain't AddRef/Release easy?).
  640. CIODescriptor* pIO = (CIODescriptor*) pResource.GetInterfacePtr();
  641. IOList.Add( pIO );
  642. } // IF an IO Resource
  643. } // WHILE retrieving descriptors
  644. resourceList.EndEnum();
  645. } // BeginEnum()
  646. } // IF walked list
  647. return fReturn;
  648. }
  649. ////////////////////////////////////////////////////////////////////////
  650. //
  651. // Function: CConfigMgrDevice::GetDMAResources
  652. //
  653. // Walks the device's allocated resource configuration and fills out
  654. // an DMA collection with DMA Resources for this device.
  655. //
  656. // Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
  657. //
  658. // Outputs: CDMACollection& DMAList - List to populate
  659. //
  660. // Return: TRUE/FALSE Error occured or not (empty list
  661. // is NOT an error).
  662. //
  663. // Comments: Requires READ Access to the data.
  664. //
  665. ////////////////////////////////////////////////////////////////////////
  666. BOOL CConfigMgrDevice::GetDMAResources( CDMACollection& DMAList, CNT4ServiceToResourceMap *pResourceMap )
  667. {
  668. BOOL fReturn = TRUE;
  669. CResourceCollection resourceList;
  670. // Clear the DMA list first
  671. DMAList.Empty();
  672. // Populate the resource list first, specifying only DMA resources, then we will
  673. // need to Dup the data into the DMA list. If we go to an AddRef/Release model, we
  674. // will be able to copy pointers directly, saving time by not forcing us to
  675. // alloc and realloc data.
  676. if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_DMA ) )
  677. {
  678. REFPTR_POSITION pos;
  679. if ( resourceList.BeginEnum( pos ) )
  680. {
  681. CResourceDescriptorPtr pResource;
  682. // Check each resource, validating it is an DMA before we cast. Because
  683. // the call to Walk should have filtered for us, these should be the
  684. // only resources returned.
  685. for ( pResource.Attach(resourceList.GetNext( pos )) ;
  686. pResource != NULL && fReturn ;
  687. pResource.Attach(resourceList.GetNext( pos )) )
  688. {
  689. ASSERT_BREAK( pResource->GetResourceType() == ResType_DMA );
  690. if ( pResource->GetResourceType() == ResType_DMA )
  691. {
  692. // Cast the resource (we know the type) and add it to the
  693. // supplied list and we're done. (Ain't AddRef/Release easy?).
  694. CDMADescriptor* pDMA = (CDMADescriptor*) pResource.GetInterfacePtr();
  695. DMAList.Add( pDMA );
  696. } // IF an DMA Resource
  697. } // WHILE retrieving descriptors
  698. resourceList.EndEnum();
  699. } // BeginEnum
  700. } // IF walked list
  701. return fReturn;
  702. }
  703. ////////////////////////////////////////////////////////////////////////
  704. //
  705. // Function: CConfigMgrDevice::GetDeviceMemoryResources
  706. //
  707. // Walks the device's allocated resource configuration and fills out
  708. // an DeviceMemory collection with DeviceMemory Resources for this device.
  709. //
  710. // Inputs: CNT4ServiceToResourceMap* pResourceMap - For NT 4.
  711. //
  712. // Outputs: CDeviceMemoryCollection& DeviceMemoryList - List to populate
  713. //
  714. // Return: TRUE/FALSE Error occured or not (empty list
  715. // is NOT an error).
  716. //
  717. // Comments: Requires READ Access to the data.
  718. //
  719. ////////////////////////////////////////////////////////////////////////
  720. BOOL CConfigMgrDevice::GetDeviceMemoryResources( CDeviceMemoryCollection& DeviceMemoryList, CNT4ServiceToResourceMap *pResourceMap )
  721. {
  722. BOOL fReturn = TRUE;
  723. CResourceCollection resourceList;
  724. // Clear the DeviceMemory list first
  725. DeviceMemoryList.Empty();
  726. // Populate the resource list first, specifying only DeviceMemory resources, then we will
  727. // need to Dup the data into the DeviceMemory list. If we go to an AddRef/Release model, we
  728. // will be able to copy pointers directly, saving time by not forcing us to
  729. // alloc and realloc data.
  730. if ( WalkAllocatedResources( resourceList, pResourceMap, ResType_Mem ) )
  731. {
  732. REFPTR_POSITION pos;
  733. if ( resourceList.BeginEnum( pos ) )
  734. {
  735. CResourceDescriptorPtr pResource;
  736. // Check each resource, validating it is an DeviceMemory before we cast. Because
  737. // the call to Walk should have filtered for us, these should be the
  738. // only resources returned.
  739. for ( pResource.Attach(resourceList.GetNext( pos )) ;
  740. pResource != NULL && fReturn ;
  741. pResource.Attach(resourceList.GetNext( pos )) )
  742. {
  743. ASSERT_BREAK( pResource->GetResourceType() == ResType_Mem );
  744. if ( pResource->GetResourceType() == ResType_Mem )
  745. {
  746. // Cast the resource (we know the type) and add it to the
  747. // supplied list and we're done. (Ain't AddRef/Release easy?).
  748. CDeviceMemoryDescriptor* pDeviceMemory = (CDeviceMemoryDescriptor*) pResource.GetInterfacePtr();;
  749. DeviceMemoryList.Add( pDeviceMemory );
  750. } // IF an DeviceMemory Resource
  751. } // WHILE retrieving descriptors
  752. resourceList.EndEnum();
  753. } // BeginEnum
  754. } // IF walked list
  755. return fReturn;
  756. }
  757. ////////////////////////////////////////////////////////////////////////
  758. //
  759. // Function: CConfigMgrDevice::WalkAllocatedResources
  760. //
  761. // Walks the device's allocated resource configuration and fills out
  762. // a resource collection with the appropriate data.
  763. //
  764. // Inputs: RESOURCEID resType - Types of resources
  765. // to return.
  766. // CNT4ServiceToResourceMap* pResourceMap - For NT 4.
  767. //
  768. // Outputs: CResourceCollection& resourceList - List to populate
  769. //
  770. // Return: TRUE/FALSE List found or not.
  771. //
  772. // Comments: Requires READ Access to the data.
  773. //
  774. ////////////////////////////////////////////////////////////////////////
  775. BOOL CConfigMgrDevice::WalkAllocatedResources( CResourceCollection& resourceList, CNT4ServiceToResourceMap *pResourceMap, RESOURCEID resType )
  776. {
  777. LOG_CONF LogConfig;
  778. RES_DES ResDes;
  779. CONFIGRET cr;
  780. BOOL fReturn = FALSE ;
  781. // Dump the resource list first
  782. resourceList.Empty();
  783. // If we're on NT 4, we gotta march to the beat of a different
  784. // drummer.
  785. #ifdef NTONLY
  786. if ( IsWinNT4() )
  787. {
  788. // Convert Resource Type from RESOURCEID to CM_RESOURCE_TYPE
  789. fReturn = WalkAllocatedResourcesNT4( resourceList, pResourceMap, RESOURCEIDToCM_RESOURCE_TYPE( resType ) );
  790. }
  791. else
  792. #endif
  793. {
  794. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  795. if ( pconfigmgr )
  796. {
  797. if ( pconfigmgr->IsValid () )
  798. {
  799. #ifdef NTONLY
  800. BOOL fIsNT5 = IsWinNT5();
  801. #endif
  802. // Get the allocated Logical Configuration. From there, we can iterate resource descriptors
  803. // until we find an IRQ Descriptor.
  804. cr = CR_NO_MORE_LOG_CONF ;
  805. if ( (
  806. pconfigmgr->CM_Get_First_Log_Conf( &LogConfig, m_dn, ALLOC_LOG_CONF ) == CR_SUCCESS ||
  807. pconfigmgr->CM_Get_First_Log_Conf( &LogConfig, m_dn, BOOT_LOG_CONF ) == CR_SUCCESS
  808. ) )
  809. {
  810. cr = CR_SUCCESS ;
  811. RESOURCEID resID;
  812. // To get the first Resource Descriptor, we pass in the logical configuration.
  813. // The config manager knows how to handle this (or at least that's what the
  814. // ahem-"documentation" sez.
  815. RES_DES LastResDes = LogConfig;
  816. do
  817. {
  818. // Get only resources of the type we were made to retrieve
  819. cr = pconfigmgr->CM_Get_Next_Res_Des( &ResDes, LastResDes, resType, &resID, 0 );
  820. // Clean up the prior resource descriptor handle
  821. if ( LastResDes != LogConfig )
  822. {
  823. pconfigmgr->CM_Free_Res_Des_Handle( LastResDes );
  824. }
  825. if ( CR_SUCCESS == cr )
  826. {
  827. // CAUTION! On NT5, if we are doing a resource Type that is NOT ResType_All,
  828. // the OS does not appear to fill out ResID. I guess the assumption being
  829. // that we already know the resource type we are trying to get. HOWEVER,
  830. // if any bits like ResType_Ignored are set, NT 5 appears to be smartly
  831. // dropping those resources, so we'll just set resID here as if the
  832. // call on NT 5 had done anything.
  833. #ifdef NTONLY
  834. if ( ResType_All != resType
  835. && fIsNT5 )
  836. {
  837. resID = resType;
  838. }
  839. #endif
  840. ULONG ulDataSize = 0;
  841. if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_Res_Des_Data_Size( &ulDataSize, ResDes, 0 ) ) )
  842. {
  843. ulDataSize += 10; // Pad for 10 bytes of safety
  844. BYTE* pbData = new BYTE[ulDataSize];
  845. if ( NULL != pbData )
  846. {
  847. try
  848. {
  849. cr = pconfigmgr->CM_Get_Res_Des_Data( ResDes, pbData, ulDataSize, 0 );
  850. if ( CR_SUCCESS == cr )
  851. {
  852. if ( !AddResourceToList( resID, pbData, ulDataSize, resourceList ) )
  853. {
  854. cr = CR_OUT_OF_MEMORY;
  855. }
  856. }
  857. }
  858. catch ( ... )
  859. {
  860. delete [] pbData;
  861. throw ;
  862. }
  863. // We're done with the data
  864. delete [] pbData;
  865. } // IF NULL != pbData
  866. else
  867. {
  868. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  869. }
  870. } // IF Get Data Size
  871. // Store the last descriptor, so we can go on to the next one.
  872. LastResDes = ResDes;
  873. } // If we got a descriptor
  874. } while ( CR_SUCCESS == cr );
  875. // If we blew out on this, we're okay, since the error means we ran out of
  876. // resource descriptors.
  877. if ( CR_NO_MORE_RES_DES == cr )
  878. {
  879. cr = CR_SUCCESS;
  880. }
  881. // Clean up the logical configuration handle
  882. pconfigmgr->CM_Free_Log_Conf_Handle( LogConfig );
  883. } // IF got alloc logconf
  884. fReturn = ( CR_SUCCESS == cr );
  885. }
  886. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  887. }
  888. } // else !NT 4
  889. return fReturn;
  890. }
  891. ////////////////////////////////////////////////////////////////////////
  892. //
  893. // Function: CConfigMgrDevice::AddResourceToList
  894. //
  895. // Copies resource data as necessary, coercing from 16 to 32 bit as
  896. // necessary, then adds the resource to the supplied list.
  897. //
  898. // Inputs: RESOURCEID resourceID - What resource is this?
  899. // LPVOID pResource - The resource
  900. // DWORD dwResourceLength - How long is it?
  901. //
  902. // Outputs: CResourceCollection& resourceList - List to populate
  903. //
  904. // Return: TRUE/FALSE Add succeeded or failed.
  905. //
  906. // Comments: None.
  907. //
  908. ////////////////////////////////////////////////////////////////////////
  909. BOOL CConfigMgrDevice::AddResourceToList( RESOURCEID resourceID, LPVOID pResource, DWORD dwResourceLength, CResourceCollection& resourceList )
  910. {
  911. IRQ_DES irqDes;
  912. IOWBEM_DES ioDes;
  913. DMA_DES dmaDes;
  914. MEM_DES memDes;
  915. // Don't know if Config Manager will return a resource ignored value,
  916. // so what we'll do here is check if the ignored bit is set, and for
  917. // now, ASSERT
  918. //ASSERT_BREAK( !(resourceID & ResType_Ignored_Bit) );
  919. // Filter out extraneous bits
  920. RESOURCEID resType = ( resourceID & RESOURCE_TYPE_MASK );
  921. // Hey, I'm an optimist
  922. BOOL fReturn = TRUE;
  923. // Different structures for 32/16 bit CFGMGR, so if
  924. // we ain't on WINNT, we need to coerce the data into
  925. // a proper structure.
  926. #ifdef WIN9XONLY
  927. {
  928. // We have to cheat here and coerce the data from a 16-bit
  929. // structure into a matching 32-bit structure.
  930. switch ( resType )
  931. {
  932. case ResType_IRQ:
  933. {
  934. IRQDes16To32( (PIRQ_DES16) pResource, &irqDes );
  935. }
  936. break;
  937. case ResType_IO:
  938. {
  939. IODes16To32( (PIO_DES16) pResource, &ioDes );
  940. }
  941. break;
  942. case ResType_DMA:
  943. {
  944. DMADes16To32( (PDMA_DES16) pResource, &dmaDes );
  945. }
  946. break;
  947. case ResType_Mem:
  948. {
  949. MEMDes16To32( (PMEM_DES16) pResource, &memDes );
  950. }
  951. break;
  952. } // switch ResourceID
  953. } // IF !IsWinNT
  954. #endif
  955. #ifdef NTONLY
  956. {
  957. // Just copy the resource data into the appropriate descriptor
  958. switch ( resType )
  959. {
  960. case ResType_IRQ:
  961. {
  962. CopyMemory( &irqDes, pResource, sizeof(IRQ_DES) );
  963. }
  964. break;
  965. case ResType_IO:
  966. {
  967. // Because 16-bit has values 32-bit does not, we cheated and came up with our
  968. // own structure. 32-bit values are at the top, so zero out the struct and
  969. // trhe other values will just be ignored...yeah, that's the ticket.
  970. ZeroMemory( &ioDes, sizeof(ioDes) );
  971. CopyMemory( &ioDes, pResource, sizeof(IO_DES) );
  972. }
  973. break;
  974. case ResType_DMA:
  975. {
  976. CopyMemory( &dmaDes, pResource, sizeof(DMA_DES) );
  977. }
  978. break;
  979. case ResType_Mem:
  980. {
  981. CopyMemory( &memDes, pResource, sizeof(MEM_DES) );
  982. }
  983. break;
  984. } // SWITCH ResourceId
  985. } // else IsWinNT
  986. #endif
  987. CResourceDescriptorPtr pResourceDescriptor;
  988. // Just copy the resource data into the appropriate descriptor
  989. bool bAdd = true;
  990. switch ( resType )
  991. {
  992. case ResType_IRQ:
  993. {
  994. pResourceDescriptor.Attach( (CResourceDescriptor*) new CIRQDescriptor( resourceID, irqDes, this ) );
  995. }
  996. break;
  997. case ResType_IO:
  998. {
  999. bAdd = (ioDes).IOD_Alloc_End >= (ioDes).IOD_Alloc_Base;
  1000. pResourceDescriptor.Attach ( (CResourceDescriptor*) new CIODescriptor( resourceID, ioDes, this ) );
  1001. }
  1002. break;
  1003. case ResType_DMA:
  1004. {
  1005. pResourceDescriptor.Attach ( (CResourceDescriptor*) new CDMADescriptor( resourceID, dmaDes, this ) );
  1006. }
  1007. break;
  1008. case ResType_Mem:
  1009. {
  1010. pResourceDescriptor.Attach ( (CResourceDescriptor*) new CDeviceMemoryDescriptor( resourceID, memDes, this ) );
  1011. }
  1012. break;
  1013. default:
  1014. {
  1015. // We don't know what it is, but make a raw one anyway
  1016. pResourceDescriptor.Attach ( new CResourceDescriptor( resourceID, pResource, dwResourceLength, this ) );
  1017. }
  1018. break;
  1019. } // SWITCH ResourceId
  1020. if (bAdd)
  1021. {
  1022. if ( NULL != pResourceDescriptor )
  1023. {
  1024. fReturn = resourceList.Add( pResourceDescriptor );
  1025. }
  1026. else
  1027. {
  1028. fReturn = FALSE;
  1029. }
  1030. }
  1031. else
  1032. {
  1033. fReturn = TRUE;
  1034. }
  1035. return fReturn;
  1036. }
  1037. ////////////////////////////////////////////////////////////////////////
  1038. //
  1039. // Function: CConfigMgrDevice::WalkAllocatedResourcesNT4
  1040. //
  1041. // Because none of the logical configuration stuff in NT4 seems to
  1042. // work worth a darn, we're gonna manhandle our own data from the
  1043. // registry data under HKLM\HARDWARE\RESOURCEMAP.
  1044. //
  1045. // Inputs: CNT4ServiceToResourceMap* pResourceMap - Resource map
  1046. // to use for the walk. We create
  1047. // one if this is NULL.
  1048. // CM_RESOURCE_TYPE resType - Resource Types to return.
  1049. //
  1050. // Outputs: CResourceCollection& resourceList - List to populate
  1051. //
  1052. // Return: TRUE/FALSE List found or not.
  1053. //
  1054. // Comments: Requires READ Access to the data.
  1055. //
  1056. ////////////////////////////////////////////////////////////////////////
  1057. #ifdef NTONLY
  1058. BOOL CConfigMgrDevice::WalkAllocatedResourcesNT4(
  1059. CResourceCollection& resourceList,
  1060. CNT4ServiceToResourceMap *pResourceMap,
  1061. CM_RESOURCE_TYPE resType )
  1062. {
  1063. BOOL fReturn = FALSE;
  1064. CHString strServiceName;
  1065. // Allocate a map if we need one. Otherwise use the one passed in that somebody
  1066. // theoretically has cached off somewhere.
  1067. CNT4ServiceToResourceMap* pLocalMap = pResourceMap;
  1068. if ( NULL == pLocalMap )
  1069. {
  1070. pLocalMap = new CNT4ServiceToResourceMap;
  1071. }
  1072. if ( NULL != pLocalMap )
  1073. {
  1074. try
  1075. {
  1076. // Get our service name. If this succeeds, pull our resources from the reource map
  1077. if ( GetService( strServiceName ) )
  1078. {
  1079. fReturn = GetServiceResourcesNT4( strServiceName, *pLocalMap, resourceList, resType );
  1080. }
  1081. }
  1082. catch ( ... )
  1083. {
  1084. if ( pLocalMap != pResourceMap )
  1085. {
  1086. delete pLocalMap;
  1087. }
  1088. throw ;
  1089. }
  1090. // Clean up the local map if we allocated one
  1091. if ( pLocalMap != pResourceMap )
  1092. {
  1093. delete pLocalMap;
  1094. }
  1095. }
  1096. else
  1097. {
  1098. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1099. }
  1100. return fReturn;
  1101. }
  1102. #endif
  1103. #ifdef NTONLY
  1104. BOOL CConfigMgrDevice::GetServiceResourcesNT4( LPCTSTR pszServiceName, CNT4ServiceToResourceMap& resourceMap, CResourceCollection& resourceList, CM_RESOURCE_TYPE cmrtFilter/*=CmResourceTypeNull*/ )
  1105. {
  1106. BOOL fReturn = TRUE;
  1107. LPRESOURCE_DESCRIPTOR pResourceDescriptor;
  1108. // Iterate the resources, looking for matches against values we may be filtering
  1109. // for.
  1110. DWORD dwNumResources = resourceMap.NumServiceResources( pszServiceName );
  1111. for ( DWORD dwCtr = 0;
  1112. dwCtr < dwNumResources
  1113. && fReturn;
  1114. dwCtr++ )
  1115. {
  1116. pResourceDescriptor = resourceMap.GetServiceResource( pszServiceName, dwCtr );
  1117. // Grab the resource if it's our filter, or our filter is NULL, meaning grab everything
  1118. if ( NULL != pResourceDescriptor
  1119. && ( CmResourceTypeNull == cmrtFilter
  1120. || cmrtFilter == pResourceDescriptor->CmResourceDescriptor.Type
  1121. )
  1122. )
  1123. {
  1124. CResourceDescriptorPtr pResource;
  1125. // Perform appropriate type coercsions, and hook the resource into the resource
  1126. /// list.
  1127. switch ( pResourceDescriptor->CmResourceDescriptor.Type )
  1128. {
  1129. case CmResourceTypeInterrupt:
  1130. {
  1131. IRQ_DES irqDes;
  1132. NT4IRQToIRQ_DES( pResourceDescriptor, &irqDes );
  1133. pResource.Attach(new CIRQDescriptor( ResType_IRQ, irqDes, this ) );
  1134. }
  1135. break;
  1136. case CmResourceTypePort:
  1137. {
  1138. IOWBEM_DES ioDes;
  1139. NT4IOToIOWBEM_DES( pResourceDescriptor, &ioDes );
  1140. pResource.Attach(new CIODescriptor( ResType_IO, ioDes, this ) );
  1141. }
  1142. break;
  1143. case CmResourceTypeMemory:
  1144. {
  1145. MEM_DES memDes;
  1146. NT4MEMToMEM_DES( pResourceDescriptor, &memDes );
  1147. pResource.Attach(new CDeviceMemoryDescriptor( ResType_Mem, memDes, this ));
  1148. }
  1149. break;
  1150. case CmResourceTypeDma:
  1151. {
  1152. DMA_DES dmaDes;
  1153. NT4DMAToDMA_DES( pResourceDescriptor, &dmaDes );
  1154. pResource.Attach(new CDMADescriptor( ResType_DMA, dmaDes, this ));
  1155. }
  1156. break;
  1157. // If it ain't one of these four, there ain't a whole heck of a
  1158. // lot we're gonna do here
  1159. }
  1160. if ( NULL != pResource )
  1161. {
  1162. fReturn = resourceList.Add( pResource );
  1163. }
  1164. else
  1165. {
  1166. // We beefed on a simple memory allocation. Get out of here.
  1167. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1168. }
  1169. } // IF resource was one we wanted to handle
  1170. } // FOR enum resources
  1171. return fReturn;
  1172. }
  1173. #endif
  1174. #ifdef NTONLY
  1175. CM_RESOURCE_TYPE CConfigMgrDevice::RESOURCEIDToCM_RESOURCE_TYPE( RESOURCEID resType )
  1176. {
  1177. CM_RESOURCE_TYPE cmResType = CmResourceTypeNull;
  1178. switch ( resType )
  1179. {
  1180. case ResType_All: cmResType = CmResourceTypeNull; break;
  1181. case ResType_IO: cmResType = CmResourceTypePort; break;
  1182. case ResType_IRQ: cmResType = CmResourceTypeInterrupt; break;
  1183. case ResType_DMA: cmResType = CmResourceTypeDma; break;
  1184. case ResType_Mem: cmResType = CmResourceTypeMemory; break;
  1185. default: cmResType = CmResourceTypeNull; break;
  1186. }
  1187. return cmResType;
  1188. }
  1189. #endif
  1190. #ifdef NTONLY
  1191. void CConfigMgrDevice::NT4IRQToIRQ_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PIRQ_DES pirqDes32 )
  1192. {
  1193. ZeroMemory( pirqDes32, sizeof(IRQ_DES) );
  1194. // 32-bit structure
  1195. //typedef struct IRQ_Des_s {
  1196. // DWORD IRQD_Count; // number of IRQ_RANGE structs in IRQ_RESOURCE
  1197. // DWORD IRQD_Type; // size (in bytes) of IRQ_RANGE (IRQType_Range)
  1198. // DWORD IRQD_Flags; // flags describing the IRQ (fIRQD flags)
  1199. // ULONG IRQD_Alloc_Num; // specifies the IRQ that was allocated
  1200. // ULONG IRQD_Affinity;
  1201. //} IRQ_DES, *PIRQ_DES;
  1202. pirqDes32->IRQD_Alloc_Num = pResourceDescriptor->CmResourceDescriptor.u.Interrupt.Level;
  1203. pirqDes32->IRQD_Affinity = pResourceDescriptor->CmResourceDescriptor.u.Interrupt.Affinity;
  1204. // We'll do our best on the flags conversion.
  1205. if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
  1206. {
  1207. pirqDes32->IRQD_Flags |= fIRQD_Share;
  1208. }
  1209. // Latched -> Edge? Have no idea, the other value in either case was Level,
  1210. // so here's a leap of faith.
  1211. if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_INTERRUPT_LATCHED )
  1212. {
  1213. pirqDes32->IRQD_Flags |= fIRQD_Edge;
  1214. }
  1215. }
  1216. #endif
  1217. #ifdef NTONLY
  1218. void CConfigMgrDevice::NT4IOToIOWBEM_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PIOWBEM_DES pioDes32 )
  1219. {
  1220. ZeroMemory( pioDes32, sizeof(IOWBEM_DES) );
  1221. // 32-bit structure
  1222. //typedef struct _IOWBEM_DES{
  1223. // DWORD IOD_Count; // number of IO_RANGE structs in IO_RESOURCE
  1224. // DWORD IOD_Type; // size (in bytes) of IO_RANGE (IOType_Range)
  1225. // DWORDLONG IOD_Alloc_Base; // base of allocated port range
  1226. // DWORDLONG IOD_Alloc_End; // end of allocated port range
  1227. // DWORD IOD_DesFlags; // flags relating to allocated port range
  1228. // BYTE IOD_Alloc_Alias; // From 16-bit-land
  1229. // BYTE IOD_Alloc_Decode; // From 16-bit-land
  1230. //} IOWBEM_DES;
  1231. LARGE_INTEGER liTemp; // Used to avoid 64bit alignment problems
  1232. liTemp.HighPart = pResourceDescriptor->CmResourceDescriptor.u.Port.Start.HighPart;
  1233. liTemp.LowPart = pResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart;
  1234. pioDes32->IOD_Alloc_Base = liTemp.QuadPart;
  1235. pioDes32->IOD_Alloc_End = pioDes32->IOD_Alloc_Base + ( pResourceDescriptor->CmResourceDescriptor.u.Port.Length - 1);
  1236. // Don't know what to do with Share disposition here, since CFGMGR32 doesn't seem to
  1237. // do it for IO Ports.
  1238. //if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
  1239. //{
  1240. // pioDes32->IOD_Flags |= fIRQD_Share;
  1241. //}
  1242. //
  1243. // Port Type flags convert straight across
  1244. //
  1245. //#define fIOD_PortType (0x1) // Bitmask,whether port is IO or memory
  1246. //#define fIOD_Memory (0x0) // Port resource really uses memory
  1247. //#define fIOD_IO (0x1) // Port resource uses IO ports
  1248. //#define CM_RESOURCE_PORT_MEMORY 0
  1249. //#define CM_RESOURCE_PORT_IO 1
  1250. pioDes32->IOD_DesFlags = pResourceDescriptor->CmResourceDescriptor.Flags;
  1251. }
  1252. #endif
  1253. #ifdef NTONLY
  1254. void CConfigMgrDevice::NT4MEMToMEM_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PMEM_DES pmemDes32 )
  1255. {
  1256. ZeroMemory( pmemDes32, sizeof(MEM_DES) );
  1257. // 32-bit structure
  1258. //typedef struct Mem_Des_s {
  1259. // DWORD MD_Count; // number of MEM_RANGE structs in MEM_RESOURCE
  1260. // DWORD MD_Type; // size (in bytes) of MEM_RANGE (MType_Range)
  1261. // DWORDLONG MD_Alloc_Base; // base memory address of range allocated
  1262. // DWORDLONG MD_Alloc_End; // end of allocated range
  1263. // DWORD MD_Flags; // flags describing allocated range (fMD flags)
  1264. // DWORD MD_Reserved;
  1265. //} MEM_DES, *PMEM_DES;
  1266. LARGE_INTEGER liTemp; // Used to avoid 64bit alignment problems
  1267. liTemp.HighPart = pResourceDescriptor->CmResourceDescriptor.u.Memory.Start.HighPart;
  1268. liTemp.LowPart = pResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart;
  1269. pmemDes32->MD_Alloc_Base = liTemp.QuadPart;
  1270. pmemDes32->MD_Alloc_End = pmemDes32->MD_Alloc_Base + ( pResourceDescriptor->CmResourceDescriptor.u.Memory.Length - 1);
  1271. // Don't know what to do with Share disposition here, since CFGMGR32 doesn't seem to
  1272. // do it for IO Ports.
  1273. //if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
  1274. //{
  1275. // pioDes32->MD_Flags |= fIRQD_Share;
  1276. //}
  1277. // Flag conversions I can do
  1278. if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_READ_WRITE )
  1279. {
  1280. pmemDes32->MD_Flags |= fMD_RAM;
  1281. pmemDes32->MD_Flags |= fMD_ReadAllowed;
  1282. }
  1283. else if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_READ_ONLY )
  1284. {
  1285. pmemDes32->MD_Flags |= fMD_ROM;
  1286. pmemDes32->MD_Flags |= fMD_ReadAllowed;
  1287. }
  1288. else if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_WRITE_ONLY )
  1289. {
  1290. pmemDes32->MD_Flags |= fMD_RAM;
  1291. pmemDes32->MD_Flags |= fMD_ReadDisallowed;
  1292. }
  1293. if ( pResourceDescriptor->CmResourceDescriptor.Flags & CM_RESOURCE_MEMORY_PREFETCHABLE )
  1294. {
  1295. pmemDes32->MD_Flags |= fMD_PrefetchAllowed;
  1296. }
  1297. // Don't know what to do with these flags:
  1298. //#define mMD_32_24 (0x2) // Bitmask, memory is 24 or 32-bit
  1299. //#define fMD_32_24 mMD_32_24 // compatibility
  1300. //#define fMD_24 (0x0) // Memory range is 24-bit
  1301. //#define fMD_32 (0x2) // Memory range is 32-bit
  1302. //#define mMD_CombinedWrite (0x10) // Bitmask,supports write-behind
  1303. //#define fMD_CombinedWrite mMD_CombinedWrite // compatibility
  1304. //#define fMD_CombinedWriteDisallowed (0x0) // no combined-write caching
  1305. //#define fMD_CombinedWriteAllowed (0x10) // supports combined-write caching
  1306. //#define mMD_Cacheable (0x20) // Bitmask,whether memory is cacheable
  1307. //#define fMD_NonCacheable (0x0) // Memory range is non-cacheable
  1308. //#define fMD_Cacheable (0x20) // Memory range is cacheable
  1309. }
  1310. #endif
  1311. #ifdef NTONLY
  1312. void CConfigMgrDevice::NT4DMAToDMA_DES( LPRESOURCE_DESCRIPTOR pResourceDescriptor, PDMA_DES pdmaDes32 )
  1313. {
  1314. ZeroMemory( pdmaDes32, sizeof(DMA_DES) );
  1315. // 32-bit structure
  1316. //typedef struct DMA_Des_s {
  1317. // DWORD DD_Count; // number of DMA_RANGE structs in DMA_RESOURCE
  1318. // DWORD DD_Type; // size (in bytes) of DMA_RANGE struct (DType_Range)
  1319. // DWORD DD_Flags; // Flags describing DMA channel (fDD flags)
  1320. // ULONG DD_Alloc_Chan; // Specifies the DMA channel that was allocated
  1321. //} DMA_DES, *PDMA_DES;
  1322. pdmaDes32->DD_Alloc_Chan = pResourceDescriptor->CmResourceDescriptor.u.Dma.Channel;
  1323. // Don't know what to do with Share disposition here, since CFGMGR32 doesn't seem to
  1324. // do it for IO Ports.
  1325. //if ( CmResourceShareShared == pResourceDescriptor->CmResourceDescriptor.ShareDisposition )
  1326. //{
  1327. // pioDes32->MD_Flags |= fIRQD_Share;
  1328. //}
  1329. // These are possible flags for DMA, but I don't see any values from the
  1330. // CHWRES.H file which make a sensible conversion to these values.
  1331. //
  1332. // Define the attribute flags for a DMA resource range. Each bit flag is
  1333. // identified with a constant bitmask. Following the bitmask definition
  1334. // are the possible values.
  1335. //
  1336. //#define mDD_Width (0x3) // Bitmask, width of the DMA channel:
  1337. //#define fDD_BYTE (0x0) // 8-bit DMA channel
  1338. //#define fDD_WORD (0x1) // 16-bit DMA channel
  1339. //#define fDD_DWORD (0x2) // 32-bit DMA channel
  1340. //#define fDD_BYTE_AND_WORD (0x3) // 8-bit and 16-bit DMA channel
  1341. //#define mDD_BusMaster (0x4) // Bitmask, whether bus mastering is supported
  1342. //#define fDD_NoBusMaster (0x0) // no bus mastering
  1343. //#define fDD_BusMaster (0x4) // bus mastering
  1344. //#define mDD_Type (0x18) // Bitmask, specifies type of DMA
  1345. //#define fDD_TypeStandard (0x00) // standard DMA
  1346. //#define fDD_TypeA (0x08) // Type-A DMA
  1347. //#define fDD_TypeB (0x10) // Type-B DMA
  1348. //#define fDD_TypeF (0x18) // Type-F DMA
  1349. }
  1350. #endif
  1351. ////////////////////////////////////////////////////////////////////////
  1352. //
  1353. // Function: CConfigMgrDevice::IRQDes16To32
  1354. //
  1355. // Coerces data from a 16-bit structure into a 32-bit structure.
  1356. //
  1357. // Inputs: PIRQ_DES16 pirqDes16 - 16-bit structure
  1358. //
  1359. // Outputs: PIRQ_DES pirqDes32 - 32-bit structure
  1360. //
  1361. // Return: None.
  1362. //
  1363. // Comments: None.
  1364. //
  1365. ////////////////////////////////////////////////////////////////////////
  1366. void CConfigMgrDevice::IRQDes16To32( PIRQ_DES16 pirqDes16, PIRQ_DES pirqDes32 )
  1367. {
  1368. ZeroMemory( pirqDes32, sizeof(IRQ_DES) );
  1369. // 16-bit Structure
  1370. //struct IRQ_Des_s {
  1371. // WORD IRQD_Flags;
  1372. // WORD IRQD_Alloc_Num; // Allocated IRQ number
  1373. // WORD IRQD_Req_Mask; // Mask of possible IRQs
  1374. // WORD IRQD_Reserved;
  1375. //};
  1376. // 32-bit structure
  1377. //typedef struct IRQ_Des_s {
  1378. // DWORD IRQD_Count; // number of IRQ_RANGE structs in IRQ_RESOURCE
  1379. // DWORD IRQD_Type; // size (in bytes) of IRQ_RANGE (IRQType_Range)
  1380. // DWORD IRQD_Flags; // flags describing the IRQ (fIRQD flags)
  1381. // ULONG IRQD_Alloc_Num; // specifies the IRQ that was allocated
  1382. // ULONG IRQD_Affinity;
  1383. //} IRQ_DES, *PIRQ_DES;
  1384. pirqDes32->IRQD_Alloc_Num = pirqDes16->IRQD_Alloc_Num;
  1385. pirqDes32->IRQD_Flags = pirqDes16->IRQD_Flags;
  1386. }
  1387. ////////////////////////////////////////////////////////////////////////
  1388. //
  1389. // Function: CConfigMgrDevice::IODes16To32
  1390. //
  1391. // Coerces data from a 16-bit structure into a 32-bit structure.
  1392. //
  1393. // Inputs: PIO_DES16 pioDes16 - 16-bit structure
  1394. //
  1395. // Outputs: PIOWBEM_DES pioDes32 - 32-bit structure
  1396. //
  1397. // Return: None.
  1398. //
  1399. // Comments: None.
  1400. //
  1401. ////////////////////////////////////////////////////////////////////////
  1402. void CConfigMgrDevice::IODes16To32( PIO_DES16 pioDes16, PIOWBEM_DES pioDes32 )
  1403. {
  1404. ZeroMemory( pioDes32, sizeof(IOWBEM_DES) );
  1405. // 16-bit structure
  1406. //struct IO_Des_s {
  1407. // WORD IOD_Count;
  1408. // WORD IOD_Type;
  1409. // WORD IOD_Alloc_Base;
  1410. // WORD IOD_Alloc_End;
  1411. // WORD IOD_DesFlags;
  1412. // BYTE IOD_Alloc_Alias;
  1413. // BYTE IOD_Alloc_Decode;
  1414. //};
  1415. // 32-bit Structure
  1416. //typedef struct _IOWBEM_DES{
  1417. // DWORD IOD_Count; // number of IO_RANGE structs in IO_RESOURCE
  1418. // DWORD IOD_Type; // size (in bytes) of IO_RANGE (IOType_Range)
  1419. // DWORDLONG IOD_Alloc_Base; // base of allocated port range
  1420. // DWORDLONG IOD_Alloc_End; // end of allocated port range
  1421. // DWORD IOD_DesFlags; // flags relating to allocated port range
  1422. // BYTE IOD_Alloc_Alias; // From 16-bit-land
  1423. // BYTE IOD_Alloc_Decode; // From 16-bit-land
  1424. //} IOWBEM_DES;
  1425. pioDes32->IOD_Count = pioDes16->IOD_Count;
  1426. pioDes32->IOD_Type = pioDes16->IOD_Type;
  1427. pioDes32->IOD_Alloc_Base = pioDes16->IOD_Alloc_Base;
  1428. pioDes32->IOD_Alloc_End = pioDes16->IOD_Alloc_End;
  1429. pioDes32->IOD_DesFlags = pioDes16->IOD_DesFlags;
  1430. pioDes32->IOD_Alloc_Alias = pioDes16->IOD_Alloc_Alias;
  1431. pioDes32->IOD_Alloc_Decode = pioDes16->IOD_Alloc_Decode;
  1432. }
  1433. ////////////////////////////////////////////////////////////////////////
  1434. //
  1435. // Function: CConfigMgrDevice::DMADes16To32
  1436. //
  1437. // Coerces data from a 16-bit structure into a 32-bit structure.
  1438. //
  1439. // Inputs: PDMA_DES16 pdmaDes16 - 16-bit structure
  1440. //
  1441. // Outputs: PDMA_DES pdmaDes32 - 32-bit structure
  1442. //
  1443. // Return: None.
  1444. //
  1445. // Comments: None.
  1446. //
  1447. ////////////////////////////////////////////////////////////////////////
  1448. void CConfigMgrDevice::DMADes16To32( PDMA_DES16 pdmaDes16, PDMA_DES pdmaDes32 )
  1449. {
  1450. ZeroMemory( pdmaDes32, sizeof(DMA_DES) );
  1451. // 16-bit structure
  1452. //struct DMA_Des_s {
  1453. // BYTE DD_Flags;
  1454. // BYTE DD_Alloc_Chan; // Channel number allocated
  1455. // BYTE DD_Req_Mask; // Mask of possible channels
  1456. // BYTE DD_Reserved;
  1457. //};
  1458. // 32-bit structure
  1459. //typedef struct DMA_Des_s {
  1460. // DWORD DD_Count; // number of DMA_RANGE structs in DMA_RESOURCE
  1461. // DWORD DD_Type; // size (in bytes) of DMA_RANGE struct (DType_Range)
  1462. // DWORD DD_Flags; // Flags describing DMA channel (fDD flags)
  1463. // ULONG DD_Alloc_Chan; // Specifies the DMA channel that was allocated
  1464. //} DMA_DES, *PDMA_DES;
  1465. pdmaDes32->DD_Flags = pdmaDes16->DD_Flags;
  1466. pdmaDes32->DD_Alloc_Chan = pdmaDes16->DD_Alloc_Chan;
  1467. }
  1468. ////////////////////////////////////////////////////////////////////////
  1469. //
  1470. // Function: CConfigMgrDevice::MEMDes16To32
  1471. //
  1472. // Coerces data from a 16-bit structure into a 32-bit structure.
  1473. //
  1474. // Inputs: PMEM_DES16 pmemDes16 - 16-bit structure
  1475. //
  1476. // Outputs: PMEM_DES pmemDes32 - 32-bit structure
  1477. //
  1478. // Return: None.
  1479. //
  1480. // Comments: None.
  1481. //
  1482. ////////////////////////////////////////////////////////////////////////
  1483. void CConfigMgrDevice::MEMDes16To32( PMEM_DES16 pmemDes16, PMEM_DES pmemDes32 )
  1484. {
  1485. ZeroMemory( pmemDes32, sizeof(MEM_DES) );
  1486. // 16-bit Structure
  1487. //struct Mem_Des_s {
  1488. // WORD MD_Count;
  1489. // WORD MD_Type;
  1490. // ULONG MD_Alloc_Base;
  1491. // ULONG MD_Alloc_End;
  1492. // WORD MD_Flags;
  1493. // WORD MD_Reserved;
  1494. //};
  1495. // 32-bit Structure
  1496. //typedef struct Mem_Des_s {
  1497. // DWORD MD_Count; // number of MEM_RANGE structs in MEM_RESOURCE
  1498. // DWORD MD_Type; // size (in bytes) of MEM_RANGE (MType_Range)
  1499. // DWORDLONG MD_Alloc_Base; // base memory address of range allocated
  1500. // DWORDLONG MD_Alloc_End; // end of allocated range
  1501. // DWORD MD_Flags; // flags describing allocated range (fMD flags)
  1502. // DWORD MD_Reserved;
  1503. //} MEM_DES, *PMEM_DES;
  1504. pmemDes32->MD_Count = pmemDes16->MD_Count;
  1505. pmemDes32->MD_Type = pmemDes16->MD_Type;
  1506. pmemDes32->MD_Alloc_Base = pmemDes16->MD_Alloc_Base;
  1507. pmemDes32->MD_Alloc_End = pmemDes16->MD_Alloc_End;
  1508. pmemDes32->MD_Flags = pmemDes16->MD_Flags;
  1509. }
  1510. ////////////////////////////////////////////////////////////////////////
  1511. //
  1512. // Function: CConfigMgrDevice::TraverseAllocationData
  1513. //
  1514. // Traverses a block of data in order to determine
  1515. // resource allocations for a particular device.
  1516. //
  1517. // Inputs: None.
  1518. //
  1519. // Outputs: CResourceCollection& resourceList - List to populate
  1520. //
  1521. // Return: None.
  1522. //
  1523. // Comments: Requires READ Access to the data.
  1524. //
  1525. ////////////////////////////////////////////////////////////////////////
  1526. void CConfigMgrDevice::TraverseAllocationData( CResourceCollection& resourceList )
  1527. {
  1528. const BYTE * pbTraverseData = m_pbAllocationData;
  1529. DWORD dwSizeRemainingData = m_dwSizeAllocationData,
  1530. dwResourceType = ResType_None,
  1531. dwResourceSize = 0;
  1532. // Clear the resource list first
  1533. resourceList.Empty();
  1534. // OWCH! The first hack. Near as I can tell, we need to jump eight bytes in to get
  1535. // to the first resource descriptor header (if there is one).
  1536. TraverseData( pbTraverseData, dwSizeRemainingData, FIRST_RESOURCE_OFFSET );
  1537. // From here on, we only want to deal with known resource information. Use the
  1538. // clever GetNextResource function to do all of our dirty work for us. If it
  1539. // returns TRUE, then it's located a resource. Allocate the proper type of
  1540. // descriptor based on type, place it in the list and go on to the next resource.
  1541. while ( GetNextResource( pbTraverseData, dwSizeRemainingData, dwResourceType, dwResourceSize ) )
  1542. {
  1543. if( dwResourceType == m_dwTypeToGet ){
  1544. PPOORMAN_RESDESC_HDR pResDescHdr = (PPOORMAN_RESDESC_HDR) pbTraverseData;
  1545. CResourceDescriptorPtr pResDesc;
  1546. // We have a valid type, however the actual resource descriptor will
  1547. // lie SIZEOF_RESDESC_HDR bytes past where we're at now (pointing at
  1548. // a resource header).
  1549. switch ( dwResourceType ){
  1550. case ResType_Mem:
  1551. {
  1552. CDeviceMemoryDescriptor* pMemDesc = new CDeviceMemoryDescriptor( pResDescHdr, this );
  1553. pResDesc.Attach(pMemDesc);
  1554. break;
  1555. }
  1556. case ResType_IO:
  1557. {
  1558. CIODescriptor* pIODesc = new CIODescriptor( pResDescHdr, this );
  1559. pResDesc.Attach(pIODesc);
  1560. break;
  1561. }
  1562. case ResType_DMA:
  1563. {
  1564. CDMADescriptor* pDMADesc = new CDMADescriptor( pResDescHdr, this );
  1565. pResDesc.Attach(pDMADesc);
  1566. break;
  1567. }
  1568. case ResType_IRQ:
  1569. {
  1570. CIRQDescriptor* pIRQDesc = new CIRQDescriptor( pResDescHdr, this );
  1571. pResDesc.Attach(pIRQDesc);
  1572. break;
  1573. }
  1574. default:
  1575. {
  1576. pResDesc.Attach (new CResourceDescriptor( pResDescHdr, this ));
  1577. }
  1578. } // SWITCH
  1579. // Give up if we have any failures, since they are most likely memory
  1580. // related, and something really bad has happened.
  1581. if ( NULL != pResDesc )
  1582. {
  1583. if ( !resourceList.Add( pResDesc ) )
  1584. {
  1585. break;
  1586. }
  1587. }
  1588. else
  1589. {
  1590. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1591. }
  1592. }
  1593. // Move the pointer to the next resource descriptor header.
  1594. TraverseData( pbTraverseData, dwSizeRemainingData, dwResourceSize );
  1595. } // WHILE finding new resources
  1596. }
  1597. ////////////////////////////////////////////////////////////////////////
  1598. //
  1599. // Function: CConfigMgrDevice::FindNextResource
  1600. //
  1601. // Iterates through a block of data, hunting for byte patterns that
  1602. // identify a resource type. In this case, as long as there are
  1603. // SIZEOF_RESDESC_HDR bytes let to work with, we extract the resource
  1604. // type and size and return those values for interpretation.
  1605. //
  1606. // Inputs: const BYTE* pbTraverseData - Data we are traversing. The
  1607. // value will change as we progress through the
  1608. // data.
  1609. // DWORD dwSizeRemainingData - How much data remains to
  1610. // be traversed.
  1611. //
  1612. // Outputs: DWORD& dwResourceType - What type of resource have we
  1613. // found.
  1614. // DWORD& dwResourceSize - How big the block of data
  1615. // describing the resource is.
  1616. //
  1617. // Return: None.
  1618. //
  1619. // Comments: None.
  1620. //
  1621. ////////////////////////////////////////////////////////////////////////
  1622. BOOL CConfigMgrDevice::GetNextResource( const BYTE *pbTraverseData, DWORD dwSizeRemainingData, DWORD& dwResourceType, DWORD& dwResourceSize )
  1623. {
  1624. BOOL fReturn = FALSE;
  1625. // If we have less than SIZEOF_RESDESC_HDR bytes to work with,
  1626. // give up, we ain't goin' nowhere.
  1627. if ( dwSizeRemainingData > SIZEOF_RESDESC_HDR )
  1628. {
  1629. PPOORMAN_RESDESC_HDR pResDescHdr = (PPOORMAN_RESDESC_HDR) pbTraverseData;
  1630. DWORD dwResourceId = 0;
  1631. dwResourceSize = pResDescHdr->dwResourceSize;
  1632. // If we run into a zero byte header, the only value will be length, which
  1633. // makes no sense, so we should probably just give up.
  1634. if ( 0 != dwResourceSize )
  1635. {
  1636. // See if it's one of the four standard types. If so, be aware that this code
  1637. // ain't checking to see if it's ignored, and that an OEM can create a replacement
  1638. // for one of these standard types, in which case strange and wondrous things
  1639. // may happen.
  1640. // Strip out any unwanted data, the first 5 bits are reserved for resource type
  1641. // identification, so mask out everything else
  1642. dwResourceType = pResDescHdr->dwResourceId;
  1643. dwResourceType &= RESOURCE_TYPE_MASK;
  1644. // We got a live one!
  1645. fReturn = TRUE;
  1646. }
  1647. }
  1648. // Return whether or not we found a resource
  1649. return fReturn;
  1650. }
  1651. ////////////////////////////////////////////////////////////////////////
  1652. //
  1653. // Function: CConfigMgrDevice::GetStatus
  1654. //
  1655. // Returns the status of the device as a string. If OK, it is "OK", if
  1656. // we have a problem, it is "Error".
  1657. //
  1658. // Inputs: None.
  1659. //
  1660. // Outputs: CHString& str - String to place status in.
  1661. //
  1662. // Return: None.
  1663. //
  1664. // Comments: None.
  1665. //
  1666. ////////////////////////////////////////////////////////////////////////
  1667. void CConfigMgrDevice::GetProblem( CHString& str )
  1668. {
  1669. // Save the string
  1670. str = ( 0 == m_dwProblem ? IDS_CfgMgrDeviceStatus_OK : IDS_CfgMgrDeviceStatus_ERR );
  1671. }
  1672. ////////////////////////////////////////////////////////////////////////
  1673. //
  1674. // Function: CConfigMgrDevice::TraverseData
  1675. //
  1676. // Helper function to safely bounce a pointer around our data. It will
  1677. // jump the pointer by the specified amount, or the amount remaining,
  1678. // whichever is smaller.
  1679. //
  1680. // Inputs: DWORD dwSizeTraverse - Size of upcoming jump.
  1681. //
  1682. // Outputs: const BYTE*& pbTraverseData - Data we are traversing. The
  1683. // value will change as we progress through the
  1684. // data.
  1685. // DWORD& dwSizeRemainingData - How much data remains to
  1686. // be traversed.
  1687. //
  1688. // Return: None.
  1689. //
  1690. // Comments: None.
  1691. //
  1692. ////////////////////////////////////////////////////////////////////////
  1693. void CConfigMgrDevice::TraverseData( const BYTE *& pbTraverseData, DWORD& dwSizeRemainingData, DWORD dwSizeTraverse )
  1694. {
  1695. // Increment the pointer and reduce the size of remaining data, do this safely, not
  1696. // traversing beyond the end of the remaining data, if that is all that is left.
  1697. pbTraverseData += min( dwSizeRemainingData, dwSizeTraverse );
  1698. dwSizeRemainingData -= min( dwSizeRemainingData, dwSizeTraverse );
  1699. }
  1700. // New functions that converse directly with the Config Manager APIs
  1701. BOOL CConfigMgrDevice::GetDeviceID( CHString& strID )
  1702. {
  1703. BOOL bRet = FALSE ;
  1704. CONFIGRET cr = CR_SUCCESS;
  1705. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1706. if ( pconfigmgr )
  1707. {
  1708. if ( pconfigmgr->IsValid () )
  1709. {
  1710. char szDeviceId[MAX_DEVICE_ID_LEN+1];
  1711. ULONG ulBuffSize = 0;
  1712. cr = pconfigmgr->CM_Get_Device_IDA( m_dn, szDeviceId, sizeof(szDeviceId), 0 );
  1713. if ( CR_SUCCESS == cr )
  1714. {
  1715. strID = szDeviceId;
  1716. }
  1717. bRet = ( CR_SUCCESS == cr );
  1718. }
  1719. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1720. }
  1721. return bRet ;
  1722. }
  1723. BOOL CConfigMgrDevice::GetStatus( LPDWORD pdwStatus, LPDWORD pdwProblem )
  1724. {
  1725. BOOL bRet = FALSE ;
  1726. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1727. if ( pconfigmgr )
  1728. {
  1729. if ( pconfigmgr->IsValid () )
  1730. {
  1731. DWORD dwStatus,
  1732. dwProblem;
  1733. CONFIGRET cr = pconfigmgr->CM_Get_DevNode_Status( &dwStatus, &dwProblem, m_dn, 0 );
  1734. // Perform pointer testing here. Ignore the man behind the curtain...
  1735. if ( CR_SUCCESS == cr )
  1736. {
  1737. if ( NULL != pdwStatus )
  1738. {
  1739. *pdwStatus = dwStatus;
  1740. }
  1741. if ( NULL != pdwProblem )
  1742. {
  1743. *pdwProblem = dwProblem;
  1744. }
  1745. }
  1746. bRet = ( CR_SUCCESS == cr );
  1747. }
  1748. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1749. }
  1750. return bRet ;
  1751. }
  1752. BOOL CConfigMgrDevice::IsUsingForcedConfig()
  1753. {
  1754. BOOL bRet = FALSE ;
  1755. LOG_CONF conf;
  1756. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1757. if ( pconfigmgr )
  1758. {
  1759. if ( pconfigmgr->IsValid () )
  1760. {
  1761. bRet = (pconfigmgr->CM_Get_First_Log_Conf(&conf, m_dn, FORCED_LOG_CONF) ==
  1762. CR_SUCCESS);
  1763. }
  1764. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1765. }
  1766. return bRet ;
  1767. }
  1768. BOOL CConfigMgrDevice::GetParent( CConfigMgrDevicePtr & pParentDevice )
  1769. {
  1770. BOOL bRet = FALSE ;
  1771. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1772. DEVNODE dn;
  1773. if ( pconfigmgr )
  1774. {
  1775. if ( pconfigmgr->IsValid () )
  1776. {
  1777. CONFIGRET cr = pconfigmgr->CM_Get_Parent( &dn, m_dn, 0 );
  1778. if ( CR_SUCCESS == cr )
  1779. {
  1780. CConfigMgrDevice* pDevice = new CConfigMgrDevice( dn );
  1781. pParentDevice.Attach(pDevice);
  1782. }
  1783. bRet = ( CR_SUCCESS == cr );
  1784. }
  1785. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1786. }
  1787. return bRet ;
  1788. }
  1789. BOOL CConfigMgrDevice::GetChild( CConfigMgrDevicePtr & pChildDevice )
  1790. {
  1791. BOOL bRet = FALSE ;
  1792. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1793. DEVNODE dn;
  1794. if ( pconfigmgr )
  1795. {
  1796. if ( pconfigmgr->IsValid () )
  1797. {
  1798. CONFIGRET cr = pconfigmgr->CM_Get_Child( &dn, m_dn, 0 );
  1799. if ( CR_SUCCESS == cr )
  1800. {
  1801. CConfigMgrDevice* pDevice = new CConfigMgrDevice( dn );
  1802. pChildDevice.Attach(pDevice);
  1803. }
  1804. bRet = ( CR_SUCCESS == cr );
  1805. }
  1806. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1807. }
  1808. return bRet ;
  1809. }
  1810. BOOL CConfigMgrDevice::GetSibling( CConfigMgrDevicePtr & pSiblingDevice )
  1811. {
  1812. BOOL bRet = FALSE ;
  1813. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1814. DEVNODE dn;
  1815. if ( pconfigmgr )
  1816. {
  1817. if ( pconfigmgr->IsValid () )
  1818. {
  1819. CONFIGRET cr = pconfigmgr->CM_Get_Sibling( &dn, m_dn, 0 );
  1820. if ( CR_SUCCESS == cr )
  1821. {
  1822. CConfigMgrDevice* pDevice = new CConfigMgrDevice( dn );
  1823. pSiblingDevice.Attach(pDevice);
  1824. }
  1825. bRet = ( CR_SUCCESS == cr );
  1826. }
  1827. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1828. }
  1829. return bRet ;
  1830. }
  1831. BOOL CConfigMgrDevice::GetStringProperty( ULONG ulProperty, CHString& strValue )
  1832. {
  1833. TCHAR Buffer[REGSTR_VAL_MAX_HCID_LEN+1];
  1834. ULONG Type;
  1835. ULONG Size = sizeof(Buffer);
  1836. BOOL bRet = FALSE ;
  1837. CONFIGRET cr = CR_SUCCESS;
  1838. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1839. if ( pconfigmgr )
  1840. {
  1841. if ( pconfigmgr->IsValid () )
  1842. {
  1843. if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
  1844. ulProperty,
  1845. &Type,
  1846. Buffer,
  1847. &Size,
  1848. 0 ) ) )
  1849. {
  1850. if ( REG_SZ == Type )
  1851. {
  1852. strValue = Buffer;
  1853. }
  1854. else
  1855. {
  1856. cr = CR_WRONG_TYPE;
  1857. }
  1858. }
  1859. bRet = ( CR_SUCCESS == cr );
  1860. }
  1861. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1862. }
  1863. return bRet ;
  1864. }
  1865. BOOL CConfigMgrDevice::GetDWORDProperty( ULONG ulProperty, DWORD *pdwVal )
  1866. {
  1867. DWORD dwVal = 0;
  1868. ULONG Type;
  1869. ULONG Size = sizeof(DWORD);
  1870. BOOL bRet = FALSE ;
  1871. CONFIGRET cr = CR_SUCCESS;
  1872. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1873. if ( pconfigmgr )
  1874. {
  1875. if ( pconfigmgr->IsValid () )
  1876. {
  1877. if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
  1878. ulProperty,
  1879. &Type,
  1880. &dwVal,
  1881. &Size,
  1882. 0 ) ) )
  1883. {
  1884. #ifdef NTONLY
  1885. {
  1886. if ( REG_DWORD == Type )
  1887. {
  1888. *pdwVal = dwVal;
  1889. }
  1890. else
  1891. {
  1892. cr = CR_WRONG_TYPE;
  1893. }
  1894. }
  1895. #endif
  1896. #ifdef WIN9XONLY
  1897. {
  1898. if ( REG_BINARY == Type ) // Apparently Win16 doesn't do REG_DWORD
  1899. {
  1900. *pdwVal = dwVal;
  1901. }
  1902. else
  1903. {
  1904. cr = CR_WRONG_TYPE;
  1905. }
  1906. }
  1907. #endif
  1908. }
  1909. bRet = ( CR_SUCCESS == cr );
  1910. }
  1911. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1912. }
  1913. return bRet ;
  1914. }
  1915. BOOL CConfigMgrDevice::GetMULTISZProperty( ULONG ulProperty, CHStringArray& strArray )
  1916. {
  1917. CONFIGRET cr = CR_SUCCESS;
  1918. BOOL bRet = FALSE ;
  1919. // No one is currently using this, so I'm not going to fix it now
  1920. #ifdef DOESNT_WORK_FOR_UNICODE
  1921. LPSTR pszStrings = NULL;
  1922. ULONG Type;
  1923. ULONG Size = 0;
  1924. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  1925. if ( pconfigmgr )
  1926. {
  1927. if ( pconfigmgr->IsValid () )
  1928. {
  1929. if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
  1930. ulProperty,
  1931. &Type,
  1932. pszStrings,
  1933. &Size,
  1934. 0 ) )
  1935. || CR_BUFFER_SMALL == cr )
  1936. {
  1937. // SZ or MULTI_SZ is Okay (32-bit has MULTI_SZ values that are SZ in 16-bit)
  1938. if ( REG_SZ == Type || REG_MULTI_SZ == Type )
  1939. {
  1940. // Pad the string, but be aware that on NT4 I have seen situations in which
  1941. // it reports less data than it actually returns (scary)
  1942. Size += 32;
  1943. pszStrings = new char[Size];
  1944. if ( NULL != pszStrings )
  1945. {
  1946. try
  1947. {
  1948. // Clear out the memory to be especially safe.
  1949. ZeroMemory( pszStrings, Size );
  1950. if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
  1951. ulProperty,
  1952. &Type,
  1953. pszStrings,
  1954. &Size,
  1955. 0 ) ) )
  1956. {
  1957. // For REG_SZ, add a single entry to the array
  1958. if ( REG_SZ == Type )
  1959. {
  1960. strArray.Add( pszStrings );
  1961. }
  1962. else if ( REG_MULTI_SZ == Type )
  1963. {
  1964. // Add strings to the array, watching out for the double NULL
  1965. // terminator for the array
  1966. LPSTR pszTemp = pszStrings;
  1967. do
  1968. {
  1969. strArray.Add( pszTemp );
  1970. pszTemp += ( lstrlen( pszTemp ) + 1 );
  1971. } while ( NULL != *pszTemp );
  1972. }
  1973. else
  1974. {
  1975. cr = CR_WRONG_TYPE;
  1976. }
  1977. } // If Got value
  1978. }
  1979. catch ( ... )
  1980. {
  1981. delete [] pszStrings;
  1982. throw ;
  1983. }
  1984. delete [] pszStrings;
  1985. } // IF alloc pszStrings
  1986. else
  1987. {
  1988. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1989. }
  1990. } // IF REG_SZ or REG_MULTI_SZ
  1991. else
  1992. {
  1993. cr = CR_WRONG_TYPE;
  1994. }
  1995. } // IF got size of entry
  1996. bRet = ( CR_SUCCESS == cr );
  1997. }
  1998. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  1999. }
  2000. #endif
  2001. return bRet ;
  2002. }
  2003. BOOL CConfigMgrDevice::GetBusInfo( INTERFACE_TYPE *pitBusType, LPDWORD pdwBusNumber, CNT4ServiceToResourceMap *pResourceMap/*=NULL*/ )
  2004. {
  2005. CMBUSTYPE busType = 0;
  2006. ULONG ulSizeOfInfo = 0;
  2007. PBYTE pbData = NULL;
  2008. BOOL fReturn = FALSE;
  2009. // Farm out to the appropriate handler
  2010. #if NTONLY > 4
  2011. fReturn = GetBusInfoNT5( pitBusType, pdwBusNumber );
  2012. #endif
  2013. #if NTONLY == 4
  2014. fReturn = GetBusInfoNT4( pitBusType, pdwBusNumber, pResourceMap );
  2015. #endif
  2016. #ifdef WIN9XONLY
  2017. {
  2018. // Buffer for data. Should be big enough for any of the values we come across.
  2019. BYTE abData[255];
  2020. ulSizeOfInfo = sizeof(abData);
  2021. // Get the type and number. If the type is PCI, then get the PCI info, and this
  2022. // will return a Bus Number value. If it returns a type other than PCI, then
  2023. // we will assume a bus number of 0.
  2024. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  2025. if ( pconfigmgr )
  2026. {
  2027. if ( pconfigmgr->IsValid () )
  2028. {
  2029. CONFIGRET cr = pconfigmgr->CM_Get_Bus_Info( m_dn, &busType, &ulSizeOfInfo, abData, 0 );
  2030. if ( CR_SUCCESS == cr )
  2031. {
  2032. // Make sure we can convert from a 16-bit type to a known 32-bit type.
  2033. // BusType_None will usually fail this, in which case we can call it
  2034. // quits.
  2035. if ( BusType16ToInterfaceType( busType, pitBusType ) )
  2036. {
  2037. if ( BusType_PCI == busType )
  2038. {
  2039. sPCIAccess *pPCIInfo = (sPCIAccess*) abData;
  2040. *pdwBusNumber = pPCIInfo->bBusNumber;
  2041. }
  2042. else
  2043. {
  2044. *pdwBusNumber = 0;
  2045. }
  2046. } // IF 16-32bit conversion
  2047. else
  2048. {
  2049. cr = CR_FAILURE;
  2050. }
  2051. } // CR_SUCCESS == cr
  2052. fReturn = ( CR_SUCCESS == cr );
  2053. }
  2054. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  2055. }
  2056. } // else !IsWinNT
  2057. #endif
  2058. return fReturn;
  2059. }
  2060. #if NTONLY > 4
  2061. // This is to hack around W2K problem where Cfg Mgr devices report they're
  2062. // using Isa on boxes that have Eisa and not Isa.
  2063. BOOL CConfigMgrDevice::IsIsaReallyEisa()
  2064. {
  2065. static bRet = -1;
  2066. if (bRet == -1)
  2067. {
  2068. // FYI: This code based on code from motherboard.cpp.
  2069. CRegistry regAdapters;
  2070. CHString strPrimarySubKey;
  2071. HRESULT hRc = WBEM_E_FAILED;
  2072. DWORD dwPrimaryRc;
  2073. // If anything below fails, we'll just assume Isa really is Isa.
  2074. bRet = FALSE;
  2075. //****************************************
  2076. // Open the registry
  2077. //****************************************
  2078. if (regAdapters.OpenAndEnumerateSubKeys(
  2079. HKEY_LOCAL_MACHINE,
  2080. L"HARDWARE\\Description\\System",
  2081. KEY_READ) == ERROR_SUCCESS)
  2082. {
  2083. BOOL bDone = FALSE,
  2084. bIsaFound = FALSE,
  2085. bEisaFound = FALSE;
  2086. // Our goal is to find any subkey that has the string "Adapter" in
  2087. // it and then read the "Identifier" value.
  2088. for ( ;
  2089. (!bIsaFound || !bEisaFound) &&
  2090. ((dwPrimaryRc = regAdapters.GetCurrentSubKeyName(strPrimarySubKey))
  2091. == ERROR_SUCCESS);
  2092. regAdapters.NextSubKey())
  2093. {
  2094. strPrimarySubKey.MakeUpper();
  2095. // If this is one of the keys we want since it has "Adapter" in
  2096. // it then get the "Identifier" value.
  2097. if (wcsstr(strPrimarySubKey, L"ADAPTER"))
  2098. {
  2099. WCHAR szKey[_MAX_PATH];
  2100. CRegistry reg;
  2101. swprintf(
  2102. szKey,
  2103. L"%s\\%s",
  2104. L"HARDWARE\\Description\\System",
  2105. (LPCWSTR) strPrimarySubKey);
  2106. if (reg.OpenAndEnumerateSubKeys(
  2107. HKEY_LOCAL_MACHINE,
  2108. szKey,
  2109. KEY_READ) == ERROR_SUCCESS)
  2110. {
  2111. CHString strSubKey;
  2112. // Enumerate the system components (like 0,1,...).
  2113. for ( ;
  2114. reg.GetCurrentSubKeyName(strSubKey) == ERROR_SUCCESS;
  2115. reg.NextSubKey())
  2116. {
  2117. CHString strBus;
  2118. if (reg.GetCurrentSubKeyValue(L"Identifier",
  2119. strBus) == ERROR_SUCCESS)
  2120. {
  2121. if (strBus == L"ISA")
  2122. bIsaFound = TRUE;
  2123. else if (strBus == L"EISA")
  2124. bEisaFound = TRUE;
  2125. }
  2126. }
  2127. }
  2128. }
  2129. }
  2130. // If we found Eisa but not Isa, assume Cfg Mgr devices that report they're
  2131. // using Isa are actually using Eisa.
  2132. if (!bIsaFound && bEisaFound)
  2133. bRet = TRUE;
  2134. }
  2135. }
  2136. return bRet;
  2137. }
  2138. #endif
  2139. #if NTONLY > 4
  2140. INTERFACE_TYPE CConfigMgrDevice::ConvertBadIsaBusType(INTERFACE_TYPE type)
  2141. {
  2142. if (type == Isa && IsIsaReallyEisa())
  2143. type = Eisa;
  2144. return type;
  2145. }
  2146. #endif
  2147. #if NTONLY > 4
  2148. BOOL CConfigMgrDevice::GetBusInfoNT5( INTERFACE_TYPE *pitBusType, LPDWORD pdwBusNumber )
  2149. {
  2150. ULONG ulSizeOfInfo = 0;
  2151. CONFIGRET cr;
  2152. // Bus Number and Type are retrieved via the Registry function. This will only
  2153. // work on NT 5.
  2154. BOOL bRet = FALSE ;
  2155. DWORD dwType = 0;
  2156. DWORD dwBusNumber;
  2157. INTERFACE_TYPE BusType;
  2158. ulSizeOfInfo = sizeof(DWORD);
  2159. CConfigMgrAPI* pconfigmgr = ( CConfigMgrAPI *) CResourceManager::sm_TheResourceManager.GetResource ( guidCFGMGRAPI, NULL ) ;
  2160. if ( pconfigmgr )
  2161. {
  2162. if ( pconfigmgr->IsValid () )
  2163. {
  2164. if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
  2165. CM_DRP_BUSNUMBER,
  2166. &dwType,
  2167. &dwBusNumber,
  2168. &ulSizeOfInfo,
  2169. 0 ) ) )
  2170. {
  2171. *pdwBusNumber = dwBusNumber;
  2172. ulSizeOfInfo = sizeof(BusType);
  2173. if ( CR_SUCCESS == ( cr = pconfigmgr->CM_Get_DevNode_Registry_PropertyA( m_dn,
  2174. CM_DRP_LEGACYBUSTYPE,
  2175. &dwType,
  2176. &BusType,
  2177. &ulSizeOfInfo,
  2178. 0 ) ) )
  2179. {
  2180. *pitBusType = ConvertBadIsaBusType(BusType);
  2181. } // IF GetBusType
  2182. } // IF GetBusNumber
  2183. bRet = ( CR_SUCCESS == cr );
  2184. }
  2185. CResourceManager::sm_TheResourceManager.ReleaseResource ( guidCFGMGRAPI, pconfigmgr ) ;
  2186. }
  2187. return bRet ;
  2188. }
  2189. #endif
  2190. #if NTONLY == 4
  2191. BOOL CConfigMgrDevice::GetBusInfoNT4( INTERFACE_TYPE *pitBusType, LPDWORD pdwBusNumber, CNT4ServiceToResourceMap *pResourceMap )
  2192. {
  2193. BOOL fReturn = FALSE;
  2194. CHString strService;
  2195. if ( GetService( strService ) )
  2196. {
  2197. CNT4ServiceToResourceMap* pLocalMap = pResourceMap;
  2198. // Instantiate a resource map if we need one. Then look for
  2199. // resources for this service
  2200. if ( NULL == pLocalMap )
  2201. {
  2202. pLocalMap = new CNT4ServiceToResourceMap;
  2203. }
  2204. if ( NULL != pLocalMap )
  2205. {
  2206. try
  2207. {
  2208. if ( 0 != pLocalMap->NumServiceResources( strService ) )
  2209. {
  2210. LPRESOURCE_DESCRIPTOR pResource = pLocalMap->GetServiceResource( strService, 0 );
  2211. // If we got a resource, then use its BUS information directly to populate
  2212. // our values.
  2213. if ( NULL != pResource )
  2214. {
  2215. fReturn = TRUE;
  2216. *pitBusType = pResource->InterfaceType;
  2217. *pdwBusNumber = pResource->Bus;
  2218. }
  2219. } // If there are resources for this service
  2220. }
  2221. catch ( ... )
  2222. {
  2223. if ( pLocalMap != pResourceMap )
  2224. {
  2225. delete pLocalMap;
  2226. }
  2227. throw ;
  2228. }
  2229. // Delete the local map if we allocated one.
  2230. if ( pLocalMap != pResourceMap )
  2231. {
  2232. delete pLocalMap;
  2233. }
  2234. } // if pLocalMap
  2235. else
  2236. {
  2237. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2238. }
  2239. } // If got service name
  2240. return fReturn;
  2241. }
  2242. #endif
  2243. BOOL CConfigMgrDevice::BusType16ToInterfaceType( CMBUSTYPE cmBusType16, INTERFACE_TYPE *pinterfaceType )
  2244. {
  2245. BOOL fReturn = TRUE;
  2246. // These are the enums defined for NT, so we'll standardize on these
  2247. //
  2248. // typedef enum Interface_Type {
  2249. // Internal,
  2250. // Isa,
  2251. // Eisa,
  2252. // MicroChannel,
  2253. // TurboChannel,
  2254. // PCIBus,
  2255. // VMEBus,
  2256. // NuBus,
  2257. // PCMCIABus,
  2258. // CBus,
  2259. // MPIBus,
  2260. // MPSABus,
  2261. // MaximumInterfaceType
  2262. // }INTERFACE_TYPE;
  2263. //
  2264. switch ( cmBusType16 )
  2265. {
  2266. case BusType_ISA:
  2267. {
  2268. *pinterfaceType = Isa;
  2269. }
  2270. break;
  2271. case BusType_EISA:
  2272. {
  2273. *pinterfaceType = Eisa;
  2274. }
  2275. break;
  2276. case BusType_PCI:
  2277. {
  2278. *pinterfaceType = PCIBus;
  2279. }
  2280. break;
  2281. case BusType_PCMCIA:
  2282. {
  2283. *pinterfaceType = PCMCIABus;
  2284. }
  2285. break;
  2286. case BusType_ISAPNP:
  2287. {
  2288. // Closest match I could find
  2289. *pinterfaceType = Isa;
  2290. }
  2291. break;
  2292. case BusType_MCA:
  2293. {
  2294. *pinterfaceType = MicroChannel;
  2295. }
  2296. break;
  2297. case BusType_BIOS:
  2298. {
  2299. *pinterfaceType = Internal;
  2300. }
  2301. break;
  2302. default:
  2303. {
  2304. // Couldn't make the conversion (e.g. BusType_None)
  2305. fReturn = FALSE;
  2306. }
  2307. }
  2308. return fReturn;
  2309. }
  2310. // Registry Access functions. Sometimes we want to access the registry directly because
  2311. // the device in question places private values in there that our regular functions cannot
  2312. // access.
  2313. BOOL CConfigMgrDevice::GetRegistryKeyName( CHString &strName)
  2314. {
  2315. CHString strDeviceID;
  2316. BOOL bRet = TRUE;
  2317. if ( GetDeviceID(strDeviceID) )
  2318. {
  2319. // Build the correct key
  2320. #ifdef NTONLY
  2321. strName = _T("SYSTEM\\CurrentControlSet\\Enum\\");
  2322. #endif
  2323. #ifdef WIN9XONLY
  2324. strName = _T("Enum\\");
  2325. #endif
  2326. strName += strDeviceID;
  2327. }
  2328. else
  2329. {
  2330. bRet = false;
  2331. }
  2332. return bRet;
  2333. }
  2334. //
  2335. // Constructor and Destructor for the Device Collection
  2336. // object.
  2337. //
  2338. ////////////////////////////////////////////////////////////////////////
  2339. //
  2340. // Function: CDeviceCollection::CDeviceCollection
  2341. //
  2342. // Class Constructor.
  2343. //
  2344. // Inputs: None.
  2345. //
  2346. // Outputs: None.
  2347. //
  2348. // Return: None.
  2349. //
  2350. // Comments: None.
  2351. //
  2352. ////////////////////////////////////////////////////////////////////////
  2353. CDeviceCollection::CDeviceCollection( void )
  2354. {
  2355. }
  2356. ////////////////////////////////////////////////////////////////////////
  2357. //
  2358. // Function: CDeviceCollection::~CDeviceCollection
  2359. //
  2360. // Class Destructor.
  2361. //
  2362. // Inputs: None.
  2363. //
  2364. // Outputs: None.
  2365. //
  2366. // Return: None.
  2367. //
  2368. // Comments: None.
  2369. //
  2370. ////////////////////////////////////////////////////////////////////////
  2371. CDeviceCollection::~CDeviceCollection( void )
  2372. {
  2373. }
  2374. BOOL CDeviceCollection::GetResourceList( CResourceCollection& resourceList )
  2375. {
  2376. REFPTR_POSITION pos = NULL;
  2377. CConfigMgrDevicePtr pDevice;
  2378. CResourceCollection deviceresourceList;
  2379. BOOL fReturn = TRUE;
  2380. // Snapshot the resources on an NT 4 box. This only needs to happen once
  2381. // and then we can pass this to devices to hook themselves up to the
  2382. // appropriate resources. This keeps us from having to build this data
  2383. // for each and every device.
  2384. #ifdef NTONLY
  2385. CNT4ServiceToResourceMap* pResourceMap = NULL;
  2386. if ( IsWinNT4() )
  2387. {
  2388. pResourceMap = new CNT4ServiceToResourceMap;
  2389. }
  2390. if (pResourceMap == NULL)
  2391. {
  2392. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2393. }
  2394. try
  2395. {
  2396. #endif
  2397. // Empty out the Resource List first
  2398. resourceList.Empty();
  2399. if ( BeginEnum( pos ) )
  2400. {
  2401. // Get the resource list from the device, then append it
  2402. // to the list passed in to us.
  2403. for ( pDevice.Attach(GetNext( pos ) );
  2404. pDevice != NULL;
  2405. pDevice.Attach(GetNext( pos ) ) )
  2406. {
  2407. #ifdef NTONLY
  2408. pDevice->GetResourceList( deviceresourceList, pResourceMap );
  2409. #endif
  2410. #ifdef WIN9XONLY
  2411. pDevice->GetResourceList( deviceresourceList, NULL );
  2412. #endif
  2413. resourceList.Append( deviceresourceList );
  2414. } // WHILE enuming devices
  2415. EndEnum();
  2416. }
  2417. else
  2418. {
  2419. fReturn = FALSE;
  2420. }
  2421. #ifdef NTONLY
  2422. }
  2423. catch ( ... )
  2424. {
  2425. if ( NULL != pResourceMap )
  2426. {
  2427. delete pResourceMap;
  2428. }
  2429. throw ;
  2430. }
  2431. // Clean up the resource map if we allocated one.
  2432. if ( NULL != pResourceMap )
  2433. {
  2434. delete pResourceMap;
  2435. }
  2436. #endif
  2437. return fReturn;
  2438. }
  2439. BOOL CDeviceCollection::GetIRQResources( CIRQCollection& IRQList )
  2440. {
  2441. REFPTR_POSITION pos = NULL;
  2442. CConfigMgrDevicePtr pDevice;
  2443. CIRQCollection deviceIRQList;
  2444. BOOL fReturn = TRUE;
  2445. // Snapshot the resources on an NT 4 box. This only needs to happen once
  2446. // and then we can pass this to devices to hook themselves up to the
  2447. // appropriate resources. This keeps us from having to build this data
  2448. // for each and every device.
  2449. CNT4ServiceToResourceMap* pResourceMap = NULL;
  2450. #ifdef NTONLY
  2451. if ( IsWinNT4() )
  2452. {
  2453. pResourceMap = new CNT4ServiceToResourceMap;
  2454. }
  2455. if (pResourceMap == NULL)
  2456. {
  2457. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2458. }
  2459. try
  2460. {
  2461. #endif
  2462. // Empty out the IRQ List first
  2463. IRQList.Empty();
  2464. if ( BeginEnum( pos ) )
  2465. {
  2466. // For each device, get the IRQs and append them to the
  2467. // supplied IRQ list
  2468. for ( pDevice.Attach( GetNext( pos ) );
  2469. pDevice != NULL;
  2470. pDevice.Attach( GetNext( pos ) ))
  2471. {
  2472. pDevice->GetIRQResources( deviceIRQList, pResourceMap );
  2473. IRQList.Append( deviceIRQList );
  2474. } // for all devices
  2475. EndEnum();
  2476. } // Begin Enum
  2477. else
  2478. {
  2479. fReturn = FALSE;
  2480. }
  2481. #ifdef NTONLY
  2482. }
  2483. catch ( ... )
  2484. {
  2485. if ( NULL != pResourceMap )
  2486. {
  2487. delete pResourceMap;
  2488. }
  2489. throw ;
  2490. }
  2491. // Clean up the resource map if we allocated one.
  2492. if ( NULL != pResourceMap )
  2493. {
  2494. delete pResourceMap;
  2495. }
  2496. #endif
  2497. return fReturn;
  2498. }
  2499. BOOL CDeviceCollection::GetIOResources( CIOCollection& IOList )
  2500. {
  2501. REFPTR_POSITION pos = NULL;
  2502. CConfigMgrDevicePtr pDevice;
  2503. CIOCollection deviceIOList;
  2504. BOOL fReturn = TRUE;
  2505. // Snapshot the resources on an NT 4 box. This only needs to happen once
  2506. // and then we can pass this to devices to hook themselves up to the
  2507. // appropriate resources. This keeps us from having to build this data
  2508. // for each and every device.
  2509. CNT4ServiceToResourceMap* pResourceMap = NULL;
  2510. #ifdef NTONLY
  2511. if ( IsWinNT4() )
  2512. {
  2513. pResourceMap = new CNT4ServiceToResourceMap;
  2514. }
  2515. if (pResourceMap == NULL)
  2516. {
  2517. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2518. }
  2519. try
  2520. {
  2521. #endif
  2522. // Empty out the IO List first
  2523. IOList.Empty();
  2524. if ( BeginEnum( pos ) )
  2525. {
  2526. // For each device, get the IO Port List and append
  2527. // it to the supplied list of IO Ports.
  2528. for ( pDevice.Attach( GetNext( pos ) );
  2529. pDevice != NULL;
  2530. pDevice.Attach( GetNext( pos ) ))
  2531. {
  2532. pDevice->GetIOResources( deviceIOList, pResourceMap );
  2533. IOList.Append( deviceIOList );
  2534. } // for all devices
  2535. EndEnum();
  2536. } // BeginEnum
  2537. else
  2538. {
  2539. fReturn = FALSE;
  2540. }
  2541. #ifdef NTONLY
  2542. }
  2543. catch ( ... )
  2544. {
  2545. if ( NULL != pResourceMap )
  2546. {
  2547. delete pResourceMap;
  2548. }
  2549. throw ;
  2550. }
  2551. // Clean up the resource map if we allocated one.
  2552. if ( NULL != pResourceMap )
  2553. {
  2554. delete pResourceMap;
  2555. }
  2556. #endif
  2557. return fReturn;
  2558. }
  2559. BOOL CDeviceCollection::GetDMAResources( CDMACollection& DMAList )
  2560. {
  2561. REFPTR_POSITION pos = NULL;
  2562. CConfigMgrDevicePtr pDevice;
  2563. CDMACollection deviceDMAList;
  2564. BOOL fReturn = TRUE;
  2565. // Snapshot the resources on an NT 4 box. This only needs to happen once
  2566. // and then we can pass this to devices to hook themselves up to the
  2567. // appropriate resources. This keeps us from having to build this data
  2568. // for each and every device.
  2569. CNT4ServiceToResourceMap* pResourceMap = NULL;
  2570. #ifdef NTONLY
  2571. if ( IsWinNT4() )
  2572. {
  2573. pResourceMap = new CNT4ServiceToResourceMap;
  2574. }
  2575. if (pResourceMap == NULL)
  2576. {
  2577. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2578. }
  2579. try
  2580. {
  2581. #endif
  2582. // Empty out the DMA List first
  2583. DMAList.Empty();
  2584. if ( BeginEnum( pos ) )
  2585. {
  2586. // For each device, get the DMA resources and append them
  2587. // to the supplied list of DMA resources
  2588. for ( pDevice.Attach( GetNext( pos ) );
  2589. pDevice != NULL;
  2590. pDevice.Attach( GetNext( pos ) ))
  2591. {
  2592. pDevice->GetDMAResources( deviceDMAList, pResourceMap );
  2593. DMAList.Append( deviceDMAList );
  2594. } // for all devices
  2595. } // BeginEnum
  2596. else
  2597. {
  2598. fReturn = FALSE;
  2599. }
  2600. #ifdef NTONLY
  2601. }
  2602. catch ( ... )
  2603. {
  2604. if ( NULL != pResourceMap )
  2605. {
  2606. delete pResourceMap;
  2607. }
  2608. throw ;
  2609. }
  2610. // Clean up the resource map if we allocated one.
  2611. if ( NULL != pResourceMap )
  2612. {
  2613. delete pResourceMap;
  2614. }
  2615. #endif
  2616. return fReturn;
  2617. }
  2618. BOOL CDeviceCollection::GetDeviceMemoryResources( CDeviceMemoryCollection& DeviceMemoryList )
  2619. {
  2620. REFPTR_POSITION pos = NULL;
  2621. CConfigMgrDevicePtr pDevice;
  2622. CDeviceMemoryCollection memoryList;
  2623. BOOL fReturn = TRUE;
  2624. // Snapshot the resources on an NT 4 box. This only needs to happen once
  2625. // and then we can pass this to devices to hook themselves up to the
  2626. // appropriate resources. This keeps us from having to build this data
  2627. // for each and every device.
  2628. CNT4ServiceToResourceMap* pResourceMap = NULL;
  2629. #ifdef NTONLY
  2630. if ( IsWinNT4() )
  2631. {
  2632. pResourceMap = new CNT4ServiceToResourceMap;
  2633. }
  2634. if (pResourceMap == NULL)
  2635. {
  2636. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2637. }
  2638. try
  2639. {
  2640. #endif
  2641. // Empty out the DeviceMemory List first
  2642. DeviceMemoryList.Empty();
  2643. if ( BeginEnum( pos ) )
  2644. {
  2645. // For each device get the list of Memory Resources and
  2646. // append it to the list of supplied Memory Resources.
  2647. for ( pDevice.Attach( GetNext( pos ) );
  2648. pDevice != NULL;
  2649. pDevice.Attach( GetNext( pos ) ))
  2650. {
  2651. pDevice->GetDeviceMemoryResources( memoryList, pResourceMap );
  2652. DeviceMemoryList.Append( memoryList );
  2653. } // for all devices
  2654. EndEnum();
  2655. } // BeginEnum()
  2656. else
  2657. {
  2658. fReturn = FALSE;
  2659. }
  2660. #ifdef NTONLY
  2661. }
  2662. catch ( ... )
  2663. {
  2664. if ( NULL != pResourceMap )
  2665. {
  2666. delete pResourceMap;
  2667. }
  2668. throw ;
  2669. }
  2670. // Clean up the resource map if we allocated one.
  2671. if ( NULL != pResourceMap )
  2672. {
  2673. delete pResourceMap;
  2674. }
  2675. #endif
  2676. return fReturn;
  2677. }
  2678. #define MAX_DOS_DEVICES 8192
  2679. /*****************************************************************************
  2680. *
  2681. * FUNCTION : QueryDosDeviceNames
  2682. *
  2683. * DESCRIPTION : Queries for all Dos Device symbolic links
  2684. *
  2685. * INPUTS : none
  2686. *
  2687. * OUTPUTS : nichts
  2688. *
  2689. * RETURNS : nada
  2690. *
  2691. * COMMENTS :
  2692. *
  2693. *****************************************************************************/
  2694. BOOL WINAPI QueryDosDeviceNames ( TCHAR *&a_DosDeviceNameList )
  2695. {
  2696. BOOL t_Status = FALSE ;
  2697. BOOL bContinue = TRUE ;
  2698. ULONG ulDosDevices = MAX_DOS_DEVICES ;
  2699. do
  2700. {
  2701. //
  2702. // let's finish loop
  2703. //
  2704. bContinue = FALSE ;
  2705. CSmartBuffer pQueryBuffer ( ( ulDosDevices * sizeof ( TCHAR ) ) );
  2706. DWORD t_QueryStatus = QueryDosDevice ( NULL , (LPTSTR)((LPBYTE)pQueryBuffer) , ulDosDevices ) ;
  2707. if ( t_QueryStatus )
  2708. {
  2709. a_DosDeviceNameList = new TCHAR [ t_QueryStatus ] ;
  2710. if (a_DosDeviceNameList == NULL)
  2711. {
  2712. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2713. }
  2714. memcpy ( a_DosDeviceNameList , (void*)((LPBYTE)pQueryBuffer) , t_QueryStatus * sizeof ( TCHAR ) ) ;
  2715. t_Status = TRUE;
  2716. }
  2717. else
  2718. {
  2719. if ( STATUS_BUFFER_TOO_SMALL == (NTSTATUS)NtCurrentTeb()->LastStatusValue )
  2720. {
  2721. //
  2722. // let's continue if the reason of failure
  2723. // is just small buffer here
  2724. //
  2725. ulDosDevices = ulDosDevices * 2 ;
  2726. bContinue = TRUE ;
  2727. }
  2728. }
  2729. }
  2730. while ( bContinue ) ;
  2731. return t_Status ;
  2732. }
  2733. /*****************************************************************************
  2734. *
  2735. * FUNCTION : FindDosDeviceName
  2736. *
  2737. * DESCRIPTION : Finds the dos device symbolic link given an NT device name
  2738. *
  2739. * INPUTS : none
  2740. *
  2741. * OUTPUTS : nichts
  2742. *
  2743. * RETURNS : nada
  2744. *
  2745. * COMMENTS :
  2746. *
  2747. *****************************************************************************/
  2748. #define MAX_MAPPED_DEVICES 26
  2749. #define MAX_DEVICENAME_LENGTH 256
  2750. BOOL WINAPI FindDosDeviceName ( const TCHAR *a_DosDeviceNameList , const CHString a_SymbolicName , CHString &a_DosDevice , BOOL a_MappedDevice )
  2751. {
  2752. BOOL t_Status = FALSE ;
  2753. CSmartBuffer t_MappedDevices ;
  2754. if ( a_MappedDevice )
  2755. {
  2756. DWORD t_Length = GetLogicalDriveStrings ( 0 , NULL ) ;
  2757. if (t_Length)
  2758. {
  2759. LPBYTE t_buff = new BYTE[(t_Length + 1) * sizeof(TCHAR)];
  2760. if (t_buff == NULL)
  2761. {
  2762. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  2763. }
  2764. t_MappedDevices = t_buff;
  2765. if (!GetLogicalDriveStrings ( t_Length , (LPTSTR)((LPBYTE)t_MappedDevices) ) )
  2766. {
  2767. DWORD t_Error = GetLastError () ;
  2768. return FALSE;
  2769. }
  2770. }
  2771. else
  2772. {
  2773. DWORD t_Error = GetLastError () ;
  2774. return FALSE;
  2775. }
  2776. }
  2777. const TCHAR *t_Device = a_DosDeviceNameList ;
  2778. while ( *t_Device != NULL )
  2779. {
  2780. CSmartBuffer pQueryBuffer ((MAX_DOS_DEVICES * sizeof (TCHAR)));
  2781. DWORD t_QueryStatus = QueryDosDevice ( t_Device , (LPTSTR)((LPBYTE)pQueryBuffer) , MAX_DOS_DEVICES ) ;
  2782. if ( t_QueryStatus )
  2783. {
  2784. TCHAR *t_Symbolic = (LPTSTR)((LPBYTE)pQueryBuffer) ;
  2785. while ( *t_Symbolic != NULL )
  2786. {
  2787. if ( _wcsicmp ( a_SymbolicName , TOBSTRT(t_Symbolic) ) == 0 )
  2788. {
  2789. /*
  2790. * Atleast get a match even if there is no mapped drive
  2791. */
  2792. t_Status = TRUE ;
  2793. a_DosDevice = t_Device ;
  2794. if ( a_MappedDevice )
  2795. {
  2796. const TCHAR *t_CurrentDevice = (const LPTSTR)((LPBYTE)t_MappedDevices) ;
  2797. while ( *t_CurrentDevice != NULL )
  2798. {
  2799. if ( _tcsnicmp ( t_Device, t_CurrentDevice , 2 ) == 0 )
  2800. {
  2801. t_Status = TRUE ;
  2802. a_DosDevice = t_Device ;
  2803. return TRUE ;
  2804. }
  2805. t_CurrentDevice = t_CurrentDevice + _tcslen ( t_CurrentDevice ) + 1 ;
  2806. }
  2807. }
  2808. else
  2809. {
  2810. return TRUE ;
  2811. }
  2812. }
  2813. t_Symbolic = t_Symbolic + _tcslen ( t_Symbolic ) + 1 ;
  2814. }
  2815. }
  2816. else
  2817. {
  2818. DWORD t_Error = GetLastError () ;
  2819. }
  2820. t_Device = t_Device + _tcslen ( t_Device ) + 1 ;
  2821. }
  2822. return t_Status ;
  2823. }
  2824. BOOL CConfigMgrDevice::IsClass(LPCWSTR pwszClassName)
  2825. {
  2826. BOOL bRet = FALSE;
  2827. CHString sTemp;
  2828. if (GetClass(sTemp))
  2829. {
  2830. if (sTemp.CompareNoCase(pwszClassName) == 0)
  2831. {
  2832. bRet = TRUE;
  2833. }
  2834. else
  2835. {
  2836. bRet = FALSE;
  2837. }
  2838. }
  2839. else
  2840. {
  2841. CHString sClass(pwszClassName);
  2842. sClass.MakeUpper();
  2843. WCHAR cGuid[128];
  2844. GUID gFoo = CConfigManager::s_ClassMap[sClass];
  2845. StringFromGUID2(gFoo, cGuid, sizeof(cGuid)/sizeof(WCHAR));
  2846. if (GetClassGUID(sTemp) && (sTemp.CompareNoCase(cGuid) == 0))
  2847. {
  2848. bRet = TRUE;
  2849. }
  2850. }
  2851. return bRet;
  2852. }
  2853. BOOL CConfigMgrDevice::GetRegStringProperty(
  2854. LPCWSTR szProperty,
  2855. CHString &strValue)
  2856. {
  2857. CHString strKeyName;
  2858. DWORD dwRet;
  2859. CRegistry reg;
  2860. if (GetRegistryKeyName(strKeyName) &&
  2861. (dwRet = reg.Open(HKEY_LOCAL_MACHINE, strKeyName,
  2862. KEY_QUERY_VALUE) == ERROR_SUCCESS))
  2863. {
  2864. dwRet = reg.GetCurrentKeyValue(szProperty, strValue);
  2865. }
  2866. return dwRet == ERROR_SUCCESS;
  2867. }