|
|
#include "global.h"
#include "protos.h"
#include "filespyview.h"
#include "fastioview.h"
#include "fsfilterview.h"
#include "leftview.h"
#include "filespyLib.h"
void DisplayIrpFields(CFileSpyView *pView, PLOG_RECORD pLog); void DisplayFastIoFields(CFastIoView *pView, PLOG_RECORD pLog); void DisplayFsFilterFields(CFsFilterView *pView, PLOG_RECORD pLog);
DWORD StartFileSpy(void) {
DWORD nBytesNeeded; CLeftView *pDriveView;
pDriveView = (CLeftView *) pLeftView;
// Open Service control manager
hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS) ;
hService = OpenServiceW(hSCManager, FILESPY_SERVICE_NAME, FILESPY_SERVICE_ACCESS); if (hService == NULL) { DisplayError(GetLastError()); return 0; }
if (!QueryServiceStatusEx( hService, SC_STATUS_PROCESS_INFO, (UCHAR *)&ServiceInfo, sizeof(ServiceInfo), &nBytesNeeded)) { DisplayError(GetLastError()); CloseServiceHandle(hSCManager); CloseServiceHandle(hService); MessageBox(NULL, L"Unable to query Service status information", L"Startup Error", MB_OK|MB_ICONEXCLAMATION); return 0; }
if(ServiceInfo.dwCurrentState != SERVICE_RUNNING) { //
// Service hasn't been started yet, so try to start service
//
if (!StartService(hService, 0, NULL)) { CloseServiceHandle(hSCManager); CloseServiceHandle(hService); MessageBox(NULL, L"Unable to start service", L"Startup Error", MB_OK|MB_ICONSTOP); return 0; } } //
// Open the device that is used to talk to FileSpy.
//
hDevice = CreateFile( FILESPY_W32_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hDevice == INVALID_HANDLE_VALUE) { CloseServiceHandle(hSCManager); CloseServiceHandle(hService); MessageBox(NULL, L"Unable to open FileSpy device", L"Device Error", MB_OK|MB_ICONSTOP); return 0; }
QueryDeviceAttachments(); pDriveView->UpdateImage();
// Create the polling thread
hPollThread = CreateThread(NULL, 0, PollFileSpy, NULL, 0, &nPollThreadId);
return 1; }
DWORD ShutdownFileSpy(void) { USHORT ti;
for (ti = 0; ti < nTotalDrives; ti++) { if (VolInfo[ti].bHook) { DetachFromDrive( VolInfo[ti].nDriveName ); } } CloseHandle(hDevice); CloseServiceHandle(hService); CloseServiceHandle(hSCManager); return 1; }
BOOL QueryDeviceAttachments(void) { WCHAR Buffer[BUFFER_SIZE]; ULONG nBytesReturned; BOOL nReturnValue; USHORT ti; PATTACHED_DEVICE pDevice;
nReturnValue = DeviceIoControl(hDevice, FILESPY_ListDevices, NULL, 0, Buffer, sizeof( Buffer ), &nBytesReturned, NULL);
if (nReturnValue && nBytesReturned) { pDevice = (PATTACHED_DEVICE) Buffer; while ( ((char *)pDevice) < (((char *)Buffer) + nBytesReturned)) { if (pDevice->LoggingOn) { //
// Locate this drive in VolInfo and set its attachment status
//
for (ti = 0; ti < nTotalDrives; ti++) { if (VolInfo[ti].nDriveName == towupper( pDevice->DeviceNames[0] )) { VolInfo[ti].bHook = 1; VolInfo[ti].nImage += IMAGE_ATTACHSTART; } } } pDevice++; } } return nReturnValue; }
DWORD AttachToDrive(WCHAR cDriveName) { WCHAR sDriveString[5]; DWORD nResult, nBytesReturned;
wcscpy(sDriveString, L" :\0"); sDriveString[0] = cDriveName;
nResult = DeviceIoControl( hDevice, FILESPY_StartLoggingDevice, sDriveString, sizeof( sDriveString), NULL, 0, &nBytesReturned, NULL); if (!nResult) { DisplayError(GetLastError()); return 0; } return 1; }
DWORD DetachFromDrive(WCHAR cDriveName) { WCHAR sDriveString[5]; DWORD nResult, nBytesReturned;
wcscpy(sDriveString, L" :\0"); sDriveString[0] = cDriveName;
nResult = DeviceIoControl( hDevice, FILESPY_StopLoggingDevice, sDriveString, sizeof(sDriveString), NULL, 0, &nBytesReturned, NULL ); if (!nResult) { DisplayError(GetLastError()); return 0; } return 1; }
DWORD WINAPI PollFileSpy(LPVOID pParm) { char pBuffer[BUFFER_SIZE]; DWORD nBytesReturned, nResult; PLOG_RECORD pLog; CFileSpyView *pIrpView; CFastIoView *pFastView; CFsFilterView *pFilterView;
UNREFERENCED_PARAMETER( pParm ); pIrpView = (CFileSpyView *) pSpyView; pFastView = (CFastIoView *) pFastIoView; pFilterView = (CFsFilterView *) pFsFilterView; while (1) { //
// Start receiving log
//
nResult = DeviceIoControl(hDevice, FILESPY_GetLog, NULL, 0, pBuffer, \ BUFFER_SIZE, &nBytesReturned, NULL);
if (nResult) {
if (nBytesReturned > 0) { pLog = (PLOG_RECORD) pBuffer;
while ((CHAR *) pLog < pBuffer + nBytesReturned) {
switch (GET_RECORD_TYPE(pLog)) { case RECORD_TYPE_IRP: DisplayIrpFields(pIrpView, pLog); break; case RECORD_TYPE_FASTIO: DisplayFastIoFields(pFastView, pLog); break; case RECORD_TYPE_FS_FILTER_OP: DisplayFsFilterFields(pFilterView, pLog); break; default: //
// Special handling required
break; }
//
// Move to the next LogRecord
//
pLog = (PLOG_RECORD) (((CHAR *) pLog) + pLog->Length); } } else { Sleep( 500 ); } } else {
return 1;
} } return 1; }
void DisplayIrpFields(CFileSpyView *pView, PLOG_RECORD pLog) { INT nItem; CHAR cStr[NAME_SIZE], cMnStr[NAME_SIZE]; WCHAR sStr[NAME_SIZE], sMnStr[NAME_SIZE]; ULONG nameLength;
if (IRPFilter[pLog->Record.RecordIrp.IrpMajor] == 0) { return; } else { if (nSuppressPagingIO && (pLog->Record.RecordIrp.IrpFlags & IRP_PAGING_IO || pLog->Record.RecordIrp.IrpFlags & IRP_SYNCHRONOUS_PAGING_IO)) { return; } }
nItem = pView->GetListCtrl().GetItemCount();
//
// nItem is 1 based but when we insert/delete items ListCtrl takes 0 based parameter
// so automatically nItem gives an insertion number which is the last item
//
pView->GetListCtrl().InsertItem( nItem,L" " ); pView->GetListCtrl().EnsureVisible( nItem, FALSE );
//
// Sequence number
//
swprintf( sStr, L"%06X ", pLog->SequenceNumber ); pView->GetListCtrl().SetItemText( nItem, 0, sStr ); //
// Irp major and minor strings
//
GetIrpName( pLog->Record.RecordIrp.IrpMajor, pLog->Record.RecordIrp.IrpMinor, (ULONG)(ULONG_PTR)pLog->Record.RecordIrp.Argument3, cStr, cMnStr); MultiByteToWideChar(CP_ACP,0,cStr,-1,sStr,sizeof(sStr)/sizeof(WCHAR)); MultiByteToWideChar(CP_ACP,0,cMnStr,-1,sMnStr,sizeof(sStr)/sizeof(WCHAR));
pView->GetListCtrl().SetItemText( nItem, 1, sStr); pView->GetListCtrl().SetItemText( nItem, 2, sMnStr); //
// FileObject
//
swprintf( sStr, L"%08X", pLog->Record.RecordIrp.FileObject ); pView->GetListCtrl().SetItemText( nItem, 3, sStr );
//
// FileName
//
nameLength = pLog->Length - SIZE_OF_LOG_RECORD; swprintf( sStr, L"%.*s", nameLength/sizeof(WCHAR), pLog->Name ); pView->GetListCtrl().SetItemText( nItem, 4, sStr );
//
// Process and thread ids
//
swprintf( sStr, L"%08X:%08X", pLog->Record.RecordIrp.ProcessId, pLog->Record.RecordIrp.ThreadId ); pView->GetListCtrl().SetItemText( nItem, 5, sStr );
//
// Originating time
//
GetTimeString( (FILETIME *) &pLog->Record.RecordIrp.OriginatingTime, sStr ); pView->GetListCtrl().SetItemText( nItem, 6, sStr );
//
// Completion time
//
GetTimeString( (FILETIME *) &pLog->Record.RecordIrp.CompletionTime, sStr ); pView->GetListCtrl().SetItemText( nItem, 7, sStr );
//
// Irp flags
//
GetFlagsString( pLog->Record.RecordIrp.IrpFlags, sStr ); pView->GetListCtrl().SetItemText( nItem, 8, sStr );
//
// Sequence number
//
swprintf( sStr, L"%08lX:%08lX", pLog->Record.RecordIrp.ReturnStatus, pLog->Record.RecordIrp.ReturnInformation); pView->GetListCtrl().SetItemText( nItem, 9, sStr ); }
void DisplayFastIoFields(CFastIoView *pView, PLOG_RECORD pLog) { INT nItem; CHAR cStr[NAME_SIZE]; WCHAR sStr[NAME_SIZE]; ULONG nameLength;
if (FASTIOFilter[pLog->Record.RecordFastIo.Type] == 0) { return; }
nItem = pView->GetListCtrl().GetItemCount();
//
// nItem is 1 based but when we insert/delete items ListCtrl takes 0 based parameter
// so automatically nItem gives an insertion number which is the last item
//
pView->GetListCtrl().InsertItem( nItem, L" " ); pView->GetListCtrl().EnsureVisible( nItem, FALSE );
//
// Sequence number
//
swprintf( sStr, L"%06X ", pLog->SequenceNumber ); pView->GetListCtrl().SetItemText( nItem, 0, sStr );
//
// Fast IO type
//
GetFastioName( pLog->Record.RecordFastIo.Type, cStr ); MultiByteToWideChar(CP_ACP,0,cStr,-1,sStr,sizeof(sStr)/sizeof(WCHAR));
pView->GetListCtrl().SetItemText( nItem, 1, sStr );
//
// FileObject
//
swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.FileObject) ; pView->GetListCtrl().SetItemText( nItem, 2, sStr );
//
// File name
//
nameLength = pLog->Length - SIZE_OF_LOG_RECORD; swprintf( sStr, L"%.*s", nameLength/sizeof(WCHAR), pLog->Name ); pView->GetListCtrl().SetItemText( nItem, 3, sStr );
//
// File offset
//
swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.FileOffset ); pView->GetListCtrl().SetItemText( nItem, 4, sStr );
//
// File length
//
swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.Length ); pView->GetListCtrl().SetItemText( nItem, 5, sStr ); //
// Fast IO can wait
//
if (pLog->Record.RecordFastIo.Wait) { pView->GetListCtrl().SetItemText(nItem, 6, L"True"); } else { pView->GetListCtrl().SetItemText(nItem, 6, L"False"); } //
// Thread and process ids
//
swprintf( sStr, L"%08X:%08X", pLog->Record.RecordFastIo.ProcessId, pLog->Record.RecordFastIo.ThreadId ); pView->GetListCtrl().SetItemText( nItem, 7, sStr );
//
// Start time
//
GetTimeString( (FILETIME *) &pLog->Record.RecordFastIo.StartTime, sStr); pView->GetListCtrl().SetItemText( nItem, 8, sStr );
//
// Completion time
//
GetTimeString( (FILETIME *) &pLog->Record.RecordFastIo.CompletionTime, sStr ); pView->GetListCtrl().SetItemText( nItem, 9, sStr );
//
// Return status
//
swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.ReturnStatus ); pView->GetListCtrl().SetItemText( nItem, 10, sStr ); }
void DisplayFsFilterFields(CFsFilterView *pView, PLOG_RECORD pLog) { INT nItem; CHAR cStr[NAME_SIZE]; WCHAR sStr[NAME_SIZE]; ULONG nameLength;
nItem = pView->GetListCtrl().GetItemCount();
//
// nItem is 1 based but when we insert/delete items ListCtrl takes 0 based parameter
// so automatically nItem gives an insertion number which is the last item
//
pView->GetListCtrl().InsertItem( nItem, L" " ); pView->GetListCtrl().EnsureVisible( nItem, FALSE );
//
// Sequence number
//
swprintf( sStr, L"%06X ", pLog->SequenceNumber ); pView->GetListCtrl().SetItemText( nItem, 0, sStr );
//
// Fs Filter operation
//
GetFsFilterOperationName( pLog->Record.RecordFsFilterOp.FsFilterOperation, cStr ); MultiByteToWideChar(CP_ACP,0,cStr,-1,sStr,sizeof(sStr)/sizeof(WCHAR));
pView->GetListCtrl().SetItemText( nItem, 1, sStr );
//
// FileObject
//
swprintf( sStr, L"%08X", pLog->Record.RecordFsFilterOp.FileObject ); pView->GetListCtrl().SetItemText( nItem, 2, sStr );
//
// File name
//
nameLength = pLog->Length - SIZE_OF_LOG_RECORD; swprintf( sStr, L"%.*s", nameLength/sizeof(WCHAR), pLog->Name ); pView->GetListCtrl().SetItemText( nItem, 3, sStr );
//
// Process and thread id
//
swprintf( sStr, L"%08X:%08X", pLog->Record.RecordFsFilterOp.ProcessId, pLog->Record.RecordFsFilterOp.ThreadId ); pView->GetListCtrl().SetItemText( nItem, 4, sStr );
//
// Originating time
//
GetTimeString( (FILETIME *) &pLog->Record.RecordFsFilterOp.OriginatingTime, sStr ); pView->GetListCtrl().SetItemText( nItem, 5, sStr );
//
// Completion time
//
GetTimeString( (FILETIME *) &pLog->Record.RecordFsFilterOp.CompletionTime, sStr ); pView->GetListCtrl().SetItemText( nItem, 6, sStr );
//
// Return status
//
swprintf( sStr, L"%08X", pLog->Record.RecordFsFilterOp.ReturnStatus ); pView->GetListCtrl().SetItemText( nItem, 7, sStr ); }
void GetFlagsString(DWORD nFlags, PWCHAR sStr) {
swprintf(sStr, L"%08lX ", nFlags); if (nFlags & IRP_NOCACHE) { wcscat( sStr, L"NOCACHE "); } if (nFlags & IRP_PAGING_IO) { wcscat(sStr, L"PAGEIO "); } if (nFlags & IRP_SYNCHRONOUS_API) { wcscat(sStr, L"SYNCAPI "); } if (nFlags & IRP_SYNCHRONOUS_PAGING_IO) { wcscat(sStr, L"SYNCPAGEIO"); } }
void GetTimeString(FILETIME *pFileTime, PWCHAR sStr) { FILETIME LocalFileTime; SYSTEMTIME SystemTime;
FileTimeToLocalFileTime(pFileTime, &LocalFileTime); FileTimeToSystemTime(&LocalFileTime, &SystemTime);
swprintf( sStr, L"%02d:%02d:%02d:%03d", SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds); }
|