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.

324 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. online.c
  5. Abstract:
  6. Functions to enumerate all currently online devices. This module
  7. walks the registry's HKEY_DYN_DATA\Config Manager\Enum branch and
  8. returns an open HKEY to the HKEY_LOCAL_MACHINE\Enum item.
  9. Author:
  10. Jim Schmidt (jimschm) 9-Apr-1997
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. #define S_COMPATIBLE_IDS TEXT("CompatibleIDs")
  15. BOOL
  16. EnumFirstActiveHardware (
  17. OUT PACTIVE_HARDWARE_ENUM EnumPtr,
  18. IN PCTSTR ClassFilter OPTIONAL
  19. )
  20. /*++
  21. Routine Description:
  22. EnumFirstActiveHardware identifies the first online device as identified
  23. in HKDD\Config Manager. Information about the device is stored in the
  24. enumeration structure, and the caller is expected to access its members
  25. directly.
  26. The caller can specify a class filter pattern to screen devices by type.
  27. Arguments:
  28. EnumPtr - Receives the enumeration state of the first device listed in
  29. HKDD\Config Manager.
  30. ClassFilter - Specifies a pattern to limit the search to. comparison is
  31. performed against the Class value of the dev node.
  32. Return Value:
  33. TRUE if an active device was found, or FALSE if enumeration is
  34. complete.
  35. --*/
  36. {
  37. ZeroMemory (EnumPtr, sizeof (ACTIVE_HARDWARE_ENUM));
  38. if (ClassFilter) {
  39. EnumPtr->ClassFilter = (PTSTR) MemAlloc (g_hHeap, 0, SizeOfString (ClassFilter));
  40. if (!EnumPtr->ClassFilter) {
  41. return FALSE;
  42. }
  43. StringCopy (EnumPtr->ClassFilter, ClassFilter);
  44. }
  45. EnumPtr->ConfigMgrKey = OpenRegKey (HKEY_DYN_DATA, S_CONFIG_MANAGER);
  46. if (!EnumPtr->ConfigMgrKey) {
  47. LOG ((LOG_ERROR, "Cannot open HKDD\\%s for hardware enumeration", S_CONFIG_MANAGER));
  48. AbortActiveHardwareEnum (EnumPtr);
  49. return FALSE;
  50. }
  51. EnumPtr->EnumKey = OpenRegKey (HKEY_LOCAL_MACHINE, S_ENUM_BRANCH);
  52. if (!EnumPtr->EnumKey) {
  53. LOG ((LOG_ERROR, "Cannot open HKLM\\%s for hardware enumeration", S_ENUM_BRANCH));
  54. AbortActiveHardwareEnum (EnumPtr);
  55. return FALSE;
  56. }
  57. return EnumNextActiveHardware (EnumPtr);
  58. }
  59. BOOL
  60. EnumNextActiveHardware (
  61. IN OUT PACTIVE_HARDWARE_ENUM EnumPtr
  62. )
  63. /*++
  64. Routine Description:
  65. EnumNextActiveHardware enumerates the next active hardware device by
  66. using the dynamic data stored in HKDD\Config Manager and finding the
  67. static HKLM\Enum entry for the device. If necessary, devices are
  68. screened based on the class pattern supplied to EnumFirstActiveHardware.
  69. Arguments:
  70. EnumPtr - Specifies the enumeration structure initialized by
  71. EnumFirstActiveHardware.
  72. Return Value:
  73. TRUE if another active device was found, or FALSE if enumeration is
  74. complete.
  75. --*/
  76. {
  77. HKEY OnlineDeviceKey;
  78. PCTSTR Data;
  79. PCTSTR Class;
  80. HKEY ActualDeviceKey;
  81. if (EnumPtr->ActualDeviceKey) {
  82. CloseRegKey (EnumPtr->ActualDeviceKey);
  83. EnumPtr->ActualDeviceKey = NULL;
  84. }
  85. do {
  86. //
  87. // Get the next registry key
  88. //
  89. if (EnumPtr->NotFirst) {
  90. if (!EnumNextRegKey (&EnumPtr->CurrentDevice)) {
  91. AbortActiveHardwareEnum (EnumPtr);
  92. return FALSE;
  93. }
  94. } else {
  95. if (!EnumFirstRegKey (&EnumPtr->CurrentDevice, EnumPtr->ConfigMgrKey)) {
  96. AbortActiveHardwareEnum (EnumPtr);
  97. return FALSE;
  98. }
  99. EnumPtr->NotFirst = TRUE;
  100. }
  101. //
  102. // Get the HardWareKey value from the current online device
  103. //
  104. OnlineDeviceKey = OpenRegKey (
  105. EnumPtr->CurrentDevice.KeyHandle,
  106. EnumPtr->CurrentDevice.SubKeyName
  107. );
  108. if (OnlineDeviceKey) {
  109. //
  110. // Get the HardWareKey value data
  111. //
  112. Data = GetRegValueString (OnlineDeviceKey, S_HARDWAREKEY_VALUENAME);
  113. if (Data) {
  114. //
  115. // Open hardware key in enum branch
  116. //
  117. _tcssafecpy (EnumPtr->RegLocation, Data, MAX_TCHAR_PATH);
  118. ActualDeviceKey = OpenRegKey (EnumPtr->EnumKey, Data);
  119. if (ActualDeviceKey) {
  120. //
  121. // Check if this is actually a device (it has a
  122. // class value)
  123. //
  124. Class = GetRegValueString (ActualDeviceKey, S_CLASS_VALUENAME);
  125. if (Class) {
  126. //
  127. // It is a valid device, now compare against pattern
  128. //
  129. if (EnumPtr->ClassFilter) {
  130. if (IsPatternMatch (EnumPtr->ClassFilter, Class)) {
  131. // Match!!
  132. EnumPtr->ActualDeviceKey = ActualDeviceKey;
  133. }
  134. } else {
  135. // Match!!
  136. EnumPtr->ActualDeviceKey = ActualDeviceKey;
  137. }
  138. MemFree (g_hHeap, 0, Class);
  139. }
  140. // Close if this device is not a match
  141. if (!EnumPtr->ActualDeviceKey) {
  142. CloseRegKey (ActualDeviceKey);
  143. }
  144. }
  145. MemFree (g_hHeap, 0, Data);
  146. }
  147. CloseRegKey (OnlineDeviceKey);
  148. }
  149. } while (!EnumPtr->ActualDeviceKey);
  150. return TRUE;
  151. }
  152. VOID
  153. AbortActiveHardwareEnum (
  154. IN PACTIVE_HARDWARE_ENUM EnumPtr
  155. )
  156. /*++
  157. Routine Description:
  158. AbortActiveHardwareEnum is required by callers who need to stop
  159. active device enumeration before it completes itself.
  160. Arguments:
  161. EnumPtr - Specifies the enumeration structure modified by
  162. EnumFirstActiveHardware or EnumNextActiveHardware
  163. Return Value:
  164. none
  165. --*/
  166. {
  167. if (EnumPtr->ClassFilter) {
  168. MemFree (g_hHeap, 0, EnumPtr->ClassFilter);
  169. }
  170. if (EnumPtr->ActualDeviceKey) {
  171. CloseRegKey (EnumPtr->ActualDeviceKey);
  172. EnumPtr->ActualDeviceKey = NULL;
  173. }
  174. if (EnumPtr->ConfigMgrKey) {
  175. CloseRegKey (EnumPtr->ConfigMgrKey);
  176. EnumPtr->ConfigMgrKey = NULL;
  177. }
  178. if (EnumPtr->EnumKey) {
  179. CloseRegKey (EnumPtr->EnumKey);
  180. EnumPtr->EnumKey = NULL;
  181. }
  182. AbortRegKeyEnum (&EnumPtr->CurrentDevice);
  183. }
  184. BOOL
  185. IsPnpIdOnline (
  186. IN PCTSTR PnpId,
  187. IN PCTSTR Class OPTIONAL
  188. )
  189. /*++
  190. Routine Description:
  191. IsPnpIdOnline enumerats all active devices and scans each registry
  192. location for the specified PNP ID.
  193. Arguments:
  194. PnpId - Specifies the PNP ID of the device that may be online.
  195. This string can be as complete as needed; it is compared
  196. against the registry key location of the device's dev node.
  197. Comparison is also performed against the CompatibleIDs
  198. value, if one exists.
  199. PnpID Example: *PNP0303
  200. Class - Specifies a device class pattern to limit the search to
  201. Return Value:
  202. TRUE if the device with the specified ID is online, or
  203. FALSE if the device was not found.
  204. --*/
  205. {
  206. ACTIVE_HARDWARE_ENUM e;
  207. PCTSTR Data;
  208. BOOL b = FALSE;
  209. if (EnumFirstActiveHardware (&e, Class)) {
  210. do {
  211. if (_tcsistr (e.RegLocation, PnpId)) {
  212. b = TRUE;
  213. break;
  214. }
  215. Data = GetRegValueString (e.ActualDeviceKey, S_COMPATIBLE_IDS);
  216. if (Data) {
  217. b = _tcsistr (Data, PnpId) != NULL;
  218. MemFree (g_hHeap, 0, Data);
  219. if (b) {
  220. break;
  221. }
  222. }
  223. } while (EnumNextActiveHardware (&e));
  224. }
  225. if (b) {
  226. AbortActiveHardwareEnum (&e);
  227. }
  228. return b;
  229. }