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.

318 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998 - 1999.
  5. //
  6. // File: usnmon.cxx
  7. //
  8. // Contents: USN monitor
  9. //
  10. // History: 18 Nov 1998 DLee Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #ifndef _WIN32_WINNT
  14. #define _WIN32_WINNT 0x0500
  15. #endif
  16. extern "C"
  17. {
  18. #include <nt.h>
  19. #include <ntioapi.h>
  20. #include <ntrtl.h>
  21. #include <nturtl.h>
  22. #include <ntexapi.h>
  23. }
  24. #include <windows.h>
  25. #include <stdio.h>
  26. #include <process.h>
  27. #define MAX_PATH_WCHARS (MAX_PATH * 4 )
  28. BOOL fVerbose = FALSE;
  29. void usage()
  30. {
  31. printf( "usage: usnmon x: [-verbose]\n" );
  32. printf( "You must be an administrator to run this application.\n" );
  33. exit( 1 );
  34. } //usage
  35. void IdToPath(
  36. HANDLE hVol,
  37. LONGLONG ll,
  38. WCHAR wcVol,
  39. WCHAR * pwcPath )
  40. {
  41. *pwcPath = 0;
  42. UNICODE_STRING uScope;
  43. uScope.Buffer = (WCHAR *) &ll;
  44. uScope.Length = sizeof ll;
  45. uScope.MaximumLength = sizeof ll;
  46. OBJECT_ATTRIBUTES ObjectAttr;
  47. InitializeObjectAttributes( &ObjectAttr, // Structure
  48. &uScope, // Name
  49. OBJ_CASE_INSENSITIVE, // Attributes
  50. hVol, // Root
  51. 0 ); // Security
  52. IO_STATUS_BLOCK IoStatus;
  53. HANDLE h = INVALID_HANDLE_VALUE;
  54. NTSTATUS Status = NtOpenFile( &h,
  55. FILE_READ_ATTRIBUTES,
  56. &ObjectAttr,
  57. &IoStatus,
  58. FILE_SHARE_READ |
  59. FILE_SHARE_WRITE |
  60. FILE_SHARE_DELETE,
  61. FILE_OPEN_BY_FILE_ID );
  62. if ( NT_ERROR( Status ) )
  63. return;
  64. static BYTE abFileNameInformation[ MAX_PATH_WCHARS * sizeof WCHAR +
  65. sizeof FILE_NAME_INFORMATION ];
  66. ULONG cbMax = sizeof abFileNameInformation;
  67. PFILE_NAME_INFORMATION FileName = (PFILE_NAME_INFORMATION) abFileNameInformation;
  68. FileName->FileNameLength = cbMax - sizeof FILE_NAME_INFORMATION;
  69. Status = NtQueryInformationFile( h,
  70. &IoStatus,
  71. FileName,
  72. cbMax,
  73. FileNameInformation );
  74. NtClose( h );
  75. if ( NT_ERROR( Status ) )
  76. return;
  77. // This is actually the full path, not the filename
  78. FileName->FileName[ FileName->FileNameLength / sizeof WCHAR ] = 0;
  79. pwcPath[0] = wcVol;
  80. pwcPath[1] = ':';
  81. wcscpy( pwcPath + 2, FileName->FileName );
  82. } //IdToPath
  83. USN PrintUsnRecords(
  84. HANDLE hVol,
  85. WCHAR wcVol,
  86. IO_STATUS_BLOCK * pIoSB,
  87. void * pBuffer,
  88. USN usnPrev )
  89. {
  90. USN usnNextStart;
  91. USN_RECORD * pUsnRec;
  92. ULONG_PTR dwByteCount = pIoSB->Information;
  93. if ( 0 != dwByteCount )
  94. {
  95. usnNextStart = *(USN *)pBuffer;
  96. pUsnRec = (USN_RECORD *)((PCHAR)pBuffer + sizeof(USN));
  97. dwByteCount -= sizeof(USN);
  98. }
  99. else
  100. {
  101. usnNextStart = usnPrev;
  102. }
  103. while ( 0 != dwByteCount )
  104. {
  105. if ( fVerbose )
  106. printf( "usn %#I64x id %#I64x ",
  107. pUsnRec->Usn,
  108. pUsnRec->FileReferenceNumber );
  109. static WCHAR awcPath[ MAX_PATH_WCHARS + 4 ];
  110. IdToPath( hVol, pUsnRec->FileReferenceNumber, wcVol, awcPath );
  111. ULONG r = pUsnRec->Reason;
  112. if ( 0 == awcPath[0] || ( r & USN_REASON_RENAME_OLD_NAME ) )
  113. {
  114. IdToPath( hVol, pUsnRec->ParentFileReferenceNumber, wcVol, awcPath );
  115. // If the parent directory has already been deleted, just
  116. // print the filename.
  117. if ( 0 == awcPath[0] )
  118. printf( "(%.*ws) ",
  119. pUsnRec->FileNameLength / sizeof WCHAR,
  120. &pUsnRec->FileName );
  121. else
  122. printf( "%ws\\%.*ws ",
  123. awcPath,
  124. pUsnRec->FileNameLength / sizeof WCHAR,
  125. &pUsnRec->FileName );
  126. }
  127. else
  128. printf( "%ws ", awcPath );
  129. if ( pUsnRec->SourceInfo & USN_SOURCE_AUXILIARY_DATA )
  130. printf( "USN_SOURCE_AUXILIARY_DATA " );
  131. if ( pUsnRec->SourceInfo & USN_SOURCE_DATA_MANAGEMENT )
  132. printf( "USN_SOURCE_DATA_MANAGEMENT " );
  133. if ( pUsnRec->SourceInfo & USN_SOURCE_REPLICATION_MANAGEMENT )
  134. printf( "USN_SOURCE_REPLICATION_MANAGEMENT " );
  135. if ( r & USN_REASON_DATA_OVERWRITE )
  136. printf( "DATA_OVERWRITE " );
  137. if ( r & USN_REASON_DATA_EXTEND )
  138. printf( "DATA_EXTEND " );
  139. if ( r & USN_REASON_DATA_TRUNCATION )
  140. printf( "DATA_TRUNCATION " );
  141. if ( r & USN_REASON_NAMED_DATA_OVERWRITE )
  142. printf( "NAMED_DATA_OVERWRITE " );
  143. if ( r & USN_REASON_NAMED_DATA_EXTEND )
  144. printf( "NAMED_DATA_EXTEND " );
  145. if ( r & USN_REASON_NAMED_DATA_TRUNCATION )
  146. printf( "NAMED_DATA_TRUNCATION " );
  147. if ( r & USN_REASON_FILE_CREATE )
  148. printf( "FILE_CREATE " );
  149. if ( r & USN_REASON_FILE_DELETE )
  150. printf( "FILE_DELETE " );
  151. if ( r & USN_REASON_EA_CHANGE )
  152. printf( "EA_CHANGE " );
  153. if ( r & USN_REASON_SECURITY_CHANGE )
  154. printf( "SECURITY_CHANGE " );
  155. if ( r & USN_REASON_RENAME_OLD_NAME )
  156. printf( "RENAME_OLD_NAME " );
  157. if ( r & USN_REASON_RENAME_NEW_NAME )
  158. printf( "RENAME_NEW_NAME " );
  159. if ( r & USN_REASON_INDEXABLE_CHANGE )
  160. printf( "INDEXABLE_CHANGE " );
  161. if ( r & USN_REASON_BASIC_INFO_CHANGE )
  162. printf( "BASIC_INFO_CHANGE " );
  163. if ( r & USN_REASON_HARD_LINK_CHANGE )
  164. printf( "HARD_LINK_CHANGE " );
  165. if ( r & USN_REASON_COMPRESSION_CHANGE )
  166. printf( "COMPRESSION_CHANGE " );
  167. if ( r & USN_REASON_ENCRYPTION_CHANGE )
  168. printf( "ENCRYPTION_CHANGE " );
  169. if ( r & USN_REASON_OBJECT_ID_CHANGE )
  170. printf( "OBJECT_ID_CHANGE " );
  171. if ( r & USN_REASON_REPARSE_POINT_CHANGE )
  172. printf( "REPARSE_POINT_CHANGE " );
  173. if ( r & USN_REASON_STREAM_CHANGE )
  174. printf( "STREAM_CHANGE " );
  175. if ( r & USN_REASON_CLOSE )
  176. printf( "CLOSE " );
  177. printf( "\n" );
  178. if ( pUsnRec->RecordLength <= dwByteCount )
  179. {
  180. dwByteCount -= pUsnRec->RecordLength;
  181. pUsnRec = (USN_RECORD *) ((PCHAR) pUsnRec + pUsnRec->RecordLength );
  182. }
  183. else
  184. {
  185. printf( "Usn read fsctl returned bogus dwByteCount %#x\n", dwByteCount );
  186. exit( -1 );
  187. }
  188. }
  189. return usnNextStart;
  190. } //PrintUsnRecords
  191. int __cdecl main(
  192. int argc,
  193. char * argv[] )
  194. {
  195. if ( 2 != argc && 3 != argc )
  196. usage();
  197. if ( 3 == argc && argv[2][1] == 'v' )
  198. fVerbose = TRUE;
  199. WCHAR wcVol = argv[1][0];
  200. WCHAR wszVolumePath[] = L"\\\\.\\a:";
  201. wszVolumePath[4] = wcVol;
  202. HANDLE hVolume = CreateFile( wszVolumePath,
  203. GENERIC_READ | GENERIC_WRITE,
  204. FILE_SHARE_READ | FILE_SHARE_WRITE,
  205. NULL,
  206. OPEN_EXISTING,
  207. FILE_FLAG_OVERLAPPED,
  208. NULL );
  209. if ( INVALID_HANDLE_VALUE == hVolume )
  210. {
  211. printf( "Usn volume open failed %d, check for admin privileges\n", GetLastError() );
  212. usage();
  213. }
  214. HANDLE hEvent = CreateEvent( 0, TRUE, FALSE, 0 );
  215. //
  216. // Get the Journal ID
  217. //
  218. USN_JOURNAL_DATA UsnJournalInfo;
  219. IO_STATUS_BLOCK IoSB;
  220. NTSTATUS status = NtFsControlFile( hVolume,
  221. hEvent,
  222. 0,
  223. 0,
  224. &IoSB,
  225. FSCTL_QUERY_USN_JOURNAL,
  226. 0,
  227. 0,
  228. &UsnJournalInfo,
  229. sizeof UsnJournalInfo );
  230. if ( STATUS_PENDING == status )
  231. WaitForSingleObject( hEvent, INFINITE );
  232. if ( !NT_SUCCESS(status) || !NT_SUCCESS(IoSB.Status) )
  233. {
  234. printf( "Error %#x / %#x returned from QUERY_USN_JOURNAL\n", status, IoSB.Status );
  235. return -1;
  236. }
  237. USN usnMax = UsnJournalInfo.NextUsn;
  238. do
  239. {
  240. READ_USN_JOURNAL_DATA usnData = { usnMax, MAXULONG, 0, 0, 1, UsnJournalInfo.UsnJournalID };
  241. static ULONGLONG readBuffer[2048];
  242. status = NtFsControlFile( hVolume,
  243. hEvent,
  244. 0,
  245. 0,
  246. &IoSB,
  247. FSCTL_READ_USN_JOURNAL,
  248. &usnData,
  249. sizeof usnData,
  250. &readBuffer,
  251. sizeof readBuffer );
  252. if ( STATUS_PENDING == status )
  253. WaitForSingleObject( hEvent, INFINITE );
  254. if ( NT_SUCCESS( status ) )
  255. status = IoSB.Status;
  256. if ( !NT_SUCCESS( status ) )
  257. {
  258. printf( "FSCTL_READ_USN_JOURNAL failed %#x\n", status );
  259. return -1;
  260. }
  261. usnMax = PrintUsnRecords( hVolume, wcVol, &IoSB, readBuffer, usnMax );
  262. } while ( TRUE );
  263. return 0;
  264. } //main