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.

332 lines
9.4 KiB

  1. // MODULE: APGTSLSTREAD.CPP
  2. //
  3. // PURPOSE: APGTS LST file reading classes
  4. //
  5. // COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
  6. //
  7. // AUTHOR: Oleg Kalosha
  8. //
  9. // ORIGINAL DATE: 7-29-98
  10. //
  11. // NOTES:
  12. // 1. Prior to 11/13/98, it wasis assumed that for a given DSC/TSM file, any other associated
  13. // filenames (BES, HTI) would not change over time. This assumption is no longer good.
  14. // It had the unfortunate consequence that if there was a typographical error in an LST
  15. // file there was no way to fix it while the system was running.
  16. // 2. While the Online Troubleshooter is running, it is possible to change the LST file in
  17. // order to add new troubleshooter topics, but it is not possible to remove troubleshooter
  18. // topics. Thus, even if a topic which was listed in the old LST file is missing from the
  19. // new one, that is not a relevant difference.
  20. // 3. Normal form of a line in this file: any of the following:
  21. // MODEM.DSC MODEM.HTI
  22. // MODEM.DSC MODEM.HTI MODEM.BES
  23. // MODEM.DSC,MODEM.HTI,MODEM.BES
  24. // MODEM.TSM,MODEM.HTI,MODEM.BES
  25. // Commas and spaces are both valid separators.
  26. // Order within a line is irrelevant, although for readability, it is best to put
  27. // the DSC/TSM file first.
  28. // Extensions are mandatory. The only way we know it's (say) a template file is
  29. // the .HTI extension.
  30. // DSC/TSM file is mandatory. The others are optional, although if the HTI file is missing,
  31. // there had better be a HNetHTIOnline / HNetHTILocal property in this network.
  32. // 4. If the same DSC/TSM file is listed more than once, the last appearance dominates the
  33. // earlier appearances.
  34. // 5. For multilingual, each language goes in a subdirectory under the resource directory.
  35. // LST file needs to contain paths relative to the resource directory, such as:
  36. // ES\MODEM.DSC ES\MODEM.HTI
  37. // DE\MODEM.DSC DE\MODEM.HTI
  38. // FR\MODEM.DSC FR\MODEM.HTI
  39. //
  40. // Version Date By Comments
  41. //--------------------------------------------------------------------
  42. // V3.0 08-04-98 OK
  43. // V3.0.1 12-21-98 JM Multilingual
  44. //
  45. #include "stdafx.h"
  46. #include "apgtslstread.h"
  47. #include "sync.h"
  48. #include <algorithm>
  49. #include "event.h"
  50. #include "CharConv.h"
  51. #include "apgtsmfc.h"
  52. #ifdef LOCAL_TROUBLESHOOTER
  53. #include "CHMFileReader.h"
  54. #endif
  55. ////////////////////////////////////////////////////////////////////////////////////
  56. // static function(s)
  57. ////////////////////////////////////////////////////////////////////////////////////
  58. CString FormFullPath(const CString& just_path, const CString& just_name)
  59. {
  60. #ifdef LOCAL_TROUBLESHOOTER
  61. if (CCHMFileReader::IsPathToCHMfile(just_path))
  62. return CCHMFileReader::FormCHMPath(just_path) + just_name;
  63. else
  64. return just_path + _T("\\") + just_name;
  65. #else
  66. return just_path + _T("\\") + just_name;
  67. #endif
  68. }
  69. ////////////////////////////////////////////////////////////////////////////////////
  70. // CTopicInfo
  71. ////////////////////////////////////////////////////////////////////////////////////
  72. bool CTopicInfo::Init(CString & strResourcePath, vector<CString> &vecstrWords)
  73. {
  74. bool bSomethingThere = false;
  75. for (vector<CString>::iterator i = vecstrWords.begin(); i != vecstrWords.end(); i++)
  76. {
  77. CString str_extension = CString(".") + CAbstractFileReader::GetJustExtension(*i);
  78. bSomethingThere = true;
  79. ///////////////////////////////////////////
  80. // We require that all *.dsc etc //
  81. // files are in the same directory //
  82. // as lst file (the resource directory) //
  83. // or (for multilingual) a subdirectory //
  84. // of the resource directory. //
  85. ///////////////////////////////////////////
  86. LPCTSTR extention = NULL;
  87. if (0 == _tcsicmp(str_extension, extention = APGTSLSTREAD_DSC) ||
  88. 0 == _tcsicmp(str_extension, extention = APGTSLSTREAD_TSM)
  89. )
  90. {
  91. m_DscFilePath = ::FormFullPath(strResourcePath, *i);
  92. m_DscFilePath.MakeLower();
  93. if (! m_NetworkName.GetLength())
  94. {
  95. // use name of DSC/TSM file, minus extension.
  96. m_NetworkName = *i;
  97. int len = m_NetworkName.GetLength()-(_tcslen(extention));
  98. m_NetworkName = m_NetworkName.Left(len);
  99. m_NetworkName.MakeLower();
  100. }
  101. continue;
  102. }
  103. if (0 == _tcsicmp(str_extension, APGTSLSTREAD_HTI))
  104. {
  105. m_HtiFilePath = ::FormFullPath(strResourcePath, *i);
  106. m_HtiFilePath.MakeLower();
  107. continue;
  108. }
  109. if (0 == _tcsicmp(str_extension, APGTSLSTREAD_BES))
  110. {
  111. m_BesFilePath = ::FormFullPath(strResourcePath, *i);
  112. m_BesFilePath.MakeLower();
  113. continue;
  114. }
  115. #ifdef LOCAL_TROUBLESHOOTER
  116. if (0 == _tcsicmp(str_extension, APGTSLSTREAD_TSC))
  117. {
  118. m_TscFilePath = ::FormFullPath(strResourcePath, *i);
  119. m_TscFilePath.MakeLower();
  120. continue;
  121. }
  122. #endif
  123. /////////////////////////////////////
  124. // Ignore anything unrecognized.
  125. }
  126. bool bRet = bSomethingThere && ! m_DscFilePath.IsEmpty();
  127. if (bRet)
  128. {
  129. CAbstractFileReader::GetFileTime(m_DscFilePath, CFileReader::eFileTimeCreated, m_DscFileCreated);
  130. if ( ! m_HtiFilePath.IsEmpty())
  131. CAbstractFileReader::GetFileTime(m_HtiFilePath, CFileReader::eFileTimeCreated, m_HtiFileCreated);
  132. if ( ! m_BesFilePath.IsEmpty())
  133. CAbstractFileReader::GetFileTime(m_BesFilePath, CFileReader::eFileTimeCreated, m_BesFileCreated);
  134. }
  135. return bRet;
  136. }
  137. ////////////////////////////////////////////////////////////////////////////////////
  138. // CAPGTSLSTReader
  139. ////////////////////////////////////////////////////////////////////////////////////
  140. CAPGTSLSTReader::CAPGTSLSTReader(CPhysicalFileReader * pPhysicalFileReader)
  141. : CINIReader(pPhysicalFileReader, _T("APGTS"))
  142. {
  143. }
  144. CAPGTSLSTReader::~CAPGTSLSTReader()
  145. {
  146. }
  147. long CAPGTSLSTReader::GetInfoCount()
  148. {
  149. long ret = 0;
  150. LOCKOBJECT();
  151. ret = m_arrTopicInfo.size();
  152. UNLOCKOBJECT();
  153. return ret;
  154. }
  155. bool CAPGTSLSTReader::GetInfo(long index, CTopicInfo& out)
  156. {
  157. LOCKOBJECT();
  158. if (index < m_arrTopicInfo.size())
  159. {
  160. out = m_arrTopicInfo[index];
  161. UNLOCKOBJECT();
  162. return true;
  163. }
  164. UNLOCKOBJECT();
  165. return false;
  166. }
  167. bool CAPGTSLSTReader::GetInfo(const CString& network_name, CTopicInfo& out)
  168. {
  169. LOCKOBJECT();
  170. for (
  171. vector<CTopicInfo>::iterator i = m_arrTopicInfo.begin();
  172. i != m_arrTopicInfo.end();
  173. i++)
  174. {
  175. if (i->GetNetworkName() == network_name)
  176. {
  177. out = *i;
  178. UNLOCKOBJECT();
  179. return true;
  180. }
  181. }
  182. UNLOCKOBJECT();
  183. return false;
  184. }
  185. void CAPGTSLSTReader::GetInfo(CTopicInfoVector & arrOut)
  186. {
  187. LOCKOBJECT();
  188. arrOut = m_arrTopicInfo;
  189. UNLOCKOBJECT();
  190. }
  191. // This will identify new troubleshooting networks, or changes to (say) the associated
  192. // HTI file, given the same DSC file. Note that we can only detect additions of topics,
  193. // not deletions. (see notes at head of this source file).
  194. // If pOld is NULL, this is equivalent to GetInfo(what_is_new).
  195. void CAPGTSLSTReader::GetDifference(const CAPGTSLSTReader * pOld, CTopicInfoVector & what_is_new)
  196. {
  197. if (pOld)
  198. {
  199. CMultiMutexObj multiMutex;
  200. multiMutex.AddHandle(GetMutexHandle());
  201. multiMutex.AddHandle(pOld->GetMutexHandle());
  202. multiMutex.Lock(__FILE__, __LINE__);
  203. vector<CTopicInfo> old_arr = pOld->m_arrTopicInfo; // to avoid const
  204. for (vector<CTopicInfo>::iterator i = m_arrTopicInfo.begin(); i != m_arrTopicInfo.end(); i++)
  205. {
  206. vector<CTopicInfo>::const_iterator res = find(old_arr.begin(), old_arr.end(), *i);
  207. if (res == old_arr.end())
  208. {
  209. try
  210. {
  211. what_is_new.push_back( *i );
  212. }
  213. catch (exception& x)
  214. {
  215. CString str;
  216. // Note STL exception in event log.
  217. CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
  218. CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
  219. SrcLoc.GetSrcFileLineStr(),
  220. CCharConversion::ConvertACharToString(x.what(), str),
  221. _T(""),
  222. EV_GTS_STL_EXCEPTION );
  223. }
  224. }
  225. }
  226. multiMutex.Unlock();
  227. }
  228. else
  229. GetInfo(what_is_new);
  230. }
  231. void CAPGTSLSTReader::Parse()
  232. {
  233. CINIReader::Parse();
  234. // parse all INI strings into something more meaningful...
  235. m_arrTopicInfo.clear();
  236. for (vector<CString>::iterator i = m_arrLines.begin(); i != m_arrLines.end(); i++)
  237. {
  238. CTopicInfo& info = *GenerateTopicInfo();
  239. if (ParseString(*i, info))
  240. {
  241. // if CTopicInfo with the same Network Name is found
  242. // we assign new object to what is already in the container
  243. vector<CTopicInfo>::iterator res;
  244. for (
  245. res = m_arrTopicInfo.begin();
  246. res != m_arrTopicInfo.end();
  247. res++)
  248. {
  249. if (res->GetNetworkName() == info.GetNetworkName())
  250. break;
  251. }
  252. if (res != m_arrTopicInfo.end())
  253. *res = info;
  254. else
  255. {
  256. try
  257. {
  258. m_arrTopicInfo.push_back(info);
  259. }
  260. catch (exception& x)
  261. {
  262. CString str;
  263. // Note STL exception in event log.
  264. CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
  265. CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
  266. SrcLoc.GetSrcFileLineStr(),
  267. CCharConversion::ConvertACharToString(x.what(), str),
  268. _T(""),
  269. EV_GTS_STL_EXCEPTION );
  270. }
  271. }
  272. }
  273. delete &info;
  274. }
  275. }
  276. bool CAPGTSLSTReader::ParseString(const CString& source, CTopicInfo& out)
  277. {
  278. bool ret = false;
  279. vector<CString> words;
  280. vector<TCHAR> separators;
  281. try
  282. {
  283. separators.push_back(_T(' '));
  284. separators.push_back(_T(',')); // remove possible trailing commas
  285. GetWords(source, words, separators);
  286. }
  287. catch (exception& x)
  288. {
  289. CString str;
  290. // Note STL exception in event log.
  291. CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
  292. CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
  293. SrcLoc.GetSrcFileLineStr(),
  294. CCharConversion::ConvertACharToString(x.what(), str),
  295. _T(""),
  296. EV_GTS_STL_EXCEPTION );
  297. }
  298. return out.Init(GetJustPath(), words);
  299. }
  300. CTopicInfo* CAPGTSLSTReader::GenerateTopicInfo()
  301. {
  302. return new CTopicInfo;
  303. }