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.

290 lines
7.9 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation 1993-1996
  4. //
  5. // File: util.c
  6. //
  7. // This files contains all common utility routines
  8. //
  9. // History:
  10. // 12-23-93 ScottH Created
  11. // 09-22-95 ScottH Ported to NT
  12. //
  13. //---------------------------------------------------------------------------
  14. #include "proj.h" // common headers
  15. //-----------------------------------------------------------------------------------
  16. // Wrapper that finds a device instance
  17. //-----------------------------------------------------------------------------------
  18. /*----------------------------------------------------------
  19. Purpose: Enumerates the HKEY_LOCAL_MACHINE branch and finds the
  20. device matching the given class and value. If there
  21. are duplicate devices that match both criteria, only the
  22. first device is returned.
  23. Returns TRUE if the device was found.
  24. Returns: see above
  25. Cond: --
  26. */
  27. BOOL
  28. PRIVATE
  29. FindDev_Find(
  30. IN LPFINDDEV pfinddev,
  31. IN LPGUID pguidClass, OPTIONAL
  32. IN LPCTSTR pszValueName,
  33. IN LPCTSTR pszValue)
  34. {
  35. BOOL bRet = FALSE;
  36. TCHAR szKey[MAX_BUF];
  37. TCHAR szName[MAX_BUF];
  38. HDEVINFO hdi;
  39. DWORD dwRW = KEY_READ;
  40. ASSERT(pfinddev);
  41. ASSERT(pszValueName);
  42. ASSERT(pszValue);
  43. if (USER_IS_ADMIN()) dwRW |= KEY_WRITE;
  44. // (scotth): hack to support no device instances because
  45. // ports do not have a class GUID. This should be fixed after SUR.
  46. // Is there a class GUID?
  47. if (pguidClass)
  48. {
  49. // Yes; use it
  50. hdi = CplDiGetClassDevs(pguidClass, NULL, NULL, 0);
  51. if (INVALID_HANDLE_VALUE != hdi)
  52. {
  53. SP_DEVINFO_DATA devData;
  54. DWORD iIndex = 0;
  55. HKEY hkey;
  56. // Look for the modem that has the matching value
  57. devData.cbSize = sizeof(devData);
  58. while (CplDiEnumDeviceInfo(hdi, iIndex, &devData))
  59. {
  60. hkey = CplDiOpenDevRegKey(hdi, &devData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, dwRW);
  61. if (INVALID_HANDLE_VALUE != hkey)
  62. {
  63. // Does the value match?
  64. DWORD cbData = sizeof(szName);
  65. if (NO_ERROR == RegQueryValueEx(hkey, pszValueName, NULL, NULL,
  66. (LPBYTE)szName, &cbData) &&
  67. IsSzEqual(pszValue, szName))
  68. {
  69. // Yes
  70. pfinddev->hkeyDrv = hkey;
  71. pfinddev->hdi = hdi;
  72. BltByte(&pfinddev->devData, &devData, sizeof(devData));
  73. // Don't close the driver key or free the DeviceInfoSet,
  74. // but exit
  75. bRet = TRUE;
  76. break;
  77. }
  78. RegCloseKey(hkey);
  79. }
  80. iIndex++;
  81. }
  82. // Free the DeviceInfoSet if nothing was found. Otherwise, we will
  83. // retain these handles so the caller can make use of this.
  84. if ( !bRet )
  85. {
  86. CplDiDestroyDeviceInfoList(hdi);
  87. }
  88. }
  89. }
  90. else
  91. {
  92. // No; HACK ALERT! Hmm, it must be a port class in SUR.
  93. #pragma data_seg(DATASEG_READONLY)
  94. static TCHAR const FAR c_szSerialComm[] = TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM");
  95. #pragma data_seg()
  96. HKEY hkeyEnum;
  97. DWORD iSubKey;
  98. TCHAR szName[MAX_BUF];
  99. DWORD cbName;
  100. DWORD cbData;
  101. DWORD dwType;
  102. DWORD dwRet;
  103. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, c_szSerialComm, &hkeyEnum);
  104. if (NO_ERROR == dwRet)
  105. {
  106. ZeroInit(pfinddev);
  107. iSubKey = 0;
  108. cbName = sizeof(szName) / sizeof(TCHAR);
  109. cbData = sizeof(pfinddev->szPort) / sizeof(TCHAR);
  110. while (NO_ERROR == RegEnumValue(hkeyEnum, iSubKey++, szName,
  111. &cbName, NULL, &dwType,
  112. (LPBYTE)pfinddev->szPort, &cbData))
  113. {
  114. if (REG_SZ == dwType &&
  115. 0 == lstrcmpi(pfinddev->szPort, pszValue))
  116. {
  117. bRet = TRUE;
  118. break;
  119. }
  120. cbName = sizeof(szName);
  121. cbData = sizeof(pfinddev->szPort);
  122. }
  123. RegCloseKey(hkeyEnum);
  124. }
  125. }
  126. return bRet;
  127. }
  128. /*----------------------------------------------------------
  129. Purpose: Creates a FINDDEV structure given the device class,
  130. and a valuename and its value.
  131. Returns: TRUE if the device is found in the system
  132. Cond: --
  133. */
  134. BOOL
  135. PUBLIC
  136. FindDev_Create(
  137. OUT LPFINDDEV FAR * ppfinddev,
  138. IN LPGUID pguidClass, OPTIONAL
  139. IN LPCTSTR pszValueName,
  140. IN LPCTSTR pszValue)
  141. {
  142. BOOL bRet;
  143. LPFINDDEV pfinddev;
  144. DEBUG_CODE( TRACE_MSG(TF_FUNC, " > FindDev_Create(....%s, %s, ...)",
  145. Dbg_SafeStr(pszValueName), Dbg_SafeStr(pszValue)); )
  146. ASSERT(ppfinddev);
  147. ASSERT(pszValueName);
  148. ASSERT(pszValue);
  149. pfinddev = (LPFINDDEV)LocalAlloc(LPTR, sizeof(*pfinddev));
  150. if (NULL == pfinddev)
  151. {
  152. bRet = FALSE;
  153. }
  154. else
  155. {
  156. bRet = FindDev_Find(pfinddev, pguidClass, pszValueName, pszValue);
  157. if (FALSE == bRet)
  158. {
  159. // Didn't find anything
  160. FindDev_Destroy(pfinddev);
  161. pfinddev = NULL;
  162. }
  163. }
  164. *ppfinddev = pfinddev;
  165. DBG_EXIT_BOOL(FindDev_Create, bRet);
  166. return bRet;
  167. }
  168. /*----------------------------------------------------------
  169. Purpose: Destroys a FINDDEV structure
  170. Returns: TRUE on success
  171. Cond: --
  172. */
  173. BOOL
  174. PUBLIC
  175. FindDev_Destroy(
  176. IN LPFINDDEV this)
  177. {
  178. BOOL bRet;
  179. if (NULL == this)
  180. {
  181. bRet = FALSE;
  182. }
  183. else
  184. {
  185. if (this->hkeyDrv)
  186. RegCloseKey(this->hkeyDrv);
  187. if (this->hdi && INVALID_HANDLE_VALUE != this->hdi)
  188. CplDiDestroyDeviceInfoList(this->hdi);
  189. LocalFreePtr(this);
  190. bRet = TRUE;
  191. }
  192. return bRet;
  193. }
  194. //-----------------------------------------------------------------------------------
  195. // Debug functions
  196. //-----------------------------------------------------------------------------------
  197. #ifdef DEBUG
  198. #pragma data_seg(DATASEG_READONLY)
  199. #ifdef WIN95
  200. struct _RETERRMAP
  201. {
  202. RETERR ret;
  203. LPCTSTR psz;
  204. } const c_rgreterrmap[] = {
  205. { NO_ERROR, "NO_ERROR" },
  206. { DI_ERROR, "DI_ERROR" },
  207. { ERR_DI_INVALID_DEVICE_ID, "ERR_DI_INVALID_DEVICE_ID" },
  208. { ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST, "ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST" },
  209. { ERR_DI_REG_API, "ERR_DI_REG_API" },
  210. { ERR_DI_LOW_MEM, "ERR_DI_LOW_MEM" },
  211. { ERR_DI_BAD_DEV_INFO, "ERR_DI_BAD_DEV_INFO" },
  212. { ERR_DI_INVALID_CLASS_INSTALLER, "ERR_DI_INVALID_CLASS_INSTALLER" },
  213. { ERR_DI_DO_DEFAULT, "ERR_DI_DO_DEFAULT" },
  214. { ERR_DI_USER_CANCEL, "ERR_DI_USER_CANCEL" },
  215. { ERR_DI_NOFILECOPY, "ERR_DI_NOFILECOPY" },
  216. { ERR_DI_BAD_CLASS_INFO, "ERR_DI_BAD_CLASS_INFO" },
  217. };
  218. #endif
  219. #pragma data_seg()
  220. #ifdef WIN95
  221. /*----------------------------------------------------------
  222. Purpose: Returns the string form of a RETERR.
  223. Returns: String ptr
  224. Cond: --
  225. */
  226. LPCTSTR PUBLIC Dbg_GetReterr(
  227. RETERR ret)
  228. {
  229. int i;
  230. for (i = 0; i < ARRAY_ELEMENTS(c_rgreterrmap); i++)
  231. {
  232. if (ret == c_rgreterrmap[i].ret)
  233. return c_rgreterrmap[i].psz;
  234. }
  235. return "Unknown RETERR";
  236. }
  237. #endif // WIN95
  238. #endif // DEBUG