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.

305 lines
11 KiB

  1. //
  2. // MODULE: TSMapAbstract.cpp
  3. //
  4. // PURPOSE: Part of launching a Local Troubleshooter from an arbitrary NT5 application
  5. // Data types and abstract classes for mapping from the application's way of naming
  6. // a problem to the Troubleshooter's way.
  7. // Implements the few concrete methods of abstract base class TSMapRuntimeAbstract.
  8. //
  9. // COMPANY: Saltmine Creative, Inc. (206)-633-4743 [email protected]
  10. //
  11. // AUTHOR: Joe Mabel
  12. //
  13. // ORIGINAL DATE: 2-26-98
  14. //
  15. //
  16. // Version Date By Comments
  17. //--------------------------------------------------------------------
  18. // V0.1 - JM Original
  19. ///////////////////////
  20. #include "stdafx.h"
  21. #include "TSLError.h"
  22. #include "RSSTACK.H"
  23. #include "TSMapAbstract.h"
  24. TSMapRuntimeAbstract::TSMapRuntimeAbstract()
  25. {
  26. m_dwStatus= 0;
  27. }
  28. TSMapRuntimeAbstract::~TSMapRuntimeAbstract()
  29. {
  30. }
  31. DWORD TSMapRuntimeAbstract::ClearAll()
  32. {
  33. m_stkStatus.RemoveAll();
  34. return 0;
  35. }
  36. // Given application, version, & problem, return troubleshooter & (optionally) problem node
  37. // In order to succeed:
  38. // - application must be an application known in the mapping file
  39. // - version must be a known version of that application (including an empty string for
  40. // the "blank version"
  41. // - problem must be the name or number of a defined problem either for that application
  42. // and version or for that application and some version down the chain of version
  43. // defaults.
  44. // May return
  45. // 0 (OK)
  46. // TSL_ERROR_UNKNOWN_APP
  47. // TSL_ERROR_UNKNOWN_VER
  48. // TSL_WARNING_UNKNOWN_APPPROBLEM - couldn't find a UID for this problem, so we can't
  49. // do this mapping
  50. // TSL_ERROR_NO_NETWORK - even after applying all default versions, there is no mapping.
  51. // May also return a hard mapping error specific to the implementation of the concrete class
  52. DWORD TSMapRuntimeAbstract::FromAppVerProbToTS (
  53. const TCHAR * const szApp, const TCHAR * const szVer, const TCHAR * const szProb,
  54. TCHAR * const szTSBN, TCHAR * const szNode)
  55. {
  56. if ( SetApp (szApp) == 0 && SetVer (szVer) == 0 && SetProb (szProb) == 0)
  57. {
  58. while ( FromProbToTS (szTSBN, szNode) == TSL_ERROR_NO_NETWORK
  59. && ApplyDefaultVer() == 0 )
  60. {
  61. // do nothing; it's all in the while-condition
  62. }
  63. }
  64. return m_dwStatus;
  65. }
  66. // Given application, version, device ID & (optionally) problem, return troubleshooter
  67. // & (independently optional) problem node
  68. // In order to succeed:
  69. // - application & version as in TSMapRuntimeAbstract::FromAppVerProbToTS
  70. // - the Device ID/Problem pair must be defined either for that application and version
  71. // or for that application and some version down the chain of version defaults.
  72. // The szProb may be an empty string, meaning we want the mapping for this device and
  73. // no specified problem.
  74. // May return
  75. // 0 (OK)
  76. // TSL_ERROR_UNKNOWN_APP
  77. // TSL_ERROR_UNKNOWN_VER
  78. // TSL_WARNING_UNKNOWN_APPPROBLEM - couldn't find a UID for this problem, so we can't
  79. // do this mapping. Note that there if there are any defined mappings independent of
  80. // problem, there will be a UID for the null string as a problem name. That will
  81. // not yield a warning. That's just dandy.
  82. // TSL_WARNING_BAD_DEV_ID - couldn't find a UID for this device, so we can't
  83. // do this mapping
  84. // TSL_ERROR_NO_NETWORK - even after applying all default versions, there is no mapping.
  85. // May also return a hard mapping error specific to the implementation of the concrete class
  86. DWORD TSMapRuntimeAbstract::FromAppVerDevIDToTS (
  87. const TCHAR * const szApp, const TCHAR * const szVer,
  88. const TCHAR * const szDevID, const TCHAR * const szProb,
  89. TCHAR * const szTSBN, TCHAR * const szNode)
  90. {
  91. if ( SetApp (szApp) == 0 && SetVer (szVer) == 0
  92. && SetDevID (szDevID) == 0 && SetProb (szProb) == 0 )
  93. {
  94. while ( FromDevToTS (szTSBN, szNode) == TSL_ERROR_NO_NETWORK
  95. && ApplyDefaultVer() == 0 )
  96. {
  97. // do nothing; it's all in the while-condition
  98. }
  99. }
  100. return m_dwStatus;
  101. }
  102. // Given application, version, Device Class GUID & (optionally) problem, return troubleshooter
  103. // & (independently optional) problem node
  104. // In order to succeed:
  105. // - application & version as in TSMapRuntimeAbstract::FromAppVerProbToTS
  106. // - the Device Class GUID/Problem pair must be defined either for that application and version
  107. // or for that application and some version down the chain of version defaults.
  108. // The szProb may be an empty string, meaning we want the mapping for this device and
  109. // no specified problem.
  110. // May return
  111. // 0 (OK)
  112. // TSL_ERROR_UNKNOWN_APP
  113. // TSL_ERROR_UNKNOWN_VER
  114. // TSL_WARNING_UNKNOWN_APPPROBLEM - couldn't find a UID for this problem, so we can't
  115. // do this mapping. Note that there if there are any defined mappings independent of
  116. // problem, there will be a UID for the null string as a problem name. That will
  117. // not yield a warning. That's just dandy.
  118. // TSL_WARNING_BAD_CLASS_GUID - couldn't find a UID for this Device Class GUID, so we can't
  119. // do this mapping
  120. // TSL_ERROR_NO_NETWORK - even after applying all default versions, there is no mapping.
  121. // May also return a hard mapping error specific to the implementation of the concrete class
  122. DWORD TSMapRuntimeAbstract::FromAppVerDevClassGUIDToTS (
  123. const TCHAR * const szApp, const TCHAR * const szVer,
  124. const TCHAR * const szDevClassGUID, const TCHAR * const szProb,
  125. TCHAR * const szTSBN, TCHAR * const szNode)
  126. {
  127. if ( SetApp (szApp) == 0 && SetVer (szVer) == 0
  128. && SetDevClassGUID (szDevClassGUID) == 0 && SetProb (szProb) == 0 )
  129. {
  130. while ( FromDevClassToTS (szTSBN, szNode) == TSL_ERROR_NO_NETWORK
  131. && ApplyDefaultVer() == 0 )
  132. {
  133. // do nothing; it's all in the while-condition
  134. }
  135. }
  136. return m_dwStatus;
  137. }
  138. // Given application, version, & at least one of
  139. // - problem
  140. // - device ID
  141. // - device class GUID
  142. // return troubleshooter & (optionally) problem node
  143. // In order to succeed:
  144. // - application must be an application known in the mapping file
  145. // - version must be a known version of that application (including an empty string for
  146. // the "blank version"
  147. // - There must be a mapping defined either for this problem, device ID, or device class
  148. // GUID alone, or for the combination of the problem & either the device ID or the
  149. // device class GUID, in conjunction with either that application and version
  150. // or for that application and some version down the chain of version defaults.
  151. // If there is more than one possible match, the algorithm dictates the following
  152. // priorities:
  153. // If there is an szProblem :
  154. // 1. szProblem with no associated device information (the "standard" mapping)
  155. // 2. szProblem and szDeviceID
  156. // 3. szProblem and pguidClass
  157. // 4. szDeviceID with no associated problem
  158. // 5. pguidClass with no associated problem
  159. // Otherwise
  160. // 1. szDeviceID with no associated problem
  161. // 2. pguidClass with no associated problem
  162. // Within each of these groupings, we follow up version defaults before we try the
  163. // next grouping.
  164. // May return
  165. // 0 (OK)
  166. // TSL_ERROR_UNKNOWN_APP
  167. // TSL_ERROR_UNKNOWN_VER
  168. // TSL_ERROR_NO_NETWORK - even after applying all default versions, there is no mapping.
  169. // May also return a hard mapping error specific to the implementation of the concrete class
  170. // In the case where we return 0 (OK) or TSL_ERROR_NO_NETWORK, the caller will want to consult
  171. // MoreStatus() for more detailed errors/warnings. In the other cases, the returned status
  172. // overwhelms any possible interest in other errors/warnings.
  173. DWORD TSMapRuntimeAbstract::FromAppVerDevAndClassToTS (
  174. const TCHAR * const szApp, const TCHAR * const szVer,
  175. const TCHAR * const szDevID, const TCHAR * const szDevClassGUID,
  176. const TCHAR * const szProb,
  177. TCHAR * const szTSBN, TCHAR * const szNode)
  178. {
  179. UID uidProb = uidNil;
  180. // keep some status info around so we don't ever notify of the same problem twice
  181. bool bBadProb = false;
  182. bool bCantUseProb = false;
  183. bool bBadDev = false;
  184. bool bBadDevClass = false;
  185. if (! HardMappingError (m_dwStatus) )
  186. ClearAll();
  187. if (! m_dwStatus)
  188. {
  189. if (szProb && *szProb)
  190. {
  191. // try problem name without device info.
  192. m_dwStatus = FromAppVerProbToTS (szApp, szVer, szProb, szTSBN, szNode);
  193. bBadProb = (m_dwStatus == TSL_WARNING_UNKNOWN_APPPROBLEM);
  194. if (DifferentMappingCouldWork (m_dwStatus))
  195. {
  196. // try the device ID + problem
  197. m_dwStatus = FromAppVerDevIDToTS (szApp, szVer, szDevID, szProb,
  198. szTSBN, szNode);
  199. bBadDev = (m_dwStatus == TSL_WARNING_BAD_DEV_ID);
  200. }
  201. if (DifferentMappingCouldWork (m_dwStatus))
  202. {
  203. // try the device class GUID + problem
  204. m_dwStatus = FromAppVerDevClassGUIDToTS (szApp, szVer, szDevClassGUID, szProb,
  205. szTSBN, szNode);
  206. bBadDevClass = (m_dwStatus == TSL_WARNING_BAD_CLASS_GUID);
  207. }
  208. // If we're still trying to map it, we couldn't make use of the problem name
  209. bCantUseProb = (DifferentMappingCouldWork(m_dwStatus));
  210. }
  211. else
  212. m_dwStatus = TSL_ERROR_NO_NETWORK;
  213. if (DifferentMappingCouldWork (m_dwStatus))
  214. {
  215. // try the device ID alone
  216. m_dwStatus = FromAppVerDevIDToTS (szApp, szVer, szDevID, NULL, szTSBN, szNode);
  217. bBadDev |= (m_dwStatus == TSL_WARNING_BAD_DEV_ID);
  218. }
  219. if (DifferentMappingCouldWork (m_dwStatus))
  220. {
  221. // try the device class GUID alone
  222. m_dwStatus = FromAppVerDevClassGUIDToTS (szApp, szVer, szDevClassGUID, NULL,
  223. szTSBN, szNode);
  224. bBadDevClass |= (m_dwStatus == TSL_WARNING_BAD_CLASS_GUID);
  225. }
  226. if (DifferentMappingCouldWork(m_dwStatus))
  227. m_dwStatus = TSL_ERROR_NO_NETWORK;
  228. }
  229. if (bBadProb
  230. && AddMoreStatus(TSL_WARNING_UNKNOWN_APPPROBLEM) == TSL_ERROR_OUT_OF_MEMORY)
  231. m_dwStatus = TSL_ERROR_OUT_OF_MEMORY;
  232. if (bCantUseProb && !bBadProb
  233. && AddMoreStatus(TSL_WARNING_UNUSED_APPPROBLEM) == TSL_ERROR_OUT_OF_MEMORY)
  234. m_dwStatus = TSL_ERROR_OUT_OF_MEMORY;
  235. if (bBadDev
  236. && AddMoreStatus(TSL_WARNING_BAD_DEV_ID) == TSL_ERROR_OUT_OF_MEMORY)
  237. m_dwStatus = TSL_ERROR_OUT_OF_MEMORY;
  238. if (bBadDevClass
  239. && AddMoreStatus(TSL_WARNING_BAD_CLASS_GUID) == TSL_ERROR_OUT_OF_MEMORY)
  240. m_dwStatus = TSL_ERROR_OUT_OF_MEMORY;
  241. return m_dwStatus;
  242. }
  243. // certain statuses are "basically healthy" returns, meaning, "no, this particular mapping
  244. // doesn't exist, but there's nothing here to rule out the possibility of another mapping."
  245. // Those return true on this function.
  246. // Note that dwStatus == 0 (OK) returns false because
  247. // if we already had a successful mapping, we don't want to try another.
  248. bool TSMapRuntimeAbstract::DifferentMappingCouldWork (DWORD dwStatus)
  249. {
  250. switch (dwStatus)
  251. {
  252. case TSL_ERROR_NO_NETWORK:
  253. case TSL_WARNING_BAD_DEV_ID:
  254. case TSL_WARNING_BAD_CLASS_GUID:
  255. case TSL_WARNING_UNKNOWN_APPPROBLEM:
  256. case TSM_STAT_UID_NOT_FOUND:
  257. case TSL_WARNING_END_OF_VER_CHAIN:
  258. return true;
  259. default:
  260. return false;
  261. }
  262. }
  263. bool TSMapRuntimeAbstract::HardMappingError (DWORD dwStatus)
  264. {
  265. return (dwStatus == TSL_ERROR_OUT_OF_MEMORY);
  266. }
  267. // Add this status to the list of warnings.
  268. // Normally returns 0, but can theoretically return TSL_ERROR_OUT_OF_MEMORY
  269. inline DWORD TSMapRuntimeAbstract::AddMoreStatus(DWORD dwStatus)
  270. {
  271. if (m_stkStatus.Push(dwStatus) == -1)
  272. return TSL_ERROR_OUT_OF_MEMORY;
  273. else
  274. return 0;
  275. }