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.

226 lines
6.1 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <assert.h>
  5. #include <pdh.h>
  6. #include <pdhp.h>
  7. #include "pdhidef.h"
  8. #include "log_bin.h"
  9. #include "log_wmi.h"
  10. #include "log_text.h"
  11. #include "log_sql.h"
  12. #include "strings.h"
  13. #include "pdhmsg.h"
  14. BOOL __stdcall
  15. IsValidLogHandle (
  16. IN HLOG hLog
  17. );
  18. PDH_FUNCTION
  19. PdhiWriteRelogRecord(
  20. IN PPDHI_LOG pLog,
  21. IN SYSTEMTIME *st
  22. )
  23. {
  24. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  25. LPWSTR szUserString = NULL;
  26. pdhStatus = WAIT_FOR_AND_LOCK_MUTEX (pLog->hLogMutex);
  27. if (pdhStatus == ERROR_SUCCESS) {
  28. switch (LOWORD(pLog->dwLogFormat)) {
  29. case PDH_LOG_TYPE_CSV:
  30. case PDH_LOG_TYPE_TSV:
  31. pdhStatus =PdhiWriteTextLogRecord (
  32. pLog,
  33. st,
  34. (LPCWSTR)szUserString);
  35. break;
  36. case PDH_LOG_TYPE_RETIRED_BIN:
  37. pdhStatus =PdhiWriteBinaryLogRecord (
  38. pLog,
  39. st,
  40. (LPCWSTR)szUserString);
  41. break;
  42. case PDH_LOG_TYPE_BINARY:
  43. pdhStatus = PdhiWriteWmiLogRecord(
  44. pLog,
  45. st,
  46. (LPCWSTR) szUserString);
  47. break;
  48. case PDH_LOG_TYPE_SQL:
  49. pdhStatus =PdhiWriteSQLLogRecord (
  50. pLog,
  51. st,
  52. (LPCWSTR)szUserString);
  53. break;
  54. case PDH_LOG_TYPE_PERFMON:
  55. default:
  56. pdhStatus = PDH_UNKNOWN_LOG_FORMAT;
  57. break;
  58. }
  59. RELEASE_MUTEX (pLog->hLogMutex);
  60. }
  61. return pdhStatus;
  62. }
  63. PDH_FUNCTION
  64. PdhRelogA(
  65. HLOG hLogIn,
  66. PPDH_RELOG_INFO_A pRelogInfo
  67. )
  68. {
  69. HRESULT hr;
  70. PDH_RELOG_INFO_W RelogInfo;
  71. memcpy( &RelogInfo, pRelogInfo, sizeof(PDH_RELOG_INFO_A) );
  72. RelogInfo.strLog = NULL;
  73. if( NULL != pRelogInfo->strLog ){
  74. RelogInfo.strLog = (LPWSTR)G_ALLOC(
  75. (strlen(pRelogInfo->strLog)+1) * sizeof(WCHAR) );
  76. if( RelogInfo.strLog ){
  77. mbstowcs(
  78. RelogInfo.strLog,
  79. pRelogInfo->strLog,
  80. (strlen(pRelogInfo->strLog)+1)
  81. );
  82. }
  83. }
  84. hr = PdhRelogW( hLogIn, &RelogInfo );
  85. G_FREE( RelogInfo.strLog );
  86. return hr;
  87. }
  88. PDH_FUNCTION
  89. PdhRelogW(
  90. HLOG hLogIn,
  91. PPDH_RELOG_INFO_W pRelogInfo
  92. )
  93. {
  94. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  95. HLOG hLogOut;
  96. PPDHI_LOG pLogIn;
  97. PPDHI_LOG pLogOut;
  98. SYSTEMTIME ut;
  99. FILETIME lt;
  100. ULONG nSampleCount = 0;
  101. ULONG nSamplesWritten = 0;
  102. if( IsValidLogHandle(hLogIn) ){
  103. HCOUNTER hCounter;
  104. HQUERY hQuery;
  105. ULONG nRecordSkip;
  106. pLogIn = (PPDHI_LOG)hLogIn;
  107. pdhStatus = PdhOpenLogW(
  108. pRelogInfo->strLog,
  109. pRelogInfo->dwFlags,
  110. &pRelogInfo->dwFileFormat,
  111. (HQUERY)pLogIn->pQuery,
  112. 0,
  113. NULL,
  114. &hLogOut
  115. );
  116. if( pdhStatus == ERROR_SUCCESS ){
  117. DWORD dwNumEntries = 1;
  118. DWORD dwBufferSize = sizeof(PDH_TIME_INFO);
  119. PDH_TIME_INFO TimeInfo;
  120. ZeroMemory( &TimeInfo, sizeof( PDH_TIME_INFO ) );
  121. pLogOut= (PPDHI_LOG)hLogOut;
  122. hQuery = (HQUERY)(pLogIn->pQuery);
  123. pdhStatus = PdhGetDataSourceTimeRangeH (
  124. hLogIn,
  125. &dwNumEntries,
  126. &TimeInfo,
  127. &dwBufferSize
  128. );
  129. if( pRelogInfo->TimeInfo.StartTime == 0 ||
  130. pRelogInfo->TimeInfo.StartTime < TimeInfo.StartTime ){
  131. pLogIn->pQuery->TimeRange.StartTime = TimeInfo.StartTime;
  132. pRelogInfo->TimeInfo.StartTime = TimeInfo.StartTime;
  133. }else{
  134. pLogIn->pQuery->TimeRange.StartTime = pRelogInfo->TimeInfo.StartTime;
  135. }
  136. if( pRelogInfo->TimeInfo.EndTime == 0 ||
  137. pRelogInfo->TimeInfo.EndTime > TimeInfo.EndTime ){
  138. pLogIn->pQuery->TimeRange.EndTime = TimeInfo.EndTime;
  139. pRelogInfo->TimeInfo.EndTime = TimeInfo.EndTime;
  140. }else{
  141. pLogIn->pQuery->TimeRange.EndTime = pRelogInfo->TimeInfo.EndTime;
  142. }
  143. nRecordSkip = pRelogInfo->TimeInfo.SampleCount >= 1 ? pRelogInfo->TimeInfo.SampleCount : 1;
  144. while( ERROR_SUCCESS == pdhStatus ){
  145. pdhStatus = PdhiCollectQueryData( (PPDHI_QUERY)hQuery, (LONGLONG *)&lt);
  146. FileTimeToSystemTime (&lt, &ut);
  147. if( nSampleCount++ % nRecordSkip ){
  148. continue;
  149. }
  150. if( ERROR_SUCCESS == pdhStatus ){
  151. pdhStatus = PdhiWriteRelogRecord( pLogOut, &ut );
  152. nSamplesWritten++;
  153. }
  154. else if (PDH_NO_DATA == pdhStatus) {
  155. // Reset pdhStatus. PDH_NO_DATA means that there are no new counter data
  156. // for collected counters. Skip current record and continue.
  157. //
  158. pdhStatus = ERROR_SUCCESS;
  159. }
  160. }
  161. //
  162. // Check for valid exit status codes
  163. //
  164. if( PDH_NO_MORE_DATA == pdhStatus ){
  165. pdhStatus = ERROR_SUCCESS;
  166. }
  167. if( ERROR_SUCCESS == pdhStatus ){
  168. pdhStatus = PdhCloseLog( hLogOut, 0 );
  169. }else{
  170. PdhCloseLog( hLogOut, 0 );
  171. }
  172. ((PPDHI_QUERY)hQuery)->hOutLog = NULL;
  173. }
  174. }else{
  175. pdhStatus = PDH_INVALID_HANDLE;
  176. }
  177. pRelogInfo->TimeInfo.SampleCount = nSamplesWritten;
  178. return pdhStatus;
  179. }