windows-nt/Source/XPSP1/NT/base/ntos/po/tests/vhib/vhib.c
2020-09-26 16:20:57 +08:00

402 lines
10 KiB
C

/*****************************************************************/
/** Microsoft LAN Manager **/
/** Copyright(c) Microsoft Corp., 1988-1991 **/
/*****************************************************************/
#include <stdio.h>
#include <process.h>
#include <setjmp.h>
#include <stdlib.h>
#include <time.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
//
// Memory map information
//
// from po.h
typedef struct _PO_MEMORY_RANGE_ARRAY {
union {
struct {
ULONG PageNo;
ULONG StartPage;
ULONG EndPage;
ULONG CheckSum;
} Range;
struct {
struct _PO_MEMORY_RANGE_ARRAY *Next;
ULONG NextTable;
ULONG CheckSum;
ULONG EntryCount;
} Link;
};
} PO_MEMORY_RANGE_ARRAY, *PPO_MEMORY_RANGE_ARRAY;
#define PO_MAX_RANGE_ARRAY (PAGE_SIZE / sizeof(PO_MEMORY_RANGE_ARRAY))
#define PO_ENTRIES_PER_PAGE (PO_MAX_RANGE_ARRAY-1)
#define PO_IMAGE_SIGNATURE 'rbih'
#define PO_IMAGE_SIGNATURE_WAKE 'ekaw'
#define PO_IMAGE_SIGNATURE_BREAK 'pkrb'
#define PO_IMAGE_HEADER_PAGE 0
#define PO_FREE_MAP_PAGE 1
#define PO_PROCESSOR_CONTEXT_PAGE 2
#define PO_FIRST_RANGE_TABLE_PAGE 3
typedef struct {
ULONG Signature;
ULONG Version;
ULONG CheckSum;
ULONG LengthSelf;
ULONG PageSelf;
ULONG PageSize;
ULONG ImageType;
LARGE_INTEGER SystemTime;
ULONGLONG InterruptTime;
ULONG FeatureFlags;
UCHAR spare[4];
ULONG NoHiberPtes;
ULONG HiberVa;
PHYSICAL_ADDRESS HiberPte;
ULONG NoFreePages;
ULONG FreeMapCheck;
ULONG WakeCheck;
ULONG TotalPages;
ULONG FirstTablePage;
ULONG LastFilePage;
} PO_MEMORY_IMAGE, *PPO_MEMORY_IMAGE;
PPO_MEMORY_IMAGE MemImage;
PPO_MEMORY_RANGE_ARRAY Table;
FILE *FpHiber, *FpHiberDbg, *FpDump;
FILE *FpSrc1, *FpSrc2;
ULONG PagesRead;
PVOID CompBuffer;
PVOID CompFragmentBuffer;
ULONG CompressedSize;
#define PAGE_SIZE 4096
#define SECTOR_SIZE 512
VOID
CheckFile (
IN FILE *Src1,
IN FILE *Src2,
IN BOOLEAN Verify,
IN BOOLEAN Compress
);
VOID __cdecl
main (argc, argv)
int argc;
char *argv[];
{
FpHiber = fopen("\\hiberfil.sys", "rb");
if (!FpHiber) {
printf ("Failed to open \\hiberfil.sys\n");
exit (1);
}
FpDump = fopen("fdump", "wb");
if (!FpHiber) {
printf ("Failed to open fdump\n");
exit (1);
}
FpHiberDbg = fopen("\\hiberfil.dbg", "rb");
//
// If only FpHiber, read it, verify it and compress it
//
if (!FpHiberDbg) {
CheckFile (FpHiber, NULL, TRUE, TRUE);
exit (0);
}
//
// FpHiber & FpHiberDbg.
// verify FpHiber
// verify FpHiberDbg
// compare FpHiber & FpHiberDbg
//
printf ("Dump of hiberfil.sys:\n");
CheckFile (FpHiber, NULL, TRUE, FALSE);
printf ("\n");
printf ("Dump of hiberfil.dbg:\n");
CheckFile (FpHiberDbg, NULL, TRUE, FALSE);
printf ("\n");
printf ("Compare of hiberfil.sys & hiberfil.dbg:\n");
CheckFile (FpHiber, FpHiberDbg, FALSE, FALSE);
}
ULONG
SimpleCheck (
IN ULONG PartialSum,
IN PVOID SourceVa,
IN ULONG Length
)
{
PUSHORT Source;
Source = (PUSHORT) SourceVa;
Length = Length / 2;
while (Length--) {
PartialSum += *Source++;
PartialSum = (PartialSum >> 16) + (PartialSum & 0xFFFF);
}
return PartialSum;
}
VOID
ReadPage (
IN ULONG PageNo,
IN PUCHAR Buffer
)
{
UCHAR BufferDbg[PAGE_SIZE];
ULONG i, j, Hits;
fseek (FpSrc1, PageNo * PAGE_SIZE, SEEK_SET);
fread (Buffer, PAGE_SIZE, 1, FpSrc1);
if (FpSrc2) {
fseek (FpSrc2, PageNo * PAGE_SIZE, SEEK_SET);
fread (BufferDbg, PAGE_SIZE, 1, FpSrc2);
Hits = 0;
for (i=0; i < PAGE_SIZE; i++) {
if (Buffer[i] != BufferDbg[i]) {
for (j=i; j < PAGE_SIZE; j++) {
if (Buffer[j] == BufferDbg[j]) {
break;
}
}
if (!Hits) {
printf (" Page %08x: ", PageNo);
} else {
printf (", ");
}
if (Hits > 3) {
printf ("...");
break;
}
Hits += 1;
printf ("%04x-%04x", i, j-1);
i = j;
}
}
if (Hits) {
printf ("\n");
}
}
PagesRead += 1;
}
BOOLEAN
CheckZeroPage (
IN PULONG Buffer
)
{
ULONG i;
UCHAR NewBuffer[PAGE_SIZE*2];
ULONG NewBufferSize;
NTSTATUS Status;
Status = RtlCompressBuffer (
COMPRESSION_FORMAT_LZNT1,
Buffer,
PAGE_SIZE,
NewBuffer,
PAGE_SIZE*2,
PAGE_SIZE,
&NewBufferSize,
CompBuffer
);
CompressedSize += NewBufferSize;
for (i=0; i < PAGE_SIZE/sizeof(ULONG); i++) {
if (Buffer[i]) {
return FALSE;
}
}
return TRUE;
}
VOID
CheckFile (
IN FILE *Src1,
IN FILE *Src2,
IN BOOLEAN Verify,
IN BOOLEAN Compress
)
{
ULONG FilePage, DestPage, PageNo, TablePage, Index, Check;
PUCHAR Buffer;
ULONG NoRuns;
ULONG MaxPageCount;
ULONG PageCount;
ULONG NoZeroPages;
ULONG CompBufferSize;
ULONG CompFragmentBufferSize;
ULONG CompressedSectors;
ULONG ZeroRuns;
BOOLEAN ZeroRun;
ULONG i;
FpSrc1 = Src1;
FpSrc2 = Src2;
RtlGetCompressionWorkSpaceSize (
COMPRESSION_FORMAT_LZNT1,
&CompBufferSize,
&CompFragmentBufferSize
);
CompBuffer = malloc(CompBufferSize);
CompFragmentBuffer = malloc(CompFragmentBufferSize);
if (Compress) {
printf ("Comp %d %d\n", CompBufferSize, CompFragmentBufferSize);
}
MemImage = malloc(PAGE_SIZE);
Buffer = malloc(PAGE_SIZE);
Table = malloc(PAGE_SIZE);
ReadPage (PO_IMAGE_HEADER_PAGE, MemImage);
Check = MemImage->CheckSum;
MemImage->CheckSum = 0;
if (Verify && Check != SimpleCheck(0, MemImage, MemImage->LengthSelf)) {
printf ("Checksum on image header bad\n");
}
ReadPage (PO_FREE_MAP_PAGE, Buffer);
if (Verify && MemImage->FreeMapCheck != SimpleCheck(0, Buffer, PAGE_SIZE)) {
printf ("Checksum on free page map bad\n");
}
ReadPage (PO_PROCESSOR_CONTEXT_PAGE, Buffer);
if (Verify && MemImage->WakeCheck != SimpleCheck(0, Buffer, PAGE_SIZE)) {
printf ("Checksum on processor context page bad\n");
}
NoRuns = 0;
MaxPageCount = 0;
NoZeroPages = 0;
CompressedSectors = 0;
ZeroRuns = 0;
TablePage = MemImage->FirstTablePage;
while (TablePage) {
ReadPage (TablePage, Table);
Check = Table[0].Link.CheckSum;
Table[0].Link.CheckSum = 0;
if (Verify && Check != SimpleCheck(0, Table, PAGE_SIZE)) {
printf ("Checksum on table page %d bad\n", TablePage);
}
for (Index=1; Index <= Table[0].Link.EntryCount; Index++) {
Check = 0;
DestPage = Table[Index].Range.StartPage;
FilePage = Table[Index].Range.PageNo;
ZeroRun = TRUE;
CompressedSize = 0;
NoRuns += 1;
PageCount = Table[Index].Range.EndPage - DestPage;
if (PageCount > MaxPageCount) {
MaxPageCount += PageCount;
}
while (DestPage < Table[Index].Range.EndPage) {
ReadPage (FilePage, Buffer);
if (Compress) {
if (CheckZeroPage(Buffer)) {
NoZeroPages += 1;
} else {
ZeroRun = FALSE;
}
}
if (Verify) {
Check = SimpleCheck(Check, Buffer, PAGE_SIZE);
if (DestPage >= 0x1a && DestPage < 0x32) {
fwrite (Buffer, PAGE_SIZE, 1, FpDump);
}
}
FilePage += 1;
DestPage += 1;
}
i = CompressedSize / SECTOR_SIZE;
if (CompressedSize % SECTOR_SIZE) {
i += 1;
}
CompressedSectors += i;
if (ZeroRun) {
ZeroRuns += 1;
}
if (Verify && Check != Table[Index].Range.CheckSum) {
printf ("Hit on range %08x - %08x. Tbl %08x %08x, File %08x %08x\n",
Table[Index].Range.StartPage,
Table[Index].Range.EndPage,
TablePage,
Table[Index].Range.CheckSum,
Table[Index].Range.PageNo,
Check
);
}
}
TablePage = Table[0].Link.NextTable;
}
if (Verify && Compress) {
printf ("Image check complete.\n");
printf ("Pages verified..: %d\n", PagesRead);
printf ("No runs.........: %d\n", NoRuns);
printf ("Average run.....: %d\n", PagesRead/ NoRuns);
printf ("Max run.........: %d\n", MaxPageCount);
printf ("No zero pages...: %d\n", NoZeroPages);
printf ("Compressed sect.: %d\n", CompressedSectors);
printf ("as pages........: %d\n", CompressedSectors * SECTOR_SIZE / PAGE_SIZE);
printf ("Zero runs.......: %d\n", ZeroRuns);
}
}