Leaked source code of windows server 2003
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.

264 lines
8.2 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. //+============================================================================
  3. //
  4. // oplog.cxx
  5. //
  6. // Implementation for COperationsLog, which maintains a simple, circular
  7. // log of events.
  8. //
  9. //+============================================================================
  10. #include "pch.cxx"
  11. #pragma hdrstop
  12. #ifndef NO_OPLOG
  13. #include "trklib.hxx"
  14. #define OPERATION_LOG_SIZE ( (( (1024*1024) - sizeof(SHeader) )/sizeof(SRecord))*sizeof(SRecord) + sizeof(SHeader) )
  15. #define OPERATION_LOG_RECORD_COUNT ( (OPERATION_LOG_SIZE - sizeof(SHeader)) / sizeof(SRecord) )
  16. //+----------------------------------------------------------------------------
  17. //
  18. // COperationLog::InitializeLogFile
  19. //
  20. // Initialize the operations log file. This is called lazily so that we don't
  21. // impact service start (and don't get called unless the oplog is turned on).
  22. //
  23. //+----------------------------------------------------------------------------
  24. HRESULT
  25. COperationLog::InitializeLogFile( )
  26. {
  27. HRESULT hr = E_FAIL;
  28. ULONG cbFile = 0;
  29. _iRecord = 0;
  30. Lock();
  31. __try
  32. {
  33. BY_HANDLE_FILE_INFORMATION FileInfo;
  34. _fLogFileInitialized = TRUE;
  35. TrkLog(( TRKDBG_VOLUME, TEXT("Initializing operation log file (%s)"), _ptszOperationLog ));
  36. // Loop twice, if we find a problem the first time, we'll delete and
  37. // try again.
  38. for( int i = 0; i < 2; i++ )
  39. {
  40. if( INVALID_HANDLE_VALUE != _hFile )
  41. CloseHandle( _hFile );
  42. // Open/create the file on the first pass, create it on the second pass.
  43. _hFile = CreateFile( _ptszOperationLog, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL,
  44. 0 == i ? OPEN_ALWAYS : CREATE_ALWAYS,
  45. FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE );
  46. if( INVALID_HANDLE_VALUE == _hFile )
  47. {
  48. TrkLog(( TRKDBG_WARNING, TEXT("Couldn't create/open status log file (%lu)"),
  49. GetLastError() ));
  50. TrkRaiseLastError();
  51. }
  52. // On the first pass, check the file to see if it looks valid.
  53. // If not, continue the loop so that a new file can be created.
  54. if( 1 == i )
  55. cbFile = 0;
  56. else
  57. {
  58. // All we check is the size. There's no support for trying
  59. // to migrate a file if we change the file size.
  60. if( !GetFileInformationByHandle( _hFile, &FileInfo ))
  61. {
  62. TrkLog(( TRKDBG_WARNING, TEXT("Couldn't get status file info") ));
  63. TrkRaiseLastError();
  64. }
  65. if( 0 != FileInfo.nFileSizeHigh )
  66. {
  67. TrkLog(( TRKDBG_WARNING, TEXT("Operation file to big") ));
  68. continue;
  69. }
  70. else if( 0 != FileInfo.nFileSizeLow
  71. &&
  72. OPERATION_LOG_SIZE != FileInfo.nFileSizeLow )
  73. {
  74. TrkLog(( TRKDBG_WARNING, TEXT( "Operation log file wrong size") ));
  75. continue;
  76. }
  77. cbFile = FileInfo.nFileSizeLow;
  78. }
  79. }
  80. // Create a mapping of the file.
  81. _hFileMapping = CreateFileMapping( _hFile, NULL, PAGE_READWRITE, 0, OPERATION_LOG_SIZE, NULL );
  82. if( INVALID_HANDLE_VALUE == _hFileMapping )
  83. {
  84. TrkLog(( TRKDBG_WARNING, TEXT("Couldn't create status log file mapping (%lu)"), GetLastError() ));
  85. TrkRaiseLastError();
  86. }
  87. // And map a view of the file.
  88. _pHeader = (SHeader*) MapViewOfFile( _hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, OPERATION_LOG_SIZE );
  89. if( NULL == _pHeader )
  90. {
  91. TrkLog(( TRKDBG_WARNING, TEXT("Couldn't map view of status log file (%lu)"),
  92. GetLastError() ));
  93. TrkRaiseLastError();
  94. }
  95. // If we opened an existing file, validate the shutdown and version.
  96. // If anything looks wrong, or if this file is new, zero it out.
  97. if( 0 == cbFile
  98. ||
  99. 0 == (_pHeader->grfFlags & PROPER_SHUTDOWN)
  100. ||
  101. OPERATION_LOG_VERSION != _pHeader->dwVersion )
  102. {
  103. TrkLog(( TRKDBG_WARNING, TEXT("Re-initializing operation log file") ));
  104. _iRecord = 0;
  105. memset( _pHeader, 0, OPERATION_LOG_SIZE );
  106. _pHeader->dwVersion = OPERATION_LOG_VERSION;
  107. }
  108. else
  109. _iRecord = _pHeader->iRecord;
  110. // Show that the file isn't properly shut down.
  111. _pHeader->grfFlags &= ~PROPER_SHUTDOWN;
  112. _prgRecords = (SRecord*) ( (BYTE*)_pHeader + sizeof(SHeader) );
  113. Flush();
  114. TrkLog(( TRKDBG_VOLUME, TEXT("Status log starts at index %d"), _iRecord ));
  115. hr = S_OK;
  116. }
  117. __except( EXCEPTION_EXECUTE_HANDLER )
  118. {
  119. hr = GetExceptionCode();
  120. }
  121. Unlock();
  122. return( hr );
  123. }
  124. //+----------------------------------------------------------------------------
  125. //
  126. // COperationsLog::Flush
  127. //
  128. // Flush the operations log to disk.
  129. //
  130. //+----------------------------------------------------------------------------
  131. void
  132. COperationLog::Flush()
  133. {
  134. __try
  135. {
  136. if( !_fLogFileInitialized )
  137. __leave;
  138. _pHeader->iRecord = _iRecord;
  139. if( NULL != _pHeader && !FlushViewOfFile( _pHeader, OPERATION_LOG_SIZE ))
  140. {
  141. TrkLog(( TRKDBG_WARNING, TEXT("Couldn't flush operation log file view") ));
  142. }
  143. if( INVALID_HANDLE_VALUE != _hFile && !FlushFileBuffers( _hFile ))
  144. {
  145. TrkLog(( TRKDBG_WARNING, TEXT("Couldn't flush operation log file") ));
  146. }
  147. }
  148. __except( BreakOnDebuggableException() )
  149. {
  150. TrkLog(( TRKDBG_WARNING, TEXT("Ignoring exception in COpLog::Flush (0x%08x)"),
  151. GetExceptionCode() ));
  152. }
  153. }
  154. //+----------------------------------------------------------------------------
  155. //
  156. // COperationLog::InternalAdd
  157. //
  158. // Add an entry to the operation log.
  159. //
  160. //+----------------------------------------------------------------------------
  161. void
  162. COperationLog::InternalAdd( DWORD dwOperation, HRESULT hr, const CMachineId &mcidSource,
  163. DWORD dwExtra0, DWORD dwExtra1, DWORD dwExtra2, DWORD dwExtra3,
  164. DWORD dwExtra4, DWORD dwExtra5, DWORD dwExtra6, DWORD dwExtra7 )
  165. {
  166. ULONG iFile = 0;
  167. ULONG cbWritten = 0;
  168. Lock();
  169. __try
  170. {
  171. // Lazy initialization of the log file.
  172. if( !_fLogFileInitialized )
  173. {
  174. if( FAILED( InitializeLogFile() ))
  175. __leave;
  176. }
  177. // Ensure we have valid mappings.
  178. if( NULL == _pHeader || NULL == _prgRecords )
  179. __leave;
  180. // Add the data to the next record.
  181. _prgRecords[_iRecord].dwOperation = dwOperation;
  182. _prgRecords[_iRecord].ftOperation = CFILETIME();
  183. _prgRecords[_iRecord].mcidSource = mcidSource;
  184. _prgRecords[_iRecord].hr = hr;
  185. _prgRecords[_iRecord].rgdwExtra[0] = dwExtra0;
  186. _prgRecords[_iRecord].rgdwExtra[1] = dwExtra1;
  187. _prgRecords[_iRecord].rgdwExtra[2] = dwExtra2;
  188. _prgRecords[_iRecord].rgdwExtra[3] = dwExtra3;
  189. _prgRecords[_iRecord].rgdwExtra[4] = dwExtra4;
  190. _prgRecords[_iRecord].rgdwExtra[5] = dwExtra5;
  191. _prgRecords[_iRecord].rgdwExtra[6] = dwExtra6;
  192. _prgRecords[_iRecord].rgdwExtra[7] = dwExtra7;
  193. // Advance the seek pointer.
  194. _iRecord++;
  195. if( OPERATION_LOG_RECORD_COUNT == _iRecord )
  196. {
  197. _iRecord = 0;
  198. TrkLog(( TRKDBG_VOLUME, TEXT("Wrapping operation log") ));
  199. }
  200. }
  201. __except( BreakOnDebuggableException() )
  202. {
  203. TrkLog(( TRKDBG_WARNING, TEXT("Ignoring exception in COpLog::InternalAdd (0x%08x)"),
  204. GetExceptionCode() ));
  205. }
  206. Unlock();
  207. }
  208. #endif // #ifndef NO_OPLOG