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.

331 lines
9.5 KiB

  1. // NCSpewFile.cpp: implementation of the CNCSpewFile class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "ncbrowse.h"
  6. #include "mainfrm.h"
  7. using namespace std;
  8. #include "NCSpewFile.h"
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[]=__FILE__;
  12. #define new DEBUG_NEW
  13. #endif
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. CNCEntry::CNCEntry(DWORD dwLineNumber, tstring szTag, time_t tmTime, tstring szDescription, DWORD dwProcessID, DWORD dwThreadID)
  18. {
  19. m_dwLineNumber = dwLineNumber;
  20. m_szTag = szTag;
  21. m_tmTime = tmTime;
  22. m_szDescription = szDescription;
  23. m_dwLevel = 0;
  24. m_dwProcessId = dwProcessID;
  25. m_dwThreadId = dwThreadID;
  26. }
  27. CNCThread::CNCThread()
  28. {
  29. m_dwProcessId = 0;
  30. m_dwThreadID = 0;
  31. }
  32. class CProtectedArchive : public CArchive
  33. {
  34. public:
  35. LPTSTR ReadString(LPTSTR lpsz, UINT nMax);
  36. };
  37. #ifdef _DEBUG
  38. #define DELETE_EXCEPTION(e) do { e->Delete(); } while (0)
  39. #else
  40. #define DELETE_EXCEPTION(e)
  41. #endif
  42. LPTSTR CProtectedArchive::ReadString(LPTSTR lpsz, UINT nMax)
  43. {
  44. // if nMax is negative (such a large number doesn't make sense given today's
  45. // 2gb address space), then assume it to mean "keep the newline".
  46. int nStop = (int)nMax < 0 ? -(int)nMax : (int)nMax;
  47. ASSERT(AfxIsValidAddress(lpsz, (nStop+1) * sizeof(TCHAR)));
  48. _TUCHAR ch;
  49. int nRead = 0;
  50. TRY
  51. {
  52. while (nRead < nStop)
  53. {
  54. *this >> ch;
  55. // stop and end-of-line (trailing '\n' is ignored)
  56. if (ch == '\n' || ch == '\r')
  57. {
  58. BOOL bBreak = TRUE;
  59. if (ch == '\r')
  60. {
  61. BYTE by;
  62. if (m_lpBufCur + sizeof(BYTE) > m_lpBufMax)
  63. {
  64. FillBuffer(sizeof(BYTE) - (UINT)(m_lpBufMax - m_lpBufCur));
  65. }
  66. by = *(UNALIGNED BYTE*)m_lpBufCur;
  67. if (by == '\n')
  68. {
  69. ch = by;
  70. m_lpBufCur += sizeof(BYTE);
  71. }
  72. else
  73. {
  74. ch = by;
  75. bBreak = FALSE;
  76. }
  77. }
  78. // store the newline when called with negative nMax
  79. if ((int)nMax != nStop)
  80. {
  81. lpsz[nRead++] = ch;
  82. }
  83. if (bBreak)
  84. {
  85. break;
  86. }
  87. }
  88. lpsz[nRead++] = ch;
  89. }
  90. }
  91. CATCH(CArchiveException, e)
  92. {
  93. if (e->m_cause == CArchiveException::endOfFile)
  94. {
  95. DELETE_EXCEPTION(e);
  96. if (nRead == 0)
  97. return NULL;
  98. }
  99. else
  100. {
  101. THROW_LAST();
  102. }
  103. }
  104. END_CATCH
  105. lpsz[nRead] = '\0';
  106. return lpsz;
  107. }
  108. enum NETCFG_LOGTYPE
  109. {
  110. LOGTYPE_UNKNOWN = 0,
  111. LOGTYPE_PROC_THREAD = 1,
  112. LOGTYPE_PROC_THREAD_TIME = 2,
  113. };
  114. CNCSpewFile::CNCSpewFile(CArchive& ar)
  115. {
  116. TCHAR szCurrentLine[8192];
  117. DWORD dwLineNum = 0;
  118. const CFile &fp = *(ar.GetFile());
  119. DWORD dwTotalSize = fp.GetLength();
  120. DWORD dwTotalSpews = 1;
  121. CSpew spew;
  122. spew.szSpewName = _T("01. Unknown O/S");
  123. m_Spews[1] = spew;
  124. CSpew *m_pCurrentSpew = &(m_Spews[1]);
  125. m_pCNCurrentThread = &(m_pCurrentSpew->m_NCThreadList);
  126. NETCFG_LOGTYPE ncfLogType = LOGTYPE_UNKNOWN;
  127. CProtectedArchive &arP = *reinterpret_cast<CProtectedArchive *>(&ar);
  128. while (arP.ReadString(szCurrentLine, 8192))
  129. {
  130. dwLineNum++;
  131. LPCTSTR sztstring = szCurrentLine;
  132. rpattern *pPat = NULL;
  133. switch (ncfLogType)
  134. {
  135. case LOGTYPE_UNKNOWN:
  136. case LOGTYPE_PROC_THREAD:
  137. pPat = new rpattern( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*) (?:\\(|\\*)((?:\\s|\\w)*)(?:\\)|\\*)(.*)") );
  138. break;
  139. case LOGTYPE_PROC_THREAD_TIME:
  140. pPat = new rpattern( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*) \\[.*\\] (?:\\(|\\*)((?:\\s|\\w)*)(?:\\)|\\*)(.*)") );
  141. break;
  142. default:
  143. ASSERT(FALSE);
  144. return;
  145. }
  146. //rpattern pat( _T("NETCFG (\\{a-f0-9}+)\\.(\\{a-f0-9}+)") );
  147. DWORD dwPosition = fp.GetPosition();
  148. TCHAR szStatusBarText[MAX_PATH];
  149. DWORD dwPercentage = 100 * dwPosition / dwTotalSize;
  150. _stprintf(szStatusBarText, _T("%d%% complete"), dwPercentage);
  151. CStatusBar &StatusBar = ((CMainFrame *)AfxGetMainWnd())->m_wndStatusBar;
  152. StatusBar.SetPaneText (0, szStatusBarText, TRUE);
  153. BOOL bProcessed = FALSE;
  154. BOOL bMatched = FALSE;
  155. BOOL bHalfMatched = FALSE;
  156. regexpr::backref_vector rgbackrefs;
  157. if (regexpr::match( sztstring, *pPat, &rgbackrefs ) )
  158. {
  159. bMatched = TRUE;
  160. if (LOGTYPE_UNKNOWN == ncfLogType)
  161. {
  162. ncfLogType = LOGTYPE_PROC_THREAD;
  163. }
  164. }
  165. else
  166. {
  167. if (LOGTYPE_UNKNOWN == ncfLogType)
  168. {
  169. delete pPat;
  170. pPat = new rpattern( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*) \\[.*\\] (?:\\(|\\*)((?:\\s|\\w)*)(?:\\)|\\*)(.*)") );
  171. if (regexpr::match( sztstring, *pPat, &rgbackrefs ) )
  172. {
  173. bMatched = TRUE;
  174. ncfLogType = LOGTYPE_PROC_THREAD_TIME;
  175. }
  176. }
  177. }
  178. if (!bMatched)
  179. {
  180. rpattern pat( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*)(.*)") );
  181. if( regexpr::match( sztstring, pat, &rgbackrefs ) )
  182. {
  183. bHalfMatched = TRUE;
  184. }
  185. }
  186. delete pPat;
  187. if (bMatched | bHalfMatched)
  188. {
  189. // Backref 0 -> Full tstring
  190. // Backref 1 -> NETCFG
  191. // Backref 2 -> ProcId
  192. // Backref 3 -> ThreadId
  193. // Backref 4 -> TagName
  194. // Backref 5 -> tstring
  195. ASSERT(rgbackrefs.size() >= 5);
  196. TCHAR szProcID[MAX_PATH];
  197. TCHAR szThreadID[MAX_PATH];
  198. TCHAR szTagName[MAX_PATH];
  199. TCHAR szDescription[8192];
  200. bProcessed = TRUE;
  201. regexpr::backref_type br = rgbackrefs[2];
  202. _stprintf(szProcID, _T("%.*s"), br.second - br.first, br.first );
  203. StrTrim(szProcID, _T(" "));
  204. LPTSTR szEndChar;
  205. DWORD dwProcId = _tcstoul(szProcID, &szEndChar, 16);
  206. br = rgbackrefs[3];
  207. _stprintf(szThreadID, _T("%.*s"), br.second - br.first, br.first );
  208. StrTrim(szThreadID, _T(" "));
  209. DWORD dwThreadId = _tcstoul(szThreadID, &szEndChar, 16);
  210. DWORD iProcThread = (dwProcId << 16) | dwThreadId;
  211. if (bMatched)
  212. {
  213. br = rgbackrefs[4];
  214. _stprintf(szTagName, _T("%.*s"), br.second - br.first, br.first );
  215. StrTrim(szTagName, _T(" "));
  216. br = rgbackrefs[5];
  217. _stprintf(szDescription, _T("%.*s"), br.second - br.first, br.first );
  218. StrTrim(szDescription, _T(" "));
  219. if (!_tcscmp(szTagName, _T("ERROR")))
  220. {
  221. _tcscpy(szTagName, _T("*ERROR*"));
  222. StrTrim(szDescription, _T(":"));
  223. StrTrim(szDescription, _T(" "));
  224. }
  225. }
  226. else
  227. {
  228. _tcscpy(szTagName, _T("*Unknown*"));
  229. br = rgbackrefs[4];
  230. _stprintf(szDescription, _T("%.*s"), br.second - br.first, br.first );
  231. StrTrim(szDescription, _T(" "));
  232. }
  233. CNCEntry NCEntry(dwLineNum, szTagName, 0, szDescription, dwProcId, dwThreadId);
  234. CNCThread &NCThread = (*m_pCNCurrentThread)[iProcThread];
  235. if (!NCThread.m_dwProcessId)
  236. {
  237. NCThread.m_dwProcessId = dwProcId;
  238. NCThread.m_dwThreadID = dwThreadId;
  239. }
  240. else
  241. {
  242. ASSERT(NCThread.m_dwProcessId == dwProcId);
  243. ASSERT(NCThread.m_dwThreadID == dwThreadId);
  244. }
  245. NCThread.m_lsLines.push_back(NCEntry);
  246. NCThread.m_Tags[szTagName]++;
  247. m_pCurrentSpew->m_lsLines.push_back(NCEntry);
  248. m_pCurrentSpew->m_Tags[szTagName]++;
  249. }
  250. if (*szCurrentLine == _T('C'))
  251. {
  252. rpattern connPat( _T("Connected to Windows (.*) compatible target") );
  253. regexpr::backref_vector rgbackrefs;
  254. if( regexpr::match( sztstring, connPat, &rgbackrefs ) )
  255. {
  256. bProcessed = TRUE;
  257. dwTotalSpews++;
  258. ASSERT(rgbackrefs.size() >= 2);
  259. regexpr::backref_type br = rgbackrefs[1];
  260. TCHAR szDescription[MAX_PATH];
  261. _stprintf(szDescription, _T("%02d. %.*s"), dwTotalSpews, br.second - br.first, br.first );
  262. CSpew spew;
  263. spew.szSpewName = szDescription;
  264. m_Spews[dwTotalSpews] = spew;
  265. m_pCurrentSpew = &(m_Spews[dwTotalSpews]);
  266. m_pCNCurrentThread = &(m_pCurrentSpew->m_NCThreadList);
  267. }
  268. }
  269. if (!bProcessed)
  270. {
  271. m_pCurrentSpew->m_SpareLines[dwLineNum] = szCurrentLine;
  272. }
  273. }
  274. }
  275. CNCSpewFile::~CNCSpewFile()
  276. {
  277. }