892 lines
21 KiB
C++
892 lines
21 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1999 - 2000
|
|
//
|
|
// File: filedata.cpp
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
// FileData.cpp: implementation of the CFileData class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#ifndef NO_STRICT
|
|
#ifndef STRICT
|
|
#define STRICT 1
|
|
#endif
|
|
#endif /* NO_STRICT */
|
|
|
|
#include <WINDOWS.H>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <wtypes.h>
|
|
#include <winnt.h>
|
|
|
|
#include <time.h>
|
|
#include "FileData.h"
|
|
#include "Globals.h"
|
|
#include "Version.h"
|
|
#include "Processes.h"
|
|
#include "ProcessInfo.h"
|
|
#include "Modules.h"
|
|
#include "UtilityFunctions.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CFileData::CFileData()
|
|
{
|
|
m_dwGetLastError = 0;
|
|
m_hFileHandle = INVALID_HANDLE_VALUE;
|
|
m_tszFilePath = NULL;
|
|
m_szLINEBUFFER[0] = 0;
|
|
m_hFileMappingObject = NULL;
|
|
m_lpBaseAddress = NULL;
|
|
m_lpCurrentFilePointer = NULL;
|
|
m_lpCurrentLocationInLINEBUFFER = NULL;
|
|
}
|
|
|
|
CFileData::~CFileData()
|
|
{
|
|
if (m_tszFilePath)
|
|
delete [] m_tszFilePath;
|
|
|
|
if (m_lpBaseAddress)
|
|
UnmapViewOfFile(m_lpBaseAddress);
|
|
|
|
if (m_hFileMappingObject)
|
|
CloseHandle(m_hFileMappingObject);
|
|
}
|
|
|
|
bool CFileData::SetFilePath(LPTSTR tszFilePath)
|
|
{
|
|
// Did we get a proper string?
|
|
if (!tszFilePath)
|
|
return false;
|
|
|
|
if (m_tszFilePath)
|
|
delete [] m_tszFilePath;
|
|
|
|
m_tszFilePath = new TCHAR[(_tcsclen(tszFilePath)+1)];
|
|
|
|
if (!m_tszFilePath)
|
|
return false;
|
|
|
|
_tcscpy(m_tszFilePath, tszFilePath);
|
|
return true;
|
|
}
|
|
|
|
LPTSTR CFileData::GetFilePath()
|
|
{
|
|
return m_tszFilePath;
|
|
}
|
|
|
|
bool CFileData::VerifyFileDirectory()
|
|
{
|
|
if (!m_tszFilePath)
|
|
return false;
|
|
|
|
TCHAR tszDrive[_MAX_DRIVE];
|
|
TCHAR tszDirectory[_MAX_DIR];
|
|
|
|
TCHAR tszDirectoryPath[_MAX_PATH];
|
|
|
|
// Get just the directory...
|
|
_tsplitpath(m_tszFilePath, tszDrive, tszDirectory, NULL, NULL);
|
|
|
|
// Now, recompose this into a directory path...
|
|
_tcscpy(tszDirectoryPath, tszDrive);
|
|
_tcscat(tszDirectoryPath, tszDirectory);
|
|
_tcscat(tszDirectoryPath, TEXT("*.*"));
|
|
|
|
WIN32_FIND_DATA FindFileData;
|
|
|
|
HANDLE hDirectoryHandle = FindFirstFile(tszDirectoryPath, &FindFileData);
|
|
|
|
if (hDirectoryHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
// Failure to find the directory...
|
|
SetLastError();
|
|
return false;
|
|
}
|
|
|
|
// Close this now that we're done...
|
|
FindClose(hDirectoryHandle);
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
DWORD CFileData::GetLastError()
|
|
{
|
|
return m_dwGetLastError;
|
|
}
|
|
*/
|
|
bool CFileData::OpenFile(DWORD dwCreateOption, bool fReadOnlyMode)
|
|
{
|
|
if (!m_tszFilePath)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Open the file for read/write
|
|
m_hFileHandle = CreateFile(m_tszFilePath,
|
|
fReadOnlyMode ? ( GENERIC_READ )
|
|
: ( GENERIC_READ | GENERIC_WRITE ),
|
|
0, // Not shareable
|
|
NULL, // Default security descriptor
|
|
dwCreateOption,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
if (m_hFileHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
SetLastError();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::CloseFile()
|
|
{
|
|
if (m_hFileHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!CloseHandle(m_hFileHandle))
|
|
{
|
|
SetLastError();
|
|
return false;
|
|
}
|
|
|
|
m_hFileHandle = INVALID_HANDLE_VALUE;
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::WriteString(LPTSTR tszString, bool fHandleQuotes /* = false */)
|
|
{
|
|
DWORD dwByteCount = 0;
|
|
DWORD dwBytesWritten;
|
|
LPSTR szStringBuffer = NULL; // Pointer to the ANSI string (after conversion if necessary)
|
|
bool fReturn = false;
|
|
|
|
if (m_hFileHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
// We'll first convert the string if we need to...
|
|
|
|
szStringBuffer = CUtilityFunctions::CopyTSTRStringToAnsi(tszString);
|
|
|
|
if (!szStringBuffer)
|
|
goto cleanup;
|
|
|
|
dwByteCount = _tcsclen(tszString); // This is the number of characters (not bytes!)
|
|
|
|
// See if we were asked to handle quotes, and if there exists a comma or quote in the string
|
|
if ( fHandleQuotes == true && ((strchr(szStringBuffer, ',') || strchr(szStringBuffer, '"' ))) )
|
|
{
|
|
unsigned int iQuotedStringIndex = 0;
|
|
unsigned int iStringBufferIndex = 0;
|
|
|
|
// Special processing is required... this doesn't happen often, so this
|
|
// allocation which I'm about to make won't be done regularly...
|
|
LPSTR szQuotedStringBuffer = new char[1024];
|
|
|
|
// Did we successfully allocate storage?
|
|
if (!szQuotedStringBuffer)
|
|
goto cleanup;
|
|
|
|
// Keep going until we're at the end of the string...
|
|
|
|
// We start by adding a quote (since we know that we have a comma or quote somewhere...
|
|
|
|
szQuotedStringBuffer[iQuotedStringIndex++] = '\"';
|
|
|
|
// Keep going until the end of the string...
|
|
while (szStringBuffer[iStringBufferIndex] != '\0')
|
|
{
|
|
// We found a quote
|
|
if (szStringBuffer[iStringBufferIndex] == '"')
|
|
{
|
|
// We found a quote... I'll copy another quote in, and the quote already here
|
|
// will ensure we have two quotes together "" which in a CSV file represents a
|
|
// single quote...
|
|
szQuotedStringBuffer[iQuotedStringIndex++] = '\"';
|
|
}
|
|
|
|
// Copy the source char to the dest...
|
|
szQuotedStringBuffer[iQuotedStringIndex++] = szStringBuffer[iStringBufferIndex++];
|
|
}
|
|
|
|
// Append the final quote (and \0)...
|
|
szQuotedStringBuffer[iQuotedStringIndex++] = '\"';
|
|
szQuotedStringBuffer[iQuotedStringIndex++] = '\0';
|
|
|
|
// Just write out the data the nice, fast way...
|
|
if (!WriteFile(m_hFileHandle, szQuotedStringBuffer, strlen(szQuotedStringBuffer), &dwBytesWritten, NULL))
|
|
{
|
|
delete [] szQuotedStringBuffer;
|
|
goto cleanup;
|
|
}
|
|
|
|
delete [] szQuotedStringBuffer;
|
|
} else
|
|
{
|
|
// Just write out the data the nice, fast way...
|
|
if (!WriteFile(m_hFileHandle, szStringBuffer, dwByteCount, &dwBytesWritten, NULL))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
fReturn = true;
|
|
|
|
cleanup:
|
|
|
|
if (szStringBuffer)
|
|
delete [] szStringBuffer;
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
bool CFileData::WriteDWORD(DWORD dwNumber)
|
|
{
|
|
TCHAR tszBuffer[10+1]; // 0xFFFFFFFF == 4294967295 (10 characters) + 1 for the \0
|
|
|
|
_stprintf(tszBuffer, TEXT("%u"), dwNumber);
|
|
|
|
if (!WriteString(tszBuffer))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::WriteTimeDateString(time_t Time)
|
|
{
|
|
enum {BUFFERSIZE = 128};
|
|
|
|
TCHAR tszBuffer[BUFFERSIZE];
|
|
struct tm * localTime = localtime(&Time);
|
|
|
|
if (localTime)
|
|
{
|
|
// This top version seems to be better Y2K friendly as I spit out the full year...
|
|
_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%B %d, %Y %H:%M:%S"), localTime);
|
|
//_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%c"), localtime(&Time));
|
|
|
|
if (!WriteString(tszBuffer, true))
|
|
return false;
|
|
} else
|
|
{ // A bad TimeDate stamp was provided
|
|
if (!WriteString(TEXT("<INVALID DATE>"), true))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::WriteFileHeader()
|
|
{
|
|
enum {BUFFERSIZE = 128};
|
|
TCHAR tszBuffer[BUFFERSIZE];
|
|
DWORD dwNum = BUFFERSIZE;
|
|
|
|
// Write the Checksym version info...
|
|
_stprintf(tszBuffer, TEXT("CHECKSYM, (%d.%d:%d.%d)\r\n"), VERSION_FILEVERSION);
|
|
|
|
if (!WriteString(tszBuffer))
|
|
return false;
|
|
|
|
// Write the current date/time info...
|
|
|
|
if (!WriteString(TEXT("Created:,")))
|
|
return false;
|
|
|
|
time_t Time;
|
|
time(&Time);
|
|
|
|
if (!WriteTimeDateString(Time))
|
|
return false;
|
|
|
|
// Write the carriage-return line-feed combo...
|
|
if (!WriteString(TEXT("\r\n")))
|
|
return false;
|
|
|
|
// Spit out the computername
|
|
if (!GetComputerName(tszBuffer, &dwNum))
|
|
return false;
|
|
|
|
if (!WriteString(TEXT("Computer:,")))
|
|
return false;
|
|
|
|
if (!WriteString(tszBuffer))
|
|
return false;
|
|
|
|
// Write the carriage-return line-feed combo... (a couple of times)...
|
|
if (!WriteString(TEXT("\r\n")))
|
|
return false;
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
void CFileData::PrintLastError()
|
|
{
|
|
CUtilityFunctions::PrintMessageString(GetLastError());
|
|
}
|
|
|
|
bool CFileData::CreateFileMapping()
|
|
{
|
|
m_hFileMappingObject = ::CreateFileMapping(m_hFileHandle,
|
|
NULL,
|
|
PAGE_READONLY | SEC_COMMIT,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
if (m_hFileMappingObject == NULL)
|
|
{
|
|
SetLastError();
|
|
return false;
|
|
}
|
|
|
|
// Okay, we'll map the view as well...
|
|
m_lpBaseAddress = MapViewOfFile(m_hFileMappingObject,
|
|
FILE_MAP_READ,
|
|
0,
|
|
0,
|
|
0);
|
|
|
|
if (m_lpBaseAddress == NULL)
|
|
{
|
|
SetLastError();
|
|
return false;
|
|
}
|
|
|
|
m_lpCurrentFilePointer = (LPSTR) m_lpBaseAddress;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::ReadFileHeader()
|
|
{
|
|
// For starters, let's read a line...
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
enum { BUFFER_SIZE = 128};
|
|
char szTemporaryBuffer[BUFFER_SIZE];
|
|
DWORD cbBytesRead;
|
|
|
|
cbBytesRead = ReadString(szTemporaryBuffer, BUFFER_SIZE);
|
|
|
|
// We gotta read something?
|
|
if (0 == cbBytesRead)
|
|
return false;
|
|
|
|
// Look for our "Magic" Value
|
|
if (_stricmp(szTemporaryBuffer, "CHECKSYM"))
|
|
{
|
|
_tprintf(TEXT("Error: Input file has invalid header. Missing CHECKSYM keyword!\n"));
|
|
return false;
|
|
}
|
|
|
|
// Read version number
|
|
// We'll do this later if needed...
|
|
|
|
// Read Created Time
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
// Read Computer this was created on
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::ReadFileLine()
|
|
{
|
|
// We're ansi oriented (since this is a CSV file -- in case you were wondering)
|
|
size_t pos;
|
|
|
|
// Find the first \r or \n character (if we're point to \0, we'll figure that out)
|
|
pos = strcspn(m_lpCurrentFilePointer, "\r\n");
|
|
|
|
// Hmm... we don't read a line that starts on \r\n very well...
|
|
if (pos == 0)
|
|
{
|
|
m_szLINEBUFFER[0] = '\0';
|
|
ResetBufferPointerToStart();
|
|
return false;
|
|
}
|
|
|
|
// Read the line into our buffer
|
|
strncpy(m_szLINEBUFFER, m_lpCurrentFilePointer, pos);
|
|
|
|
// Null terminate for ease of use...
|
|
m_szLINEBUFFER[pos] = '\0';
|
|
|
|
ResetBufferPointerToStart();
|
|
|
|
// Advance the current file pointer to just beyond the last character we read...
|
|
// This should advance to the \r\n or \0
|
|
m_lpCurrentFilePointer += pos;
|
|
|
|
// We want this file pointer to advance beyond any \r \n chars we may have found...
|
|
while (*m_lpCurrentFilePointer)
|
|
{
|
|
// Advance pointer to non- \r or \n
|
|
if ( (*m_lpCurrentFilePointer == '\r') ||
|
|
(*m_lpCurrentFilePointer == '\n') )
|
|
{
|
|
m_lpCurrentFilePointer++;
|
|
}
|
|
else
|
|
{
|
|
break; // Found either the \0 or something else...
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
DWORD CFileData::ReadString(LPSTR szStringBuffer, DWORD iStringBufferSize)
|
|
{
|
|
// If we give a buffer size, we have to give a buffer...
|
|
if ( szStringBuffer == NULL && iStringBufferSize )
|
|
return 0;
|
|
|
|
// The ReadFileLine() call puts us at the start of a line (after
|
|
// the \r \n combinations... It's possible that we're at the
|
|
// end...
|
|
|
|
// If we're pointing to the end of the file, let's bail...
|
|
if (*m_lpCurrentLocationInLINEBUFFER == '\0')
|
|
return 0;
|
|
|
|
DWORD iBytesCopied = 0;
|
|
bool fFinished = false;
|
|
bool fFoundSeparatorChars = false; // These might be '\r', '\n', or ','
|
|
bool fQuoteMode = false;
|
|
|
|
while (!fFinished)
|
|
{
|
|
switch (*m_lpCurrentLocationInLINEBUFFER)
|
|
{
|
|
case '"':
|
|
// Okay, we found a quote... that's cool.. but are we quoting a quote,
|
|
// or... are we in quote mode?
|
|
|
|
// Probe ahead... is the next char a '"' also?
|
|
if ( *(m_lpCurrentLocationInLINEBUFFER+1) == '"')
|
|
{
|
|
// Yes it is... so go ahead and copy the quote
|
|
CopyCharIfRoom(iStringBufferSize, szStringBuffer, &iBytesCopied, &fFinished);
|
|
if (!fFinished)
|
|
*(m_lpCurrentLocationInLINEBUFFER++); // Skip the quote
|
|
}
|
|
else
|
|
{
|
|
*(m_lpCurrentLocationInLINEBUFFER++);
|
|
fQuoteMode = !fQuoteMode; // Toggle the quote mode...
|
|
continue;
|
|
}
|
|
|
|
case '\0':
|
|
fFinished = true;
|
|
break;
|
|
|
|
case ',':
|
|
if (!fQuoteMode)
|
|
{ // If we're not in quote mode, then this marks the end of a field...
|
|
fFinished = true;
|
|
fFoundSeparatorChars = true;
|
|
*(m_lpCurrentLocationInLINEBUFFER++);
|
|
}
|
|
else
|
|
{
|
|
// Okay, this marks a new character that happens to be a comma...
|
|
CopyCharIfRoom(iStringBufferSize, szStringBuffer, &iBytesCopied, &fFinished);
|
|
}
|
|
break;
|
|
|
|
case '\r':
|
|
case '\n':
|
|
// We note that we found these, and simply advance the pointer...
|
|
fFoundSeparatorChars = true;
|
|
*(m_lpCurrentLocationInLINEBUFFER++);
|
|
break;
|
|
|
|
default:
|
|
|
|
if (fFoundSeparatorChars)
|
|
{
|
|
// We were scanning... found a separator after some data... so we bail
|
|
fFinished = true;
|
|
break;
|
|
}
|
|
|
|
CopyCharIfRoom(iStringBufferSize, szStringBuffer, &iBytesCopied, &fFinished);
|
|
}
|
|
}
|
|
|
|
if (iStringBufferSize) // We only NULL terminate a buffer if one was provided...
|
|
szStringBuffer[iBytesCopied] = '\0'; // Null terminate this puppy...
|
|
|
|
return iBytesCopied;
|
|
}
|
|
|
|
//
|
|
// This function is responsible for reading through the CSV file and creating any necessary
|
|
// objects and populating them with data...
|
|
//
|
|
bool CFileData::DispatchCollectionObject(CProcesses ** lplpProcesses, CProcessInfo ** lplpProcess, CModules ** lplpModules, CModules ** lplpKernelModeDrivers, CModuleInfoCache * lpModuleInfoCache, CFileData * lpOutputFile)
|
|
{
|
|
enum { BUFFER_SIZE = 128};
|
|
char szTemporaryBuffer[BUFFER_SIZE];
|
|
TCHAR tszTemporaryBuffer[BUFFER_SIZE];
|
|
DWORD cbBytesRead;
|
|
bool fContinueReading = true;
|
|
|
|
// Read the Output Type
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
while (fContinueReading)
|
|
{
|
|
// If this is the second iteration (or more) we may not be at the
|
|
// start of our buffer (causing the read of the output type to fail)
|
|
ResetBufferPointerToStart();
|
|
|
|
// Read the Output Type line...
|
|
cbBytesRead = ReadString(szTemporaryBuffer, BUFFER_SIZE);
|
|
|
|
// We gotta read something?
|
|
if (0 == cbBytesRead)
|
|
return true;
|
|
|
|
// I hate to do this... but we read this stuff as ASCII... may need to
|
|
// convert to a TCHAR format to be neutral...
|
|
CUtilityFunctions::CopyAnsiStringToTSTR(szTemporaryBuffer, tszTemporaryBuffer, cbBytesRead+1);
|
|
|
|
// Printout the section we're attempting to read...
|
|
if (!g_lpProgramOptions->GetMode(CProgramOptions::QuietMode))
|
|
_tprintf(TEXT(" Reading %s data...\n"), tszTemporaryBuffer);
|
|
|
|
if ( _tcsicmp(g_tszCollectionArray[Processes].tszCSVLabel, tszTemporaryBuffer) == 0 )
|
|
{
|
|
/*
|
|
[PROCESSES]
|
|
*/
|
|
|
|
// Read to the end of the line
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
// Yup, it is... let's create a Processes Object
|
|
if (*lplpProcesses == NULL)
|
|
{
|
|
// Allocate a structure for our Processes Object.
|
|
*lplpProcesses = new CProcesses();
|
|
|
|
if (!*lplpProcesses)
|
|
{
|
|
_tprintf(TEXT("Unable to allocate memory for the processes object!\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
// The Processes Object will init differently depending on what
|
|
// Command-Line arguments have been provided...
|
|
if (!(*lplpProcesses)->Initialize(lpModuleInfoCache, this, lpOutputFile))
|
|
{
|
|
_tprintf(TEXT("Unable to initialize Processes Object!\n"));
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
// Okay, go get the Process Data...
|
|
(*lplpProcesses)->GetProcessesData();
|
|
|
|
} else
|
|
if ( _tcsicmp(g_tszCollectionArray[Process].tszCSVLabel, tszTemporaryBuffer) == 0 )
|
|
{
|
|
/*
|
|
[PROCESS]
|
|
*/
|
|
// Read to the end of the line
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
// Yup, it is... let's create a ProcessInfo Object
|
|
if (*lplpProcess== NULL)
|
|
{
|
|
// Allocate a structure for our ProcessInfo Object.
|
|
*lplpProcess = new CProcessInfo();
|
|
|
|
if (!*lplpProcess)
|
|
{
|
|
_tprintf(TEXT("Unable to allocate memory for the processinfo object!\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
// The Modules Object will init differently depending on what
|
|
// Command-Line arguments have been provided...
|
|
if (!(*lplpProcess)->Initialize(lpModuleInfoCache, this, lpOutputFile, NULL))
|
|
{
|
|
_tprintf(TEXT("Unable to initialize Modules Object!\n"));
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
// Okay, go get the Process Data
|
|
(*lplpProcess)->GetProcessData();
|
|
} else
|
|
if ( _tcsicmp(g_tszCollectionArray[Modules].tszCSVLabel, tszTemporaryBuffer) == 0 )
|
|
{
|
|
/*
|
|
[MODULES]
|
|
*/
|
|
// Read to the end of the line
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
// Yup, it is... let's create a Modules Object
|
|
if (*lplpModules == NULL)
|
|
{
|
|
// Allocate a structure for our Modules Object.
|
|
*lplpModules = new CModules();
|
|
|
|
if (!*lplpModules)
|
|
{
|
|
_tprintf(TEXT("Unable to allocate memory for the modules object!\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
// The Modules Object will init differently depending on what
|
|
// Command-Line arguments have been provided...
|
|
if (!(*lplpModules)->Initialize(lpModuleInfoCache, this, lpOutputFile, NULL))
|
|
{
|
|
_tprintf(TEXT("Unable to initialize Modules Object!\n"));
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
// Okay, go get the Modules Data (collected from the filesystem)
|
|
(*lplpModules)->GetModulesData(CProgramOptions::InputModulesDataFromFileSystemMode, true);
|
|
} else
|
|
if ( _tcsicmp(g_tszCollectionArray[KernelModeDrivers].tszCSVLabel, tszTemporaryBuffer) == 0 )
|
|
{
|
|
/*
|
|
[KERNEL-MODE DRIVERS]
|
|
*/
|
|
// Read to the end of the line
|
|
if (!ReadFileLine())
|
|
return false;
|
|
|
|
// Yup, it is... let's create a Modules Object
|
|
if (*lplpKernelModeDrivers == NULL)
|
|
{
|
|
// Allocate a structure for our Modules Object.
|
|
*lplpKernelModeDrivers = new CModules();
|
|
|
|
if (!*lplpKernelModeDrivers)
|
|
{
|
|
_tprintf(TEXT("Unable to allocate memory for the modules object!\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
// The Modules Object will init differently depending on what
|
|
// Command-Line arguments have been provided...
|
|
if (!(*lplpKernelModeDrivers)->Initialize(lpModuleInfoCache, this, lpOutputFile, NULL))
|
|
{
|
|
_tprintf(TEXT("Unable to initialize Modules Object!\n"));
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
// Okay, go get the Modules Data (collected from the filesystem)
|
|
(*lplpKernelModeDrivers)->GetModulesData(CProgramOptions::InputDriversFromLiveSystemMode, true);
|
|
} else
|
|
{
|
|
_tprintf(TEXT("Unrecognized section %s found!\n"), tszTemporaryBuffer);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
return false;
|
|
}
|
|
|
|
bool CFileData::ReadDWORD(LPDWORD lpDWORD)
|
|
{
|
|
char szTempBuffer[10+1]; // 0xFFFFFFFF == 4294967295 (10 characters) + 1 for the \0
|
|
|
|
if (!ReadString(szTempBuffer, 10+1))
|
|
return false;
|
|
|
|
// Convert it... baby...
|
|
*lpDWORD = atoi(szTempBuffer);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::CopyCharIfRoom(DWORD iStringBufferSize, LPSTR szStringBuffer, LPDWORD piBytesCopied, bool *pfFinished)
|
|
{
|
|
if (iStringBufferSize)
|
|
{
|
|
// If we have room to copy the data... let's do it...
|
|
if (*piBytesCopied < iStringBufferSize)
|
|
{
|
|
szStringBuffer[(*piBytesCopied)++] = *(m_lpCurrentLocationInLINEBUFFER++);
|
|
} else
|
|
{
|
|
// No room... we're done.
|
|
*pfFinished = true;
|
|
}
|
|
} else
|
|
{
|
|
// Just advance the pointer... we have no buffer to copy to...
|
|
*(m_lpCurrentLocationInLINEBUFFER++);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::ResetBufferPointerToStart()
|
|
{
|
|
// Reset the Pointer with our line buffer to the start of this buffer
|
|
m_lpCurrentLocationInLINEBUFFER = m_szLINEBUFFER;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFileData::EndOfFile()
|
|
{
|
|
//return (*m_lpCurrentFilePointer == '\0');
|
|
return (*m_lpCurrentLocationInLINEBUFFER == '\0');
|
|
}
|
|
|
|
bool CFileData::WriteFileTimeString(FILETIME ftFileTime)
|
|
{
|
|
enum {BUFFERSIZE = 128};
|
|
|
|
TCHAR tszBuffer[BUFFERSIZE];
|
|
FILETIME ftLocalFileTime;
|
|
SYSTEMTIME lpSystemTime;
|
|
int cch = 0;
|
|
|
|
// Let's convert this to a local file time first...
|
|
if (!FileTimeToLocalFileTime(&ftFileTime, &ftLocalFileTime))
|
|
return false;
|
|
|
|
FileTimeToSystemTime( &ftLocalFileTime, &lpSystemTime );
|
|
|
|
|
|
cch = GetDateFormat( LOCALE_USER_DEFAULT,
|
|
0,
|
|
&lpSystemTime,
|
|
TEXT("MMMM d',' yyyy"),
|
|
tszBuffer,
|
|
BUFFERSIZE );
|
|
|
|
if (!cch)
|
|
return false;
|
|
|
|
tszBuffer[cch-1] = TEXT(' ');
|
|
|
|
//
|
|
// Get time and format to characters
|
|
//
|
|
|
|
GetTimeFormat( LOCALE_USER_DEFAULT,
|
|
0,
|
|
&lpSystemTime, // use current time
|
|
NULL, // use default format
|
|
tszBuffer + cch,
|
|
BUFFERSIZE - cch );
|
|
|
|
|
|
// <Full Month Name> <day>, <Year with Century> <Hour>:<Minute>:<Second>
|
|
//_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%B %d, %Y %H:%M:%S"), localtime(&Time));
|
|
//_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%c"), localtime(&Time));
|
|
|
|
if (!WriteString(tszBuffer, true))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Exception Monitor prefers a MM/DD/YYYY HH:MM:SS format...
|
|
bool CFileData::WriteTimeDateString2(time_t Time)
|
|
{
|
|
enum {BUFFERSIZE = 128};
|
|
|
|
TCHAR tszBuffer[BUFFERSIZE];
|
|
|
|
// This top version seems to be better Y2K friendly as I spit out the full year...
|
|
_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%m/%d/%Y %H:%M:%S"), localtime(&Time));
|
|
//_tcsftime(tszBuffer, BUFFERSIZE, TEXT("%c"), localtime(&Time));
|
|
|
|
if (!WriteString(tszBuffer, true))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Exception Monitor prefers a MM/DD/YYYY HH:MM:SS format...
|
|
bool CFileData::WriteFileTimeString2(FILETIME ftFileTime)
|
|
{
|
|
enum {BUFFERSIZE = 128};
|
|
|
|
TCHAR tszBuffer[BUFFERSIZE];
|
|
FILETIME ftLocalFileTime;
|
|
SYSTEMTIME lpSystemTime;
|
|
int cch = 0;
|
|
|
|
// Let's convert this to a local file time first...
|
|
if (!FileTimeToLocalFileTime(&ftFileTime, &ftLocalFileTime))
|
|
return false;
|
|
|
|
FileTimeToSystemTime( &ftLocalFileTime, &lpSystemTime );
|
|
|
|
|
|
cch = GetDateFormat( LOCALE_USER_DEFAULT,
|
|
0,
|
|
&lpSystemTime,
|
|
TEXT("MM/dd/yyyy"),
|
|
tszBuffer,
|
|
BUFFERSIZE );
|
|
|
|
if (!cch)
|
|
return false;
|
|
|
|
tszBuffer[cch-1] = TEXT(' ');
|
|
|
|
//
|
|
// Get time and format to characters
|
|
//
|
|
|
|
GetTimeFormat( LOCALE_USER_DEFAULT,
|
|
0,
|
|
&lpSystemTime, // use current time
|
|
TEXT("HH:mm:ss"), // use default format
|
|
tszBuffer + cch,
|
|
BUFFERSIZE - cch );
|
|
|
|
if (!WriteString(tszBuffer, true))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
//#endif
|