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.

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( "usage: usndump <drive_letter>, e.g. usndump c\n" );
  18. printf( " requires administrative privileges to run\n" );
  19. }
  20. DECLARE_INFOLEVEL(ci)
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Function: PrintUsnRecords
  24. //
  25. // Purpose: Prints usn records from buffer
  26. //
  27. // History: 05-Jul-97 SitaramR Created
  28. // 21-May-98 KLam Added SourceInfo as output
  29. //
  30. //----------------------------------------------------------------------------
  31. void PrintUsnRecords( IO_STATUS_BLOCK *iosb, void *pBuffer )
  32. {
  33. USN usnNextStart;
  34. USN_RECORD * pUsnRec;
  35. ULONG_PTR dwByteCount = iosb->Information;
  36. if ( dwByteCount != 0 )
  37. {
  38. usnNextStart = *(USN *)pBuffer;
  39. pUsnRec = (USN_RECORD *)((PCHAR)pBuffer + sizeof(USN));
  40. dwByteCount -= sizeof(USN);
  41. }
  42. while ( dwByteCount != 0 )
  43. {
  44. if ( pUsnRec->MajorVersion != 2 || pUsnRec->MinorVersion != 0 )
  45. {
  46. printf( "Unrecognized USN version, Major=%u, Minor=%u\n",
  47. pUsnRec->MajorVersion, pUsnRec->MinorVersion );
  48. break;
  49. }
  50. if ( 0 != pUsnRec->SourceInfo )
  51. printf( "FileId=%#I64x, ParentFileId=%#I64x, Usn=%#I64x, Reason=%#x, SourceInfo=%#x, FileAttr=%#x, FileName=%.*ws\n",
  52. pUsnRec->FileReferenceNumber,
  53. pUsnRec->ParentFileReferenceNumber,
  54. pUsnRec->Usn,
  55. pUsnRec->Reason,
  56. pUsnRec->SourceInfo,
  57. pUsnRec->FileAttributes,
  58. pUsnRec->FileNameLength / sizeof WCHAR ,
  59. &pUsnRec->FileName );
  60. else
  61. printf( "FileId=%#I64x, ParentFileId=%#I64x, Usn=%#I64x, Reason=%#x, FileAttr=%#x, FileName=%.*ws\n",
  62. pUsnRec->FileReferenceNumber,
  63. pUsnRec->ParentFileReferenceNumber,
  64. pUsnRec->Usn,
  65. pUsnRec->Reason,
  66. pUsnRec->FileAttributes,
  67. pUsnRec->FileNameLength / sizeof WCHAR,
  68. &pUsnRec->FileName );
  69. if ( pUsnRec->RecordLength <= dwByteCount )
  70. {
  71. dwByteCount -= pUsnRec->RecordLength;
  72. pUsnRec = (USN_RECORD *) ((PCHAR) pUsnRec + pUsnRec->RecordLength );
  73. }
  74. else
  75. {
  76. printf( "***--- Usn read fsctl returned bogus dwByteCount 0x%x ---***\n", dwByteCount );
  77. THROW( CException( STATUS_UNSUCCESSFUL ) );
  78. }
  79. }
  80. }
  81. //+---------------------------------------------------------------------------
  82. //
  83. // Function: main
  84. //
  85. // Purpose: Main dump routine
  86. //
  87. // History: 05-Jul-97 SitaramR Created
  88. //
  89. //----------------------------------------------------------------------------
  90. int __cdecl main( int argc, char * argv[] )
  91. {
  92. if ( argc != 2 )
  93. {
  94. Usage();
  95. return 0;
  96. }
  97. WCHAR wcDriveLetter = argv[1][0];
  98. TRY
  99. {
  100. //
  101. // Looking at a file?
  102. //
  103. if ( strlen(argv[1]) > 2 )
  104. {
  105. int ccUnicodeStr = strlen( argv[1] ) + 1;
  106. WCHAR * pUnicodeStr = new WCHAR[ccUnicodeStr];
  107. if ( !MultiByteToWideChar( CP_ACP, 0, argv[1], -1, pUnicodeStr, ccUnicodeStr ) )
  108. {
  109. printf("MultiByteToWideChar failed.\n");
  110. delete [] pUnicodeStr;
  111. return 0;
  112. }
  113. CFunnyPath funnyPath( pUnicodeStr );
  114. delete [] pUnicodeStr;
  115. HANDLE hFile = CreateFile( funnyPath.GetPath(),
  116. GENERIC_READ,
  117. FILE_SHARE_READ,
  118. NULL,
  119. OPEN_EXISTING,
  120. FILE_FLAG_BACKUP_SEMANTICS,
  121. NULL );
  122. if ( INVALID_HANDLE_VALUE == hFile && ERROR_ACCESS_DENIED == GetLastError() )
  123. hFile = CreateFile( funnyPath.GetPath(),
  124. GENERIC_READ,
  125. FILE_SHARE_READ | FILE_SHARE_WRITE,
  126. NULL,
  127. OPEN_EXISTING,
  128. 0,
  129. NULL );
  130. if ( hFile == INVALID_HANDLE_VALUE )
  131. {
  132. printf( "***--- Usn file open failed 0x%x, check for admin privileges ---***\n", GetLastError() );
  133. THROW( CException( HRESULT_FROM_WIN32( GetLastError() ) ) );
  134. }
  135. NTSTATUS status;
  136. SHandle xFile( hFile );
  137. IO_STATUS_BLOCK iosb;
  138. ULONGLONG readBuffer[100];
  139. for ( unsigned i = 0; i < sizeof(readBuffer)/sizeof(readBuffer[0]); i++ )
  140. readBuffer[i] = 0xFFFFFFFFFFFFFFFFi64;
  141. USN_RECORD *pUsnRec;
  142. status = NtFsControlFile( hFile,
  143. NULL,
  144. NULL,
  145. NULL,
  146. &iosb,
  147. FSCTL_READ_FILE_USN_DATA,
  148. NULL,
  149. NULL,
  150. &readBuffer,
  151. sizeof(readBuffer) );
  152. if ( !NT_SUCCESS(status) || !NT_SUCCESS(iosb.Status) )
  153. {
  154. printf( "***--- Error 0x%x / 0x%x returned from READ_FILE_USN_DATA ---***\n", status, iosb.Status );
  155. return 0;
  156. }
  157. pUsnRec = (USN_RECORD *) &readBuffer;
  158. if ( pUsnRec->MajorVersion != 2 || pUsnRec->MinorVersion != 0 )
  159. printf( "Unrecognized USN version, Major=%u, Minor=%u\n",
  160. pUsnRec->MajorVersion, pUsnRec->MinorVersion );
  161. else
  162. printf( "FileId=%#I64x, ParentFileId=%#I64x, Usn=%#I64x, FileAttr=%#x, FileName=%.*ws\n",
  163. pUsnRec->FileReferenceNumber,
  164. pUsnRec->ParentFileReferenceNumber,
  165. 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. }