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.

435 lines
7.9 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. resenum.c
  5. Abstract:
  6. Win95 hardware resource enumeration routines.
  7. Author:
  8. Jim Schmidt (jimschm) 28-Jul-1998
  9. Revision History:
  10. jimschm 28-Sep-1998 Auto DMA added to resource enum
  11. --*/
  12. #include "pch.h"
  13. #include <cfgmgr32.h>
  14. BOOL
  15. pFindDynamicValue (
  16. IN PCTSTR DevNode,
  17. OUT PTSTR DynamicKey
  18. );
  19. PBYTE
  20. GetDevNodeResources (
  21. IN PCTSTR DevNodeKey
  22. )
  23. {
  24. PBYTE Data = NULL;
  25. TCHAR DynDataKey[MAX_REGISTRY_KEY];
  26. HKEY Key;
  27. //
  28. // Given a dev node, locate the dynamic entry
  29. //
  30. if (!pFindDynamicValue (DevNodeKey, DynDataKey)) {
  31. return NULL;
  32. }
  33. //
  34. // Get resource binary blob from HKEY_DYN_DATA\Config Manager\Enum\*\Allocation.
  35. //
  36. Key = OpenRegKeyStr (DynDataKey);
  37. if (!Key) {
  38. DEBUGMSG ((DBG_WHOOPS, "Can't open key: %s", DynDataKey));
  39. return NULL;
  40. }
  41. Data = GetRegValueBinary (Key, S_ALLOCATION);
  42. CloseRegKey (Key);
  43. return Data;
  44. }
  45. VOID
  46. FreeDevNodeResources (
  47. IN PBYTE ResourceData
  48. )
  49. {
  50. if (ResourceData) {
  51. MemFree (g_hHeap, 0, ResourceData);
  52. }
  53. }
  54. BOOL
  55. pFindDynamicValue (
  56. IN PCTSTR DevNode,
  57. OUT PTSTR DynamicKey
  58. )
  59. {
  60. REGKEY_ENUM e;
  61. PCTSTR HardwareKey;
  62. HKEY SubKey;
  63. BOOL Found = FALSE;
  64. TCHAR BaseCfgMgrKey[MAX_REGISTRY_KEY];
  65. StringCopy (BaseCfgMgrKey, TEXT("HKDD\\"));
  66. StringCat (BaseCfgMgrKey, S_CONFIG_MANAGER);
  67. if (StringIMatchCharCount (TEXT("HKLM\\Enum\\"), DevNode, 10)) {
  68. DevNode = CharCountToPointer (DevNode, 10);
  69. } else if (StringIMatchCharCount (TEXT("HKEY_LOCAL_MACHINE\\Enum\\"), DevNode, 24)) {
  70. DevNode = CharCountToPointer (DevNode, 24);
  71. }
  72. if (EnumFirstRegKeyStr (&e, BaseCfgMgrKey)) {
  73. do {
  74. SubKey = OpenRegKey (e.KeyHandle, e.SubKeyName);
  75. if (!SubKey) {
  76. DEBUGMSG ((DBG_ERROR, "Can't open subkey %s in HKDD\\Config Manager\\Enum", e.SubKeyName));
  77. continue;
  78. }
  79. HardwareKey = GetRegValueString (SubKey, S_HARDWAREKEY_VALUENAME);
  80. if (HardwareKey) {
  81. if (StringIMatch (DevNode, HardwareKey)) {
  82. Found = TRUE;
  83. AbortRegKeyEnum (&e);
  84. StringCopy (DynamicKey, BaseCfgMgrKey);
  85. StringCopy (AppendWack (DynamicKey), e.SubKeyName);
  86. }
  87. MemFree (g_hHeap, 0, HardwareKey);
  88. }
  89. CloseRegKey (SubKey);
  90. } while (!Found && EnumNextRegKey (&e));
  91. }
  92. return Found;
  93. }
  94. BOOL
  95. EnumFirstDevNodeResourceEx (
  96. OUT PDEVNODERESOURCE_ENUM EnumPtr,
  97. IN PBYTE DevNodeResources
  98. )
  99. {
  100. ZeroMemory (EnumPtr, sizeof (DEVNODERESOURCE_ENUM));
  101. EnumPtr->Resources = DevNodeResources;
  102. if (!DevNodeResources) {
  103. return FALSE;
  104. }
  105. if (*((PDWORD) EnumPtr->Resources) != 0x0400) {
  106. DEBUGMSG ((DBG_ERROR, "Enumeration of dev node resources, cfg mgr != v4"));
  107. return FALSE;
  108. }
  109. EnumPtr->NextResource = DevNodeResources + sizeof (DWORD) * 2;
  110. return EnumNextDevNodeResourceEx (EnumPtr);
  111. }
  112. BOOL
  113. EnumNextDevNodeResourceEx (
  114. IN OUT PDEVNODERESOURCE_ENUM EnumPtr
  115. )
  116. {
  117. DWORD Len;
  118. Len = *((PDWORD) EnumPtr->NextResource);
  119. if (!Len) {
  120. return FALSE;
  121. }
  122. EnumPtr->Resource = EnumPtr->NextResource;
  123. EnumPtr->ResourceData = EnumPtr->Resource + sizeof (DWORD) * 2;
  124. EnumPtr->Type = *((PDWORD) (EnumPtr->Resource + sizeof (DWORD)));
  125. EnumPtr->NextResource += Len;
  126. return TRUE;
  127. }
  128. BOOL
  129. EnumFirstDevNodeResource (
  130. OUT PDEVNODERESOURCE_ENUM EnumPtr,
  131. IN PCTSTR DevNode
  132. )
  133. {
  134. if (!EnumFirstDevNodeResourceEx (
  135. EnumPtr,
  136. GetDevNodeResources (DevNode)
  137. )) {
  138. FreeDevNodeResources (EnumPtr->Resources);
  139. return FALSE;
  140. }
  141. return TRUE;
  142. }
  143. BOOL
  144. EnumNextDevNodeResource (
  145. IN OUT PDEVNODERESOURCE_ENUM EnumPtr
  146. )
  147. {
  148. if (!EnumNextDevNodeResourceEx (EnumPtr)) {
  149. FreeDevNodeResources (EnumPtr->Resources);
  150. return FALSE;
  151. }
  152. return TRUE;
  153. }
  154. BOOL
  155. pIsDisplayableType (
  156. IN PDEVNODESTRING_ENUM EnumPtr
  157. )
  158. {
  159. BOOL b = TRUE;
  160. switch (EnumPtr->Enum.Type) {
  161. case ResType_Mem:
  162. break;
  163. case ResType_IO:
  164. break;
  165. case ResType_DMA:
  166. break;
  167. case ResType_IRQ:
  168. break;
  169. default:
  170. b = FALSE;
  171. break;
  172. }
  173. return b;
  174. }
  175. VOID
  176. pFormatMemoryResource (
  177. IN OUT PDEVNODESTRING_ENUM EnumPtr
  178. )
  179. {
  180. PMEM_RESOURCE_9X MemRes;
  181. MemRes = (PMEM_RESOURCE_9X) EnumPtr->Enum.ResourceData;
  182. wsprintf (
  183. EnumPtr->Value,
  184. TEXT("%08X - %08X"),
  185. MemRes->MEM_Header.MD_Alloc_Base,
  186. MemRes->MEM_Header.MD_Alloc_End
  187. );
  188. }
  189. VOID
  190. pFormatIoResource (
  191. IN OUT PDEVNODESTRING_ENUM EnumPtr
  192. )
  193. {
  194. PIO_RESOURCE_9X IoRes;
  195. IoRes = (PIO_RESOURCE_9X) EnumPtr->Enum.ResourceData;
  196. wsprintf (
  197. EnumPtr->Value,
  198. TEXT("%04X - %04X"),
  199. IoRes->IO_Header.IOD_Alloc_Base,
  200. IoRes->IO_Header.IOD_Alloc_End
  201. );
  202. }
  203. VOID
  204. pAddChannel (
  205. IN OUT PTSTR String,
  206. IN UINT Channel
  207. )
  208. {
  209. if (String[0]) {
  210. StringCat (String, TEXT(" "));
  211. }
  212. wsprintf (
  213. GetEndOfString (String),
  214. TEXT("%02X"),
  215. Channel
  216. );
  217. }
  218. VOID
  219. pFormatDmaResource (
  220. IN OUT PDEVNODESTRING_ENUM EnumPtr
  221. )
  222. {
  223. PDMA_RESOURCE_9X DmaRes;
  224. DWORD Bit, Channel;
  225. PCTSTR ResText;
  226. DmaRes = (PDMA_RESOURCE_9X) EnumPtr->Enum.ResourceData;
  227. EnumPtr->Value[0] = 0;
  228. Channel = 0;
  229. for (Bit = 1 ; Bit ; Bit <<= 1) {
  230. if (DmaRes->DMA_Bits & Bit) {
  231. pAddChannel (EnumPtr->Value, Channel);
  232. }
  233. Channel++;
  234. }
  235. if (EnumPtr->Value[0] == 0) {
  236. ResText = GetStringResource (MSG_AUTO_DMA);
  237. if (ResText) { // otherwise... do nothing, I guess, since this function
  238. // doesn't return a status value right now.
  239. StringCopy (EnumPtr->Value, ResText);
  240. FreeStringResource (ResText);
  241. }
  242. }
  243. }
  244. VOID
  245. pFormatIrqResource (
  246. IN OUT PDEVNODESTRING_ENUM EnumPtr
  247. )
  248. {
  249. PIRQ_RESOURCE_9X IrqRes;
  250. IrqRes = (PIRQ_RESOURCE_9X) EnumPtr->Enum.ResourceData;
  251. wsprintf (
  252. EnumPtr->Value,
  253. TEXT("%02X"),
  254. IrqRes->AllocNum
  255. );
  256. }
  257. BOOL
  258. pEnumDevNodeStringWorker (
  259. IN OUT PDEVNODESTRING_ENUM EnumPtr
  260. )
  261. {
  262. UINT Id = 0;
  263. PCTSTR Name;
  264. //
  265. // Format each type of resource for display
  266. //
  267. switch (EnumPtr->Enum.Type) {
  268. case ResType_Mem:
  269. Id = MSG_RESTYPE_MEMORY;
  270. pFormatMemoryResource (EnumPtr);
  271. break;
  272. case ResType_IO:
  273. Id = MSG_RESTYPE_IO;
  274. pFormatIoResource (EnumPtr);
  275. break;
  276. case ResType_DMA:
  277. Id = MSG_RESTYPE_DMA;
  278. pFormatDmaResource (EnumPtr);
  279. break;
  280. case ResType_IRQ:
  281. Id = MSG_RESTYPE_IRQ;
  282. pFormatIrqResource (EnumPtr);
  283. break;
  284. }
  285. if (Id) {
  286. Name = GetStringResource (Id);
  287. if (Name) {
  288. StringCopy (
  289. EnumPtr->ResourceName,
  290. Name
  291. );
  292. FreeStringResource (Name);
  293. return TRUE;
  294. }
  295. }
  296. return FALSE;
  297. }
  298. BOOL
  299. EnumFirstDevNodeString (
  300. OUT PDEVNODESTRING_ENUM EnumPtr,
  301. IN PCTSTR DevNodeKeyStr
  302. )
  303. {
  304. if (!EnumFirstDevNodeResource (&EnumPtr->Enum, DevNodeKeyStr)) {
  305. return FALSE;
  306. }
  307. if (pIsDisplayableType (EnumPtr)) {
  308. return pEnumDevNodeStringWorker (EnumPtr);
  309. }
  310. return EnumNextDevNodeString (EnumPtr);
  311. }
  312. BOOL
  313. EnumNextDevNodeString (
  314. IN OUT PDEVNODESTRING_ENUM EnumPtr
  315. )
  316. {
  317. do {
  318. if (!EnumNextDevNodeResource (&EnumPtr->Enum)) {
  319. return FALSE;
  320. }
  321. } while (!pIsDisplayableType (EnumPtr));
  322. return pEnumDevNodeStringWorker (EnumPtr);
  323. }