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.

347 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1997-1998
  5. //
  6. // File: usndump.cxx
  7. //
  8. // Contents: Usn dump utility. Needs admin privileges to run.
  9. //
  10. // History: 05-Jul-97 SitaramR Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. void Usage()
  16. {
  17. printf( "Needs admin privileges to run, usage: usndump <drive_letter>, e.g. usndump c\n" );
  18. }
  19. DECLARE_INFOLEVEL(ci)
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Function: PrintUsnRecords
  23. //
  24. // Purpose: Prints usn records from buffer
  25. //
  26. // History: 05-Jul-97 SitaramR Created
  27. // 21-May-98 KLam Added SourceInfo as output
  28. //
  29. //----------------------------------------------------------------------------
  30. void PrintUsnRecords( IO_STATUS_BLOCK *iosb, void *pBuffer )
  31. {
  32. USN usnNextStart;
  33. USN_RECORD * pUsnRec;
  34. ULONG_PTR dwByteCount = iosb->Information;
  35. if ( dwByteCount != 0 )
  36. {
  37. usnNextStart = *(USN *)pBuffer;
  38. pUsnRec = (USN_RECORD *)((PCHAR)pBuffer + sizeof(USN));
  39. dwByteCount -= sizeof(USN);
  40. }
  41. while ( dwByteCount != 0 )
  42. {
  43. if ( pUsnRec->MajorVersion != 2 || pUsnRec->MinorVersion != 0 )
  44. {
  45. printf( "Unrecognized USN version, Major=%u, Minor=%u\n",
  46. pUsnRec->MajorVersion, pUsnRec->MinorVersion );
  47. break;
  48. }
  49. if ( 0 != pUsnRec->SourceInfo )
  50. printf( "FileId=%#I64x, ParentFileId=%#I64x, Usn=%#I64x, Reason=%#x, SourceInfo=%#x, FileAttr=%#x, FileName=%.*ws\n",
  51. pUsnRec->FileReferenceNumber,
  52. pUsnRec->ParentFileReferenceNumber,
  53. pUsnRec->Usn,
  54. pUsnRec->Reason,
  55. pUsnRec->SourceInfo,
  56. pUsnRec->FileAttributes,
  57. pUsnRec->FileNameLength / sizeof WCHAR ,
  58. &pUsnRec->FileName );
  59. else
  60. printf( "FileId=%#I64x, ParentFileId=%#I64x, Usn=%#I64x, Reason=%#x, FileAttr=%#x, FileName=%.*ws\n",
  61. pUsnRec->FileReferenceNumber,
  62. pUsnRec->ParentFileReferenceNumber,
  63. pUsnRec->Usn,
  64. pUsnRec->Reason,
  65. pUsnRec->FileAttributes,
  66. pUsnRec->FileNameLength / sizeof WCHAR,
  67. &pUsnRec->FileName );
  68. if ( pUsnRec->RecordLength <= dwByteCount )
  69. {
  70. dwByteCount -= pUsnRec->RecordLength;
  71. pUsnRec = (USN_RECORD *) ((PCHAR) pUsnRec + pUsnRec->RecordLength );
  72. }
  73. else
  74. {
  75. printf( "***--- Usn read fsctl returned bogus dwByteCount 0x%x ---***\n", dwByteCount );
  76. THROW( CException( STATUS_UNSUCCESSFUL ) );
  77. }
  78. }
  79. }
  80. //+---------------------------------------------------------------------------
  81. //
  82. // Function: main
  83. //
  84. // Purpose: Main dump routine
  85. //
  86. // History: 05-Jul-97 SitaramR Created
  87. //
  88. //----------------------------------------------------------------------------
  89. int __cdecl main( int argc, char * argv[] )
  90. {
  91. if ( argc != 2 )
  92. {
  93. Usage();
  94. return 0;
  95. }
  96. WCHAR wcDriveLetter = argv[1][0];
  97. TRY
  98. {
  99. //
  100. // Looking at a file?
  101. //
  102. if ( strlen(argv[1]) > 2 )
  103. {
  104. int ccUnicodeStr = strlen( argv[1] ) + 1;
  105. WCHAR * pUnicodeStr = new WCHAR[ccUnicodeStr];
  106. if ( !MultiByteToWideChar( CP_ACP, 0, argv[1], -1, pUnicodeStr, ccUnicodeStr ) )
  107. {
  108. printf("MultiByteToWideChar failed.\n");
  109. delete [] pUnicodeStr;
  110. return 0;
  111. }
  112. CFunnyPath funnyPath( pUnicodeStr );
  113. delete [] pUnicodeStr;
  114. HANDLE hFile = CreateFile( funnyPath.GetPath(),
  115. GENERIC_READ,
  116. FILE_SHARE_READ,
  117. NULL,
  118. OPEN_EXISTING,
  119. FILE_FLAG_BACKUP_SEMANTICS,
  120. NULL );
  121. if ( INVALID_HANDLE_VALUE == hFile && ERROR_ACCESS_DENIED == GetLastError() )
  122. hFile = CreateFile( funnyPath.GetPath(),
  123. GENERIC_READ,
  124. FILE_SHARE_READ | FILE_SHARE_WRITE,
  125. NULL,
  126. OPEN_EXISTING,
  127. 0,
  128. NULL );
  129. if ( hFile == INVALID_HANDLE_VALUE )
  130. {
  131. printf( "***--- Usn file open failed 0x%x, check for admin privileges ---***\n", GetLastError() );
  132. THROW( CException( HRESULT_FROM_WIN32( GetLastError() ) ) );
  133. }
  134. NTSTATUS status;
  135. SHandle xFile( hFile );
  136. IO_STATUS_BLOCK iosb;
  137. ULONGLONG readBuffer[100];
  138. for ( unsigned i = 0; i < sizeof(readBuffer)/sizeof(readBuffer[0]); i++ )
  139. readBuffer[i] = 0xFFFFFFFFFFFFFFFFi64;
  140. USN_RECORD *pUsnRec;
  141. status = NtFsControlFile( hFile,
  142. NULL,
  143. NULL,
  144. NULL,
  145. &iosb,
  146. FSCTL_READ_FILE_USN_DATA,
  147. NULL,
  148. NULL,
  149. &readBuffer,
  150. sizeof(readBuffer) );
  151. if ( !NT_SUCCESS(status) || !NT_SUCCESS(iosb.Status) )
  152. {
  153. printf( "***--- Error 0x%x / 0x%x returned from READ_FILE_USN_DATA ---***\n", status, iosb.Status );
  154. return 0;
  155. }
  156. pUsnRec = (USN_RECORD *) &readBuffer;
  157. if ( pUsnRec->MajorVersion != 2 || pUsnRec->MinorVersion != 0 )
  158. printf( "Unrecognized USN version, Major=%u, Minor=%u\n",
  159. pUsnRec->MajorVersion, pUsnRec->MinorVersion );
  160. else
  161. printf( "FileId=%#I64x, ParentFileId=%#I64x, Usn=%#I64x, FileAttr=%#x, FileName=%.*ws\n",
  162. pUsnRec->FileReferenceNumber,
  163. pUsnRec->ParentFileReferenceNumber,
  164. (ULONG)(pUsnRec->Usn>>32),
  165. (ULONG)pUsnRec->Usn,
  166. pUsnRec->FileAttributes,
  167. pUsnRec->FileNameLength / sizeof(WCHAR),
  168. &pUsnRec->FileName );
  169. }
  170. else
  171. {
  172. //
  173. // Create the volume handle that will be used for usn fsctls
  174. //
  175. WCHAR wszVolumePath[] = L"\\\\.\\a:";
  176. wszVolumePath[4] = wcDriveLetter;
  177. HANDLE hVolume = CreateFile( wszVolumePath,
  178. GENERIC_READ | GENERIC_WRITE,
  179. FILE_SHARE_READ | FILE_SHARE_WRITE,
  180. NULL,
  181. OPEN_EXISTING,
  182. 0,
  183. NULL );
  184. if ( hVolume == INVALID_HANDLE_VALUE )
  185. {
  186. printf( "***--- Usn volume open failed 0x%x, check for admin privileges ---***\n", GetLastError() );
  187. THROW( CException( HRESULT_FROM_WIN32( GetLastError() ) ) );
  188. }
  189. SWin32Handle xHandleVolume( hVolume );
  190. IO_STATUS_BLOCK iosb;
  191. //
  192. // Get the Journal ID
  193. //
  194. USN_JOURNAL_DATA UsnJournalInfo;
  195. NTSTATUS status = NtFsControlFile( hVolume,
  196. NULL,
  197. NULL,
  198. NULL,
  199. &iosb,
  200. FSCTL_QUERY_USN_JOURNAL,
  201. 0,
  202. 0,
  203. &UsnJournalInfo,
  204. sizeof(UsnJournalInfo) );
  205. if ( status == STATUS_PENDING )
  206. {
  207. printf( "***--- Status_pending returned for synchronous read fsctl ---***\n" );
  208. return 0;
  209. }
  210. if ( !NT_SUCCESS(status) || !NT_SUCCESS(iosb.Status) )
  211. {
  212. printf( "***--- Error 0x%x / 0x%x returned from QUERY_USN_JOURNAL ---***\n", status, iosb.Status );
  213. return 0;
  214. }
  215. READ_USN_JOURNAL_DATA usnData = {0, MAXULONG, 0, 0, 0, UsnJournalInfo.UsnJournalID};
  216. ULONGLONG readBuffer[2048];
  217. status = NtFsControlFile( hVolume,
  218. NULL,
  219. NULL,
  220. NULL,
  221. &iosb,
  222. FSCTL_READ_USN_JOURNAL,
  223. &usnData,
  224. sizeof(usnData),
  225. &readBuffer,
  226. sizeof(readBuffer) );
  227. if ( status == STATUS_PENDING )
  228. {
  229. printf( "***--- Status_pending returned for synchronous read fsctl ---***\n" );
  230. return 0;
  231. }
  232. if ( NT_SUCCESS( status ) )
  233. {
  234. status = iosb.Status;
  235. if ( STATUS_KEY_DELETED == status ||
  236. STATUS_JOURNAL_ENTRY_DELETED == status )
  237. {
  238. printf( "***--- Status key deleted, rerun ---***\n" );
  239. return 0;
  240. }
  241. PrintUsnRecords( &iosb, readBuffer );
  242. //
  243. // Read usn records until the end of usn journal
  244. //
  245. USN usnStart = 0;
  246. while ( NT_SUCCESS( status ) )
  247. {
  248. ULONG_PTR dwByteCount = iosb.Information;
  249. if ( dwByteCount <= sizeof(USN) )
  250. return 0;
  251. else
  252. {
  253. usnStart = *(USN *)&readBuffer;
  254. usnData.StartUsn = usnStart;
  255. status = NtFsControlFile( hVolume,
  256. NULL,
  257. NULL,
  258. NULL,
  259. &iosb,
  260. FSCTL_READ_USN_JOURNAL,
  261. &usnData,
  262. sizeof(usnData),
  263. &readBuffer,
  264. sizeof(readBuffer) );
  265. if ( NT_SUCCESS( status ) )
  266. status = iosb.Status;
  267. else
  268. {
  269. printf( "***--- Error 0x%x returned from read fsctl ---***\n", status );
  270. return 0;
  271. }
  272. if ( STATUS_KEY_DELETED == status ||
  273. STATUS_JOURNAL_ENTRY_DELETED == status )
  274. {
  275. printf( "***--- Status key deleted, rerun usndump ---***\n" );
  276. return 0;
  277. }
  278. PrintUsnRecords( &iosb, readBuffer );
  279. }
  280. }
  281. return 0;
  282. }
  283. else
  284. printf( "***--- Usn read fsctl returned 0x%x, check if usn journal has created on that volume ---***\n",
  285. status );
  286. }
  287. return 0;
  288. }
  289. CATCH( CException, e )
  290. {
  291. printf( "***--- Caught exception 0x%x ---***\n", e.GetErrorCode() );
  292. }
  293. END_CATCH
  294. return 0;
  295. }