15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains unit tests for PEImage.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/pe_image.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Just counts the number of invocations.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExportsCallback(const PEImage &image,
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     DWORD ordinal,
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     DWORD hint,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     LPCSTR name,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     PVOID function,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     LPCSTR forward,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     PVOID cookie) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* count = reinterpret_cast<int*>(cookie);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*count)++;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Just counts the number of invocations.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImportsCallback(const PEImage &image,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     LPCSTR module,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     DWORD ordinal,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     LPCSTR name,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     DWORD hint,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     PIMAGE_THUNK_DATA iat,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     PVOID cookie) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* count = reinterpret_cast<int*>(cookie);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*count)++;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Just counts the number of invocations.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SectionsCallback(const PEImage &image,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       PIMAGE_SECTION_HEADER header,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       PVOID section_start,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       DWORD section_size,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       PVOID cookie) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* count = reinterpret_cast<int*>(cookie);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*count)++;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Just counts the number of invocations.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RelocsCallback(const PEImage &image,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    WORD type,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PVOID address,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PVOID cookie) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* count = reinterpret_cast<int*>(cookie);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*count)++;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Just counts the number of invocations.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImportChunksCallback(const PEImage &image,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LPCSTR module,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          PIMAGE_THUNK_DATA name_table,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          PIMAGE_THUNK_DATA iat,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          PVOID cookie) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* count = reinterpret_cast<int*>(cookie);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*count)++;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Just counts the number of invocations.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DelayImportChunksCallback(const PEImage &image,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PImgDelayDescr delay_descriptor,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               LPCSTR module,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PIMAGE_THUNK_DATA name_table,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PIMAGE_THUNK_DATA iat,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PIMAGE_THUNK_DATA bound_iat,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PIMAGE_THUNK_DATA unload_iat,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PVOID cookie) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* count = reinterpret_cast<int*>(cookie);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*count)++;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Identifiers for the set of supported expectations.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ExpectationSet {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WIN_2K_SET,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WIN_XP_SET,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WIN_VISTA_SET,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WIN_7_SET,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WIN_8_SET,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNSUPPORTED_SET,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We'll be using some known values for the tests.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum Value {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sections = 0,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  imports_dlls,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delay_dlls,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exports,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  imports,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delay_imports,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  relocs
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExpectationSet GetExpectationSet(DWORD os) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os == 50)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WIN_2K_SET;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os == 51)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WIN_XP_SET;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os == 60)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WIN_VISTA_SET;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os == 61)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WIN_7_SET;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os >= 62)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WIN_8_SET;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return UNSUPPORTED_SET;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Retrieves the expected value from advapi32.dll based on the OS.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetExpectedValue(Value value, DWORD os) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int xp_delay_dlls = 2;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int xp_exports = 675;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int xp_imports = 422;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int xp_delay_imports = 8;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int xp_relocs = 9180;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int vista_delay_dlls = 4;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int vista_exports = 799;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int vista_imports = 476;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int vista_delay_imports = 24;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int vista_relocs = 10188;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int w2k_delay_dlls = 0;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int w2k_exports = 566;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int w2k_imports = 357;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int w2k_delay_imports = 0;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int w2k_relocs = 7388;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win7_delay_dlls = 7;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win7_exports = 806;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win7_imports = 568;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win7_delay_imports = 71;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int win7_relocs = 7812;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int win7_sections = 4;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win8_delay_dlls = 9;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win8_exports = 806;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win8_imports = 568;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win8_delay_imports = 113;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int win8_relocs = 9478;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int win8_sections = 4;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int win8_import_dlls = 17;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 32-bit process on a 32-bit system.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os_info->architecture() == base::win::OSInfo::X86_ARCHITECTURE) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    win8_sections = 5;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    win8_import_dlls = 19;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 64-bit process on a 64-bit system.
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (os_info->wow64_status() == base::win::OSInfo::WOW64_DISABLED) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    win7_sections = 6;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    win7_relocs = 2712;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Contains the expected value, for each enumerated property (Value), and the
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OS version: [Value][os_version]
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int expected[][5] = {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {4, 4, 4, win7_sections, win8_sections},
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {3, 3, 3, 13, win8_import_dlls},
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {w2k_delay_dlls, xp_delay_dlls, vista_delay_dlls, win7_delay_dlls,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     win8_delay_dlls},
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {w2k_exports, xp_exports, vista_exports, win7_exports, win8_exports},
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {w2k_imports, xp_imports, vista_imports, win7_imports, win8_imports},
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {w2k_delay_imports, xp_delay_imports,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     vista_delay_imports, win7_delay_imports, win8_delay_imports},
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {w2k_relocs, xp_relocs, vista_relocs, win7_relocs, win8_relocs}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(arraysize(expected[0]) == UNSUPPORTED_SET,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 expected_value_set_mismatch);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value > relocs)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectationSet expected_set = GetExpectationSet(os);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expected_set >= arraysize(expected)) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This should never happen.  Log a failure if it does.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(UNSUPPORTED_SET, expected_set);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_set = WIN_2K_SET;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return expected[value][expected_set];
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(jschuh): crbug.com/167707 Need to fix test on Win64 bots
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_EnumeratesPE DISABLED_EnumeratesPE
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_EnumeratesPE EnumeratesPE
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we are able to enumerate stuff from a PE file, and that
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the actual number of items found is within the expected range.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(PEImageTest, MAYBE_EnumeratesPE) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMODULE module = LoadLibrary(L"advapi32.dll");
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(NULL != module);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PEImage pe(module);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count = 0;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pe.VerifyMagic());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD os = pe.GetNTHeaders()->OptionalHeader.MajorOperatingSystemVersion;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  os = os * 10 + pe.GetNTHeaders()->OptionalHeader.MinorOperatingSystemVersion;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip this test for unsupported OS versions.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetExpectationSet(os) == UNSUPPORTED_SET)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pe.EnumSections(SectionsCallback, &count);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GetExpectedValue(sections, os), count);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  count = 0;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pe.EnumImportChunks(ImportChunksCallback, &count);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GetExpectedValue(imports_dlls, os), count);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  count = 0;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pe.EnumDelayImportChunks(DelayImportChunksCallback, &count);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GetExpectedValue(delay_dlls, os), count);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  count = 0;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pe.EnumExports(ExportsCallback, &count);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(count, GetExpectedValue(exports, os) - 20);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(count, GetExpectedValue(exports, os) + 100);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  count = 0;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pe.EnumAllImports(ImportsCallback, &count);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(count, GetExpectedValue(imports, os) - 20);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(count, GetExpectedValue(imports, os) + 100);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  count = 0;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pe.EnumAllDelayImports(ImportsCallback, &count);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(count, GetExpectedValue(delay_imports, os) - 2);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(count, GetExpectedValue(delay_imports, os) + 8);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  count = 0;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pe.EnumRelocs(RelocsCallback, &count);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(count, GetExpectedValue(relocs, os) - 150);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(count, GetExpectedValue(relocs, os) + 1500);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeLibrary(module);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can locate an specific exported symbol, by name and by ordinal.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PEImageTest, RetrievesExports) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMODULE module = LoadLibrary(L"advapi32.dll");
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(NULL != module);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PEImage pe(module);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WORD ordinal;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pe.GetProcOrdinal("RegEnumKeyExW", &ordinal));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FARPROC address1 = pe.GetProcAddress("RegEnumKeyExW");
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FARPROC address2 = pe.GetProcAddress(reinterpret_cast<char*>(ordinal));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(address1 != NULL);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(address2 != NULL);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(address1 == address2);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeLibrary(module);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace win
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
272