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.

266 lines
7.2 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: v3applog.cpp
  6. //
  7. // Purpose: Reading WindowsUpdate V3 history logging
  8. //
  9. // History: 22-Feb-99 YAsmi Created
  10. // 02-May-01 JHou Modified
  11. //
  12. //=======================================================================
  13. #include "iuengine.h"
  14. #include <iucommon.h>
  15. #include "v3applog.h"
  16. //
  17. // CV3AppLog class
  18. //
  19. //--------------------------------------------------------------------------------
  20. // CV3AppLog::CV3AppLog
  21. //
  22. // if the pszLogFileName=NULL, then the caller must set the log file name by
  23. // calling SetLogFile before using
  24. //--------------------------------------------------------------------------------
  25. CV3AppLog::CV3AppLog(LPCTSTR pszLogFileName) :
  26. m_pFileBuf(NULL),
  27. m_pFieldBuf(NULL),
  28. m_pLine(NULL),
  29. m_dwFileSize(0),
  30. m_dwBufLen(0),
  31. m_dwFileOfs(0)
  32. {
  33. m_pszLogFN = NULL;
  34. SetLogFile(pszLogFileName);
  35. }
  36. //--------------------------------------------------------------------------------
  37. // CV3AppLog::~CV3AppLog
  38. //
  39. // free resources
  40. //--------------------------------------------------------------------------------
  41. CV3AppLog::~CV3AppLog()
  42. {
  43. SafeHeapFree(m_pszLogFN);
  44. SafeHeapFree(m_pFileBuf);
  45. SafeHeapFree(m_pFieldBuf);
  46. }
  47. //--------------------------------------------------------------------------------
  48. // CV3AppLog::CheckBuf
  49. //
  50. // allocates the internal buffer to be atleast dwSize big. Does not do anything
  51. // if the the buffer is already big enough
  52. //--------------------------------------------------------------------------------
  53. void CV3AppLog::CheckBuf(DWORD dwSize)
  54. {
  55. if (m_dwBufLen >= dwSize)
  56. return;
  57. SafeHeapFree(m_pFieldBuf);
  58. m_dwBufLen = dwSize + 16;
  59. m_pFieldBuf = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, m_dwBufLen);
  60. }
  61. //--------------------------------------------------------------------------------
  62. // CV3AppLog::SetLogFile
  63. //
  64. // sets the log file name. Use this function if you did not specify the file name
  65. // in the ctor
  66. //--------------------------------------------------------------------------------
  67. void CV3AppLog::SetLogFile(LPCTSTR pszLogFileName)
  68. {
  69. SafeHeapFree(m_pszLogFN);
  70. if (pszLogFileName != NULL)
  71. {
  72. m_pszLogFN = (LPTSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH * sizeof (TCHAR));
  73. if (NULL != m_pszLogFN)
  74. {
  75. HRESULT hr;
  76. hr = StringCchCopyEx(m_pszLogFN, MAX_PATH, pszLogFileName, NULL, NULL, MISTSAFE_STRING_FLAGS);
  77. if (FAILED(hr))
  78. {
  79. SafeHeapFree(m_pszLogFN);
  80. m_pszLogFN = NULL;
  81. }
  82. }
  83. }
  84. }
  85. //--------------------------------------------------------------------------------
  86. // CV3AppLog::StartReading
  87. //
  88. // Reads the entire log in memory so we can read lines. Following is an example:
  89. //
  90. // CV3AppLog V3His("C:\\wuhistv3.log");
  91. // V3His.StartReading();
  92. // while (V3His.ReadLine())
  93. // // do something;
  94. // V3His.StopReading();
  95. //--------------------------------------------------------------------------------
  96. void CV3AppLog::StartReading()
  97. {
  98. if (NULL != m_pszLogFN)
  99. {
  100. m_dwFileSize = 0;
  101. m_dwFileOfs = 0;
  102. SafeHeapFree(m_pFileBuf);
  103. HANDLE hFile = CreateFile(m_pszLogFN, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  104. if (hFile == INVALID_HANDLE_VALUE)
  105. return;
  106. m_dwFileSize = GetFileSize(hFile, NULL);
  107. if (m_dwFileSize >0)
  108. {
  109. m_pFileBuf = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, m_dwFileSize+1);
  110. if (NULL == m_pFileBuf)
  111. {
  112. m_dwFileSize = 0;
  113. }
  114. else
  115. {
  116. DWORD dwBytes;
  117. if (!ReadFile(hFile, m_pFileBuf, m_dwFileSize, &dwBytes, NULL) || dwBytes != m_dwFileSize)
  118. {
  119. SafeHeapFree(m_pFileBuf);
  120. m_dwFileSize = 0;
  121. }
  122. }
  123. }
  124. CloseHandle(hFile);
  125. }
  126. }
  127. //--------------------------------------------------------------------------------
  128. // CV3AppLog::ReadLine
  129. //
  130. // reads a line from the memory buffer where the entire file was loaded
  131. // moves the internal pointer to the next line.
  132. //--------------------------------------------------------------------------------
  133. BOOL CV3AppLog::ReadLine()
  134. {
  135. DWORD dwOrgOfs;
  136. if (m_dwFileSize == 0 || m_dwFileOfs >= m_dwFileSize || (NULL == m_pFileBuf))
  137. return FALSE;
  138. // setup the start of field parsing
  139. m_pLine = &m_pFileBuf[m_dwFileOfs];
  140. dwOrgOfs = m_dwFileOfs;
  141. while (m_dwFileOfs < m_dwFileSize && m_pFileBuf[m_dwFileOfs] != '\r')
  142. m_dwFileOfs++;
  143. if ((m_dwFileOfs - dwOrgOfs) > 2048)
  144. {
  145. // self imposed limit of 2048 chars in a line
  146. // we consider a file with a longer line of text an invalid log file
  147. m_dwFileOfs = m_dwFileSize;
  148. m_pLine = NULL;
  149. return FALSE;
  150. }
  151. // this is where we have the \r (13), we replace it with a 0 to create
  152. // end of string here
  153. m_pFileBuf[m_dwFileOfs] = '\0';
  154. // point the ofset to next line
  155. m_dwFileOfs += 2;
  156. // allocate enough memory to parse out fields when CopyNextField is called
  157. CheckBuf(m_dwFileOfs - dwOrgOfs - 2);
  158. if (NULL == m_pFieldBuf)
  159. {
  160. return FALSE;
  161. }
  162. return TRUE;
  163. }
  164. //--------------------------------------------------------------------------------
  165. // CV3AppLog::CopyNextField
  166. //
  167. // parses out the current line separated by the LOG_FIELD_SEPARATOR
  168. // and copies the string to pszBuf upto cBufSize long field and moves internal
  169. // pointer to next field. When the end of line is reached, returns a blank string
  170. //
  171. // RETURNS: TRUE if more fields are left, FALSE otherwise
  172. //
  173. // NOTES: Once you get a field you cannot get it again.
  174. //--------------------------------------------------------------------------------
  175. BOOL CV3AppLog::CopyNextField(LPSTR pszBuf, int cBufSize)
  176. {
  177. BOOL bMoreFields = FALSE;
  178. if (m_pLine == NULL || *m_pLine == '\0')
  179. {
  180. //there are no more fields
  181. m_pFieldBuf[0] = '\0';
  182. m_pLine = NULL;
  183. }
  184. else
  185. {
  186. LPCSTR p = strstr(m_pLine, LOG_FIELD_SEPARATOR);
  187. if (p != NULL)
  188. {
  189. DWORD cch;
  190. // this will fail if the size of the field is > 4GB. But it should be
  191. // very unlikely that this will ever happen...
  192. cch = (DWORD)(DWORD_PTR)(p - m_pLine);
  193. if (cch >= m_dwBufLen)
  194. cch = m_dwBufLen - 1;
  195. // copy the field to buffer but there are still more fields
  196. // this is safe because we made sure above that the max amount of data
  197. // copied will be ARRAYSIZE(buffer) - 1 giving us room for the NULL at the end
  198. CopyMemory(m_pFieldBuf, m_pLine, cch * sizeof(m_pFieldBuf[0]));
  199. m_pFieldBuf[cch] = '\0';
  200. m_pLine = const_cast<LPSTR>(p + strlen(LOG_FIELD_SEPARATOR));
  201. bMoreFields = TRUE;
  202. }
  203. else
  204. {
  205. // this is the last field, there are no more fields
  206. // don't care if this fails- it will always truncate the string which is
  207. // exactly what we want
  208. (void)StringCchCopyExA(m_pFieldBuf, m_dwBufLen, m_pLine, NULL, NULL, MISTSAFE_STRING_FLAGS);
  209. m_pLine = NULL;
  210. }
  211. }
  212. // don't care if this fails- it will always truncate the string which is exactly what
  213. // we want
  214. (void)StringCchCopyExA(pszBuf, cBufSize, m_pFieldBuf, NULL, NULL, MISTSAFE_STRING_FLAGS);
  215. return bMoreFields;
  216. }
  217. //--------------------------------------------------------------------------------
  218. // CV3AppLog::StopReading
  219. //
  220. // free up memory from allocated in StartReading
  221. //--------------------------------------------------------------------------------
  222. void CV3AppLog::StopReading()
  223. {
  224. SafeHeapFree(m_pFileBuf);
  225. m_dwFileSize = 0;
  226. }