summaryrefslogtreecommitdiffstats
path: root/chrome_frame/module_utils.h
blob: e5d8a68157e3cd05d0437b908d4ce486513c4ac9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_FRAME_MODULE_UTILS_H_
#define CHROME_FRAME_MODULE_UTILS_H_

#include <ObjBase.h>
#include <windows.h>

#include <map>

// A helper class that will find the named loaded module in the current
// process with the lowest version, increment its ref count and return
// a pointer to its DllGetClassObject() function if it exports one. If
// the oldest named module is the current module, then this class does nothing
// (does not muck with module ref count) and calls to
// get_dll_get_class_object_ptr() will return NULL.
class DllRedirector {
 public:
  typedef std::map<std::wstring, HMODULE> PathToHModuleMap;

  DllRedirector();
  ~DllRedirector();

  // Must call this before calling get_dll_get_class_object_ptr(). On first call
  // this performs the work of scanning the loaded modules for an old version
  // to delegate to. Not thread safe.
  void EnsureInitialized(const wchar_t* module_name, REFCLSID clsid);

  LPFNGETCLASSOBJECT get_dll_get_class_object_ptr() const;

 private:

  // Returns the pointer to the named loaded module's DllGetClassObject export
  // or NULL if either the pointer could not be found or if the pointer would
  // point into the current module.
  // Sets module_handle_ and increments the modules reference count.
  //
  // For sanity's sake, the module must return a non-null class factory for
  // the given class id.
  LPFNGETCLASSOBJECT GetDllGetClassObjectFromModuleName(
      const wchar_t* module_name, REFCLSID clsid);

  // Returns a handle in |module_handle| to the loaded module called
  // |module_name| in the current process. If there are multiple modules with
  // the same name, it returns the module with the oldest version number in its
  // VERSIONINFO block. The version string is expected to be of a form that
  // base::Version can parse.
  //
  // For sanity's sake, when there are multiple instances of the module,
  // |product_short_name|, if non-NULL, must match the module's
  // ProductShortName value
  //
  // Returns true if a named module with the given ProductShortName can be
  // found, returns false otherwise. Can return the current module handle.
  bool GetOldestNamedModuleHandle(const std::wstring& module_name,
                                  REFCLSID clsid,
                                  HMODULE* module_handle);

  // Given a PathToBaseAddressMap, iterates over the module images whose paths
  // are the keys and returns the handle to the module with the lowest
  // version number in its VERSIONINFO block whose DllGetClassObject returns a
  // class factory for the given CLSID.
  HMODULE GetHandleOfOldestModule(const PathToHModuleMap& map, REFCLSID clsid);

 private:
  // Helper function to return the DllGetClassObject function pointer from
  // the given module. On success, the return value is non-null and module
  // will have had its reference count incremented.
  LPFNGETCLASSOBJECT GetDllGetClassObjectPtr(HMODULE module);

  HMODULE module_handle_;
  LPFNGETCLASSOBJECT dcgo_ptr_;
  bool initialized_;

  friend class ModuleUtilsTest;
};

#endif  // CHROME_FRAME_MODULE_UTILS_H_