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.

309 lines
9.4 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 ];
  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 ( r & USN_REASON_DATA_OVERWRITE )
  130. printf( "DATA_OVERWRITE " );
  131. if ( r & USN_REASON_DATA_EXTEND )
  132. printf( "DATA_EXTEND " );
  133. if ( r & USN_REASON_DATA_TRUNCATION )
  134. printf( "DATA_TRUNCATION " );
  135. if ( r & USN_REASON_NAMED_DATA_OVERWRITE )
  136. printf( "NAMED_DATA_OVERWRITE " );
  137. if ( r & USN_REASON_NAMED_DATA_EXTEND )
  138. printf( "NAMED_DATA_EXTEND " );
  139. if ( r & USN_REASON_NAMED_DATA_TRUNCATION )
  140. printf( "NAMED_DATA_TRUNCATION " );
  141. if ( r & USN_REASON_FILE_CREATE )
  142. printf( "FILE_CREATE " );
  143. if ( r & USN_REASON_FILE_DELETE )
  144. printf( "FILE_DELETE " );
  145. if ( r & USN_REASON_EA_CHANGE )
  146. printf( "EA_CHANGE " );
  147. if ( r & USN_REASON_SECURITY_CHANGE )
  148. printf( "SECURITY_CHANGE " );
  149. if ( r & USN_REASON_RENAME_OLD_NAME )
  150. printf( "RENAME_OLD_NAME " );
  151. if ( r & USN_REASON_RENAME_NEW_NAME )
  152. printf( "RENAME_NEW_NAME " );
  153. if ( r & USN_REASON_INDEXABLE_CHANGE )
  154. printf( "INDEXABLE_CHANGE " );
  155. if ( r & USN_REASON_BASIC_INFO_CHANGE )
  156. printf( "BASIC_INFO_CHANGE " );
  157. if ( r & USN_REASON_HARD_LINK_CHANGE )
  158. printf( "HARD_LINK_CHANGE " );
  159. if ( r & USN_REASON_COMPRESSION_CHANGE )
  160. printf( "COMPRESSION_CHANGE " );
  161. if ( r & USN_REASON_ENCRYPTION_CHANGE )
  162. printf( "ENCRYPTION_CHANGE " );
  163. if ( r & USN_REASON_OBJECT_ID_CHANGE )
  164. printf( "OBJECT_ID_CHANGE " );
  165. if ( r & USN_REASON_REPARSE_POINT_CHANGE )
  166. printf( "REPARSE_POINT_CHANGE " );
  167. if ( r & USN_REASON_STREAM_CHANGE )
  168. printf( "STREAM_CHANGE " );
  169. if ( r & USN_REASON_CLOSE )
  170. printf( "CLOSE " );
  171. printf( "\n" );
  172. if ( pUsnRec->RecordLength <= dwByteCount )
  173. {
  174. dwByteCount -= pUsnRec->RecordLength;
  175. pUsnRec = (USN_RECORD *) ((PCHAR) pUsnRec + pUsnRec->RecordLength );
  176. }
  177. else
  178. {
  179. printf( "Usn read fsctl returned bogus dwByteCount %#x\n", dwByteCount );
  180. exit( -1 );
  181. }
  182. }
  183. return usnNextStart;
  184. } //PrintUsnRecords
  185. int __cdecl main(
  186. int argc,
  187. char * argv[] )
  188. {
  189. if ( 2 != argc && 3 != argc )
  190. usage();
  191. if ( 3 == argc && argv[2][1] == 'v' )
  192. fVerbose = TRUE;
  193. WCHAR wcVol = argv[1][0];
  194. WCHAR wszVolumePath[] = L"\\\\.\\a:";
  195. wszVolumePath[4] = wcVol;
  196. HANDLE hVolume = CreateFile( wszVolumePath,
  197. GENERIC_READ | GENERIC_WRITE,
  198. FILE_SHARE_READ | FILE_SHARE_WRITE,
  199. NULL,
  200. OPEN_EXISTING,
  201. FILE_FLAG_OVERLAPPED,
  202. NULL );
  203. if ( INVALID_HANDLE_VALUE == hVolume )
  204. {
  205. printf( "Usn volume open failed %d, check for admin privileges\n", GetLastError() );
  206. usage();
  207. }
  208. HANDLE hEvent = CreateEvent( 0, TRUE, FALSE, 0 );
  209. //
  210. // Get the Journal ID
  211. //
  212. USN_JOURNAL_DATA UsnJournalInfo;
  213. IO_STATUS_BLOCK IoSB;
  214. NTSTATUS status = NtFsControlFile( hVolume,
  215. hEvent,
  216. 0,
  217. 0,
  218. &IoSB,
  219. FSCTL_QUERY_USN_JOURNAL,
  220. 0,
  221. 0,
  222. &UsnJournalInfo,
  223. sizeof UsnJournalInfo );
  224. if ( STATUS_PENDING == status )
  225. WaitForSingleObject( hEvent, INFINITE );
  226. if ( !NT_SUCCESS(status) || !NT_SUCCESS(IoSB.Status) )
  227. {
  228. printf( "Error %#x / %#x returned from QUERY_USN_JOURNAL\n", status, IoSB.Status );
  229. return -1;
  230. }
  231. USN usnMax = UsnJournalInfo.NextUsn;
  232. do
  233. {
  234. READ_USN_JOURNAL_DATA usnData = { usnMax, MAXULONG, 0, 0, 1, UsnJournalInfo.UsnJournalID };
  235. static ULONGLONG readBuffer[2048];
  236. status = NtFsControlFile( hVolume,
  237. hEvent,
  238. 0,
  239. 0,
  240. &IoSB,
  241. FSCTL_READ_USN_JOURNAL,
  242. &usnData,
  243. sizeof usnData,
  244. &readBuffer,
  245. sizeof readBuffer );
  246. if ( STATUS_PENDING == status )
  247. WaitForSingleObject( hEvent, INFINITE );
  248. if ( NT_SUCCESS( status ) )
  249. status = IoSB.Status;
  250. if ( !NT_SUCCESS( status ) )
  251. {
  252. printf( "FSCTL_READ_USN_JOURNAL failed %#x\n", status );
  253. return -1;
  254. }
  255. usnMax = PrintUsnRecords( hVolume, wcVol, &IoSB, readBuffer, usnMax );
  256. } while ( TRUE );
  257. return 0;
  258. } //main