www.pudn.com > Ó²ÅÌµÄ¼à¿Ø.rar > fspyLog.c


 
/*++ 
 
Copyright (c) 1989-1999  Microsoft Corporation 
 
Module Name: 
 
    fspyLog.c 
 
Abstract: 
 
    This module contains functions used to retrieve and see the log records  
    recorded by filespy.sys. 
     
Author: 
 
    Molly Brown (MollyBro) 21-Apr-1999 
 
Environment: 
 
    User mode 
 
 
Revision History: 
 
--*/ 
#include  
#include  
#include  
#include  
#include "fspyLog.h" 
#include "filespy.h" 
 
#define TIME_BUFFER_LENGTH 20 
#define TIME_ERROR         "time error" 
 
DWORD WINAPI  
RetrieveLogRecords( 
    LPVOID lpParameter 
) 
{ 
    PLOG_CONTEXT   context = (PLOG_CONTEXT)lpParameter; 
    CHAR           buffer[BUFFER_SIZE]; 
    DWORD          bytesReturned = 0; 
    BOOL           bResult; 
    DWORD          result; 
    PLOG_RECORD    pLogRecord; 
  
    printf("Log: Starting up\n"); 
 
    while(TRUE){ 
        // 
        // Check to see if we should shut down 
        // 
        if (context->CleaningUp) { 
            break; 
        } 
 
        // 
        // Request log data from filespy 
        // 
        bResult = DeviceIoControl( context->Device, 
                                   FILESPY_GetLog, 
                                   NULL, 
                                   0, 
                                   buffer, 
                                   BUFFER_SIZE, 
                                   &bytesReturned, 
                                   NULL); 
        if (!bResult) { 
            result = GetLastError(); 
            printf("ERROR controlling device: 0x%x\n", result); 
        } 
 
        // 
        // buffer is filled with a series of LOG_RECORD structures, one 
        // right after another.  Each LOG_RECORD says how long it is, so 
        // we know where the next LOG_RECORD begins. 
        // 
        pLogRecord = (PLOG_RECORD) buffer; 
         
        // Logic to write record to screen and/or file 
        while((BYTE *) pLogRecord < buffer + bytesReturned){ 
            PRECORD_IRP     pRecordIrp; 
            PRECORD_FASTIO  pRecordFastIo; 
             
            // 
            // A LOG_RECORD could have Irp or FastIo data in it.  This 
            // is denoted in the low-order byte of the RecordType flag. 
            // 
            switch (GET_RECORD_TYPE(pLogRecord)) { 
            case RECORD_TYPE_IRP: 
                // 
                // We've got an Irp record, so output this data correctly. 
                // 
                pRecordIrp = &(pLogRecord->Record.RecordIrp); 
                if (context->LogToScreen) { 
                    IrpScreenDump( 
                        pLogRecord->SequenceNumber,  
                        pLogRecord->Name, 
                        pRecordIrp); 
                } 
                if (context->LogToFile) { 
                    IrpFileDump( 
                        pLogRecord->SequenceNumber, 
                        pLogRecord->Name, 
                        pRecordIrp,  
                        context->OutputFile); 
                } 
                break; 
 
            case RECORD_TYPE_FASTIO: 
                // 
                // We've got a FastIo record, so output this data correctly. 
                // 
                pRecordFastIo = &(pLogRecord->Record.RecordFastIo); 
                if (context->LogToScreen) { 
                    FastIoScreenDump( 
                        pLogRecord->SequenceNumber, 
                        pLogRecord->Name, 
                        pRecordFastIo); 
                } 
                if (context->LogToFile) { 
                    FastIoFileDump( 
                        pLogRecord->SequenceNumber, 
                        pLogRecord->Name, 
                        pRecordFastIo,  
                        context->OutputFile); 
                } 
                break; 
 
            default: 
                printf("Filmon:  Unknown log record type\n"); 
            } 
 
            // 
            // The RecordType could also designate that we are out of memory 
            // or hit our program defined memory limit, so check for these 
            // cases. 
            // 
            if (pLogRecord->RecordType & RECORD_TYPE_OUT_OF_MEMORY) { 
                if (context->LogToScreen) { 
                    printf("M %08X SYSTEM OUT OF MEMORY\n", 
                           pLogRecord->SequenceNumber); 
                } 
                if (context->LogToFile) { 
                    fprintf(context->OutputFile, 
                            "M:\t%u", 
                            pLogRecord->SequenceNumber); 
                } 
            } else if (pLogRecord->RecordType &  
                       RECORD_TYPE_EXCEED_MEMORY_ALLOWANCE) { 
                if (context->LogToScreen) { 
                    printf("M %08X EXCEEDED MEMORY ALLOWANCE\n", 
                           pLogRecord->SequenceNumber); 
                } 
                if (context->LogToFile) { 
                    fprintf(context->OutputFile, 
                            "M:\t%u", 
                            pLogRecord->SequenceNumber); 
                } 
            } 
            // 
            // Move to next LOG_RECORD 
            // 
            pLogRecord =  
                (PLOG_RECORD) (((BYTE *) pLogRecord) + pLogRecord->Length); 
        } 
         
        if (bytesReturned == 0) { 
            Sleep( 500 ); 
        } 
    } 
 
    printf("Log: Shutting down\n"); 
    ReleaseSemaphore(context->ShutDown, 1, NULL); 
    printf("Log: All done\n"); 
    return 0; 
} 
 
VOID 
PrintIrpCode( 
    UCHAR   MajorCode, 
    UCHAR   MinorCode, 
    FILE   *OutputFile, 
    BOOLEAN PrintMajorCode 
) 
{ 
    CHAR *irpMajorString, *irpMinorString = NULL; 
    CHAR formatBuf[128]; 
    CHAR errorBuf[128];  
 
    switch (MajorCode) { 
    case IRP_MJ_CREATE: 
        irpMajorString = IRP_MJ_CREATE_STRING; 
        break; 
    case IRP_MJ_CREATE_NAMED_PIPE: 
        irpMajorString = IRP_MJ_CREATE_NAMED_PIPE_STRING; 
        break; 
    case IRP_MJ_CLOSE: 
        irpMajorString = IRP_MJ_CLOSE_STRING; 
        break; 
    case IRP_MJ_READ: 
        irpMajorString = IRP_MJ_READ_STRING; 
        switch (MinorCode) { 
        case IRP_MN_NORMAL:  
            irpMinorString = IRP_MN_NORMAL_STRING; 
            break; 
        case IRP_MN_DPC:  
            irpMinorString = IRP_MN_DPC_STRING; 
            break; 
        case IRP_MN_MDL:  
            irpMinorString = IRP_MN_MDL_STRING; 
            break; 
        case IRP_MN_COMPLETE:  
            irpMinorString = IRP_MN_COMPLETE_STRING; 
            break; 
        case IRP_MN_COMPRESSED:  
            irpMinorString = IRP_MN_COMPRESSED_STRING; 
            break; 
        case IRP_MN_MDL_DPC: 
            irpMinorString = IRP_MN_MDL_DPC_STRING; 
            break; 
        case IRP_MN_COMPLETE_MDL: 
            irpMinorString = IRP_MN_COMPLETE_MDL_STRING; 
            break; 
        case IRP_MN_COMPLETE_MDL_DPC: 
            irpMinorString = IRP_MN_COMPLETE_MDL_DPC_STRING; 
            break; 
        default: 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
     
    case IRP_MJ_WRITE: 
        irpMajorString = IRP_MJ_WRITE_STRING; 
        switch (MinorCode) { 
        case IRP_MN_NORMAL:  
            irpMinorString = IRP_MN_NORMAL_STRING; 
            break; 
        case IRP_MN_DPC:  
            irpMinorString = IRP_MN_DPC_STRING; 
            break; 
        case IRP_MN_MDL:  
            irpMinorString = IRP_MN_MDL_STRING; 
            break; 
        case IRP_MN_COMPLETE:  
            irpMinorString = IRP_MN_COMPLETE_STRING; 
            break; 
        case IRP_MN_COMPRESSED:  
            irpMinorString = IRP_MN_COMPRESSED_STRING; 
            break; 
        case IRP_MN_MDL_DPC: 
            irpMinorString = IRP_MN_MDL_DPC_STRING; 
            break; 
        case IRP_MN_COMPLETE_MDL: 
            irpMinorString = IRP_MN_COMPLETE_MDL_STRING; 
            break; 
        case IRP_MN_COMPLETE_MDL_DPC: 
            irpMinorString = IRP_MN_COMPLETE_MDL_DPC_STRING; 
            break; 
        default: 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
     
    case IRP_MJ_QUERY_INFORMATION: 
        irpMajorString = IRP_MJ_QUERY_INFORMATION_STRING; 
        break; 
    case IRP_MJ_SET_INFORMATION: 
        irpMajorString = IRP_MJ_SET_INFORMATION_STRING; 
        break; 
    case IRP_MJ_QUERY_EA: 
        irpMajorString = IRP_MJ_QUERY_EA_STRING; 
        break; 
    case IRP_MJ_SET_EA: 
        irpMajorString = IRP_MJ_SET_EA_STRING; 
        break; 
    case IRP_MJ_FLUSH_BUFFERS: 
        irpMajorString = IRP_MJ_FLUSH_BUFFERS_STRING; 
        break; 
    case IRP_MJ_QUERY_VOLUME_INFORMATION: 
        irpMajorString = IRP_MJ_QUERY_VOLUME_INFORMATION_STRING; 
        break; 
    case IRP_MJ_SET_VOLUME_INFORMATION: 
        irpMajorString = IRP_MJ_SET_VOLUME_INFORMATION_STRING; 
        break; 
    case IRP_MJ_DIRECTORY_CONTROL: 
        irpMajorString = IRP_MJ_DIRECTORY_CONTROL_STRING; 
        switch (MinorCode) { 
        case IRP_MN_QUERY_DIRECTORY:  
            irpMinorString = IRP_MN_QUERY_DIRECTORY_STRING; 
            break; 
        case IRP_MN_NOTIFY_CHANGE_DIRECTORY:  
            irpMinorString = IRP_MN_NOTIFY_CHANGE_DIRECTORY_STRING; 
            break; 
        default: 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
     
    case IRP_MJ_FILE_SYSTEM_CONTROL: 
        irpMajorString = IRP_MJ_FILE_SYSTEM_CONTROL_STRING; 
        switch (MinorCode) { 
        case IRP_MN_USER_FS_REQUEST:  
            irpMinorString = IRP_MN_USER_FS_REQUEST_STRING; 
            break; 
        case IRP_MN_MOUNT_VOLUME:  
            irpMinorString = IRP_MN_MOUNT_VOLUME_STRING; 
            break; 
        case IRP_MN_VERIFY_VOLUME:  
            irpMinorString = IRP_MN_VERIFY_VOLUME_STRING; 
            break; 
        case IRP_MN_LOAD_FILE_SYSTEM:  
            irpMinorString = IRP_MN_LOAD_FILE_SYSTEM_STRING; 
            break; 
        case IRP_MN_TRACK_LINK:  
            irpMinorString = IRP_MN_TRACK_LINK_STRING; 
            break; 
        default: 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
     
    case IRP_MJ_DEVICE_CONTROL: 
        irpMajorString = IRP_MJ_DEVICE_CONTROL_STRING; 
        switch (MinorCode) { 
        case IRP_MN_SCSI_CLASS:  
            irpMinorString = IRP_MN_SCSI_CLASS_STRING; 
            break; 
        default: 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
     
    case IRP_MJ_INTERNAL_DEVICE_CONTROL: 
        irpMajorString = IRP_MJ_INTERNAL_DEVICE_CONTROL_STRING; 
        break; 
    case IRP_MJ_SHUTDOWN: 
        irpMajorString = IRP_MJ_SHUTDOWN_STRING; 
        break; 
    case IRP_MJ_LOCK_CONTROL: 
        irpMajorString = IRP_MJ_LOCK_CONTROL_STRING; 
        switch (MinorCode) { 
        case IRP_MN_LOCK:  
            irpMinorString = IRP_MN_LOCK_STRING; 
            break; 
        case IRP_MN_UNLOCK_SINGLE:  
            irpMinorString = IRP_MN_UNLOCK_SINGLE_STRING; 
            break; 
        case IRP_MN_UNLOCK_ALL:  
            irpMinorString = IRP_MN_UNLOCK_ALL_STRING; 
            break; 
        case IRP_MN_UNLOCK_ALL_BY_KEY:  
            irpMinorString = IRP_MN_UNLOCK_ALL_BY_KEY_STRING; 
            break; 
        default: 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
 
    case IRP_MJ_CLEANUP: 
        irpMajorString = IRP_MJ_CLEANUP_STRING; 
        break; 
    case IRP_MJ_CREATE_MAILSLOT: 
        irpMajorString = IRP_MJ_CREATE_MAILSLOT_STRING; 
        break; 
    case IRP_MJ_QUERY_SECURITY: 
        irpMajorString = IRP_MJ_QUERY_SECURITY_STRING; 
        break; 
    case IRP_MJ_SET_SECURITY: 
        irpMajorString = IRP_MJ_SET_SECURITY_STRING; 
        break; 
    case IRP_MJ_POWER: 
        irpMajorString = IRP_MJ_POWER_STRING; 
        switch (MinorCode) { 
        case IRP_MN_WAIT_WAKE:  
            irpMinorString = IRP_MN_WAIT_WAKE_STRING; 
            break; 
        case IRP_MN_POWER_SEQUENCE:  
            irpMinorString = IRP_MN_POWER_SEQUENCE_STRING; 
            break; 
        case IRP_MN_SET_POWER:  
            irpMinorString = IRP_MN_SET_POWER_STRING; 
            break; 
        case IRP_MN_QUERY_POWER:  
            irpMinorString = IRP_MN_QUERY_POWER_STRING; 
            break; 
        default : 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
 
    case IRP_MJ_SYSTEM_CONTROL: 
        irpMajorString = IRP_MJ_SYSTEM_CONTROL_STRING; 
        switch (MinorCode) { 
        case IRP_MN_QUERY_ALL_DATA:  
            irpMinorString = IRP_MN_QUERY_ALL_DATA_STRING; 
            break; 
        case IRP_MN_QUERY_SINGLE_INSTANCE:  
            irpMinorString = IRP_MN_QUERY_SINGLE_INSTANCE_STRING; 
            break; 
        case IRP_MN_CHANGE_SINGLE_INSTANCE:  
            irpMinorString = IRP_MN_CHANGE_SINGLE_INSTANCE_STRING; 
            break; 
        case IRP_MN_CHANGE_SINGLE_ITEM:  
            irpMinorString = IRP_MN_CHANGE_SINGLE_ITEM_STRING; 
            break; 
        case IRP_MN_ENABLE_EVENTS:  
            irpMinorString = IRP_MN_ENABLE_EVENTS_STRING; 
            break; 
        case IRP_MN_DISABLE_EVENTS:  
            irpMinorString = IRP_MN_DISABLE_EVENTS_STRING; 
            break; 
        case IRP_MN_ENABLE_COLLECTION:  
            irpMinorString = IRP_MN_ENABLE_COLLECTION_STRING; 
            break; 
        case IRP_MN_DISABLE_COLLECTION:  
            irpMinorString = IRP_MN_DISABLE_COLLECTION_STRING; 
            break; 
        case IRP_MN_REGINFO:  
            irpMinorString = IRP_MN_REGINFO_STRING; 
            break; 
        case IRP_MN_EXECUTE_METHOD:  
            irpMinorString = IRP_MN_EXECUTE_METHOD_STRING; 
            break; 
        default : 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
 
    case IRP_MJ_DEVICE_CHANGE: 
        irpMajorString = IRP_MJ_DEVICE_CHANGE_STRING; 
        break; 
    case IRP_MJ_QUERY_QUOTA: 
        irpMajorString = IRP_MJ_QUERY_QUOTA_STRING; 
        break; 
    case IRP_MJ_SET_QUOTA: 
        irpMajorString = IRP_MJ_SET_QUOTA_STRING; 
        break; 
    case IRP_MJ_PNP: 
        irpMajorString = IRP_MJ_PNP_STRING; 
        switch (MinorCode) { 
        case IRP_MN_START_DEVICE:  
            irpMinorString = IRP_MN_START_DEVICE_STRING; 
            break; 
        case IRP_MN_QUERY_REMOVE_DEVICE:  
            irpMinorString = IRP_MN_QUERY_REMOVE_DEVICE_STRING; 
            break; 
        case IRP_MN_REMOVE_DEVICE:  
            irpMinorString = IRP_MN_REMOVE_DEVICE_STRING; 
            break; 
        case IRP_MN_CANCEL_REMOVE_DEVICE:  
            irpMinorString = IRP_MN_CANCEL_REMOVE_DEVICE_STRING; 
            break; 
        case IRP_MN_STOP_DEVICE:  
            irpMinorString = IRP_MN_STOP_DEVICE_STRING; 
            break; 
        case IRP_MN_QUERY_STOP_DEVICE:  
            irpMinorString = IRP_MN_QUERY_STOP_DEVICE_STRING; 
            break; 
        case IRP_MN_CANCEL_STOP_DEVICE:  
            irpMinorString = IRP_MN_CANCEL_STOP_DEVICE_STRING; 
            break; 
        case IRP_MN_QUERY_DEVICE_RELATIONS:  
            irpMinorString = IRP_MN_QUERY_DEVICE_RELATIONS_STRING; 
            break; 
        case IRP_MN_QUERY_INTERFACE:  
            irpMinorString = IRP_MN_QUERY_INTERFACE_STRING; 
            break; 
        case IRP_MN_QUERY_CAPABILITIES:  
            irpMinorString = IRP_MN_QUERY_CAPABILITIES_STRING; 
            break; 
        case IRP_MN_QUERY_RESOURCES:  
            irpMinorString = IRP_MN_QUERY_RESOURCES_STRING; 
            break; 
        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:  
            irpMinorString = IRP_MN_QUERY_RESOURCE_REQUIREMENTS_STRING; 
            break; 
        case IRP_MN_QUERY_DEVICE_TEXT:  
            irpMinorString = IRP_MN_QUERY_DEVICE_TEXT_STRING; 
            break; 
        case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:  
            irpMinorString = IRP_MN_FILTER_RESOURCE_REQUIREMENTS_STRING; 
            break; 
        case IRP_MN_READ_CONFIG:  
            irpMinorString = IRP_MN_READ_CONFIG_STRING; 
            break; 
        case IRP_MN_WRITE_CONFIG:  
            irpMinorString = IRP_MN_WRITE_CONFIG_STRING; 
            break; 
        case IRP_MN_EJECT:  
            irpMinorString = IRP_MN_EJECT_STRING; 
            break; 
        case IRP_MN_SET_LOCK:  
            irpMinorString = IRP_MN_SET_LOCK_STRING; 
            break; 
        case IRP_MN_QUERY_ID:  
            irpMinorString = IRP_MN_QUERY_ID_STRING; 
            break; 
        case IRP_MN_QUERY_PNP_DEVICE_STATE:  
            irpMinorString = IRP_MN_QUERY_PNP_DEVICE_STATE_STRING; 
            break; 
        case IRP_MN_QUERY_BUS_INFORMATION:  
            irpMinorString = IRP_MN_QUERY_BUS_INFORMATION_STRING; 
            break; 
        case IRP_MN_DEVICE_USAGE_NOTIFICATION:  
            irpMinorString = IRP_MN_DEVICE_USAGE_NOTIFICATION_STRING; 
            break; 
        case IRP_MN_SURPRISE_REMOVAL:  
            irpMinorString = IRP_MN_SURPRISE_REMOVAL_STRING; 
            break; 
        case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:  
            irpMinorString = IRP_MN_QUERY_LEGACY_BUS_INFORMATION_STRING; 
            break; 
        default : 
            sprintf(errorBuf,"Unknown Irp minor code (%u)",MinorCode); 
            irpMinorString = errorBuf; 
        } 
        break; 
     
    default: 
        sprintf(errorBuf,"Unknown Irp major function (%u)",MajorCode); 
        irpMajorString = errorBuf; 
    } 
 
    if (OutputFile) { 
        if (irpMinorString) { 
            sprintf(formatBuf,"%s  %s",irpMajorString, irpMinorString); 
            fprintf(OutputFile, "\t%-50s", formatBuf); 
        } else { 
            fprintf(OutputFile, "\t%-50s", irpMajorString); 
        } 
    } else { 
        if (PrintMajorCode) { 
            printf("%-31s ", irpMajorString); 
        } else { 
            if (irpMinorString) { 
                printf("                                                   %-35s\n", 
                        irpMinorString); 
            } 
        } 
    } 
} 
 
VOID 
PrintFastIoType( 
    FASTIO_TYPE   Code, 
    FILE         *OutputFile 
) 
{ 
    CHAR *outputString; 
 
    switch (Code) { 
    case CHECK_IF_POSSIBLE: 
        outputString = CHECK_IF_POSSIBLE_STRING; 
        break; 
    case READ: 
        outputString = READ_STRING; 
        break; 
    case WRITE: 
        outputString = WRITE_STRING; 
        break; 
    case QUERY_BASIC_INFO: 
        outputString = QUERY_BASIC_INFO_STRING; 
        break; 
    case QUERY_STANDARD_INFO: 
        outputString = QUERY_STANDARD_INFO_STRING; 
        break; 
    case LOCK: 
        outputString = LOCK_STRING; 
        break; 
    case UNLOCK_SINGLE: 
        outputString = UNLOCK_SINGLE_STRING; 
        break; 
    case UNLOCK_ALL: 
        outputString = UNLOCK_ALL_STRING; 
        break; 
    case UNLOCK_ALL_BY_KEY: 
        outputString = UNLOCK_ALL_BY_KEY_STRING; 
        break; 
    case DEVICE_CONTROL: 
        outputString = DEVICE_CONTROL_STRING; 
        break; 
    case ACQUIRE_FILE: 
        outputString = ACQUIRE_FILE_STRING; 
        break; 
    case RELEASE_FILE: 
        outputString = RELEASE_FILE_STRING; 
        break; 
    case DETACH_DEVICE: 
        outputString = DETACH_DEVICE_STRING; 
        break; 
    case QUERY_NETWORK_OPEN_INFO: 
        outputString = QUERY_NETWORK_OPEN_INFO_STRING; 
        break; 
    case ACQUIRE_FOR_MOD_WRITE: 
        outputString = ACQUIRE_FOR_MOD_WRITE_STRING; 
        break; 
    case MDL_READ: 
        outputString = MDL_READ_STRING; 
        break; 
    case MDL_READ_COMPLETE: 
        outputString = MDL_READ_COMPLETE_STRING; 
        break; 
    case MDL_WRITE: 
        outputString = MDL_WRITE_STRING; 
        break; 
    case MDL_WRITE_COMPLETE: 
        outputString = MDL_WRITE_COMPLETE_STRING; 
        break; 
    case READ_COMPRESSED: 
        outputString = READ_COMPRESSED_STRING; 
        break; 
    case WRITE_COMPRESSED: 
        outputString = WRITE_COMPRESSED_STRING; 
        break; 
    case MDL_READ_COMPLETE_COMPRESSED: 
        outputString = MDL_READ_COMPLETE_COMPRESSED_STRING; 
        break; 
    case PREPARE_MDL_WRITE: 
        outputString = PREPARE_MDL_WRITE_STRING; 
        break; 
    case MDL_WRITE_COMPLETE_COMPRESSED: 
        outputString = MDL_WRITE_COMPLETE_COMPRESSED_STRING; 
        break; 
    case QUERY_OPEN: 
        outputString = QUERY_OPEN_STRING; 
        break; 
    case RELEASE_FOR_MOD_WRITE: 
        outputString = RELEASE_FOR_MOD_WRITE_STRING; 
        break; 
    case ACQUIRE_FOR_CC_FLUSH: 
        outputString = ACQUIRE_FOR_CC_FLUSH_STRING; 
        break; 
    case RELEASE_FOR_CC_FLUSH: 
        outputString = RELEASE_FOR_CC_FLUSH_STRING; 
        break; 
    default : 
        outputString = "Unknown Fast I/O type"; 
        break; 
    } 
 
    if (OutputFile) { 
        fprintf(OutputFile, "%-50s", outputString); 
    } else { 
        printf("%-31s ", outputString); 
    } 
} 
 
 
/*++ 
Routine Name: 
     
    FormatSystemTime 
 
Routine Description: 
 
    Formats the values in a SystemTime struct into the buffer  
    passed in.  The resulting string is NULL terminated.  The format 
    for the time is: 
        hours:minutes:seconds:milliseconds 
     
Arguments: 
 
    SystemTime - the struct to format 
    Buffer - the buffer to place the formatted time in 
    BufferLength - the size of the buffer 
 
Return Value: 
 
    The length of the string returned in Buffer. 
 
--*/ 
ULONG 
FormatSystemTime( 
    SYSTEMTIME *SystemTime, 
    CHAR       *Buffer, 
    ULONG       BufferLength 
) 
{ 
    CHAR  *writePosition; 
    ULONG  returnLength = 0; 
 
    writePosition = Buffer; 
 
    if (BufferLength < TIME_BUFFER_LENGTH) { 
        // Buffer is too short so exit 
        return 0; 
    } 
 
    returnLength = sprintf( 
        Buffer,  
        "%02d:%02d:%02d:%03d",  
        SystemTime->wHour, 
        SystemTime->wMinute, 
        SystemTime->wSecond, 
        SystemTime->wMilliseconds); 
 
    return returnLength; 
} 
 
/*++ 
Routine Name: 
     
    IrpFileDump 
 
Routine Description: 
 
    Prints a Irp log record to the specified file.  The output is in a tab 
    delimited format with the fields in the following order: 
     
    SequenceNumber, OriginatingTime, CompletionTime, IrpMajor, IrpMinor, 
    IrpFlags, NoCache, Paging I/O, Synchronous, Synchronous paging, FileName, 
    ReturnStatus, FileName 
     
     
Arguments: 
 
    SequenceNumber - the sequence number for this log record 
    Name - the name of the file that this Irp relates to 
    RecordIrp - the Irp record to print 
    File - the file to print to 
 
Return Value: 
 
    None. 
 
--*/ 
VOID 
IrpFileDump( 
    ULONG       SequenceNumber, 
    WCHAR      *Name, 
    PRECORD_IRP RecordIrp, 
    FILE       *File 
) 
{ 
    FILETIME    localTime; 
    SYSTEMTIME  systemTime; 
    CHAR        time[TIME_BUFFER_LENGTH]; 
 
    fprintf(File, "I\t%08X", SequenceNumber); 
 
    // Convert originating time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordIrp->OriginatingTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime,  
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        fprintf(File, "\t%-12s", time); 
    } else { 
        fprintf(File, "\t%-12s", TIME_ERROR); 
    } 
 
    // Convert completion time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordIrp->CompletionTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime,  
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        fprintf(File, "\t%-12s", time); 
    } else { 
        fprintf(File, "\t%-12s", TIME_ERROR); 
    } 
 
    fprintf(File, "\t%8x.%-4x ", RecordIrp->ProcessId, RecordIrp->ThreadId); 
 
    PrintIrpCode(RecordIrp->IrpMajor, RecordIrp->IrpMinor, File, TRUE); 
 
    // Interpret set flags 
    fprintf(File, "\t%08lx ", RecordIrp->IrpFlags); 
    fprintf(File, 
        "%s",  
        (RecordIrp->IrpFlags & IRP_NOCACHE) ? "N":"-"); 
    fprintf(File, 
        "%s",  
        (RecordIrp->IrpFlags & IRP_PAGING_IO) ? "P":"-"); 
    fprintf(File, 
        "%s",  
        (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_API) ? "S":"-"); 
    fprintf(File, 
        "%s",  
        (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) ? "Y":"-"); 
 
    fprintf(File, "\t%08p", RecordIrp->FileObject); 
    fprintf(File, "\t%08lx:%08lx",  
            RecordIrp->ReturnStatus,  
            RecordIrp->ReturnInformation); 
    fprintf(File, "\t%S", Name); 
    fprintf(File, "\n"); 
} 
 
/*++ 
Routine Name: 
     
    IrpScreenDump 
 
Routine Description: 
 
    Prints a Irp log record to the screen in the following order: 
    SequenceNumber, OriginatingTime, CompletionTime, IrpMajor, IrpMinor,  
    IrpFlags, NoCache, Paging I/O, Synchronous, Synchronous paging,  
    FileName, ReturnStatus, FileName 
     
Arguments: 
 
    SequenceNumber - the sequence number for this log record 
    Name - the file name to which this Irp relates 
    RecordIrp - the Irp record to print 
 
Return Value: 
 
    None. 
 
--*/ 
VOID 
IrpScreenDump( 
    ULONG       SequenceNumber, 
    WCHAR      *Name, 
    PRECORD_IRP RecordIrp 
) 
{ 
    FILETIME    localTime; 
    SYSTEMTIME  systemTime; 
    CHAR        time[TIME_BUFFER_LENGTH]; 
 
    printf("I %08X ", SequenceNumber); 
 
    // Convert originating time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordIrp->OriginatingTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime, 
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        printf("%-12s ", time); 
    } else { 
        printf("%-12s ", TIME_ERROR); 
    } 
 
    // Convert completion time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordIrp->CompletionTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime, 
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        printf("%-12s ", time); 
    } else { 
        printf("%-12s ", TIME_ERROR); 
    } 
 
    printf("%8x.%-4x ", RecordIrp->ProcessId, RecordIrp->ThreadId); 
 
    PrintIrpCode(RecordIrp->IrpMajor, RecordIrp->IrpMinor, NULL, TRUE); 
 
    // Interpret set flags 
    printf("%08lx ", RecordIrp->IrpFlags); 
    printf( 
        "%s",  
        (RecordIrp->IrpFlags & IRP_NOCACHE) ? "N":"-"); 
    printf( 
        "%s",  
        (RecordIrp->IrpFlags & IRP_PAGING_IO) ? "P":"-"); 
    printf( 
        "%s",  
        (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_API) ? "S":"-"); 
    printf( 
        "%s ",  
        (RecordIrp->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) ? "Y":"-"); 
     
    printf("%08p ", RecordIrp->FileObject); 
    printf("%08lx:%08lx ",  
           RecordIrp->ReturnStatus, 
           RecordIrp->ReturnInformation); 
    printf("%S", Name); 
    printf("\n"); 
    PrintIrpCode(RecordIrp->IrpMajor, RecordIrp->IrpMinor, NULL, FALSE); 
} 
 
/*++ 
Routine Name: 
     
    FastIoFileDump 
 
Routine Description: 
 
    Prints a FastIo log record to the specified file.  The output is in a tab 
    delimited format with the fields in the following order: 
    SequenceNumber, StartTime, CompletionTime, Fast I/O Type, FileName,  
    Length, Wait, ReturnStatus, FileName 
     
Arguments: 
 
    SequenceNumber - the sequence number for this log record 
    Name - the name of the file referenced by this Fast I/O operation 
    RecordFastIo - the FastIo record to print 
    File - the file to print to 
 
Return Value: 
 
    None. 
 
--*/ 
VOID 
FastIoFileDump( 
    ULONG          SequenceNumber, 
    WCHAR         *Name, 
    PRECORD_FASTIO RecordFastIo, 
    FILE          *File 
) 
{ 
    SYSTEMTIME     systemTime; 
    FILETIME       localTime; 
    CHAR           time[TIME_BUFFER_LENGTH]; 
 
    fprintf(File, "F\t%08X", SequenceNumber); 
 
    // Convert start time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordFastIo->StartTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime, 
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        fprintf(File, "\t%-12s", time); 
    } else { 
        fprintf(File, "\t%-12s", TIME_ERROR); 
    } 
 
    // Convert completion time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordFastIo->CompletionTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime, 
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        fprintf(File, "\t%-12s", time); 
    } else { 
        fprintf(File, "\t%-12s", TIME_ERROR); 
    } 
 
    fprintf(File, "\t%8x.%-4x ", RecordFastIo->ProcessId, RecordFastIo->ThreadId); 
 
    fprintf(File, "\t"); 
    PrintFastIoType(RecordFastIo->Type, File); 
 
    fprintf(File, "\t%s", (RecordFastIo->Wait)?"T":"F"); 
    fprintf(File, "\t%08x", RecordFastIo->Length); 
    fprintf(File, "\t%016I64x ", RecordFastIo->FileOffset); 
 
    fprintf(File, "\t%08p", RecordFastIo->FileObject); 
    fprintf(File, "\t%08x", RecordFastIo->ReturnStatus); 
    fprintf(File, "\t%S", Name); 
    fprintf(File, "\n"); 
} 
 
/*++ 
Routine Name: 
     
    FastIoScreenDump 
 
Routine Description: 
 
    Prints a FastIo log record to the screen in the following order: 
    SequenceNumber, StartTime, CompletionTime, Fast I/O Type, FileName,  
    Length, Wait, ReturnStatus, FileName 
     
Arguments: 
 
    SequenceNumber - the sequence number for this log record 
    Name - the name of the file referenced by this Fast I/O operation 
    RecordIrp - the Irp record to print 
 
Return Value: 
 
    None. 
 
--*/ 
VOID 
FastIoScreenDump( 
    ULONG          SequenceNumber, 
    WCHAR         *Name, 
    PRECORD_FASTIO RecordFastIo 
) 
{ 
    SYSTEMTIME  systemTime; 
    FILETIME    localTime; 
    CHAR        time[TIME_BUFFER_LENGTH]; 
 
    printf("F %08X ", SequenceNumber); 
     
    // Convert start time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordFastIo->StartTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime, 
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        printf("%-12s ", time); 
    } else { 
        printf("%-12s ", TIME_ERROR); 
    } 
 
    // Convert completion time 
    FileTimeToLocalFileTime( 
        (FILETIME *)&(RecordFastIo->CompletionTime), 
        &localTime); 
    FileTimeToSystemTime( 
        &localTime, 
        &systemTime); 
    if (FormatSystemTime(&systemTime, time, TIME_BUFFER_LENGTH)) { 
        printf("%-12s ", time); 
    } else { 
        printf("%-12s ", TIME_ERROR); 
    } 
 
    printf("%8x.%-4x ", RecordFastIo->ProcessId, RecordFastIo->ThreadId); 
 
    PrintFastIoType(RecordFastIo->Type, NULL); 
 
    printf("%s ", (RecordFastIo->Wait)?"T":"F"); 
    printf("%08x ", RecordFastIo->Length); 
    printf("%016I64x ", RecordFastIo->FileOffset); 
 
    printf("%08p ", RecordFastIo->FileObject); 
    printf("%08x ", RecordFastIo->ReturnStatus); 
    printf("%S", Name); 
    printf("\n"); 
}