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.

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