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.

967 lines
25 KiB

  1. /*++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. fspyLog.c
  5. Abstract:
  6. This module contains functions used to retrieve and see the log records
  7. recorded by filespy.sys.
  8. Environment:
  9. User mode
  10. // @@BEGIN_DDKSPLIT
  11. Author:
  12. Molly Brown (MollyBro) 21-Apr-1999
  13. Revision History:
  14. Molly Brown (mollybro) 21-May-2002
  15. Modify sample to make it support running on Windows 2000 or later if
  16. built in the latest build environment and allow it to be built in W2K
  17. and later build environments.
  18. // @@END_DDKSPLIT
  19. --*/
  20. #include <stdio.h>
  21. #include <windows.h>
  22. #include <stdlib.h>
  23. #include <winioctl.h>
  24. #include "fspyLog.h"
  25. #include "filespyLib.h"
  26. #define TIME_BUFFER_LENGTH 20
  27. #define TIME_ERROR L"time error"
  28. #define FlagOn(F,SF) ( \
  29. (((F) & (SF))) \
  30. )
  31. DWORD WINAPI
  32. RetrieveLogRecords (
  33. LPVOID lpParameter
  34. )
  35. {
  36. PLOG_CONTEXT context = (PLOG_CONTEXT)lpParameter;
  37. CHAR buffer[BUFFER_SIZE];
  38. DWORD bytesReturned = 0;
  39. BOOL bResult;
  40. DWORD result;
  41. PLOG_RECORD pLogRecord;
  42. printf("Log: Starting up\n");
  43. while (TRUE) {
  44. //
  45. // Check to see if we should shut down
  46. //
  47. if (context->CleaningUp) {
  48. break;
  49. }
  50. //
  51. // Request log data from filespy
  52. //
  53. bResult = DeviceIoControl( context->Device,
  54. FILESPY_GetLog,
  55. NULL,
  56. 0,
  57. buffer,
  58. BUFFER_SIZE,
  59. &bytesReturned,
  60. NULL);
  61. if (!bResult) {
  62. result = GetLastError();
  63. printf("ERROR controlling device: 0x%x\n", result);
  64. }
  65. //
  66. // Buffer is filled with a series of LOG_RECORD structures, one
  67. // right after another. Each LOG_RECORD says how long it is, so
  68. // we know where the next LOG_RECORD begins.
  69. //
  70. pLogRecord = (PLOG_RECORD) buffer;
  71. //
  72. // Logic to write record to screen and/or file
  73. //
  74. while ((BYTE *) pLogRecord < buffer + bytesReturned) {
  75. PRECORD_IRP pRecordIrp;
  76. PRECORD_FASTIO pRecordFastIo;
  77. #if WINVER >= 0x0501
  78. PRECORD_FS_FILTER_OPERATION pRecordFsFilterOp;
  79. #endif
  80. ULONG nameLength;
  81. //
  82. // Calculate the length of the name in the log record.
  83. //
  84. nameLength = wcslen( pLogRecord->Name ) * sizeof( WCHAR );
  85. //
  86. // A LOG_RECORD could have Irp or FastIo data in it. This
  87. // is denoted in the low-order byte of the RecordType flag.
  88. //
  89. switch (GET_RECORD_TYPE(pLogRecord)) {
  90. case RECORD_TYPE_IRP:
  91. //
  92. // We've got an Irp record, so output this data correctly.
  93. //
  94. pRecordIrp = &(pLogRecord->Record.RecordIrp);
  95. if (context->LogToScreen) {
  96. IrpScreenDump( pLogRecord->SequenceNumber,
  97. pLogRecord->Name,
  98. nameLength,
  99. pRecordIrp,
  100. context->VerbosityFlags);
  101. }
  102. if (context->LogToFile) {
  103. IrpFileDump( pLogRecord->SequenceNumber,
  104. pLogRecord->Name,
  105. nameLength,
  106. pRecordIrp,
  107. context->OutputFile,
  108. context->VerbosityFlags);
  109. }
  110. break;
  111. case RECORD_TYPE_FASTIO:
  112. //
  113. // We've got a FastIo record, so output this data correctly.
  114. //
  115. pRecordFastIo = &(pLogRecord->Record.RecordFastIo);
  116. if (context->LogToScreen) {
  117. FastIoScreenDump( pLogRecord->SequenceNumber,
  118. pLogRecord->Name,
  119. nameLength,
  120. pRecordFastIo);
  121. }
  122. if (context->LogToFile) {
  123. FastIoFileDump( pLogRecord->SequenceNumber,
  124. pLogRecord->Name,
  125. nameLength,
  126. pRecordFastIo,
  127. context->OutputFile);
  128. }
  129. break;
  130. #if WINVER >= 0x0501 /* See comment in DriverEntry */
  131. case RECORD_TYPE_FS_FILTER_OP:
  132. //
  133. // We've got a FsFilter operation record, so output this
  134. // data correctly.
  135. //
  136. pRecordFsFilterOp = &(pLogRecord->Record.RecordFsFilterOp);
  137. if (context->LogToScreen) {
  138. FsFilterOperationScreenDump( pLogRecord->SequenceNumber,
  139. pLogRecord->Name,
  140. nameLength,
  141. pRecordFsFilterOp );
  142. }
  143. if (context->LogToFile) {
  144. FsFilterOperationFileDump( pLogRecord->SequenceNumber,
  145. pLogRecord->Name,
  146. nameLength,
  147. pRecordFsFilterOp,
  148. context->OutputFile );
  149. }
  150. break;
  151. #endif
  152. default:
  153. printf("FileSpy: Unknown log record type\n");
  154. }
  155. //
  156. // The RecordType could also designate that we are out of memory
  157. // or hit our program defined memory limit, so check for these
  158. // cases.
  159. //
  160. if (pLogRecord->RecordType & RECORD_TYPE_OUT_OF_MEMORY) {
  161. if (context->LogToScreen) {
  162. printf("M %08X SYSTEM OUT OF MEMORY\n", pLogRecord->SequenceNumber);
  163. }
  164. if (context->LogToFile) {
  165. fprintf(context->OutputFile, "M:\t%u", pLogRecord->SequenceNumber);
  166. }
  167. } else if (pLogRecord->RecordType & RECORD_TYPE_EXCEED_MEMORY_ALLOWANCE) {
  168. if (context->LogToScreen) {
  169. printf("M %08X EXCEEDED MEMORY ALLOWANCE\n", pLogRecord->SequenceNumber);
  170. }
  171. if (context->LogToFile) {
  172. fprintf(context->OutputFile, "M:\t%u", pLogRecord->SequenceNumber);
  173. }
  174. }
  175. //
  176. // Move to next LOG_RECORD
  177. //
  178. pLogRecord = (PLOG_RECORD) (((BYTE *) pLogRecord) + pLogRecord->Length);
  179. }
  180. if (bytesReturned == 0) {
  181. Sleep( 500 );
  182. }
  183. }
  184. printf("Log: Shutting down\n");
  185. ReleaseSemaphore(context->ShutDown, 1, NULL);
  186. printf("Log: All done\n");
  187. return 0;
  188. }
  189. VOID
  190. PrintIrpCode (
  191. UCHAR MajorCode,
  192. UCHAR MinorCode,
  193. ULONG FsControlCode,
  194. FILE *OutputFile,
  195. BOOLEAN PrintMajorCode
  196. )
  197. {
  198. CHAR irpMajorString[OPERATION_NAME_BUFFER_SIZE];
  199. CHAR irpMinorString[OPERATION_NAME_BUFFER_SIZE];
  200. CHAR formatBuf[OPERATION_NAME_BUFFER_SIZE*2];
  201. GetIrpName(MajorCode,MinorCode,FsControlCode,irpMajorString,irpMinorString);
  202. if (OutputFile) {
  203. sprintf(formatBuf, "%s %s", irpMajorString, irpMinorString);
  204. fprintf(OutputFile, "\t%-50s", formatBuf);
  205. } else {
  206. if (PrintMajorCode) {
  207. printf("%-31s ", irpMajorString);
  208. } else {
  209. if (irpMinorString[0] != 0) {
  210. printf(" %-35s\n",
  211. irpMinorString);
  212. }
  213. }
  214. }
  215. }
  216. VOID
  217. PrintFastIoType (
  218. FASTIO_TYPE Code,
  219. FILE *OutputFile
  220. )
  221. {
  222. CHAR outputString[OPERATION_NAME_BUFFER_SIZE];
  223. GetFastioName(Code,outputString);
  224. if (OutputFile) {
  225. fprintf(OutputFile, "\t%-50s", outputString);
  226. } else {
  227. printf("%-31s ", outputString);
  228. }
  229. }
  230. #if WINVER >= 0x0501 /* See comment in DriverEntry */
  231. VOID
  232. PrintFsFilterOperation (
  233. UCHAR Operation,
  234. FILE *OutputFile
  235. )
  236. {
  237. CHAR outputString[OPERATION_NAME_BUFFER_SIZE];
  238. GetFsFilterOperationName(Operation,outputString);
  239. if (OutputFile) {
  240. fprintf( OutputFile, "\t%-50s", outputString );
  241. } else {
  242. printf( "%-31s ", outputString );
  243. }
  244. }
  245. #endif
  246. ULONG
  247. FormatSystemTime (
  248. SYSTEMTIME *SystemTime,
  249. PWCHAR Buffer,
  250. ULONG BufferLength
  251. )
  252. /*++
  253. Routine Name:
  254. FormatSystemTime
  255. Routine Description:
  256. Formats the values in a SystemTime struct into the buffer
  257. passed in. The resulting string is NULL terminated. The format
  258. for the time is:
  259. hours:minutes:seconds:milliseconds
  260. Arguments:
  261. SystemTime - the struct to format
  262. Buffer - the buffer to place the formatted time in
  263. BufferLength - the size of the buffer in characters
  264. Return Value:
  265. The number of characters returned in Buffer.
  266. --*/
  267. {
  268. PWCHAR writePosition;
  269. ULONG returnLength = 0;
  270. writePosition = Buffer;
  271. if (BufferLength < TIME_BUFFER_LENGTH) {
  272. //
  273. // Buffer is too short so exit
  274. //
  275. return 0;
  276. }
  277. returnLength = swprintf( Buffer,
  278. L"%02d:%02d:%02d:%03d",
  279. SystemTime->wHour,
  280. SystemTime->wMinute,
  281. SystemTime->wSecond,
  282. SystemTime->wMilliseconds);
  283. return returnLength;
  284. }
  285. VOID
  286. IrpFileDump (
  287. ULONG SequenceNumber,
  288. PWCHAR Name,
  289. ULONG NameLength,
  290. PRECORD_IRP RecordIrp,
  291. FILE *File,
  292. ULONG VerbosityFlags
  293. )
  294. /*++
  295. Routine Name:
  296. IrpFileDump
  297. Routine Description:
  298. Prints a Irp log record to the specified file. The output is in a tab
  299. delimited format with the fields in the following order:
  300. SequenceNumber, OriginatingTime, CompletionTime, IrpMajor, IrpMinor,
  301. IrpFlags, NoCache, Paging I/O, Synchronous, Synchronous paging, FileName,
  302. ReturnStatus, FileName
  303. Arguments:
  304. SequenceNumber - the sequence number for this log record
  305. Name - the name of the file that this Irp relates to
  306. NameLength - the length of Name in bytes
  307. RecordIrp - the Irp record to print
  308. File - the file to print to
  309. Return Value:
  310. None.
  311. --*/
  312. {
  313. FILETIME localTime;
  314. SYSTEMTIME systemTime;
  315. WCHAR time[TIME_BUFFER_LENGTH];
  316. fprintf(File, "I\t%08X", SequenceNumber);
  317. //
  318. // Convert originating time
  319. //
  320. FileTimeToLocalFileTime( (FILETIME *)&(RecordIrp->OriginatingTime), &localTime );
  321. FileTimeToSystemTime( &localTime, &systemTime );
  322. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  323. fprintf( File, "\t%-12S", time );
  324. } else {
  325. fprintf( File, "\t%-12S", TIME_ERROR );
  326. }
  327. //
  328. // Convert completion time
  329. //
  330. FileTimeToLocalFileTime( (FILETIME *)&(RecordIrp->CompletionTime), &localTime );
  331. FileTimeToSystemTime( &localTime, &systemTime );
  332. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  333. fprintf( File, "\t%-12S", time );
  334. } else {
  335. fprintf( File, "\t%-12S", TIME_ERROR );
  336. }
  337. fprintf( File, "\t%8x.%-4x ", RecordIrp->ProcessId, RecordIrp->ThreadId );
  338. PrintIrpCode( RecordIrp->IrpMajor, RecordIrp->IrpMinor, (ULONG)(ULONG_PTR)RecordIrp->Argument3, File, TRUE );
  339. fprintf( File, "\t%p", (PVOID)RecordIrp->DeviceObject );
  340. fprintf( File, "\t%p", (PVOID)RecordIrp->FileObject );
  341. fprintf( File, "\t%08lx:%08lx", RecordIrp->ReturnStatus, RecordIrp->ReturnInformation );
  342. //
  343. // Interpret set flags
  344. //
  345. fprintf( File, "\t%08lx ", RecordIrp->IrpFlags );
  346. fprintf( File, "%s", (RecordIrp->IrpFlags & IRP_NOCACHE) ? "N":"-" );
  347. fprintf( File, "%s", (RecordIrp->IrpFlags & IRP_PAGING_IO) ? "P":"-" );
  348. fprintf( File, "%s", (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_API) ? "S":"-" );
  349. fprintf( File, "%s", (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) ? "Y":"-" );
  350. if (FlagOn( VerbosityFlags, FS_VF_DUMP_PARAMETERS )) {
  351. fprintf( File,
  352. "%p %p %p %p ",
  353. RecordIrp->Argument1,
  354. RecordIrp->Argument2,
  355. RecordIrp->Argument3,
  356. RecordIrp->Argument4 );
  357. if (IRP_MJ_CREATE == RecordIrp->IrpMajor) {
  358. fprintf( File, "DesiredAccess->%08lx ", RecordIrp->DesiredAccess );
  359. }
  360. }
  361. fprintf( File, "\t%.*S", NameLength/sizeof(WCHAR), Name );
  362. fprintf( File, "\n" );
  363. }
  364. VOID
  365. IrpScreenDump (
  366. ULONG SequenceNumber,
  367. PWCHAR Name,
  368. ULONG NameLength,
  369. PRECORD_IRP RecordIrp,
  370. ULONG VerbosityFlags
  371. )
  372. /*++
  373. Routine Name:
  374. IrpScreenDump
  375. Routine Description:
  376. Prints a Irp log record to the screen in the following order:
  377. SequenceNumber, OriginatingTime, CompletionTime, IrpMajor, IrpMinor,
  378. IrpFlags, NoCache, Paging I/O, Synchronous, Synchronous paging,
  379. FileName, ReturnStatus, FileName
  380. Arguments:
  381. SequenceNumber - the sequence number for this log record
  382. Name - the file name to which this Irp relates
  383. NameLength - the length of Name in bytes
  384. RecordIrp - the Irp record to print
  385. Return Value:
  386. None.
  387. --*/
  388. {
  389. FILETIME localTime;
  390. SYSTEMTIME systemTime;
  391. WCHAR time[TIME_BUFFER_LENGTH];
  392. printf( "I %08X ", SequenceNumber );
  393. //
  394. // Convert originating time
  395. //
  396. FileTimeToLocalFileTime( (FILETIME *)&(RecordIrp->OriginatingTime), &localTime );
  397. FileTimeToSystemTime( &localTime, &systemTime );
  398. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  399. printf( "%-12S ", time );
  400. } else {
  401. printf( "%-12S ", TIME_ERROR );
  402. }
  403. //
  404. // Convert completion time
  405. //
  406. FileTimeToLocalFileTime( (FILETIME *)&(RecordIrp->CompletionTime), &localTime );
  407. FileTimeToSystemTime( &localTime, &systemTime );
  408. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  409. printf( "%-12S ", time );
  410. } else {
  411. printf( "%-12S ", TIME_ERROR );
  412. }
  413. printf( "%8x.%-4x ", RecordIrp->ProcessId, RecordIrp->ThreadId );
  414. PrintIrpCode( RecordIrp->IrpMajor, RecordIrp->IrpMinor, (ULONG)(ULONG_PTR)RecordIrp->Argument3, NULL, TRUE );
  415. printf( "%p ", (PVOID)RecordIrp->DeviceObject );
  416. printf( "%p ", (PVOID)RecordIrp->FileObject );
  417. printf( "%08lx:%08lx ", RecordIrp->ReturnStatus, RecordIrp->ReturnInformation );
  418. //
  419. // Interpret set flags
  420. //
  421. printf( "%08lx ", RecordIrp->IrpFlags );
  422. printf( "%s", (RecordIrp->IrpFlags & IRP_NOCACHE) ? "N":"-" );
  423. printf( "%s", (RecordIrp->IrpFlags & IRP_PAGING_IO) ? "P":"-" );
  424. printf( "%s", (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_API) ? "S":"-" );
  425. printf( "%s ", (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) ? "Y":"-" );
  426. if (FlagOn( VerbosityFlags, FS_VF_DUMP_PARAMETERS )) {
  427. printf( "%p %p %p %p ",
  428. RecordIrp->Argument1,
  429. RecordIrp->Argument2,
  430. RecordIrp->Argument3,
  431. RecordIrp->Argument4 );
  432. if (IRP_MJ_CREATE == RecordIrp->IrpMajor) {
  433. printf( "DesiredAccess->%08lx ", RecordIrp->DesiredAccess );
  434. }
  435. }
  436. printf( "%.*S", NameLength/sizeof(WCHAR), Name );
  437. printf( "\n" );
  438. PrintIrpCode( RecordIrp->IrpMajor, RecordIrp->IrpMinor, (ULONG)(ULONG_PTR)RecordIrp->Argument3, NULL, FALSE );
  439. }
  440. VOID
  441. FastIoFileDump (
  442. ULONG SequenceNumber,
  443. PWCHAR Name,
  444. ULONG NameLength,
  445. PRECORD_FASTIO RecordFastIo,
  446. FILE *File
  447. )
  448. /*++
  449. Routine Name:
  450. FastIoFileDump
  451. Routine Description:
  452. Prints a FastIo log record to the specified file. The output is in a tab
  453. delimited format with the fields in the following order:
  454. SequenceNumber, StartTime, CompletionTime, Fast I/O Type, FileName,
  455. Length, Wait, ReturnStatus, FileName
  456. Arguments:
  457. SequenceNumber - the sequence number for this log record
  458. Name - the name of the file referenced by this Fast I/O operation
  459. NameLength - the length of name in bytes
  460. RecordFastIo - the FastIo record to print
  461. File - the file to print to
  462. Return Value:
  463. None.
  464. --*/
  465. {
  466. SYSTEMTIME systemTime;
  467. FILETIME localTime;
  468. WCHAR time[TIME_BUFFER_LENGTH];
  469. fprintf( File, "F\t%08X", SequenceNumber );
  470. //
  471. // Convert start time
  472. //
  473. FileTimeToLocalFileTime( (FILETIME *)&(RecordFastIo->StartTime), &localTime );
  474. FileTimeToSystemTime( &localTime, &systemTime );
  475. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  476. fprintf( File, "\t%-12S", time );
  477. } else {
  478. fprintf( File, "\t%-12S", TIME_ERROR );
  479. }
  480. //
  481. // Convert completion time
  482. //
  483. FileTimeToLocalFileTime( (FILETIME *)&(RecordFastIo->CompletionTime), &localTime );
  484. FileTimeToSystemTime( &localTime, &systemTime );
  485. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  486. fprintf( File, "\t%-12S", time );
  487. } else {
  488. fprintf( File, "\t%-12S", TIME_ERROR );
  489. }
  490. fprintf( File, "\t%8x.%-4x ", RecordFastIo->ProcessId, RecordFastIo->ThreadId );
  491. PrintFastIoType( RecordFastIo->Type, File );
  492. fprintf( File, "\t%p", (PVOID)RecordFastIo->DeviceObject );
  493. fprintf( File, "\t%p", (PVOID)RecordFastIo->FileObject );
  494. fprintf( File, "\t%08x", RecordFastIo->ReturnStatus );
  495. fprintf( File, "\t%s", (RecordFastIo->Wait)?"T":"F" );
  496. fprintf( File, "\t%08x", RecordFastIo->Length );
  497. fprintf( File, "\t%016I64x ", RecordFastIo->FileOffset.QuadPart );
  498. fprintf( File, "\t%.*S", NameLength/sizeof(WCHAR), Name );
  499. fprintf( File, "\n" );
  500. }
  501. VOID
  502. FastIoScreenDump (
  503. ULONG SequenceNumber,
  504. PWCHAR Name,
  505. ULONG NameLength,
  506. PRECORD_FASTIO RecordFastIo
  507. )
  508. /*++
  509. Routine Name:
  510. FastIoScreenDump
  511. Routine Description:
  512. Prints a FastIo log record to the screen in the following order:
  513. SequenceNumber, StartTime, CompletionTime, Fast I/O Type, FileName,
  514. Length, Wait, ReturnStatus, FileName
  515. Arguments:
  516. SequenceNumber - the sequence number for this log record
  517. Name - the name of the file referenced by this Fast I/O operation
  518. NameLength - the length of name in bytes
  519. RecordIrp - the Irp record to print
  520. Return Value:
  521. None.
  522. --*/
  523. {
  524. SYSTEMTIME systemTime;
  525. FILETIME localTime;
  526. WCHAR time[TIME_BUFFER_LENGTH];
  527. printf( "F %08X ", SequenceNumber );
  528. //
  529. // Convert start time
  530. //
  531. FileTimeToLocalFileTime( (FILETIME *)&(RecordFastIo->StartTime), &localTime );
  532. FileTimeToSystemTime( &localTime, &systemTime );
  533. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  534. printf( "%-12S ", time );
  535. } else {
  536. printf( "%-12S ", TIME_ERROR );
  537. }
  538. //
  539. // Convert completion time
  540. //
  541. FileTimeToLocalFileTime( (FILETIME *)&(RecordFastIo->CompletionTime), &localTime );
  542. FileTimeToSystemTime( &localTime, &systemTime );
  543. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  544. printf( "%-12S ", time );
  545. } else {
  546. printf( "%-12S ", TIME_ERROR );
  547. }
  548. printf( "%8x.%-4x ", RecordFastIo->ProcessId, RecordFastIo->ThreadId );
  549. PrintFastIoType( RecordFastIo->Type, NULL );
  550. printf( "%p ", (PVOID)RecordFastIo->DeviceObject );
  551. printf( "%p ", (PVOID)RecordFastIo->FileObject );
  552. printf( "%08x ", RecordFastIo->ReturnStatus );
  553. printf( "%s ", (RecordFastIo->Wait)?"T":"F" );
  554. printf( "%08x ", RecordFastIo->Length );
  555. printf( "%016I64x ", RecordFastIo->FileOffset.QuadPart );
  556. printf( "%.*S", NameLength/sizeof(WCHAR), Name );
  557. printf ("\n" );
  558. }
  559. #if WINVER >= 0x0501 /* See comment in DriverEntry */
  560. VOID
  561. FsFilterOperationFileDump (
  562. ULONG SequenceNumber,
  563. PWCHAR Name,
  564. ULONG NameLength,
  565. PRECORD_FS_FILTER_OPERATION RecordFsFilterOp,
  566. FILE *File
  567. )
  568. /*++
  569. Routine Name:
  570. FsFilterOperationFileDump
  571. Routine Description:
  572. Prints a FsFilterOperation log record to the specified file. The output is in a tab
  573. delimited format with the fields in the following order:
  574. SequenceNumber, OriginatingTime, CompletionTime, ProcessId, ThreadId,
  575. Operation, FileObject, ReturnStatus, FileName
  576. Arguments:
  577. SequenceNumber - the sequence number for this log record
  578. Name - the name of the file that this operation relates to
  579. NameLength - the length of Name in bytes
  580. RecordFsFilterOp - the FsFilter operation record to print
  581. File - the file to print to
  582. Return Value:
  583. None.
  584. --*/
  585. {
  586. FILETIME localTime;
  587. SYSTEMTIME systemTime;
  588. WCHAR time[TIME_BUFFER_LENGTH];
  589. fprintf(File, "O\t%08X", SequenceNumber);
  590. //
  591. // Convert originating time
  592. //
  593. FileTimeToLocalFileTime( (FILETIME *)&(RecordFsFilterOp->OriginatingTime), &localTime );
  594. FileTimeToSystemTime( &localTime, &systemTime );
  595. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  596. fprintf( File, "\t%-12S", time );
  597. } else {
  598. fprintf( File, "\t%-12S", TIME_ERROR );
  599. }
  600. //
  601. // Convert completion time
  602. //
  603. FileTimeToLocalFileTime( (FILETIME *)&(RecordFsFilterOp->CompletionTime), &localTime );
  604. FileTimeToSystemTime( &localTime, &systemTime );
  605. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  606. fprintf( File, "\t%-12S", time );
  607. } else {
  608. fprintf( File, "\t%-12S", TIME_ERROR );
  609. }
  610. //
  611. // Output the process and thread id
  612. //
  613. fprintf( File, "\t%8x.%-4x ", RecordFsFilterOp->ProcessId, RecordFsFilterOp->ThreadId );
  614. //
  615. // Output the FsFilter operation parameters
  616. //
  617. PrintFsFilterOperation( RecordFsFilterOp->FsFilterOperation, File );
  618. fprintf( File, "\t%p", (PVOID)RecordFsFilterOp->DeviceObject );
  619. fprintf( File, "\t%p", (PVOID)RecordFsFilterOp->FileObject );
  620. fprintf( File, "\t%08lx", RecordFsFilterOp->ReturnStatus );
  621. fprintf( File, "\t%.*S", NameLength/sizeof(WCHAR), Name );
  622. fprintf( File, "\n" );
  623. }
  624. VOID
  625. FsFilterOperationScreenDump (
  626. ULONG SequenceNumber,
  627. PWCHAR Name,
  628. ULONG NameLength,
  629. PRECORD_FS_FILTER_OPERATION RecordFsFilterOp
  630. )
  631. /*++
  632. Routine Name:
  633. FsFilterOperationScreenDump
  634. Routine Description:
  635. Prints a FsFilterOperation log record to the screen in the following order:
  636. SequenceNumber, OriginatingTime, CompletionTime, ProcessId, ThreadId,
  637. Operation, FileObject, ReturnStatus, FileName
  638. Arguments:
  639. SequenceNumber - the sequence number for this log record
  640. Name - the file name to which this Irp relates
  641. NameLength - the length of name in bytes
  642. RecordFsFilterOp - the FsFilterOperation record to print
  643. Return Value:
  644. None.
  645. --*/
  646. {
  647. FILETIME localTime;
  648. SYSTEMTIME systemTime;
  649. WCHAR time[TIME_BUFFER_LENGTH];
  650. printf( "O %08X ", SequenceNumber );
  651. //
  652. // Convert originating time
  653. //
  654. FileTimeToLocalFileTime( (FILETIME *)&(RecordFsFilterOp->OriginatingTime), &localTime );
  655. FileTimeToSystemTime( &localTime, &systemTime );
  656. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  657. printf( "%-12S ", time );
  658. } else {
  659. printf( "%-12S ", TIME_ERROR );
  660. }
  661. //
  662. // Convert completion time
  663. //
  664. FileTimeToLocalFileTime( (FILETIME *)&(RecordFsFilterOp->CompletionTime), &localTime );
  665. FileTimeToSystemTime( &localTime, &systemTime );
  666. if (FormatSystemTime( &systemTime, time, TIME_BUFFER_LENGTH )) {
  667. printf( "%-12S ", time );
  668. } else {
  669. printf( "%-12S ", TIME_ERROR );
  670. }
  671. printf( "%8x.%-4x ", RecordFsFilterOp->ProcessId, RecordFsFilterOp->ThreadId );
  672. PrintFsFilterOperation( RecordFsFilterOp->FsFilterOperation, NULL );
  673. //
  674. // Print FsFilter operation specific values.
  675. //
  676. printf( "%p ", (PVOID)RecordFsFilterOp->DeviceObject );
  677. printf( "%p ", (PVOID)RecordFsFilterOp->FileObject );
  678. printf( "%08lx ", RecordFsFilterOp->ReturnStatus );
  679. printf( "%.*S", NameLength/sizeof(WCHAR),Name );
  680. printf( "\n" );
  681. }
  682. #endif