Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
10 KiB

  1. /*****************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1988-1991 **/
  4. /*****************************************************************/
  5. #include <stdio.h>
  6. #include <process.h>
  7. #include <setjmp.h>
  8. #include <stdlib.h>
  9. #include <time.h>
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <windows.h>
  14. //
  15. // Memory map information
  16. //
  17. // from po.h
  18. typedef struct _PO_MEMORY_RANGE_ARRAY {
  19. union {
  20. struct {
  21. ULONG PageNo;
  22. ULONG StartPage;
  23. ULONG EndPage;
  24. ULONG CheckSum;
  25. } Range;
  26. struct {
  27. struct _PO_MEMORY_RANGE_ARRAY *Next;
  28. ULONG NextTable;
  29. ULONG CheckSum;
  30. ULONG EntryCount;
  31. } Link;
  32. };
  33. } PO_MEMORY_RANGE_ARRAY, *PPO_MEMORY_RANGE_ARRAY;
  34. #define PO_MAX_RANGE_ARRAY (PAGE_SIZE / sizeof(PO_MEMORY_RANGE_ARRAY))
  35. #define PO_ENTRIES_PER_PAGE (PO_MAX_RANGE_ARRAY-1)
  36. #define PO_IMAGE_SIGNATURE 'rbih'
  37. #define PO_IMAGE_SIGNATURE_WAKE 'ekaw'
  38. #define PO_IMAGE_SIGNATURE_BREAK 'pkrb'
  39. #define PO_IMAGE_HEADER_PAGE 0
  40. #define PO_FREE_MAP_PAGE 1
  41. #define PO_PROCESSOR_CONTEXT_PAGE 2
  42. #define PO_FIRST_RANGE_TABLE_PAGE 3
  43. typedef struct {
  44. ULONG Signature;
  45. ULONG Version;
  46. ULONG CheckSum;
  47. ULONG LengthSelf;
  48. ULONG PageSelf;
  49. ULONG PageSize;
  50. ULONG ImageType;
  51. LARGE_INTEGER SystemTime;
  52. ULONGLONG InterruptTime;
  53. ULONG FeatureFlags;
  54. UCHAR spare[4];
  55. ULONG NoHiberPtes;
  56. ULONG HiberVa;
  57. PHYSICAL_ADDRESS HiberPte;
  58. ULONG NoFreePages;
  59. ULONG FreeMapCheck;
  60. ULONG WakeCheck;
  61. ULONG TotalPages;
  62. ULONG FirstTablePage;
  63. ULONG LastFilePage;
  64. } PO_MEMORY_IMAGE, *PPO_MEMORY_IMAGE;
  65. PPO_MEMORY_IMAGE MemImage;
  66. PPO_MEMORY_RANGE_ARRAY Table;
  67. FILE *FpHiber, *FpHiberDbg, *FpDump;
  68. FILE *FpSrc1, *FpSrc2;
  69. ULONG PagesRead;
  70. PVOID CompBuffer;
  71. PVOID CompFragmentBuffer;
  72. ULONG CompressedSize;
  73. #define PAGE_SIZE 4096
  74. #define SECTOR_SIZE 512
  75. VOID
  76. CheckFile (
  77. IN FILE *Src1,
  78. IN FILE *Src2,
  79. IN BOOLEAN Verify,
  80. IN BOOLEAN Compress
  81. );
  82. VOID __cdecl
  83. main (argc, argv)
  84. int argc;
  85. char *argv[];
  86. {
  87. FpHiber = fopen("\\hiberfil.sys", "rb");
  88. if (!FpHiber) {
  89. printf ("Failed to open \\hiberfil.sys\n");
  90. exit (1);
  91. }
  92. FpDump = fopen("fdump", "wb");
  93. if (!FpHiber) {
  94. printf ("Failed to open fdump\n");
  95. exit (1);
  96. }
  97. FpHiberDbg = fopen("\\hiberfil.dbg", "rb");
  98. //
  99. // If only FpHiber, read it, verify it and compress it
  100. //
  101. if (!FpHiberDbg) {
  102. CheckFile (FpHiber, NULL, TRUE, TRUE);
  103. exit (0);
  104. }
  105. //
  106. // FpHiber & FpHiberDbg.
  107. // verify FpHiber
  108. // verify FpHiberDbg
  109. // compare FpHiber & FpHiberDbg
  110. //
  111. printf ("Dump of hiberfil.sys:\n");
  112. CheckFile (FpHiber, NULL, TRUE, FALSE);
  113. printf ("\n");
  114. printf ("Dump of hiberfil.dbg:\n");
  115. CheckFile (FpHiberDbg, NULL, TRUE, FALSE);
  116. printf ("\n");
  117. printf ("Compare of hiberfil.sys & hiberfil.dbg:\n");
  118. CheckFile (FpHiber, FpHiberDbg, FALSE, FALSE);
  119. }
  120. ULONG
  121. SimpleCheck (
  122. IN ULONG PartialSum,
  123. IN PVOID SourceVa,
  124. IN ULONG Length
  125. )
  126. {
  127. PUSHORT Source;
  128. Source = (PUSHORT) SourceVa;
  129. Length = Length / 2;
  130. while (Length--) {
  131. PartialSum += *Source++;
  132. PartialSum = (PartialSum >> 16) + (PartialSum & 0xFFFF);
  133. }
  134. return PartialSum;
  135. }
  136. VOID
  137. ReadPage (
  138. IN ULONG PageNo,
  139. IN PUCHAR Buffer
  140. )
  141. {
  142. UCHAR BufferDbg[PAGE_SIZE];
  143. ULONG i, j, Hits;
  144. fseek (FpSrc1, PageNo * PAGE_SIZE, SEEK_SET);
  145. fread (Buffer, PAGE_SIZE, 1, FpSrc1);
  146. if (FpSrc2) {
  147. fseek (FpSrc2, PageNo * PAGE_SIZE, SEEK_SET);
  148. fread (BufferDbg, PAGE_SIZE, 1, FpSrc2);
  149. Hits = 0;
  150. for (i=0; i < PAGE_SIZE; i++) {
  151. if (Buffer[i] != BufferDbg[i]) {
  152. for (j=i; j < PAGE_SIZE; j++) {
  153. if (Buffer[j] == BufferDbg[j]) {
  154. break;
  155. }
  156. }
  157. if (!Hits) {
  158. printf (" Page %08x: ", PageNo);
  159. } else {
  160. printf (", ");
  161. }
  162. if (Hits > 3) {
  163. printf ("...");
  164. break;
  165. }
  166. Hits += 1;
  167. printf ("%04x-%04x", i, j-1);
  168. i = j;
  169. }
  170. }
  171. if (Hits) {
  172. printf ("\n");
  173. }
  174. }
  175. PagesRead += 1;
  176. }
  177. BOOLEAN
  178. CheckZeroPage (
  179. IN PULONG Buffer
  180. )
  181. {
  182. ULONG i;
  183. UCHAR NewBuffer[PAGE_SIZE*2];
  184. ULONG NewBufferSize;
  185. NTSTATUS Status;
  186. Status = RtlCompressBuffer (
  187. COMPRESSION_FORMAT_LZNT1,
  188. Buffer,
  189. PAGE_SIZE,
  190. NewBuffer,
  191. PAGE_SIZE*2,
  192. PAGE_SIZE,
  193. &NewBufferSize,
  194. CompBuffer
  195. );
  196. CompressedSize += NewBufferSize;
  197. for (i=0; i < PAGE_SIZE/sizeof(ULONG); i++) {
  198. if (Buffer[i]) {
  199. return FALSE;
  200. }
  201. }
  202. return TRUE;
  203. }
  204. VOID
  205. CheckFile (
  206. IN FILE *Src1,
  207. IN FILE *Src2,
  208. IN BOOLEAN Verify,
  209. IN BOOLEAN Compress
  210. )
  211. {
  212. ULONG FilePage, DestPage, PageNo, TablePage, Index, Check;
  213. PUCHAR Buffer;
  214. ULONG NoRuns;
  215. ULONG MaxPageCount;
  216. ULONG PageCount;
  217. ULONG NoZeroPages;
  218. ULONG CompBufferSize;
  219. ULONG CompFragmentBufferSize;
  220. ULONG CompressedSectors;
  221. ULONG ZeroRuns;
  222. BOOLEAN ZeroRun;
  223. ULONG i;
  224. FpSrc1 = Src1;
  225. FpSrc2 = Src2;
  226. RtlGetCompressionWorkSpaceSize (
  227. COMPRESSION_FORMAT_LZNT1,
  228. &CompBufferSize,
  229. &CompFragmentBufferSize
  230. );
  231. CompBuffer = malloc(CompBufferSize);
  232. CompFragmentBuffer = malloc(CompFragmentBufferSize);
  233. if (Compress) {
  234. printf ("Comp %d %d\n", CompBufferSize, CompFragmentBufferSize);
  235. }
  236. MemImage = malloc(PAGE_SIZE);
  237. Buffer = malloc(PAGE_SIZE);
  238. Table = malloc(PAGE_SIZE);
  239. ReadPage (PO_IMAGE_HEADER_PAGE, MemImage);
  240. Check = MemImage->CheckSum;
  241. MemImage->CheckSum = 0;
  242. if (Verify && Check != SimpleCheck(0, MemImage, MemImage->LengthSelf)) {
  243. printf ("Checksum on image header bad\n");
  244. }
  245. ReadPage (PO_FREE_MAP_PAGE, Buffer);
  246. if (Verify && MemImage->FreeMapCheck != SimpleCheck(0, Buffer, PAGE_SIZE)) {
  247. printf ("Checksum on free page map bad\n");
  248. }
  249. ReadPage (PO_PROCESSOR_CONTEXT_PAGE, Buffer);
  250. if (Verify && MemImage->WakeCheck != SimpleCheck(0, Buffer, PAGE_SIZE)) {
  251. printf ("Checksum on processor context page bad\n");
  252. }
  253. NoRuns = 0;
  254. MaxPageCount = 0;
  255. NoZeroPages = 0;
  256. CompressedSectors = 0;
  257. ZeroRuns = 0;
  258. TablePage = MemImage->FirstTablePage;
  259. while (TablePage) {
  260. ReadPage (TablePage, Table);
  261. Check = Table[0].Link.CheckSum;
  262. Table[0].Link.CheckSum = 0;
  263. if (Verify && Check != SimpleCheck(0, Table, PAGE_SIZE)) {
  264. printf ("Checksum on table page %d bad\n", TablePage);
  265. }
  266. for (Index=1; Index <= Table[0].Link.EntryCount; Index++) {
  267. Check = 0;
  268. DestPage = Table[Index].Range.StartPage;
  269. FilePage = Table[Index].Range.PageNo;
  270. ZeroRun = TRUE;
  271. CompressedSize = 0;
  272. NoRuns += 1;
  273. PageCount = Table[Index].Range.EndPage - DestPage;
  274. if (PageCount > MaxPageCount) {
  275. MaxPageCount += PageCount;
  276. }
  277. while (DestPage < Table[Index].Range.EndPage) {
  278. ReadPage (FilePage, Buffer);
  279. if (Compress) {
  280. if (CheckZeroPage(Buffer)) {
  281. NoZeroPages += 1;
  282. } else {
  283. ZeroRun = FALSE;
  284. }
  285. }
  286. if (Verify) {
  287. Check = SimpleCheck(Check, Buffer, PAGE_SIZE);
  288. if (DestPage >= 0x1a && DestPage < 0x32) {
  289. fwrite (Buffer, PAGE_SIZE, 1, FpDump);
  290. }
  291. }
  292. FilePage += 1;
  293. DestPage += 1;
  294. }
  295. i = CompressedSize / SECTOR_SIZE;
  296. if (CompressedSize % SECTOR_SIZE) {
  297. i += 1;
  298. }
  299. CompressedSectors += i;
  300. if (ZeroRun) {
  301. ZeroRuns += 1;
  302. }
  303. if (Verify && Check != Table[Index].Range.CheckSum) {
  304. printf ("Hit on range %08x - %08x. Tbl %08x %08x, File %08x %08x\n",
  305. Table[Index].Range.StartPage,
  306. Table[Index].Range.EndPage,
  307. TablePage,
  308. Table[Index].Range.CheckSum,
  309. Table[Index].Range.PageNo,
  310. Check
  311. );
  312. }
  313. }
  314. TablePage = Table[0].Link.NextTable;
  315. }
  316. if (Verify && Compress) {
  317. printf ("Image check complete.\n");
  318. printf ("Pages verified..: %d\n", PagesRead);
  319. printf ("No runs.........: %d\n", NoRuns);
  320. printf ("Average run.....: %d\n", PagesRead/ NoRuns);
  321. printf ("Max run.........: %d\n", MaxPageCount);
  322. printf ("No zero pages...: %d\n", NoZeroPages);
  323. printf ("Compressed sect.: %d\n", CompressedSectors);
  324. printf ("as pages........: %d\n", CompressedSectors * SECTOR_SIZE / PAGE_SIZE);
  325. printf ("Zero runs.......: %d\n", ZeroRuns);
  326. }
  327. }