windows-nt/Source/XPSP1/NT/sdktools/debuggers/snapshot/snapshot.cpp
2020-09-26 16:20:57 +08:00

1937 lines
59 KiB
C++

#define UNICODE
#define _UNICODE
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <wtypes.h>
#include <mountmgr.h>
#include <winioctl.h>
#include <ntddvol.h>
#include <ntddscsi.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <tchar.h>
#ifdef UNICODE
# define _stnprintf _snwprintf
#else
# define _stnprintf _snprintf
#endif
#define BUFFER_SIZE 64*1024*sizeof(TCHAR)
#define MIN_BUFFER_SIZE 1024*sizeof(TCHAR)
#define MAX_BUFFER_SIZE 10*1024*1024*sizeof(TCHAR)
#define MAXSTR 4*1024
#define DEFAULT_HISTORYFILES 10
VOID
PrintLoadedDrivers(
HANDLE hFile
);
ULONG
LogSystemSnapshot(
LPCTSTR *lpStrings,
PLONG BuffSize,
LPTSTR lpszBuff
);
UINT LogSystemSnapshotToFile(
HANDLE hFile
);
void WriteToLogFileW(
HANDLE hFile,
LPCWSTR lpwszInput
)
{
DWORD dwWriten;
BYTE *bBuffer;
int nLen, nRetLen;
nLen = wcslen(lpwszInput);
bBuffer = (BYTE*)malloc(nLen * sizeof(WCHAR));
if(bBuffer == 0)
return;
nRetLen = WideCharToMultiByte(CP_ACP, 0, lpwszInput, -1, (LPSTR)bBuffer, nLen * sizeof(WCHAR), NULL, NULL);
if(nRetLen != 0){
WriteFile(hFile, (LPVOID)bBuffer, nRetLen-1, &dwWriten, NULL);
}
free(bBuffer);
}
void WriteToLogFileA(
HANDLE hFile,
LPCSTR lpszInput
)
{
DWORD dwWriten;
WriteFile(hFile, (LPVOID)lpszInput, strlen(lpszInput), &dwWriten, NULL);
}
void WriteToLogFile(
HANDLE hFile,
LPCTSTR lpszInput
)
{
DWORD dwWriten;
#ifdef _UNICODE
WriteToLogFileW(hFile, lpszInput);
#else
WriteToLogFileA(hFile, lpszInput);
#endif //_UNICODE
}
void
LogLogicalDriveInfo(
HANDLE hFile
);
void
LogHardwareInfo(
HANDLE hFile
);
void
LogPhyicalDiskInfo(
HANDLE hFile
);
void
LogHotfixes(
HANDLE hFile
);
void
LogOsInfo(
HANDLE hFile
);
void
LogBIOSInfo(
HANDLE hFile
);
NTSTATUS
SnapshotRegOpenKey(
IN LPCWSTR lpKeyName,
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE KeyHandle
);
NTSTATUS
SnapshotRegQueryValueKey(
IN HANDLE KeyHandle,
IN LPCWSTR lpValueName,
IN ULONG Length,
OUT PVOID KeyValue,
OUT PULONG ResultLength
);
NTSTATUS
SnapshotRegEnumKey(
IN HANDLE KeyHandle,
IN ULONG Index,
OUT LPWSTR lpKeyName,
OUT PULONG lpNameLength
);
void
DeleteOldFiles(
LPCTSTR lpPath
);
ULONG CurrentBufferSize;
LPCTSTR StateTable[] = {
TEXT("Initialized"),
TEXT("Ready"),
TEXT("Running"),
TEXT("Standby"),
TEXT("Terminated"),
TEXT("Wait:"),
TEXT("Transition"),
TEXT("Unknown"),
TEXT("Unknown"),
TEXT("Unknown"),
TEXT("Unknown"),
TEXT("Unknown")
};
LPCTSTR WaitTable[] = {
TEXT("Executive"),
TEXT("FreePage"),
TEXT("PageIn"),
TEXT("PoolAllocation"),
TEXT("DelayExecution"),
TEXT("Suspended"),
TEXT("UserRequest"),
TEXT("Executive"),
TEXT("FreePage"),
TEXT("PageIn"),
TEXT("PoolAllocation"),
TEXT("DelayExecution"),
TEXT("Suspended"),
TEXT("UserRequest"),
TEXT("EventPairHigh"),
TEXT("EventPairLow"),
TEXT("LpcReceive"),
TEXT("LpcReply"),
TEXT("VirtualMemory"),
TEXT("PageOut"),
TEXT("Spare1"),
TEXT("Spare2"),
TEXT("Spare3"),
TEXT("Spare4"),
TEXT("Spare5"),
TEXT("Spare6"),
TEXT("Spare7"),
TEXT("Unknown"),
TEXT("Unknown"),
TEXT("Unknown")
};
LPCTSTR Empty = TEXT(" ");
BOOLEAN fUserOnly = TRUE;
BOOLEAN fSystemOnly = TRUE;
BOOLEAN fVerbose = FALSE;
BOOLEAN fPrintIt;
TCHAR lpszBuffer[BUFFER_SIZE];
TCHAR lpszFileName[MAX_PATH * sizeof(TCHAR)] ;
TCHAR lpszHdrBuffer[MAX_PATH* sizeof(TCHAR)] ;
ULONG LogSystemSnapshot(DWORD Flags, LPCTSTR *lpStrings, PLONG BuffSize, LPTSTR lpszBuff)
{
SYSTEMTIME systime;
TIME_ZONE_INFORMATION TimeZone ;
LPTSTR lpszTemp;
HANDLE hFile = NULL;
UINT res = 0;
LONG lBuffSize ;
GetLocalTime(&systime);
lBuffSize = *BuffSize ;
*BuffSize = 0 ;
// Set up the log path %SYSTEMDIR%\Logfiles\Shutdown
GetSystemDirectory(lpszFileName, MAX_PATH);
lstrcat(lpszFileName, TEXT("\\LogFiles")); // making sure the path ..
CreateDirectory(lpszFileName, NULL);
lstrcat(lpszFileName, TEXT("\\ShutDown")); // .. exists
CreateDirectory(lpszFileName, NULL);
DeleteOldFiles(lpszFileName);
lstrcat(lpszFileName, TEXT("\\ShutDown_"));
lpszTemp = (LPTSTR)(lpszFileName + (lstrlen(lpszFileName)));
_stnprintf(lpszTemp,MAX_PATH - (lstrlen(lpszFileName)),
TEXT("%4d%02d%02d%02d%02d%02d.state"),
systime.wYear, systime.wMonth, systime.wDay,
systime.wHour, systime.wMinute, systime.wSecond);
hFile = CreateFile(lpszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return HandleToUlong(INVALID_HANDLE_VALUE);
GetTimeZoneInformation(&TimeZone);
_stnprintf(lpszHdrBuffer, MAX_PATH,
TEXT("System State Snapshot of System %s on Shutdown\n")
TEXT("Initiated by %s at %d-%d-%d %d:%d:%d (%s(%d))\n")
TEXT("Reason = %s/%s\n")
TEXT("Type = %s\n")
TEXT("Comment = %s\n\n"),
lpStrings[1],lpStrings[0],
systime.wYear, systime.wMonth, systime.wDay,
systime.wHour, systime.wMinute, systime.wSecond,
TimeZone.StandardName,TimeZone.Bias,
lpStrings[2],lpStrings[3],lpStrings[4],lpStrings[5]);
WriteToLogFile(hFile, lpszHdrBuffer);
// Ok write the snapshot to the file
res = LogSystemSnapshotToFile(hFile);
CloseHandle(hFile);
if (lBuffSize >= (LONG)_tcslen(lpszFileName)) {
wsprintf(lpszBuff,TEXT("%s"),lpszFileName);
*BuffSize = _tcslen(lpszFileName) ;
}
return res;
}
UINT LogSystemSnapshotToFile(
HANDLE hFile
)
{
PSYSTEM_PROCESS_INFORMATION ProcessInfo;
PSYSTEM_THREAD_INFORMATION ThreadInfo;
BYTE* LargeBuffer1;
NTSTATUS status;
ULONG i;
ULONG TotalOffset = 0;
TIME_FIELDS UserTime;
TIME_FIELDS KernelTime;
TIME_FIELDS UpTime;
SYSTEM_BASIC_INFORMATION BasicInfo;
SYSTEM_TIMEOFDAY_INFORMATION TimeOfDayInfo;
PSYSTEM_PAGEFILE_INFORMATION PageFileInfo;
LARGE_INTEGER Time;
ANSI_STRING pname;
SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
SYSTEM_FILECACHE_INFORMATION FileCache;
SIZE_T SumCommit;
SIZE_T SumWorkingSet;
if (hFile == INVALID_HANDLE_VALUE)
return 1;
//SetFileApisToOEM();
LargeBuffer1 = (BYTE*) VirtualAlloc (NULL,
MAX_BUFFER_SIZE,
MEM_RESERVE,
PAGE_READWRITE);
if (LargeBuffer1 == NULL) {
WriteToLogFile(hFile, TEXT("Memory allocation failed\n"));
return 0;
}
if (VirtualAlloc (LargeBuffer1,
BUFFER_SIZE,
MEM_COMMIT,
PAGE_READWRITE) == NULL) {
VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_RELEASE);
WriteToLogFile(hFile, TEXT("Memory commit failed\n"));
return 0;
}
CurrentBufferSize = BUFFER_SIZE;
status = NtQuerySystemInformation(
SystemBasicInformation,
&BasicInfo,
sizeof(SYSTEM_BASIC_INFORMATION),
NULL
);
if (!NT_SUCCESS(status)) {
VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_RELEASE | MEM_DECOMMIT);
wsprintf(lpszBuffer, TEXT("Query info failed %lx\n"),status);
WriteToLogFile(hFile, lpszBuffer);
return(status);
}
status = NtQuerySystemInformation(
SystemTimeOfDayInformation,
&TimeOfDayInfo,
sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
NULL
);
if (!NT_SUCCESS(status)) {
VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_RELEASE | MEM_DECOMMIT);
wsprintf(lpszBuffer, TEXT("Query info failed %lx\n"),status);
WriteToLogFile(hFile, lpszBuffer);
return(status);
}
Time.QuadPart = TimeOfDayInfo.CurrentTime.QuadPart -
TimeOfDayInfo.BootTime.QuadPart;
RtlTimeToElapsedTimeFields ( &Time, &UpTime);
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("memory: %4ld kb uptime:%3ld %2ld:%02ld:%02ld.%03ld \n\n"),
BasicInfo.NumberOfPhysicalPages * (BasicInfo.PageSize/1024),
UpTime.Day,
UpTime.Hour,
UpTime.Minute,
UpTime.Second,
UpTime.Milliseconds);
WriteToLogFile(hFile, lpszBuffer);
PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)LargeBuffer1;
status = NtQuerySystemInformation(
SystemPageFileInformation,
PageFileInfo,
CurrentBufferSize,
NULL
);
if (NT_SUCCESS(status)) {
//
// Print out the page file information.
//
if (PageFileInfo->TotalSize == 0) {
WriteToLogFile(hFile, TEXT("no page files in use\n"));
} else {
for (; ; ) {
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("PageFile: %ls\n"), PageFileInfo->PageFileName.Buffer);
WriteToLogFile(hFile, lpszBuffer);
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("\tCurrent Size: %6ld kb Total Used: %6ld kb Peak Used %6ld kb\n"),
PageFileInfo->TotalSize*(BasicInfo.PageSize/1024),
PageFileInfo->TotalInUse*(BasicInfo.PageSize/1024),
PageFileInfo->PeakUsage*(BasicInfo.PageSize/1024));
WriteToLogFile(hFile, lpszBuffer);
if (PageFileInfo->NextEntryOffset == 0) {
break;
}
PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)(
(PCHAR)PageFileInfo + PageFileInfo->NextEntryOffset);
}
}
}
retry:
status = NtQuerySystemInformation(
SystemProcessInformation,
LargeBuffer1,
CurrentBufferSize,
NULL
);
if (status == STATUS_INFO_LENGTH_MISMATCH) {
//
// Increase buffer size.
//
CurrentBufferSize += 8192;
if (VirtualAlloc (LargeBuffer1,
CurrentBufferSize,
MEM_COMMIT,
PAGE_READWRITE) == NULL) {
WriteToLogFile(hFile, TEXT("Memory commit failed\n"));
VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_DECOMMIT | MEM_RELEASE);
return 0;
}
goto retry;
}
if (!NT_SUCCESS(status)) {
_stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("Query info failed %lx\n"),status);
WriteToLogFile(hFile,lpszBuffer);
return(status);
}
//
// display pmon style process output, then detailed output that includes
// per thread stuff
//
TotalOffset = 0;
SumCommit = 0;
SumWorkingSet = 0;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
while (TRUE) {
SumCommit += ProcessInfo->PrivatePageCount / 1024;
SumWorkingSet += ProcessInfo->WorkingSetSize / 1024;
if (ProcessInfo->NextEntryOffset == 0) {
break;
}
TotalOffset += ProcessInfo->NextEntryOffset;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
}
status = NtQuerySystemInformation(
SystemPerformanceInformation,
&PerfInfo,
sizeof(PerfInfo),
NULL
);
if ( !NT_SUCCESS(status) ) {
VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_DECOMMIT | MEM_RELEASE);
_stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("Query perf Failed %lx\n"),status);
WriteToLogFile(hFile, lpszBuffer);
return 0;
}
status = NtQuerySystemInformation(
SystemFileCacheInformation,
&FileCache,
sizeof(FileCache),
NULL
);
if ( !NT_SUCCESS(status) ) {
VirtualFree(LargeBuffer1, MAX_BUFFER_SIZE, MEM_DECOMMIT | MEM_RELEASE);
_stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("Query file cache Failed %lx\n"),status);
WriteToLogFile(hFile, lpszBuffer);
return 0;
}
NtQuerySystemInformation(
SystemBasicInformation,
&BasicInfo,
sizeof(BasicInfo),
NULL
);
SumWorkingSet += FileCache.CurrentSize/1024;
_stnprintf (lpszBuffer, BUFFER_SIZE,
TEXT("\n Memory:%7ldK Avail:%7ldK TotalWs:%7ldK InRam Kernel:%5ldK P:%5ldK\n"),
BasicInfo.NumberOfPhysicalPages*(BasicInfo.PageSize/1024),
PerfInfo.AvailablePages*(BasicInfo.PageSize/1024),
SumWorkingSet,
(PerfInfo.ResidentSystemCodePage + PerfInfo.ResidentSystemDriverPage)*(BasicInfo.PageSize/1024),
(PerfInfo.ResidentPagedPoolPage)*(BasicInfo.PageSize/1024)
);
WriteToLogFile(hFile, lpszBuffer);
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT(" Commit:%7ldK/%7ldK Limit:%7ldK Peak:%7ldK Pool N:%5ldK P:%5ldK\n"),
PerfInfo.CommittedPages*(BasicInfo.PageSize/1024),
SumCommit,
PerfInfo.CommitLimit*(BasicInfo.PageSize/1024),
PerfInfo.PeakCommitment*(BasicInfo.PageSize/1024),
PerfInfo.NonPagedPoolPages*(BasicInfo.PageSize/1024),
PerfInfo.PagedPoolPages*(BasicInfo.PageSize/1024)
);
WriteToLogFile(hFile, lpszBuffer);
TotalOffset = 0;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
WriteToLogFile(hFile, TEXT("\n"));
WriteToLogFile(hFile, TEXT(" User Time Kernel Time Ws Faults Commit Pri Hnd Thd Pid Name\n"));
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT(" %6ld %8ld %s\n"),
FileCache.CurrentSize/1024,
FileCache.PageFaultCount,
TEXT("File Cache")
);
WriteToLogFile(hFile, lpszBuffer);
while (TRUE) {
pname.Buffer = NULL;
if ( ProcessInfo->ImageName.Buffer ) {
RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE);
}
RtlTimeToElapsedTimeFields ( &ProcessInfo->UserTime, &UserTime);
RtlTimeToElapsedTimeFields ( &ProcessInfo->KernelTime, &KernelTime);
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("%3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld"),
UserTime.Hour,
UserTime.Minute,
UserTime.Second,
UserTime.Milliseconds,
KernelTime.Hour,
KernelTime.Minute,
KernelTime.Second,
KernelTime.Milliseconds
);
WriteToLogFile(hFile, lpszBuffer);
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("%6ld %8ld %7ld"),
ProcessInfo->WorkingSetSize / 1024,
ProcessInfo->PageFaultCount,
ProcessInfo->PrivatePageCount / 1024
);
WriteToLogFile(hFile, lpszBuffer);
#ifdef _UNICODE
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT(" %2ld %4ld %3ld %3ld %S\n"),
ProcessInfo->BasePriority,
ProcessInfo->HandleCount,
ProcessInfo->NumberOfThreads,
HandleToUlong(ProcessInfo->UniqueProcessId),
ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
);
#else
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT(" %2ld %4ld %3ld %3ld %s\n"),
ProcessInfo->BasePriority,
ProcessInfo->HandleCount,
ProcessInfo->NumberOfThreads,
HandleToUlong(ProcessInfo->UniqueProcessId),
ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
);
#endif //_UNICODE
WriteToLogFile(hFile, lpszBuffer);
if ( pname.Buffer ) {
RtlFreeAnsiString(&pname);
}
if (ProcessInfo->NextEntryOffset == 0) {
break;
}
TotalOffset += ProcessInfo->NextEntryOffset;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
}
//
// Beginning of normal old style pstat output
//
/*
if (0==1) {
TotalOffset = 0;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
WriteToLogFile(hFile, TEXT("\n"));
while (TRUE) {
fPrintIt = FALSE;
if ( (ProcessInfo->ImageName.Buffer && fUserOnly) ||
(ProcessInfo->ImageName.Buffer==NULL && fSystemOnly) ) {
fPrintIt = TRUE;
pname.Buffer = NULL;
if ( ProcessInfo->ImageName.Buffer ) {
RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE);
}
wsprintf(lpszBuffer, TEXT("pid:%3lx pri:%2ld Hnd:%5ld Pf:%7ld Ws:%7ldK %s\n"),
HandleToUlong(ProcessInfo->UniqueProcessId),
ProcessInfo->BasePriority,
ProcessInfo->HandleCount,
ProcessInfo->PageFaultCount,
ProcessInfo->WorkingSetSize / 1024,
ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
);
WriteToLogFile(hFile, lpszBuffer);
if ( pname.Buffer ) {
RtlFreeAnsiString(&pname);
}
}
i = 0;
ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
if (ProcessInfo->NumberOfThreads) {
WriteToLogFile(hFile, TEXT(" tid pri Ctx Swtch StrtAddr User Time Kernel Time State\n"));
}
while (i < ProcessInfo->NumberOfThreads) {
RtlTimeToElapsedTimeFields ( &ThreadInfo->UserTime, &UserTime);
RtlTimeToElapsedTimeFields ( &ThreadInfo->KernelTime, &KernelTime);
if ( fPrintIt ) {
wsprintf(lpszBuffer, TEXT(" %3lx %2ld %9ld %p"),
ProcessInfo->UniqueProcessId == 0 ? 0 : HandleToUlong(ThreadInfo->ClientId.UniqueThread),
ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->Priority,
ThreadInfo->ContextSwitches,
ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->StartAddress
);
WriteToLogFile(hFile, lpszBuffer);
wsprintf(lpszBuffer, TEXT(" %2ld:%02ld:%02ld.%03ld %2ld:%02ld:%02ld.%03ld"),
UserTime.Hour,
UserTime.Minute,
UserTime.Second,
UserTime.Milliseconds,
KernelTime.Hour,
KernelTime.Minute,
KernelTime.Second,
KernelTime.Milliseconds
);
WriteToLogFile(hFile, lpszBuffer);
wsprintf(lpszBuffer, TEXT(" %s%s\n"),
StateTable[ThreadInfo->ThreadState],
(ThreadInfo->ThreadState == 5) ?
WaitTable[ThreadInfo->WaitReason] : Empty
);
WriteToLogFile(hFile, lpszBuffer);
}
ThreadInfo += 1;
i += 1;
}
if (ProcessInfo->NextEntryOffset == 0) {
break;
}
TotalOffset += ProcessInfo->NextEntryOffset;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
if ( fPrintIt ) {
WriteToLogFile(hFile, TEXT("\n"));
}
}
}
*/
PrintLoadedDrivers(hFile);
//Now let us log the hardware and logical drive info
WriteToLogFile(hFile, TEXT("\n"));
LogOsInfo(hFile);
LogHotfixes(hFile);
LogBIOSInfo(hFile);
LogHardwareInfo(hFile);
LogPhyicalDiskInfo(hFile);
LogLogicalDriveInfo(hFile);
return 0;
}
typedef struct _MODULE_DATA {
ULONG CodeSize;
ULONG DataSize;
ULONG BssSize;
ULONG RoDataSize;
ULONG ImportDataSize;
ULONG ExportDataSize;
ULONG ResourceDataSize;
ULONG PagedSize;
ULONG InitSize;
ULONG CheckSum;
ULONG TimeDateStamp;
} MODULE_DATA, *PMODULE_DATA;
typedef struct _LOADED_IMAGE {
BYTE* MappedAddress;
PIMAGE_NT_HEADERS FileHeader;
PIMAGE_SECTION_HEADER LastRvaSection;
int NumberOfSections;
PIMAGE_SECTION_HEADER Sections;
} LOADED_IMAGE, *PLOADED_IMAGE;
VOID
SumModuleData(
PMODULE_DATA Sum,
PMODULE_DATA Current
)
{
Sum->CodeSize += Current->CodeSize;
Sum->DataSize += Current->DataSize;
Sum->BssSize += Current->BssSize;
Sum->RoDataSize += Current->RoDataSize;
Sum->ImportDataSize += Current->ImportDataSize;
Sum->ExportDataSize += Current->ExportDataSize;
Sum->ResourceDataSize += Current->ResourceDataSize;
Sum->PagedSize += Current->PagedSize;
Sum->InitSize += Current->InitSize;
}
VOID
PrintModuleSeperator(
HANDLE hFile
)
{
WriteToLogFile(hFile, TEXT("------------------------------------------------------------------------------\n"));
}
VOID
PrintModuleHeader(
HANDLE hFile
)
{
WriteToLogFile(hFile, TEXT(" ModuleName Load Addr Code Data Paged LinkDate\n"));
PrintModuleSeperator(hFile);
}
VOID
GetModuleData(
HANDLE hFile,
PMODULE_DATA Mod
)
{
HANDLE hMappedFile;
PIMAGE_DOS_HEADER DosHeader;
LOADED_IMAGE LoadedImage;
ULONG SectionAlignment;
PIMAGE_SECTION_HEADER Section;
int i;
ULONG Size;
hMappedFile = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL
);
if ( !hMappedFile ) {
return;
}
LoadedImage.MappedAddress = (BYTE*) MapViewOfFile(
hMappedFile,
FILE_MAP_READ,
0,
0,
0
);
CloseHandle(hMappedFile);
if ( !LoadedImage.MappedAddress ) {
return;
}
//
// Everything is mapped. Now check the image and find nt image headers
//
DosHeader = (PIMAGE_DOS_HEADER)LoadedImage.MappedAddress;
if ( DosHeader->e_magic != IMAGE_DOS_SIGNATURE ) {
UnmapViewOfFile(LoadedImage.MappedAddress);
return;
}
LoadedImage.FileHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
if ( LoadedImage.FileHeader->Signature != IMAGE_NT_SIGNATURE ) {
UnmapViewOfFile(LoadedImage.MappedAddress);
return;
}
LoadedImage.NumberOfSections = LoadedImage.FileHeader->FileHeader.NumberOfSections;
LoadedImage.Sections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)LoadedImage.FileHeader + sizeof(IMAGE_NT_HEADERS));
LoadedImage.LastRvaSection = LoadedImage.Sections;
//
// Walk through the sections and tally the dater
//
SectionAlignment = LoadedImage.FileHeader->OptionalHeader.SectionAlignment;
for (Section = LoadedImage.Sections,i=0; i<LoadedImage.NumberOfSections; i++,Section++) {
Size = Section->Misc.VirtualSize;
if (Size == 0) {
Size = Section->SizeOfRawData;
}
Size = (Size + SectionAlignment - 1) & ~(SectionAlignment - 1);
if (!memcmp((const char*) Section->Name,"PAGE", 4 )) {
Mod->PagedSize += Size;
} else if (!_stricmp((const char*) Section->Name,"INIT" )) {
Mod->InitSize += Size;
} else if (!_stricmp((const char*) Section->Name,".bss" )) {
Mod->BssSize = Size;
} else if (!_stricmp((const char*) Section->Name,".edata" )) {
Mod->ExportDataSize = Size;
} else if (!_stricmp((const char*) Section->Name,".idata" )) {
Mod->ImportDataSize = Size;
} else if (!_stricmp((const char*) Section->Name,".rsrc" )) {
Mod->ResourceDataSize = Size;
} else if (Section->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
Mod->CodeSize += Size;
} else if (Section->Characteristics & IMAGE_SCN_MEM_WRITE) {
Mod->DataSize += Size;
} else if (Section->Characteristics & IMAGE_SCN_MEM_READ) {
Mod->RoDataSize += Size;
} else {
Mod->DataSize += Size;
}
}
Mod->CheckSum = LoadedImage.FileHeader->OptionalHeader.CheckSum;
Mod->TimeDateStamp = LoadedImage.FileHeader->FileHeader.TimeDateStamp;
UnmapViewOfFile(LoadedImage.MappedAddress);
return;
}
TCHAR lpszTimeBuffer[MAX_PATH];
VOID
PrintLoadedDrivers(
HANDLE hFile
)
{
ULONG i, j, ulLen;
LPSTR s;
TCHAR ModuleName[MAX_PATH];
HANDLE FileHandle;
TCHAR KernelPath[MAX_PATH];
TCHAR DriversPath[MAX_PATH];
LPTSTR ModuleInfo;
ULONG ModuleInfoLength;
ULONG ReturnedLength;
PRTL_PROCESS_MODULES Modules;
PRTL_PROCESS_MODULE_INFORMATION Module;
NTSTATUS Status;
MODULE_DATA Sum;
MODULE_DATA Current;
__int64 timeStamp;
FILETIME ft;
SYSTEMTIME st;
WriteToLogFile(hFile, TEXT("\n"));
//
// Locate system drivers.
//
ModuleInfoLength = 64000;
while (1) {
ModuleInfo = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ModuleInfoLength * sizeof(TCHAR));
if (ModuleInfo == NULL) {
wsprintf (lpszBuffer, TEXT("Failed to allocate memory for module information buffer of size %d\n"),
ModuleInfoLength);
WriteToLogFile(hFile, lpszBuffer);
return;
}
Status = NtQuerySystemInformation (
SystemModuleInformation,
ModuleInfo,
ModuleInfoLength * sizeof(TCHAR),
&ReturnedLength);
if (!NT_SUCCESS(Status)) {
HeapFree(GetProcessHeap(), 0, (LPVOID)ModuleInfo);
if (Status == STATUS_INFO_LENGTH_MISMATCH &&
ReturnedLength > ModuleInfoLength * sizeof(TCHAR)) {
ModuleInfoLength = ReturnedLength / sizeof(TCHAR);
continue;
}
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("query system info failed status - %lx\n"),Status);
WriteToLogFile(hFile, lpszBuffer);
return;
}
break;
}
GetSystemDirectory(KernelPath,sizeof(KernelPath)/sizeof(TCHAR));
lstrcpy(DriversPath, KernelPath);
lstrcat(DriversPath,TEXT("\\Drivers"));
ZeroMemory(&Sum,sizeof(Sum));
PrintModuleHeader(hFile);
Modules = (PRTL_PROCESS_MODULES)ModuleInfo;
Module = &Modules->Modules[ 0 ];
for (i=0; i<Modules->NumberOfModules; i++) {
ZeroMemory(&Current,sizeof(Current));
s = (LPSTR)&Module->FullPathName[ Module->OffsetToFileName ];
//
// try to open the file
//
SetCurrentDirectory(KernelPath);
#ifdef _UNICODE
MultiByteToWideChar(CP_ACP, 0, s, -1, ModuleName, MAX_PATH);
#else
strcpy(ModuleName, s);
#endif //_UNICODE
FileHandle = CreateFile(
ModuleName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if ( FileHandle == INVALID_HANDLE_VALUE ) {
SetCurrentDirectory(DriversPath);
FileHandle = CreateFile(
ModuleName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
}
if ( FileHandle != INVALID_HANDLE_VALUE ) {
GetModuleData(FileHandle,&Current);
CloseHandle(FileHandle);
}
else
continue;
SumModuleData(&Sum,&Current);
if (Current.TimeDateStamp) {
timeStamp = Current.TimeDateStamp;
timeStamp += (__int64)11644444799; //difference between filetime and time_t in seconds.
timeStamp *= 10000000; // turn into 100 nano seconds.
ft.dwLowDateTime = (DWORD)timeStamp;
for (j = 0; j < 32; j++)
timeStamp /= 2;
ft.dwHighDateTime = (DWORD)timeStamp;
FileTimeToSystemTime(&ft, &st);
_stnprintf(lpszTimeBuffer, BUFFER_SIZE,
TEXT("%d-%d-%d %d:%d:%d\n"), st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond);
_stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("%12s %p %7d %7d %7d "),//%12s %p
ModuleName,
Module->ImageBase,
Current.CodeSize,
Current.DataSize,
Current.PagedSize
);
WriteToLogFile(hFile, lpszBuffer);
WriteToLogFile(hFile, lpszTimeBuffer);
} else {
_stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("%12s %p %7d %7d %7d %S"),
ModuleName,
Module->ImageBase,
Current.CodeSize,
Current.DataSize,
Current.PagedSize,
"\n"
);
WriteToLogFile(hFile, lpszBuffer);
}
Module++;
}
PrintModuleSeperator(hFile);
_stnprintf(lpszBuffer, BUFFER_SIZE, TEXT("%12S %7d %7d %7d\n"),
"Total",
Sum.CodeSize,
Sum.DataSize,
Sum.PagedSize
);
WriteToLogFile(hFile, lpszBuffer);
HeapFree(GetProcessHeap(), 0, (LPVOID)ModuleInfo);
}
void
LogLogicalDriveInfo(
HANDLE hFile
)
{
DWORD dwDriveMask;
static TCHAR* tszDrives = TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
ULARGE_INTEGER i64FreeBytesToCaller;
ULARGE_INTEGER i64TotalBytesToCaller;
ULARGE_INTEGER i64TotalFreeBytesOnDrive;
int iMask;
TCHAR tszDrive[5]; //Buffer for drive such as "A:\".
TCHAR tszBuffer[1024]; //buffer to contain info for one logical drive.
int i;
dwDriveMask = GetLogicalDrives();
if(dwDriveMask != 0){
WriteToLogFile(hFile, TEXT("Logical Drive Info:\n"));
}
for(i = 0; i < (int)_tcslen(tszDrives); i++){
iMask = dwDriveMask & 0x1;
_stprintf(tszDrive, TEXT("%c:\\"), tszDrives[i]);
dwDriveMask >>= 1;
if(iMask && GetDriveType(tszDrive) == DRIVE_FIXED
&& GetDiskFreeSpaceEx(tszDrive, &i64FreeBytesToCaller, &i64TotalBytesToCaller, &i64TotalFreeBytesOnDrive))
{
_stprintf(tszBuffer, TEXT("\t%s\n")
TEXT("\t\t Free Disk Space(Bytes): %I64d\n")
TEXT("\t\tTotal Disk Space(Bytes): %I64d\n"),
tszDrive,
i64TotalFreeBytesOnDrive,
i64TotalBytesToCaller
);
WriteToLogFile(hFile, tszBuffer);
}
}
WriteToLogFile(hFile, TEXT("\n"));
}
NTSTATUS
SnapshotRegOpenKey(
IN LPCWSTR lpKeyName,
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE KeyHandle
)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
RtlInitUnicodeString( &KeyName, lpKeyName );
RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
NTSTATUS Status;
InitializeObjectAttributes(
&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = (NTSTATUS)NtOpenKey( KeyHandle, KEY_READ, &ObjectAttributes );
return Status;
}
NTSTATUS
SnapshotRegQueryValueKey(
IN HANDLE KeyHandle,
IN LPCWSTR lpValueName,
IN ULONG Length,
OUT PVOID KeyValue,
OUT PULONG ResultLength
)
{
UNICODE_STRING ValueName;
ULONG BufferLength;
NTSTATUS Status;
PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
RtlInitUnicodeString( &ValueName, lpValueName );
BufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + Length;
KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) malloc(BufferLength);
if (KeyValueInformation == NULL) {
return STATUS_NO_MEMORY;
}
Status = NtQueryValueKey(
KeyHandle,
&ValueName,
KeyValuePartialInformation,
KeyValueInformation,
BufferLength,
ResultLength
);
if (NT_SUCCESS(Status)) {
RtlCopyMemory(KeyValue,
KeyValueInformation->Data,
KeyValueInformation->DataLength
);
*ResultLength = KeyValueInformation->DataLength;
if (KeyValueInformation->Type == REG_SZ) {
if (KeyValueInformation->DataLength + sizeof(WCHAR) > Length) {
KeyValueInformation->DataLength -= sizeof(WCHAR);
}
((PUCHAR)KeyValue)[KeyValueInformation->DataLength++] = 0;
((PUCHAR)KeyValue)[KeyValueInformation->DataLength] = 0;
*ResultLength = KeyValueInformation->DataLength + sizeof(WCHAR);
}
}
free(KeyValueInformation);
return Status;
}
NTSTATUS
SnapshotRegEnumKey(
IN HANDLE KeyHandle,
IN ULONG Index,
OUT LPWSTR lpKeyName,
OUT PULONG lpNameLength
)
{
UNICODE_STRING ValueName;
ULONG BufferLength;
NTSTATUS Status;
PKEY_BASIC_INFORMATION pKeyBasicInformation;
RtlInitUnicodeString( &ValueName, lpKeyName );
BufferLength = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + *lpNameLength;
pKeyBasicInformation = (PKEY_BASIC_INFORMATION) malloc(BufferLength);
if (pKeyBasicInformation == NULL) {
return STATUS_NO_MEMORY;
}
Status = NtEnumerateKey(
KeyHandle,
Index,
KeyBasicInformation,
(PVOID)pKeyBasicInformation,
BufferLength,
lpNameLength
);
if (NT_SUCCESS(Status)) {
RtlCopyMemory(lpKeyName,
pKeyBasicInformation->Name,
pKeyBasicInformation->NameLength
);
*lpNameLength = pKeyBasicInformation->NameLength;
if(*lpNameLength > 0)
lpKeyName[(*lpNameLength) - 1] = L'\0';
else lpKeyName[0] = L'\0';
}
free((BYTE*)pKeyBasicInformation);
return Status;
}
void
LogHardwareInfo(
HANDLE hFile
)
{
LPCWSTR ComputerNameKey = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName";
LPCWSTR ComputerNameValsz = L"ComputerName";
LPCWSTR ProcessorKey = L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
LPCWSTR ProcessorSpeedValdw = L"~MHz";
LPCWSTR ProcessorIdentifierValsz = L"Identifier";
LPCWSTR ProcessorVendorValsz = L"VendorIdentifier";
LPCWSTR NetcardKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
LPCWSTR NetcardDescsz = L"Description";
LPCWSTR NetcardServiceNamesz = L"ServiceName";
HANDLE hKey;
HANDLE hSubkey;
WCHAR szVal[MAX_PATH];
WCHAR szSubkey[MAX_PATH];
DWORD dwVal;
DWORD dwSize;
DWORD dwSubkeyIndex;
DWORD dwRes;
NTSTATUS Status = STATUS_SUCCESS;
//Get Computer Name
Status = SnapshotRegOpenKey(ComputerNameKey, KEY_READ, &hKey);
if(!NT_SUCCESS(Status)){
WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
return;
}
dwSize = MAX_PATH * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(hKey, ComputerNameValsz, dwSize, szVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
return;
}
NtClose(hKey);
WriteToLogFile(hFile, TEXT("Active Computer Name: "));
szVal[dwSize] = '\0';
WriteToLogFileW(hFile, szVal);
WriteToLogFile(hFile, TEXT("\n"));
//Get Processor Info
Status = SnapshotRegOpenKey(ProcessorKey, KEY_READ, &hKey);
if(!NT_SUCCESS(Status)){
WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
return;
}
dwSubkeyIndex = 0;
dwSize = MAX_PATH * sizeof(WCHAR);
WriteToLogFile(hFile, TEXT("Processor Info:\n"));
Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
while(NT_SUCCESS(Status)){
wcscpy(szVal, ProcessorKey);
wcscat(szVal, L"\\");
wcscat(szVal, szSubkey);
Status = SnapshotRegOpenKey(szVal, KEY_READ, &hSubkey);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
return;
}
dwSize = sizeof(DWORD);
Status = SnapshotRegQueryValueKey(hSubkey, ProcessorSpeedValdw, dwSize, &dwVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
NtClose(hSubkey);
WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
return;
}
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("\tProcessor %s:\n")
TEXT("\t\tSpeed(~MHz): %d\n"),
szSubkey, dwVal);
WriteToLogFile(hFile, lpszBuffer);
dwSize = MAX_PATH * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(hSubkey, ProcessorIdentifierValsz, dwSize, szVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
NtClose(hSubkey);
WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
return;
}
WriteToLogFile(hFile, TEXT("\t\tIdentifier: "));
WriteToLogFileW(hFile, szVal);
WriteToLogFile(hFile, TEXT("\n"));
dwSize = MAX_PATH * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(hSubkey, ProcessorVendorValsz, dwSize, &szVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
NtClose(hSubkey);
WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
return;
}
WriteToLogFile(hFile, TEXT("\t\tVendor Identifier: "));
WriteToLogFileW(hFile, szVal);
WriteToLogFile(hFile, TEXT("\n"));
NtClose(hSubkey);
dwSubkeyIndex++;
Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
}
NtClose(hKey);
//Get NetCard Info
Status = SnapshotRegOpenKey(NetcardKey, KEY_READ, &hKey);
if(!NT_SUCCESS(Status)){
WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
return;
}
WriteToLogFile(hFile, TEXT("NIC Info:\n"));
dwSubkeyIndex = 0;
dwSize = MAX_PATH * sizeof(WCHAR);
Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
while(NT_SUCCESS(Status)){
wcscpy(szVal, NetcardKey);
wcscat(szVal, L"\\");
wcscat(szVal, szSubkey);
Status = SnapshotRegOpenKey(szVal, KEY_READ, &hSubkey);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
WriteToLogFile(hFile, TEXT("Failed to open registry key for hardware information\n\n"));
return;
}
dwSize = MAX_PATH * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(hSubkey, NetcardDescsz, dwSize, &szVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
NtClose(hSubkey);
WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
return;
}
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("\tNIC %s:\n"),
szSubkey);
WriteToLogFile(hFile, lpszBuffer);
WriteToLogFile(hFile, TEXT("\t\tDescription: "));
WriteToLogFileW(hFile, szVal);
WriteToLogFile(hFile, TEXT("\n"));
dwSize = MAX_PATH * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(hSubkey, NetcardServiceNamesz, dwSize, &szVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
NtClose(hSubkey);
WriteToLogFile(hFile, TEXT("Failed to query registry key value for hardware information\n\n"));
return;
}
WriteToLogFile(hFile, TEXT("\t\tService Name: "));
WriteToLogFileW(hFile, szVal);
WriteToLogFile(hFile, TEXT("\n"));
NtClose(hSubkey);
dwSubkeyIndex++;
Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
}
NtClose(hKey);
}
BOOL
SnapshotIsVolumeName(
LPWSTR Name
)
{
if (Name[0] == '\\' &&
(Name[1] == '?' || Name[1] == '\\') &&
Name[2] == '?' &&
Name[3] == '\\' &&
Name[4] == 'V' &&
Name[5] == 'o' &&
Name[6] == 'l' &&
Name[7] == 'u' &&
Name[8] == 'm' &&
Name[9] == 'e' &&
Name[10] == '{' &&
Name[19] == '-' &&
Name[24] == '-' &&
Name[29] == '-' &&
Name[34] == '-' &&
Name[47] == '}' ) {
return TRUE;
}
return FALSE;
}
void
LogPhyicalDiskInfo(
HANDLE hFile
)
{
PMOUNTMGR_MOUNT_POINTS mountPoints;
MOUNTMGR_MOUNT_POINT mountPoint;
ULONG returnSize, success;
SYSTEM_DEVICE_INFORMATION DevInfo;
NTSTATUS Status = STATUS_SUCCESS;
ULONG NumberOfDisks;
PWCHAR deviceNameBuffer;
ULONG i;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatus;
DISK_GEOMETRY disk_geometry;
PDISK_CACHE_INFORMATION disk_cache;
PSCSI_ADDRESS scsi_address;
PWCHAR KeyName;
WCHAR wszVal[MAXSTR];
HANDLE hDisk = INVALID_HANDLE_VALUE;
UNICODE_STRING UnicodeName;
ULONG SizeNeeded;
HKEY KeyHandle;
DWORD dwSize;
//
// Get the Number of Physical Disks
//
RtlZeroMemory(&DevInfo, sizeof(DevInfo));
Status = NtQuerySystemInformation(
SystemDeviceInformation,
&DevInfo, sizeof (DevInfo), NULL);
if (!NT_SUCCESS(Status)) {
WriteToLogFile(hFile, TEXT("Failed to query system information.\n\n"));
return;
}
NumberOfDisks = DevInfo.NumberOfDisks;
//
// Open Each Physical Disk and get Disk Layout information
//
WriteToLogFile(hFile, TEXT("Physical Disk Info:\n"));
for (i=0; i < NumberOfDisks; i++) {
DISK_CACHE_INFORMATION cacheInfo;
WCHAR driveBuffer[20];
HANDLE PartitionHandle;
HANDLE KeyHandle;
ULONG DataLength;
//
// Get Partition0 handle to get the Disk layout
//
deviceNameBuffer = (PWCHAR) lpszBuffer;
swprintf(deviceNameBuffer, L"\\Device\\Harddisk%d\\Partition0", i);
RtlInitUnicodeString(&UnicodeName, deviceNameBuffer);
InitializeObjectAttributes(
&ObjectAttributes,
&UnicodeName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = NtOpenFile(
&PartitionHandle,
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
&ObjectAttributes,
&IoStatus,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE
);
if (!NT_SUCCESS(Status)) {
WriteToLogFile(hFile, TEXT("Failed calling NtOpenFile.\n\n"));
return;
}
RtlZeroMemory(&disk_geometry, sizeof(DISK_GEOMETRY));
// get geomerty information, the caller wants this
Status = NtDeviceIoControlFile(PartitionHandle,
0,
NULL,
NULL,
&IoStatus,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&disk_geometry,
sizeof (DISK_GEOMETRY)
);
if (!NT_SUCCESS(Status)) {
NtClose(PartitionHandle);
WriteToLogFile(hFile, TEXT("Failed calling NtDeviceIoControlFile 1.\n\n"));
return;
}
scsi_address = (PSCSI_ADDRESS) lpszBuffer;
Status = NtDeviceIoControlFile(PartitionHandle,
0,
NULL,
NULL,
&IoStatus,
IOCTL_SCSI_GET_ADDRESS,
NULL,
0,
scsi_address,
sizeof (SCSI_ADDRESS)
);
NtClose(PartitionHandle);
if (!NT_SUCCESS(Status)) {
WriteToLogFile(hFile, TEXT("Failed calling NtDeviceIoControlFile 2.\n\n"));
return;
}
//
// Get Manufacturer's name from Registry
// We need to get the SCSI Address and then query the Registry with it.
//
KeyName = (PWCHAR) lpszBuffer;
swprintf(KeyName,
L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi\\Scsi Port %d\\Scsi Bus %d\\Target ID %d\\Logical Unit Id %d",
scsi_address->PortNumber, scsi_address->PathId, scsi_address->TargetId, scsi_address->Lun
);
Status = SnapshotRegOpenKey(KeyName, KEY_READ, &KeyHandle);
if (!NT_SUCCESS(Status)){
WriteToLogFile(hFile, TEXT("Failed to open registry key for physical disk information\n\n"));
return;
}
else {
dwSize = MAXSTR * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(KeyHandle, L"Identifier", dwSize, wszVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(KeyHandle);
WriteToLogFile(hFile, TEXT("Failed to query registry value for physical disk information\n\n"));
return;
}
NtClose(KeyHandle);
}
//
// Package all information about this disk and write an event record
//
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("\tDisk %d:\n")
TEXT("\t\tBytes Per Sector: %d\n")
TEXT("\t\tSectors Per Track: %d\n")
TEXT("\t\tTracks Per Cylinder: %d\n")
TEXT("\t\tNumber of Cylinders: %I64d\n")
TEXT("\t\tPort Number: %d\n")
TEXT("\t\tPath ID: %d\n")
TEXT("\t\tTarget ID: %d\n")
TEXT("\t\tLun: %d\n"),
i,
disk_geometry.BytesPerSector,
disk_geometry.SectorsPerTrack,
disk_geometry.TracksPerCylinder,
disk_geometry.Cylinders.QuadPart,
scsi_address->PortNumber,
scsi_address->PathId,
scsi_address->TargetId,
scsi_address->Lun
);
WriteToLogFile(hFile, lpszBuffer);
WriteToLogFile(hFile, TEXT("\t\tManufacturer: "));
WriteToLogFileW(hFile, wszVal);
WriteToLogFile(hFile, TEXT("\n"));
}
//
// Get Logical Disk Information
//
wcscpy(wszVal, MOUNTMGR_DEVICE_NAME);
RtlInitUnicodeString(&UnicodeName, (LPWSTR)wszVal);
UnicodeName.MaximumLength = MAXSTR;
InitializeObjectAttributes(
&ObjectAttributes,
&UnicodeName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
Status = NtCreateFile(
&hDisk,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE,
NULL, 0);
if (!NT_SUCCESS(Status) ) {
WriteToLogFile(hFile, TEXT("Failed calling NtCreateFile\n\n"));
return;
}
RtlZeroMemory(lpszBuffer, MAXSTR*sizeof(WCHAR));
RtlZeroMemory(&mountPoint, sizeof(MOUNTMGR_MOUNT_POINT));
returnSize = 0;
mountPoints = (PMOUNTMGR_MOUNT_POINTS) &lpszBuffer[0];
Status = NtDeviceIoControlFile(hDisk,
0,
NULL,
NULL,
&IoStatus,
IOCTL_MOUNTMGR_QUERY_POINTS,
mountPoints,
sizeof(MOUNTMGR_MOUNT_POINT),
mountPoints,
4096
);
if (NT_SUCCESS(Status)) {
WCHAR name[MAX_PATH];
CHAR OutBuffer[MAXSTR];
PMOUNTMGR_MOUNT_POINT point;
UNICODE_STRING VolumePoint;
PVOLUME_DISK_EXTENTS VolExt;
PDISK_EXTENT DiskExt;
ULONG i;
int iDisk, iPartition;
iDisk = -1;
WriteToLogFile(hFile, TEXT("Disk Partition Info:\n"));
for (i=0; i<mountPoints->NumberOfMountPoints; i++) {
point = &mountPoints->MountPoints[i];
if (point->SymbolicLinkNameLength) {
RtlCopyMemory(name,
(PCHAR) mountPoints + point->SymbolicLinkNameOffset,
point->SymbolicLinkNameLength);
name[point->SymbolicLinkNameLength/sizeof(WCHAR)] = 0;
if (SnapshotIsVolumeName(name)) {
continue;
}
}
if (point->DeviceNameLength) {
HANDLE hVolume;
ULONG dwBytesReturned;
PSTORAGE_DEVICE_NUMBER Number;
DWORD IErrorMode;
RtlCopyMemory(name,
(PCHAR) mountPoints + point->DeviceNameOffset,
point->DeviceNameLength);
name[point->DeviceNameLength/sizeof(WCHAR)] = 0;
RtlInitUnicodeString(&UnicodeName, name);
UnicodeName.MaximumLength = MAXSTR;
//
// If the device name does not have the harddisk prefix
// then it may be a floppy or cdrom and we want avoid
// calling NtCreateFile on them.
//
if(_wcsnicmp(name,L"\\device\\harddisk",16)) {
continue;
}
InitializeObjectAttributes(
&ObjectAttributes,
&UnicodeName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
//
// We do not want any pop up dialog here in case we are unable to
// access the volume.
//
IErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
Status = NtCreateFile(
&hVolume,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0);
SetErrorMode(IErrorMode);
if (!NT_SUCCESS(Status)) {
continue;
}
RtlZeroMemory(OutBuffer, MAXSTR);
dwBytesReturned = 0;
VolExt = (PVOLUME_DISK_EXTENTS) &OutBuffer;
Status = NtDeviceIoControlFile(hVolume,
0,
NULL,
NULL,
&IoStatus,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL,
0,
&OutBuffer,
4096
);
if (NT_SUCCESS(Status) ) {
ULONG j;
ULONG NumberOfExtents = VolExt->NumberOfDiskExtents;
TCHAR tszTemp[MAXSTR];
if(iDisk == -1 || iDisk != (&VolExt->Extents[0])->DiskNumber){
_stnprintf(tszTemp, MAXSTR, TEXT("\tDisk %d:\n"), (&VolExt->Extents[0])->DiskNumber);
WriteToLogFile(hFile, tszTemp);
iDisk = (&VolExt->Extents[0])->DiskNumber;
iPartition = 0;
}
_stnprintf(tszTemp, MAXSTR,
TEXT("\t\tPartition %d:\n"),
iPartition);
WriteToLogFile(hFile, tszTemp);
for (j=0; j < NumberOfExtents; j++) {
DiskExt = &VolExt->Extents[j];
_stnprintf(tszTemp, MAXSTR,
TEXT("\t\t\tExtent %d(disk %d):\n")
TEXT("\t\t\t\tStartingOffset: %I64d\n")
TEXT("\t\t\t\tPartitionSize: %I64d\n"),
j,
DiskExt->DiskNumber,
DiskExt->StartingOffset.QuadPart,
DiskExt->ExtentLength.QuadPart);
WriteToLogFile(hFile, tszTemp);
}
iPartition++;
}
NtClose(hVolume);
}
}
}
NtClose(hDisk);
}
void
LogHotfixes(
HANDLE hFile
)
{
LPCWSTR HotFixKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix";
LPCWSTR wszValName = L"Installed";
HANDLE hKey, hSubkey;
NTSTATUS Status = STATUS_SUCCESS;
UINT i;
DWORD dwSize, dwVal, dwSubkeyIndex;
WCHAR szKey[MAXSTR];
WCHAR szSubkey[MAXSTR];
Status = SnapshotRegOpenKey(HotFixKey, KEY_READ, &hKey);
if (!NT_SUCCESS(Status) ) {
WriteToLogFile(hFile, TEXT("Hotfix registry key does not exist or open failed\n\n"));
return;
}
WriteToLogFile(hFile, TEXT("Hotfix Info:\n"));
dwSubkeyIndex = 0;
dwSize = MAXSTR * sizeof(WCHAR);
Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
while(NT_SUCCESS(Status)){
wcscpy(szKey, HotFixKey);
wcscat(szKey, L"\\");
wcscat(szKey, szSubkey);
Status = SnapshotRegOpenKey(szKey, KEY_READ, &hSubkey);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
return;
}
dwSize = sizeof(DWORD);
Status = SnapshotRegQueryValueKey(hSubkey, wszValName, dwSize, &dwVal, &dwSize);
if(!NT_SUCCESS(Status)){
NtClose(hKey);
NtClose(hSubkey);
WriteToLogFile(hFile, TEXT("Failed to query registry key value for hotfix info\n\n"));
return;
}
_stnprintf(lpszBuffer, BUFFER_SIZE,
TEXT("\t%s: %d\n"),
szSubkey, dwVal);
WriteToLogFile(hFile, lpszBuffer);
NtClose(hSubkey);
dwSubkeyIndex++;
Status = SnapshotRegEnumKey(hKey, dwSubkeyIndex, szSubkey, &dwSize);
}
NtClose(hKey);
}
void
LogOsInfo(
HANDLE hFile
)
{
LPCWSTR OsInfoKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion";
LPCWSTR awszValName[] = {
L"BuildLab",
L"CurrentBuildNumber",
L"CurrentType",
L"CurrentVersion",
//L"InstallDate",
L"PathName",
L"ProductId",
L"ProductName",
L"RegDone",
L"RegisteredOrgnization",
L"RegisteredOwner",
L"SoftwareType",
L"SourcePath",
L"SystemRoot",
L"CSDVersion"
};
UINT uVals = sizeof(awszValName) / sizeof(LPCWSTR);
HANDLE hKey;
NTSTATUS Status = STATUS_SUCCESS;
UINT i;
WCHAR wszVal[MAXSTR];
DWORD dwSize;
Status = SnapshotRegOpenKey(OsInfoKey, KEY_READ, &hKey);
if (!NT_SUCCESS(Status) ) {
WriteToLogFile(hFile, TEXT("Failed to open registry key for os version info\n\n"));
return;
}
WriteToLogFile(hFile, TEXT("OS Version Info:\n"));
for(i = 0; i < uVals; i++){
dwSize = MAXSTR * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(hKey, awszValName[i], dwSize, wszVal, &dwSize);
if(!NT_SUCCESS(Status)){
continue;
}
WriteToLogFile(hFile, TEXT("\t"));
WriteToLogFileW(hFile, awszValName[i]);
WriteToLogFile(hFile, TEXT(": "));
WriteToLogFileW(hFile, wszVal);
WriteToLogFile(hFile, TEXT("\n"));
}
NtClose(hKey);
}
void
LogBIOSInfo(
HANDLE hFile
)
{
LPCWSTR BiosInfoKey = L"\\Registry\\Machine\\Hardware\\Description\\System";
LPCWSTR awszValName[] = {
L"Identifier",
L"SystemBiosDate",
L"SystemBiosVersion",
L"VideoBiosDate",
L"VideoBiosVersion"
};
UINT uVals = sizeof(awszValName) / sizeof(LPCWSTR);
HANDLE hKey;
NTSTATUS Status = STATUS_SUCCESS;
UINT i;
WCHAR wszVal[MAXSTR];
LPWSTR pwsz;
DWORD dwSize, dwLen;
Status = SnapshotRegOpenKey(BiosInfoKey, KEY_READ, &hKey);
if (!NT_SUCCESS(Status) ) {
WriteToLogFile(hFile, TEXT("Failed to open registry key for BIOS info\n\n"));
return;
}
WriteToLogFile(hFile, TEXT("BIOS Info:\n"));
for(i = 0; i < uVals; i++){
dwSize = MAXSTR * sizeof(WCHAR);
Status = SnapshotRegQueryValueKey(hKey, awszValName[i], dwSize, wszVal, &dwSize);
if(!NT_SUCCESS(Status)){
continue;
}
WriteToLogFile(hFile, TEXT("\t"));
WriteToLogFileW(hFile, awszValName[i]);
WriteToLogFile(hFile, TEXT(": "));
dwLen = 0;
pwsz = wszVal;
while(dwLen + 1< dwSize / sizeof(WCHAR)){
if(dwLen != 0)
WriteToLogFile(hFile, TEXT(" "));
WriteToLogFileW(hFile, pwsz);
dwLen += wcslen(pwsz) + 1;
pwsz += wcslen(pwsz) + 1;
}
WriteToLogFile(hFile, TEXT("\n"));
}
NtClose(hKey);
}
void
DeleteOldFiles(
LPCTSTR lpPath
)
{
LPCWSTR ReliabilityKey = L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Reliability";
LPCWSTR lpValName = L"SnapshotHistoryFiles";
HANDLE hKey, hFile;
NTSTATUS Status = STATUS_SUCCESS;
DWORD dwSize, dwVal;
TCHAR szFileName[MAX_PATH];
WIN32_FIND_DATA winData;
BOOL bFound = TRUE;
SYSTEMTIME systime;
FILETIME filetime;
__int64 i64Filetime, i64Filetime1;
GetSystemTime(&systime);
SystemTimeToFileTime(&systime, &filetime);
i64Filetime = (__int64)filetime.dwHighDateTime;
i64Filetime <<= 32;
i64Filetime |= (__int64)filetime.dwLowDateTime;
Status = SnapshotRegOpenKey(ReliabilityKey, KEY_ALL_ACCESS, &hKey);
if (NT_SUCCESS(Status)){
dwSize = sizeof(DWORD);
Status = SnapshotRegQueryValueKey(hKey, lpValName, dwSize, &dwVal, &dwSize);
if(!NT_SUCCESS(Status)){
dwVal = DEFAULT_HISTORYFILES;
}
NtClose(hKey);
}
else {
dwVal = DEFAULT_HISTORYFILES;
}
lstrcpy(szFileName, lpPath);
lstrcat(szFileName, TEXT("\\ShutDown_on_*"));
hFile = FindFirstFile(szFileName, &winData);
while(hFile != INVALID_HANDLE_VALUE && bFound){
i64Filetime1 = (__int64)winData.ftCreationTime.dwHighDateTime;
i64Filetime1 <<= 32;
i64Filetime1 |= (__int64)winData.ftCreationTime.dwLowDateTime;
if(i64Filetime - i64Filetime1 >= (const __int64)24*60*60*10000000 * dwVal){
lstrcpy(szFileName, lpPath);
lstrcat(szFileName, TEXT("\\"));
lstrcat(szFileName,winData.cFileName);
DeleteFile(szFileName);
}
bFound = FindNextFile(hFile, &winData);
}
if(hFile != INVALID_HANDLE_VALUE)
FindClose(hFile);
}