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.

359 lines
6.9 KiB

  1. #include "precomp.h"
  2. #ifdef PLS_DEBUG
  3. #include "plog.h"
  4. CCallLog::CCallLog(int size)
  5. {
  6. m_bValid = false;
  7. DBG_SAVE_FILE_LINE
  8. m_pLogEntry = new CPacketLogEntry[size];
  9. if (m_pLogEntry == NULL)
  10. {
  11. WARNING_OUT(("CCallLog:Out of memory"));
  12. return;
  13. }
  14. m_currentIndex = 0;
  15. m_size = size;
  16. m_bValid = true;
  17. }
  18. CCallLog::~CCallLog()
  19. {
  20. if (m_bValid)
  21. {
  22. delete [] m_pLogEntry;
  23. }
  24. }
  25. bool CCallLog::AddEntry(DWORD dwTimeStamp, DWORD dwSeqNum, LARGE_INTEGER LL_ArrivalTime, DWORD dwSize, bool fMark)
  26. {
  27. CPacketLogEntry Entry;
  28. if (m_bValid == false) return false;
  29. Entry.dwTimeStamp = dwTimeStamp;
  30. Entry.dwSequenceNumber = dwSeqNum;
  31. Entry.LL_ArrivalTime = LL_ArrivalTime;
  32. Entry.dwSize = dwSize;
  33. Entry.dwLosses = 0;
  34. Entry.bLate = false;
  35. Entry.bMark = fMark;
  36. if (SizeCheck() == false)
  37. return false;
  38. m_pLogEntry[m_currentIndex++] = Entry;
  39. return true;
  40. }
  41. bool CCallLog::SizeCheck()
  42. {
  43. if (m_bValid == false)
  44. return false;
  45. if (m_currentIndex < m_size)
  46. return true;
  47. return false;
  48. }
  49. bool CCallLog::Flush(HANDLE hFile)
  50. {
  51. int index;
  52. CPacketLogEntry *pEntry;
  53. char szOutputLine[80];
  54. DWORD dwNumWritten;
  55. __int64 ArrivalTime64;
  56. __int64 PerfFreq64;
  57. LARGE_INTEGER LL_PerfFreq;
  58. if (m_bValid == false)
  59. return false;
  60. if (hFile == INVALID_HANDLE_VALUE)
  61. return false;
  62. PerformStats();
  63. // what's the performance frequency of this machine
  64. QueryPerformanceFrequency(&LL_PerfFreq);
  65. PerfFreq64 = LL_PerfFreq.QuadPart;
  66. for (index = 0; index < m_currentIndex; index++)
  67. {
  68. pEntry = &m_pLogEntry[index];
  69. ArrivalTime64 = pEntry->LL_ArrivalTime.QuadPart * 1000;
  70. ArrivalTime64 = ArrivalTime64 / PerfFreq64;
  71. sprintf(szOutputLine, "%d\t%d\t%d\t%d\t%d",
  72. pEntry->dwTimeStamp,
  73. pEntry->dwSequenceNumber,
  74. (int)ArrivalTime64,
  75. pEntry->dwSize,
  76. pEntry->dwLosses);
  77. if (pEntry->bMark)
  78. strcat(szOutputLine, "\tMARK");
  79. else strcat(szOutputLine, "\t");
  80. if (pEntry->bLate)
  81. strcat(szOutputLine, "\tLATE");
  82. strcat(szOutputLine, "\n");
  83. WriteFile(hFile, szOutputLine, strlen(szOutputLine), &dwNumWritten, NULL);
  84. }
  85. return true;
  86. }
  87. CCallLog& CCallLog::operator=(const CCallLog& log)
  88. {
  89. WARNING_OUT(("CCallLog:Assignment not supported"));
  90. return *this;
  91. }
  92. CCallLog::CCallLog(const CCallLog& log)
  93. {
  94. WARNING_OUT(("CCallLog:Copy constructor not supported"));
  95. return;
  96. }
  97. bool CCallLog::PerformStats()
  98. {
  99. int index, probeIndex;
  100. DWORD nextExpected;
  101. bool bFound;
  102. if (m_bValid == false)
  103. return false;
  104. if (m_currentIndex == 0)
  105. return false;
  106. // Set the current "loss" value for each entry to 0
  107. for (index = 0; index < m_currentIndex; index++)
  108. {
  109. m_pLogEntry[index].dwLosses = 0;
  110. m_pLogEntry[index].bLate = false;
  111. }
  112. // the first packet will always be a match with nextExpected
  113. nextExpected = m_pLogEntry[0].dwSequenceNumber;
  114. for (index = 0; index < m_currentIndex; index++)
  115. {
  116. if (nextExpected > 65535)
  117. nextExpected = 0;
  118. // if the packet has the next expected seq num, then everything is ok
  119. if (m_pLogEntry[index].dwSequenceNumber == nextExpected)
  120. {
  121. nextExpected++;
  122. continue;
  123. }
  124. // we've detected a missing packet... time to go hunting
  125. else if (m_pLogEntry[index].dwSequenceNumber > nextExpected)
  126. {
  127. bFound = false;
  128. probeIndex = index+1;
  129. while ((probeIndex < m_currentIndex) &&
  130. (probeIndex < (index+PLOG_MAX_NOT_LATE)) )
  131. {
  132. if (m_pLogEntry[index].dwSequenceNumber == nextExpected)
  133. bFound = true;
  134. probeIndex++;
  135. }
  136. // the packet was merely out of sequence
  137. if (bFound == true)
  138. {
  139. nextExpected++;
  140. continue;
  141. }
  142. // the packet is probably lost
  143. // notice that we are simply incrementing dwLoss measure,
  144. // rolling the index back one
  145. m_pLogEntry[index].dwLosses++;
  146. nextExpected++;
  147. index--; // this is so we can continue to count additional
  148. // loss packets for the same index
  149. continue; // back to the top of the for-loop
  150. }
  151. // a packet that was either previously thought of as lost or late
  152. else
  153. {
  154. m_pLogEntry[index].bLate = true;
  155. }
  156. }
  157. return true;
  158. }
  159. // --------------------------------------------------------------
  160. CPacketLog::CPacketLog(LPTSTR szDiskFile):
  161. m_hFile(INVALID_HANDLE_VALUE),
  162. m_nExtension(0)
  163. {
  164. m_pCallLog = NULL;
  165. strcpy(m_szDiskFile, szDiskFile);
  166. }
  167. // initializes an output file. Closes the current file if still open
  168. bool CPacketLog::InitFile()
  169. {
  170. char szFileName[120];
  171. if (m_hFile != INVALID_HANDLE_VALUE)
  172. {
  173. CloseHandle(m_hFile);
  174. m_hFile = INVALID_HANDLE_VALUE;
  175. }
  176. sprintf(szFileName, "%s%d%s", m_szDiskFile, m_nExtension, PLOG_FILE_EXT);
  177. m_hFile = CreateFile(szFileName,
  178. GENERIC_READ|GENERIC_WRITE,
  179. 0, NULL, OPEN_EXISTING,
  180. FILE_ATTRIBUTE_NORMAL, NULL);
  181. while ((m_hFile != INVALID_HANDLE_VALUE) && (m_nExtension < 100))
  182. {
  183. CloseHandle(m_hFile);
  184. sprintf(szFileName, "%s%d%s", m_szDiskFile, m_nExtension, PLOG_FILE_EXT);
  185. m_hFile = CreateFile(szFileName,
  186. GENERIC_READ|GENERIC_WRITE,
  187. 0, NULL, OPEN_EXISTING,
  188. FILE_ATTRIBUTE_NORMAL, NULL);
  189. m_nExtension++;
  190. }
  191. m_hFile = CreateFile(szFileName,
  192. GENERIC_READ|GENERIC_WRITE,
  193. FILE_SHARE_READ,
  194. NULL,
  195. CREATE_ALWAYS,
  196. FILE_ATTRIBUTE_NORMAL,
  197. NULL);
  198. if (m_hFile == INVALID_HANDLE_VALUE)
  199. {
  200. WARNING_OUT(("CPacketLog:Unable to initialize output file"));
  201. return false;
  202. }
  203. return true;
  204. }
  205. CPacketLog::CPacketLog(const CPacketLog& packet_log)
  206. {
  207. // it wouldn't be an error if duphandle was used correctly
  208. ERROR_OUT(("CPacketLog:Invalid to create a new packetLog via a copy constructor"));
  209. return;
  210. }
  211. CPacketLog& CPacketLog::operator=(const CPacketLog& packet_log)
  212. {
  213. // it wouldn't be an error if duphandle was used correctly
  214. ERROR_OUT(("CPacketLog:Invalid to create a new packetLog via the assignment operator"));
  215. return *this;
  216. }
  217. CPacketLog::~CPacketLog()
  218. {
  219. if (m_pCallLog != NULL)
  220. {
  221. Flush();
  222. delete (m_pCallLog);
  223. }
  224. if (m_hFile != INVALID_HANDLE_VALUE)
  225. CloseHandle(m_hFile);
  226. }
  227. bool CPacketLog::Flush()
  228. {
  229. char *szCallHeader = "CALLSTART\n";
  230. DWORD dwNumWritten;
  231. if (m_pCallLog == NULL)
  232. return false;
  233. WriteFile(m_hFile, szCallHeader, strlen(szCallHeader), &dwNumWritten, NULL);
  234. m_pCallLog->Flush(m_hFile);
  235. return true;
  236. }
  237. bool CPacketLog::MarkCallStart()
  238. {
  239. // write the previous call to file
  240. if (m_pCallLog != NULL)
  241. {
  242. Flush();
  243. CloseHandle(m_hFile);
  244. m_hFile = INVALID_HANDLE_VALUE;
  245. delete m_pCallLog;
  246. }
  247. if (false == InitFile())
  248. {
  249. return false;
  250. }
  251. DBG_SAVE_FILE_LINE
  252. m_pCallLog = new CCallLog(PLOG_MAX_PACKETS_CALL);
  253. if (m_pCallLog == NULL)
  254. return false;
  255. return true;
  256. }
  257. bool CPacketLog::AddEntry(DWORD dwTimeStamp, DWORD dwSeqNum, LARGE_INTEGER LL_ArrivalTime, DWORD dwSize, bool fMark)
  258. {
  259. if (m_pCallLog == NULL)
  260. {
  261. if (false == MarkCallStart())
  262. return false;
  263. }
  264. return (m_pCallLog->AddEntry(dwTimeStamp, dwSeqNum, LL_ArrivalTime, dwSize, fMark));
  265. }
  266. // if-def pls_debug
  267. #endif