Source code of Windows XP (NT5)
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.

1062 lines
25 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include <stdio.h>
  4. #include <tchar.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <regstr.h>
  8. #include <cfgmgr32.h>
  9. #include "netinfo.h"
  10. // Globals
  11. DEV_INFO *g_pdiDevList; // Head of device list
  12. /*++
  13. Routine Description: (21) GetDevNodeInfoAndCreateNewDevInfoNode
  14. Creates new list node, then gets registry and resource information for
  15. a specific device and copies it into that node. Finally, adds new node
  16. to beginning of linked list
  17. Arguments:
  18. dnDevNode: the device to find information about
  19. szDevNodeID: the registry path name of the device
  20. szEnumBuffer: name of enumerator this device is under
  21. Return Value:
  22. BOOL: TRUE if function succeeds, FALSE if not
  23. --*/
  24. BOOL GetDevNodeInfoAndCreateNewDevInfoNode(IN DEVNODE dnDevNode,
  25. IN PTCHAR szDevNodeID,
  26. IN PTCHAR szEnumBuffer)
  27. {
  28. LOG_CONF lcLogConf = 0, lcLogConfNew;
  29. CONFIGRET cmret, cmret2;
  30. PDEV_INFO pdiDevInfo=(PDEV_INFO)malloc(sizeof(DEV_INFO));
  31. int i;
  32. BOOL boolForcedFound = FALSE, boolAllocFound = FALSE;
  33. USHORT ushLogConfType[4] = {BOOT_LOG_CONF, ALLOC_LOG_CONF, BASIC_LOG_CONF, FORCED_LOG_CONF};
  34. if (pdiDevInfo == NULL)
  35. goto RetFALSE;
  36. // If this is not a PnP device, skip it
  37. if (!lstrcmpi(szEnumBuffer, TEXT("Root"))) {
  38. free(pdiDevInfo);
  39. goto RetTRUE;
  40. }
  41. //
  42. // Initialize fields inside the node
  43. //
  44. if (!InitializeInfoNode(pdiDevInfo, szDevNodeID, dnDevNode)) {
  45. // This is a device we don't want to list. Skip it
  46. free(pdiDevInfo);
  47. goto RetTRUE;
  48. }
  49. for (i = 0; i < NUM_LOG_CONF_TYPES; i++) {
  50. // Get logical configuration information
  51. cmret = CM_Get_First_Log_Conf(&lcLogConfNew,
  52. dnDevNode,
  53. ushLogConfType[i]);
  54. while (CR_SUCCESS == cmret) {
  55. lcLogConf = lcLogConfNew;
  56. if (ALLOC_LOG_CONF == ushLogConfType[i]) {
  57. boolAllocFound = TRUE;
  58. }
  59. if (!(GetResDesList(pdiDevInfo, lcLogConf, ushLogConfType[i]))) {
  60. goto RetFALSE;
  61. }
  62. cmret = CM_Get_Next_Log_Conf(&lcLogConfNew,
  63. lcLogConf,
  64. 0);
  65. cmret2 = CM_Free_Log_Conf_Handle(lcLogConf);
  66. }
  67. }
  68. //
  69. // If device has no Alloc configurations, skip
  70. // to the next device
  71. //
  72. if (!boolAllocFound) {
  73. //free(pdiDevInfo);
  74. //goto RetTRUE;
  75. }
  76. //
  77. // Insert new pdiDevInfo into Linked List of DevNodes
  78. //
  79. if (g_pdiDevList == NULL) {
  80. //
  81. // DevList is empty
  82. //
  83. g_pdiDevList = pdiDevInfo;
  84. } else {
  85. //
  86. // Add new pdiDevInfo to beginning of linked list
  87. //
  88. pdiDevInfo->Next = g_pdiDevList;
  89. g_pdiDevList->Prev = pdiDevInfo;
  90. g_pdiDevList = pdiDevInfo;
  91. }
  92. RetTRUE:
  93. return TRUE;
  94. RetFALSE:
  95. return FALSE;
  96. }
  97. /*++
  98. Routine Description: (20) ParseEnumerator
  99. Gets devices listed under enumerator name in registry
  100. Arguments:
  101. szEnumBuffer: the enumerator name
  102. Return Value:
  103. BOOL: TRUE if function succeeds, FALSE if not
  104. --*/
  105. BOOL
  106. ParseEnumerator(IN PTCHAR szEnumBuffer)
  107. {
  108. PTCHAR szDevIDBuffer = NULL;
  109. PTCHAR szDevNodeID = NULL;
  110. ULONG ulDevIDBufferLen = 0, ulCount = 0, ulStart = 0;
  111. CONFIGRET cmret = CR_SUCCESS;
  112. DEVNODE dnDevNode;
  113. BOOL bReturn = TRUE;
  114. //
  115. // Get buffer length
  116. //
  117. cmret = CM_Get_Device_ID_List_Size(&ulDevIDBufferLen,
  118. szEnumBuffer,
  119. CM_GETIDLIST_FILTER_ENUMERATOR);
  120. if (CR_SUCCESS != cmret) {
  121. //ErrorLog(20, TEXT("CM_Get_Device_ID_List_Size"), cmret, NULL);
  122. bReturn = FALSE;
  123. goto RetFALSE;
  124. }
  125. if ((szDevIDBuffer =(PTCHAR) malloc(sizeof(TCHAR) * ulDevIDBufferLen)) == NULL ||
  126. (szDevNodeID =(PTCHAR) malloc(sizeof(TCHAR) * ulDevIDBufferLen)) == NULL) {
  127. bReturn = FALSE;
  128. goto RetFALSE;
  129. }
  130. //
  131. // Get the Device ID List
  132. //
  133. cmret = CM_Get_Device_ID_List(szEnumBuffer,
  134. szDevIDBuffer,
  135. ulDevIDBufferLen,
  136. CM_GETIDLIST_FILTER_ENUMERATOR);
  137. if (CR_SUCCESS != cmret) {
  138. //ErrorLog(20, TEXT("CM_Get_Device_ID_List"), cmret, NULL);
  139. bReturn = FALSE;
  140. goto RetFALSE;
  141. }
  142. //
  143. // Note that ulDevIDBufferLen is a loose upper bound. The API may have
  144. // returned a size greater than the actual size of the list of strings.
  145. //
  146. for (ulCount = 0; ulCount < ulDevIDBufferLen; ulCount++) {
  147. ulStart = ulCount;
  148. if (szDevIDBuffer[ulCount] != '\0') {
  149. cmret = CM_Locate_DevNode(&dnDevNode,
  150. szDevIDBuffer + ulCount,
  151. CM_LOCATE_DEVNODE_NORMAL);
  152. //
  153. // Go to the next substring
  154. //
  155. while (szDevIDBuffer[ulCount] != TEXT('\0')) {
  156. ulCount++;
  157. }
  158. // Stop when we reach the double-NULL terminator
  159. if (szDevIDBuffer[ulCount+1] == TEXT('\0')) {
  160. ulCount=ulDevIDBufferLen;
  161. continue;
  162. }
  163. if (cmret == CR_SUCCESS) {
  164. _tcsncpy(szDevNodeID, szDevIDBuffer + ulStart, ulDevIDBufferLen);
  165. // Found the DevNode, so add its information to the device list
  166. if (!(GetDevNodeInfoAndCreateNewDevInfoNode(dnDevNode,
  167. szDevNodeID,
  168. szEnumBuffer))) {
  169. bReturn = FALSE;
  170. goto RetFALSE;
  171. }
  172. }
  173. }
  174. }
  175. bReturn = TRUE;
  176. RetFALSE:
  177. // fix to rajeshm old code. Selective free bug number 137987
  178. if (NULL != szDevIDBuffer)
  179. free (szDevIDBuffer);
  180. if (NULL != szDevNodeID)
  181. free (szDevNodeID);
  182. return bReturn;
  183. }
  184. void
  185. CollectDevData() {
  186. CONFIGRET cmret = CR_SUCCESS;
  187. ULONG ulIndexNum = 0;
  188. ULONG ulEnumBufferLen = 0;
  189. PTCHAR szEnumBuffer;
  190. szEnumBuffer = (PTCHAR) malloc(sizeof(TCHAR) * MAX_DEVNODE_ID_LEN);
  191. if (NULL == szEnumBuffer)
  192. return;
  193. for (ulIndexNum = 0; cmret == CR_SUCCESS; ulIndexNum++) {
  194. ulEnumBufferLen = MAX_DEVNODE_ID_LEN;
  195. cmret = CM_Enumerate_Enumerators( ulIndexNum,
  196. szEnumBuffer,
  197. &ulEnumBufferLen,
  198. 0);
  199. if (cmret == CR_SUCCESS)
  200. ParseEnumerator(szEnumBuffer);
  201. }
  202. free (szEnumBuffer);
  203. }
  204. BOOL CopyRegistryLine(IN DEVNODE dnDevNode,
  205. IN ULONG ulPropertyType,
  206. IN PDEV_INFO pdiDevInfo)
  207. /*++
  208. Routine Description: (22) CopyRegistryLine
  209. Copies one specific string of registry data to new list node
  210. Arguments:
  211. dnDevNode: the device to get information about
  212. ulpropertyType: which registry string to get
  213. pdiDevInfo: the new list node
  214. Return Value:
  215. BOOL: TRUE if function succeeds, FALSE if not
  216. --*/
  217. {
  218. ULONG ulRegDataLen = 0, ulRegDataType = 0;
  219. CONFIGRET cmret = CR_SUCCESS;
  220. PTCHAR szRegData = NULL;
  221. //
  222. // Get the length of the buffer don't bother checking return value
  223. // If RegProperty doesn't exist, we'll just move on
  224. //
  225. CM_Get_DevNode_Registry_Property(dnDevNode,
  226. ulPropertyType,
  227. NULL,
  228. NULL,
  229. &ulRegDataLen,
  230. 0);
  231. if (!ulRegDataLen ||
  232. (szRegData = (PTCHAR) malloc(sizeof(TCHAR) * ulRegDataLen)) == NULL) {
  233. goto RetFALSE;
  234. }
  235. //
  236. // Now get the registry information
  237. //
  238. cmret = CM_Get_DevNode_Registry_Property( dnDevNode,
  239. ulPropertyType,
  240. &ulRegDataType,
  241. szRegData,
  242. &ulRegDataLen,
  243. 0);
  244. if (CR_SUCCESS == cmret) {
  245. if (!(CopyRegDataToDevInfoNode(pdiDevInfo,
  246. ulPropertyType,
  247. szRegData))) {
  248. goto RetFALSE;
  249. }
  250. }
  251. if (szRegData == NULL)
  252. free (szRegData);
  253. return TRUE;
  254. RetFALSE:
  255. return FALSE;
  256. } /* CopyRegistryLine */
  257. /*++
  258. Routine Description: (23) CopyRegDataToDevInfoNode
  259. Copies a registry string to a list node
  260. Arguments:
  261. pdiDevInfo: the new list node
  262. ulPropertyType: which registry string to copy
  263. szRegData: the data to be copied
  264. Return Value:
  265. BOOL: TRUE if function succeeds, FALSE if not
  266. --*/
  267. BOOL CopyRegDataToDevInfoNode(IN OUT PDEV_INFO pdiDevInfo,
  268. IN ULONG ulPropertyType,
  269. IN PTCHAR szRegData)
  270. {
  271. if (pdiDevInfo == NULL) {
  272. goto RetFALSE;
  273. }
  274. switch (ulPropertyType) {
  275. case CM_DRP_DEVICEDESC:
  276. _tcsncpy(pdiDevInfo->szDescription, szRegData, MAX_PATH );
  277. break;
  278. case CM_DRP_HARDWAREID:
  279. _tcsncpy(pdiDevInfo->szHardwareID, szRegData, MAX_PATH );
  280. break;
  281. case CM_DRP_SERVICE:
  282. _tcsncpy(pdiDevInfo->szService, szRegData, MAX_PATH );
  283. break;
  284. case CM_DRP_CLASS:
  285. _tcsncpy(pdiDevInfo->szClass, szRegData, MAX_PATH );
  286. break;
  287. case CM_DRP_MFG:
  288. _tcsncpy(pdiDevInfo->szManufacturer, szRegData, MAX_PATH );
  289. break;
  290. case CM_DRP_CONFIGFLAGS:
  291. _tcsncpy(pdiDevInfo->szConfigFlags, szRegData, MAX_PATH );
  292. break;
  293. }
  294. return TRUE;
  295. RetFALSE:
  296. return FALSE;
  297. } /* CopyRegDataToDevInfoNode */
  298. /*++
  299. Routine Description: (58) InitializeInfoNode
  300. Initialized fields inside the new node
  301. Arguments:
  302. pdiDevInfo: the node
  303. szDevNodeID: used to find the dnDevNode in the future
  304. dnDevNode: the device we're storing information about
  305. Return Value:
  306. BOOL: TRUE if we should keep this node, FALSE if we should throw it away
  307. --*/
  308. BOOL InitializeInfoNode(IN PDEV_INFO pdiDevInfo,
  309. IN PTCHAR szDevNodeID,
  310. IN DEVNODE dnDevNode)
  311. {
  312. if (pdiDevInfo) {
  313. pdiDevInfo->Next = NULL;
  314. pdiDevInfo->Prev = NULL;
  315. pdiDevInfo->szDevNodeID[0] = TEXT('\0');
  316. pdiDevInfo->szDescription[0] = TEXT('\0');
  317. pdiDevInfo->szHardwareID[0] = TEXT('\0');
  318. pdiDevInfo->szService[0] = TEXT('\0');
  319. pdiDevInfo->szClass[0] = TEXT('\0');
  320. pdiDevInfo->szManufacturer[0] = TEXT('\0');
  321. pdiDevInfo->szConfigFlags[0] = TEXT('\0');
  322. pdiDevInfo->szFriendlyName[0] = TEXT('\0');
  323. pdiDevInfo->boolSavedOrigConfiguration = FALSE;
  324. pdiDevInfo->boolDisabled = FALSE;
  325. pdiDevInfo->prddForcedResDesData = NULL;
  326. pdiDevInfo->prddAllocResDesData = NULL;
  327. pdiDevInfo->prddBasicResDesData = NULL;
  328. pdiDevInfo->prddBootResDesData = NULL;
  329. //
  330. // Store devNodeID in pdiDevInfo to get handles to devnode in future
  331. //
  332. _tcsncpy(pdiDevInfo->szDevNodeID, szDevNodeID, MAX_PATH);
  333. // Extract information from the registry about this DevNode
  334. CopyRegistryLine(dnDevNode, CM_DRP_DEVICEDESC, pdiDevInfo);
  335. CopyRegistryLine(dnDevNode, CM_DRP_HARDWAREID, pdiDevInfo);
  336. CopyRegistryLine(dnDevNode, CM_DRP_SERVICE, pdiDevInfo);
  337. CopyRegistryLine(dnDevNode, CM_DRP_CLASS, pdiDevInfo);
  338. CopyRegistryLine(dnDevNode, CM_DRP_MFG, pdiDevInfo);
  339. CopyRegistryLine(dnDevNode, CM_DRP_CONFIGFLAGS, pdiDevInfo);
  340. RecordFriendlyName(pdiDevInfo);
  341. }
  342. //
  343. // Check the friendly name to see if we want to throw this node away
  344. //
  345. if (strcmp(pdiDevInfo->szFriendlyName, "STORAGE/Volume") == 0 ||
  346. strcmp(pdiDevInfo->szFriendlyName, "Unknown Device") == 0) {
  347. return FALSE;
  348. }
  349. return TRUE;
  350. } /* InitializeInfoNode */
  351. /*++
  352. Routine Description: (57) RecordFriendlyName
  353. Finds the best user friendly name for this device
  354. Arguments:
  355. pdiDevInfo: node containing all possible names
  356. Return Value:
  357. void
  358. --*/
  359. void
  360. RecordFriendlyName(IN PDEV_INFO pdiDevInfo)
  361. {
  362. if (pdiDevInfo) {
  363. if (pdiDevInfo->szDescription && pdiDevInfo->szDescription[0] != TEXT('\0'))
  364. _tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szDescription, MAX_PATH );
  365. else if (pdiDevInfo->szHardwareID && pdiDevInfo->szHardwareID[0] != TEXT('\0'))
  366. _tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szHardwareID, MAX_PATH);
  367. else if (pdiDevInfo->szManufacturer && pdiDevInfo->szManufacturer[0] != TEXT('\0'))
  368. _tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szHardwareID, MAX_PATH);
  369. else if (pdiDevInfo->szService && pdiDevInfo->szService[0] != TEXT('\0'))
  370. _tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szService, MAX_PATH);
  371. else if (pdiDevInfo->szClass && pdiDevInfo->szClass[0] != TEXT('\0'))
  372. _tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szClass, MAX_PATH);
  373. else
  374. _tcscpy(pdiDevInfo->szFriendlyName, TEXT("Unknown Device"));
  375. }
  376. } /* RecordFriendlyName */
  377. /*++
  378. Routine Description: (24) GetResDesList
  379. Creates new resource data node and copies resource information to that node
  380. Arguments:
  381. pdiDevInfo: the list node which will contain the new resource node
  382. lcLogConf: the logical configuration information
  383. ulLogConfType: FORCED, ALLOC, BOOT, or BASIC logical configuration
  384. Return Value:
  385. BOOL: TRUE if function succeeds, FALSE if not
  386. --*/
  387. BOOL
  388. GetResDesList(IN OUT PDEV_INFO pdiDevInfo,
  389. IN LOG_CONF lcLogConf,
  390. IN ULONG ulLogConfType)
  391. {
  392. CONFIGRET cmret, cmret2;
  393. RES_DES rdResDes = 0, rdResDesNew;
  394. RESOURCEID ridResourceID = 0;
  395. PRES_DES_DATA prddResDesData;
  396. prddResDesData = (PRES_DES_DATA)malloc(sizeof(RES_DES_DATA));
  397. if (prddResDesData == NULL)
  398. goto c0;
  399. prddResDesData->Next = NULL;
  400. prddResDesData->Prev = NULL;
  401. prddResDesData->pmresMEMResource = NULL;
  402. prddResDesData->piresIOResource = NULL;
  403. prddResDesData->pdresDMAResource = NULL;
  404. prddResDesData->pqresIRQResource = NULL;
  405. cmret = CM_Get_Next_Res_Des(&rdResDesNew,
  406. lcLogConf,
  407. ResType_All,
  408. &ridResourceID,
  409. 0);
  410. //
  411. // Go through each resource type and copy data to new node
  412. //
  413. while (CR_SUCCESS == cmret) {
  414. rdResDes = rdResDesNew;
  415. if (ridResourceID >= ResType_Mem && ridResourceID <= ResType_IRQ) {
  416. if (!(ProcessResDesInfo(prddResDesData,
  417. rdResDes,
  418. ridResourceID))) {
  419. goto c1;
  420. }
  421. }
  422. cmret = CM_Get_Next_Res_Des(&rdResDesNew,
  423. rdResDes,
  424. ResType_All,
  425. &ridResourceID,
  426. 0);
  427. cmret2 = CM_Free_Res_Des_Handle(rdResDes);
  428. if (cmret2 != CR_SUCCESS) {
  429. //ErrorLog(24, TEXT("CM_Free_Res_Des_Handle"), cmret2, NULL);
  430. }
  431. }
  432. // Add the new node to the linked list
  433. switch (ulLogConfType) {
  434. case FORCED_LOG_CONF:
  435. if (!pdiDevInfo->prddForcedResDesData) {
  436. //
  437. // This is the first entry into the linked list
  438. //
  439. pdiDevInfo->prddForcedResDesData = prddResDesData;
  440. } else {
  441. //
  442. // Add new node to beginning of linked list
  443. //
  444. prddResDesData->Next = pdiDevInfo->prddForcedResDesData;
  445. pdiDevInfo->prddForcedResDesData->Prev = prddResDesData;
  446. pdiDevInfo->prddForcedResDesData = prddResDesData;
  447. }
  448. break;
  449. case ALLOC_LOG_CONF:
  450. if (!pdiDevInfo->prddAllocResDesData) {
  451. //
  452. // This is the first entry into the linked list
  453. //
  454. pdiDevInfo->prddAllocResDesData = prddResDesData;
  455. } else {
  456. //
  457. // Add new node to beginning of linked list
  458. //
  459. prddResDesData->Next = pdiDevInfo->prddAllocResDesData;
  460. pdiDevInfo->prddAllocResDesData->Prev = prddResDesData;
  461. pdiDevInfo->prddAllocResDesData = prddResDesData;
  462. }
  463. break;
  464. case BASIC_LOG_CONF:
  465. if (!pdiDevInfo->prddBasicResDesData) {
  466. //
  467. // This is the first entry into the linked list
  468. //
  469. pdiDevInfo->prddBasicResDesData = prddResDesData;
  470. } else {
  471. //
  472. // Add new node to beginning of linked list
  473. //
  474. prddResDesData->Next = pdiDevInfo->prddBasicResDesData;
  475. pdiDevInfo->prddBasicResDesData->Prev = prddResDesData;
  476. pdiDevInfo->prddBasicResDesData = prddResDesData;
  477. }
  478. break;
  479. case BOOT_LOG_CONF:
  480. if (!pdiDevInfo->prddBootResDesData) {
  481. //
  482. // This is the first entry into the linked list
  483. //
  484. pdiDevInfo->prddBootResDesData = prddResDesData;
  485. } else {
  486. //
  487. // Add new node to beginning of linked list
  488. //
  489. prddResDesData->Next = pdiDevInfo->prddBootResDesData;
  490. pdiDevInfo->prddBootResDesData->Prev = prddResDesData;
  491. pdiDevInfo->prddBootResDesData = prddResDesData;
  492. }
  493. break;
  494. default:
  495. goto c1;
  496. }
  497. return TRUE;
  498. c1:
  499. free(prddResDesData);
  500. c0:
  501. return FALSE;
  502. }
  503. /* GetResDestList */
  504. /*++
  505. Routine Description: (25) ProcessResDesInfo
  506. Gets information for one resource descriptor
  507. Arguments:
  508. prddResDesData: the new resource data node receiving the info
  509. rdResDes: the resource descriptor containing the info
  510. ridResourceID: tells the resource type (DMA, IO, MEM, IRQ, or CS)
  511. Return Value:
  512. BOOL: TRUE if function succeeds, FALSE if not
  513. --*/
  514. BOOL
  515. ProcessResDesInfo(IN OUT PRES_DES_DATA prddResDesData,
  516. IN RES_DES rdResDes,
  517. IN RESOURCEID ridResourceID)
  518. {
  519. PVOID pvResDesDataBuffer = NULL;
  520. ULONG ulResDesDataBufferLen;
  521. CONFIGRET cmret;
  522. cmret = CM_Get_Res_Des_Data_Size(&ulResDesDataBufferLen,
  523. rdResDes,
  524. 0);
  525. if (CR_SUCCESS != cmret) {
  526. //ErrorLog(25, TEXT("CM_Get_Res_Des_Data_Size"), cmret, NULL);
  527. goto RetFALSE;
  528. }
  529. if ((pvResDesDataBuffer = malloc(sizeof(PVOID) * ulResDesDataBufferLen))
  530. == NULL) {
  531. // Log(25, SEV2, TEXT("resDesDataBuffer malloc size of %d failed."),
  532. // ulResDesDataBufferLen);
  533. goto RetFALSE;
  534. }
  535. //
  536. // Get the data
  537. //
  538. cmret = CM_Get_Res_Des_Data(rdResDes,
  539. pvResDesDataBuffer,
  540. ulResDesDataBufferLen,
  541. 0);
  542. if (CR_SUCCESS != cmret) {
  543. //ErrorLog(25, TEXT("CM_Get_Res_Des_Data"), cmret, NULL);
  544. goto RetFALSE;
  545. }
  546. //
  547. // Copy data into ResDesData node
  548. //
  549. switch (ridResourceID) {
  550. case ResType_Mem:
  551. prddResDesData->pmresMEMResource = (PMEM_RESOURCE)pvResDesDataBuffer;
  552. break;
  553. case ResType_IO:
  554. prddResDesData->piresIOResource = (PIO_RESOURCE)pvResDesDataBuffer;
  555. break;
  556. case ResType_DMA:
  557. prddResDesData->pdresDMAResource = (PDMA_RESOURCE)pvResDesDataBuffer;
  558. break;
  559. case ResType_IRQ:
  560. prddResDesData->pqresIRQResource = (PIRQ_RESOURCE)pvResDesDataBuffer;
  561. break;
  562. default:
  563. // Log(25, SEV2, TEXT("Illegal ResourceID - %ul"), ridResourceID);
  564. goto RetFALSE;
  565. }
  566. return TRUE;
  567. RetFALSE:
  568. return FALSE;
  569. } /* ProcessResDesInfo */
  570. /*++
  571. Routine Description: (26) UpdateDeviceList
  572. Frees resource information for all devices and then collects the
  573. information again
  574. Arguments:
  575. none (g_pdiDevList is global head of device list)
  576. Return Value:
  577. BOOL: TRUE if function succeeds, FALSE if not
  578. --*/
  579. BOOL UpdateDeviceList()
  580. {
  581. PDEV_INFO pdiTmpDevInfo;
  582. pdiTmpDevInfo = g_pdiDevList;
  583. //
  584. // Go through linked list and delete each node's ResDes lists
  585. //
  586. while (pdiTmpDevInfo) {
  587. if (pdiTmpDevInfo->prddForcedResDesData) {
  588. DeleteResDesDataNode(pdiTmpDevInfo->prddForcedResDesData);
  589. pdiTmpDevInfo->prddForcedResDesData = NULL;
  590. }
  591. if (pdiTmpDevInfo->prddAllocResDesData) {
  592. DeleteResDesDataNode(pdiTmpDevInfo->prddAllocResDesData);
  593. pdiTmpDevInfo->prddAllocResDesData = NULL;
  594. }
  595. if (pdiTmpDevInfo->prddBasicResDesData) {
  596. DeleteResDesDataNode(pdiTmpDevInfo->prddBasicResDesData);
  597. pdiTmpDevInfo->prddBasicResDesData = NULL;
  598. }
  599. if (pdiTmpDevInfo->prddBootResDesData) {
  600. DeleteResDesDataNode(pdiTmpDevInfo->prddBootResDesData);
  601. pdiTmpDevInfo->prddBootResDesData = NULL;
  602. }
  603. pdiTmpDevInfo = pdiTmpDevInfo->Next;
  604. }
  605. pdiTmpDevInfo = g_pdiDevList;
  606. //
  607. // Recreate the ResDesLists for each node
  608. //
  609. while (pdiTmpDevInfo) {
  610. if (!(RecreateResDesList(pdiTmpDevInfo, FORCED_LOG_CONF)))
  611. goto RetFALSE;
  612. if (!(RecreateResDesList(pdiTmpDevInfo, ALLOC_LOG_CONF)))
  613. goto RetFALSE;
  614. if (!(RecreateResDesList(pdiTmpDevInfo, BASIC_LOG_CONF)))
  615. goto RetFALSE;
  616. if (!(RecreateResDesList(pdiTmpDevInfo, BOOT_LOG_CONF)))
  617. goto RetFALSE;
  618. pdiTmpDevInfo = pdiTmpDevInfo->Next;
  619. }
  620. return TRUE;
  621. RetFALSE:
  622. return FALSE;
  623. } /* UpdateDeviceList */
  624. /*++
  625. Routine Description: (27) DeleteResDesDataNode
  626. Deletes a string of RES_DES_DATA structures
  627. Arguments:
  628. prddTmpResDes: the head of the linked list
  629. Return Value:
  630. void
  631. --*/
  632. void
  633. DeleteResDesDataNode(IN PRES_DES_DATA prddTmpResDes)
  634. {
  635. PRES_DES_DATA prddNextResDes;
  636. while (prddTmpResDes) {
  637. prddNextResDes = prddTmpResDes->Next;
  638. free (prddTmpResDes);
  639. prddTmpResDes = prddNextResDes;
  640. }
  641. } /* DeleteResDesDataNode */
  642. /*++
  643. Routine Description: (56) CopyDataToLogConf
  644. Calls CM_Add_Res_Des to add a resDes to a lcLogConf
  645. Arguments:
  646. lcLogConf: the lcLogConf receiving the resDes
  647. ridResType: ResType_Mem, IO, DMA or IRQ
  648. pvResData: the new data
  649. ulResourceLen: size of the data
  650. Return Value:
  651. BOOL: TRUE if the CM call succeeds, FALSE if not
  652. --*/
  653. BOOL
  654. CopyDataToLogConf(IN LOG_CONF lcLogConf,
  655. IN RESOURCEID ridResType,
  656. IN PVOID pvResData,
  657. IN ULONG ulResourceLen)
  658. {
  659. CONFIGRET cmret;
  660. RES_DES rdResDes;
  661. //
  662. // Copy the data to the logConf
  663. //
  664. cmret = CM_Add_Res_Des(&rdResDes,
  665. lcLogConf,
  666. ridResType,
  667. pvResData,
  668. ulResourceLen,
  669. 0);
  670. if (CR_SUCCESS != cmret) {
  671. goto RetFALSE;
  672. }
  673. return TRUE;
  674. RetFALSE:
  675. return FALSE;
  676. } /* CopyDataToLogConf */
  677. /*++
  678. Routine Description: (28) RecreateResDesList
  679. Uses CM calls to find ResDes information and creates linked list
  680. of this information inside of given DEV_INFO
  681. Arguments:
  682. pdiTmpDevInfo: the node receiving the information
  683. ulLogConfType: the LogConf type (FORCED_LOG_CONF,
  684. ALLOC_LOG_CONF,
  685. BASIC_LOG_CONF,
  686. BOOT_LOG_CONF)
  687. Return Value:
  688. BOOL: TRUE if function succeeds, FALSE if not
  689. --*/
  690. BOOL
  691. RecreateResDesList(IN OUT PDEV_INFO pdiTmpDevInfo,
  692. IN ULONG ulLogConfType)
  693. {
  694. CONFIGRET cmret, cmret2;
  695. DEVNODE dnDevNode;
  696. LOG_CONF lcLogConf, lcLogConfNew;
  697. //
  698. // Get handle to the devnode
  699. //
  700. cmret = CM_Locate_DevNode(&dnDevNode,
  701. pdiTmpDevInfo->szDevNodeID,
  702. CM_LOCATE_DEVNODE_NORMAL);
  703. if (CR_SUCCESS != cmret) {
  704. //ErrorLog(28, TEXT("CM_Locate_DevNode"), cmret, NULL);
  705. goto RetFALSE;
  706. }
  707. //
  708. // Get logical configuration information
  709. //
  710. cmret = CM_Get_First_Log_Conf(&lcLogConfNew,
  711. dnDevNode,
  712. ulLogConfType);
  713. while (CR_SUCCESS == cmret) {
  714. lcLogConf = lcLogConfNew;
  715. if (!(GetResDesList(pdiTmpDevInfo, lcLogConf, ulLogConfType))) {
  716. goto RetFALSE;
  717. }
  718. cmret = CM_Get_Next_Log_Conf(&lcLogConfNew,
  719. lcLogConf,
  720. 0);
  721. cmret2 = CM_Free_Log_Conf_Handle(lcLogConf);
  722. if (CR_SUCCESS != cmret2) {
  723. //ErrorLog(28, TEXT("CM_Free_Log_Conf"), cmret2, NULL);
  724. }
  725. }
  726. return TRUE;
  727. RetFALSE:
  728. return FALSE;
  729. } /* RecreateResDesList */
  730. void Cleanup()
  731. {
  732. PDEV_INFO pdiDevInfo = g_pdiDevList;
  733. PDEV_INFO pdiNextInfoNode;
  734. while (pdiDevInfo) {
  735. pdiNextInfoNode = pdiDevInfo->Next;
  736. DeleteResDesDataNode(pdiDevInfo->prddForcedResDesData);
  737. DeleteResDesDataNode(pdiDevInfo->prddAllocResDesData);
  738. DeleteResDesDataNode(pdiDevInfo->prddBasicResDesData);
  739. DeleteResDesDataNode(pdiDevInfo->prddBootResDesData);
  740. free(pdiDevInfo);
  741. pdiDevInfo = pdiNextInfoNode;
  742. }
  743. } /* Cleanup */