Home | History | Annotate | Download | only in app
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <windows.h>
      6 #if defined(_WIN32_WINNT_WIN8) && _MSC_VER < 1700
      7 // The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h, and in
      8 // delayimp.h previous to VS2012.
      9 #undef FACILITY_VISUALCPP
     10 #endif
     11 #include <DelayIMP.h>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/compiler_specific.h"
     15 #include "base/scoped_native_library.h"
     16 #include "chrome/app/delay_load_hook_win.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace {
     20 
     21 class ChromeDelayLoadHookTest : public testing::Test {
     22  public:
     23   ChromeDelayLoadHookTest() : proc_ptr_(NULL) {
     24   }
     25 
     26   virtual void SetUp() OVERRIDE {
     27     SetupInfo("kernel32.dll");
     28   }
     29 
     30   void SetupInfo(const char* dll_name) {
     31     info_.cb = sizeof(info_);
     32     info_.pidd =  NULL;
     33     info_.ppfn = &proc_ptr_;
     34     info_.szDll = dll_name;
     35     info_.dlp.fImportByName = TRUE;
     36     info_.dlp.szProcName = "CreateFileA";
     37     info_.hmodCur = NULL;
     38     info_.pfnCur = NULL;
     39     info_.dwLastError = 0;
     40   }
     41 
     42   FARPROC proc_ptr_;
     43   DelayLoadInfo info_;
     44 };
     45 
     46 }  // namespace
     47 
     48 TEST_F(ChromeDelayLoadHookTest, HooksAreSetAtLinkTime) {
     49   // This test verifies that referencing the ChromeDelayLoadHook at link
     50   // time results in overriding the delay loader's hook instances in the CRT
     51   // ropriately.
     52   EXPECT_TRUE(__pfnDliNotifyHook2 == ChromeDelayLoadHook);
     53   EXPECT_TRUE(__pfnDliFailureHook2 == ChromeDelayLoadHook);
     54 }
     55 
     56 TEST_F(ChromeDelayLoadHookTest, NonSuffixedDllsAreNotHandled) {
     57   // The hook should ignore non-suffixed DLLs.
     58   SetupInfo("kernel32.dll");
     59 
     60   HMODULE none = reinterpret_cast<HMODULE>(
     61       ChromeDelayLoadHook(dliNotePreLoadLibrary, &info_));
     62    // Make sure the library is released on exit.
     63    base::ScopedNativeLibrary lib_holder(none);
     64 
     65    ASSERT_TRUE(none == NULL);
     66 }
     67 
     68 TEST_F(ChromeDelayLoadHookTest, SuffixedDllsAreRedirected) {
     69   // Check that a DLL name of the form "foo-delay.dll" gets redirected to
     70   // the "foo.dll".
     71   SetupInfo("kernel32-delay.dll");
     72   HMODULE kernel32 = reinterpret_cast<HMODULE>(
     73       ChromeDelayLoadHook(dliNotePreLoadLibrary, &info_));
     74 
     75    // Make sure the library is released on exit.
     76    base::ScopedNativeLibrary lib_holder(kernel32);
     77 
     78    ASSERT_TRUE(kernel32 == ::GetModuleHandle(L"kernel32.dll"));
     79 }
     80 
     81 TEST_F(ChromeDelayLoadHookTest, IgnoresUnhandledNotifications) {
     82   SetupInfo("kernel32-delay.dll");
     83 
     84   // The hook should ignore all notifications but the preload notifications.
     85   EXPECT_TRUE(ChromeDelayLoadHook(dliNoteStartProcessing, &info_) == NULL);
     86   EXPECT_TRUE(ChromeDelayLoadHook(dliNotePreGetProcAddress, &info_) == NULL);
     87   EXPECT_TRUE(ChromeDelayLoadHook(dliNoteEndProcessing, &info_) == NULL);
     88   EXPECT_TRUE(ChromeDelayLoadHook(dliFailLoadLib, &info_) == NULL);
     89   EXPECT_TRUE(ChromeDelayLoadHook(dliFailGetProc, &info_) == NULL);
     90 }
     91