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.

283 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. UsnTest.c
  5. Abstract:
  6. This is the main module for the UsnJournal test.
  7. Author:
  8. Tom Miller 14-Jan-1997
  9. Revision History:
  10. --*/
  11. #include "UsnTest.h"
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <time.h>
  18. #include <windows.h>
  19. //
  20. // Current delay is 10 seconds
  21. //
  22. #define DELAY_TIME ((LONGLONG)(-100000000))
  23. void
  24. UsnTest(
  25. IN PCHAR DrivePath,
  26. IN ULONG Async
  27. );
  28. CHAR *
  29. FileTimeToString(
  30. FILETIME *pft
  31. );
  32. int
  33. __cdecl main( argc, argv )
  34. int argc;
  35. char *argv[];
  36. {
  37. char *p;
  38. int i;
  39. char c;
  40. char DrivePath[ 4 ];
  41. ULONG Async = FALSE;
  42. if ( argc > 1 ) {
  43. if (argc > 2) {
  44. Async = TRUE;
  45. }
  46. while (--argc) {
  47. p = *++argv;
  48. if ( isalpha(*p) ) {
  49. sprintf( DrivePath, "%c:", *p );
  50. UsnTest( DrivePath, Async );
  51. break;
  52. }
  53. }
  54. } else {
  55. printf( "UsnTest <DriveLetter> [A](for asyncmode)" );
  56. }
  57. return( 0 );
  58. }
  59. void
  60. UsnTest(
  61. IN PCHAR DrivePath,
  62. IN ULONG Async
  63. )
  64. {
  65. UCHAR VolumePath[16];
  66. HANDLE VolumeHandle;
  67. HANDLE Event;
  68. DWORD ReturnedByteCount;
  69. CREATE_USN_JOURNAL_DATA CreateUsnJournalData = {0x800000, 0x100000};
  70. READ_USN_JOURNAL_DATA ReadUsnJournalData = {0, MAXULONG, 0, DELAY_TIME, 1};
  71. ULONGLONG Buffer[1024];
  72. PUSN_RECORD UsnRecord;
  73. NTSTATUS Status;
  74. IO_STATUS_BLOCK Iosb;
  75. //
  76. // Create the event.
  77. //
  78. Status = NtCreateEvent( &Event, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
  79. if (!NT_SUCCESS(Status)) {
  80. printf( "NtCreateEvent failed with %08lx\n", Status );
  81. return;
  82. }
  83. //
  84. // Get a volume handle.
  85. //
  86. _strupr( DrivePath );
  87. sprintf( VolumePath, "\\\\.\\%s", DrivePath );
  88. VolumeHandle = CreateFile( VolumePath,
  89. GENERIC_READ | GENERIC_WRITE,
  90. FILE_SHARE_READ | FILE_SHARE_WRITE,
  91. NULL,
  92. OPEN_EXISTING,
  93. (Async ? FILE_FLAG_OVERLAPPED : 0),
  94. NULL );
  95. if (VolumeHandle == INVALID_HANDLE_VALUE ) {
  96. fprintf( stderr, "UsnTest: Unable to open %s volume (%u)\n", &VolumePath, GetLastError() );
  97. return;
  98. }
  99. //
  100. // Create the Usn Journal if it does not exist.
  101. //
  102. printf( "Creating UsnJournal on %s\n", DrivePath );
  103. if (!NT_SUCCESS( Status = NtFsControlFile( VolumeHandle,
  104. NULL,
  105. NULL,
  106. NULL,
  107. &Iosb,
  108. FSCTL_CREATE_USN_JOURNAL,
  109. &CreateUsnJournalData,
  110. sizeof(CreateUsnJournalData),
  111. NULL,
  112. 0 ))) {
  113. printf( "Create Usn Journal failed (%08lx)\n", Status );
  114. return;
  115. } else {
  116. while (TRUE) {
  117. Status = NtFsControlFile( VolumeHandle,
  118. Async ? Event : NULL,
  119. NULL,
  120. NULL,
  121. &Iosb,
  122. FSCTL_READ_USN_JOURNAL,
  123. &ReadUsnJournalData,
  124. sizeof(ReadUsnJournalData),
  125. &Buffer,
  126. sizeof(Buffer) );
  127. if (Status == STATUS_PENDING) {
  128. NtWaitForSingleObject( Event, TRUE, NULL );
  129. }
  130. if (NT_SUCCESS(Status)) {
  131. Status = Iosb.Status;
  132. }
  133. if (Status == STATUS_KEY_DELETED) {
  134. printf( "\n\nUsn %08lx, %08lx has been deleted, seeking to new journal start\n\n\n",
  135. (ULONG)ReadUsnJournalData.StartUsn,
  136. (ULONG)(ReadUsnJournalData.StartUsn >> 32) );
  137. ReadUsnJournalData.StartUsn = 0;
  138. continue;
  139. }
  140. if (!NT_SUCCESS(Status)) {
  141. printf( "Read Usn Journal failed (%08lx)\n", Status );
  142. return;
  143. }
  144. ReturnedByteCount = Iosb.Information;
  145. if (ReturnedByteCount != 0) {
  146. UsnRecord = (PUSN_RECORD)((PCHAR)&Buffer + sizeof(USN));
  147. ReturnedByteCount -= sizeof(USN);
  148. ReadUsnJournalData.StartUsn = *(USN *)&Buffer;
  149. printf( "Next Usn will be: %08lx, %08lx\n",
  150. (ULONG)ReadUsnJournalData.StartUsn,
  151. (ULONG)(ReadUsnJournalData.StartUsn >> 32) );
  152. }
  153. while (ReturnedByteCount != 0) {
  154. printf( "Usn: %08lx, %08lx, RecordLength: %lx, FileRef: %08lx, %08lx, ParentRef: %08lx, %08lx\n",
  155. (ULONG)UsnRecord->Usn,
  156. (ULONG)(UsnRecord->Usn >> 32),
  157. UsnRecord->RecordLength,
  158. (ULONG)UsnRecord->FileReferenceNumber,
  159. (ULONG)(UsnRecord->FileReferenceNumber >> 32),
  160. (ULONG)UsnRecord->ParentFileReferenceNumber,
  161. (ULONG)(UsnRecord->ParentFileReferenceNumber >> 32) );
  162. printf( " Reason: %08lx, SecurityId: %08lx, TimeStamp: %s\n FileName: %S\n",
  163. UsnRecord->Reason,
  164. UsnRecord->SecurityId,
  165. FileTimeToString((FILETIME *)&UsnRecord->TimeStamp),
  166. &UsnRecord->FileName );
  167. if (UsnRecord->RecordLength <= ReturnedByteCount) {
  168. ReturnedByteCount -= UsnRecord->RecordLength;
  169. UsnRecord = (PUSN_RECORD)((PCHAR)UsnRecord + UsnRecord->RecordLength);
  170. } else {
  171. printf( "********Bogus ReturnedByteCount: %08lx\n", UsnRecord->RecordLength );
  172. ReturnedByteCount = 0;
  173. }
  174. }
  175. //
  176. // Show the end of the request.
  177. //
  178. printf( "\n" );
  179. //
  180. // Keep growing the data we will wait for, just to try some different cases.
  181. // Basically this converges quickly to always waiting for a full buffer, or
  182. // else the timeout.
  183. //
  184. if (ReadUsnJournalData.BytesToWaitFor < sizeof(Buffer)) {
  185. if (!Async || (ReadUsnJournalData.BytesToWaitFor < 512)) {
  186. ReadUsnJournalData.BytesToWaitFor << 2;
  187. }
  188. }
  189. }
  190. }
  191. CloseHandle( VolumeHandle );
  192. return;
  193. }
  194. char *Days[] =
  195. {
  196. "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  197. };
  198. char *Months[] =
  199. {
  200. "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  201. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  202. };
  203. CHAR *
  204. FileTimeToString(FILETIME *FileTime)
  205. {
  206. FILETIME LocalFileTime;
  207. SYSTEMTIME SystemTime;
  208. static char Buffer[32];
  209. Buffer[0] = '\0';
  210. if (FileTime->dwHighDateTime != 0 || FileTime->dwLowDateTime != 0)
  211. {
  212. if (!FileTimeToLocalFileTime(FileTime, &LocalFileTime) ||
  213. !FileTimeToSystemTime(&LocalFileTime, &SystemTime))
  214. {
  215. return("Time???");
  216. }
  217. sprintf(
  218. Buffer,
  219. "%s %s %2d, %4d %02d:%02d:%02d",
  220. Days[SystemTime.wDayOfWeek],
  221. Months[SystemTime.wMonth - 1],
  222. SystemTime.wDay,
  223. SystemTime.wYear,
  224. SystemTime.wHour,
  225. SystemTime.wMinute,
  226. SystemTime.wSecond);
  227. }
  228. return(Buffer);
  229. }