Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: base/native_library_win.cc

Issue 2744043003: Use LoadLibraryExW if applicable in LoadNativeLibrary on Windows (Closed)
Patch Set: Add UMA_histogram Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/native_library.h" 5 #include "base/native_library.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/metrics/histogram_macros.h"
10 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
14 15
15 namespace base { 16 namespace base {
16 17
18 typedef HMODULE(WINAPI* AddDllDirectory)(PCWSTR NewDirectory);
17 typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); 19 typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name);
20 typedef HMODULE(WINAPI* LoadLibraryFunctionEx)(const wchar_t* file_name,
21 HANDLE hFile,
22 DWORD dwFlags);
xhwang 2017/03/13 20:47:09 nit: line 19 has a space after HMODULE. Is the new
chengx 2017/03/13 22:20:22 Sorry, it is typo. Now it is fixed.
18 23
19 namespace { 24 namespace {
20 25 // This helper method uses LoadLibrary() WinAPI.
21 NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path, 26 NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path,
22 LoadLibraryFunction load_library_api, 27 LoadLibraryFunction load_library_api,
23 NativeLibraryLoadError* error) { 28 NativeLibraryLoadError* error) {
24 // LoadLibrary() opens the file off disk. 29 // LoadLibrary() opens the file off disk.
25 ThreadRestrictions::AssertIOAllowed(); 30 ThreadRestrictions::AssertIOAllowed();
26 31
27 // Switch the current directory to the library directory as the library 32 // Switch the current directory to the library directory as the library
28 // may have dependencies on DLLs in this directory. 33 // may have dependencies on DLLs in this directory.
29 bool restore_directory = false; 34 bool restore_directory = false;
30 FilePath current_directory; 35 FilePath current_directory;
(...skipping 10 matching lines...) Expand all
41 // GetLastError() needs to be called immediately after |load_library_api|. 46 // GetLastError() needs to be called immediately after |load_library_api|.
42 error->code = GetLastError(); 47 error->code = GetLastError();
43 } 48 }
44 49
45 if (restore_directory) 50 if (restore_directory)
46 SetCurrentDirectory(current_directory); 51 SetCurrentDirectory(current_directory);
47 52
48 return module; 53 return module;
49 } 54 }
50 55
56 // This helper method uses LoadLibraryEx() WinAPI.
57 NativeLibrary LoadNativeLibraryHelperEx(const FilePath& library_path,
58 LoadLibraryFunctionEx load_library_api,
59 NativeLibraryLoadError* error) {
60 // LoadLibraryEx() opens the file off disk.
61 ThreadRestrictions::AssertIOAllowed();
62
63 HMODULE module = (*load_library_api)(
64 library_path.value().c_str(), NULL,
xhwang 2017/03/13 20:47:08 here and everywhere, s/NULL/nullptr?
chengx 2017/03/13 22:20:22 Done.
65 LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
xhwang 2017/03/13 20:47:09 nit: Add a comment why we need LOAD_LIBRARY_SEARCH
chengx 2017/03/13 22:20:22 Done.
66 if (!module && error) {
67 // GetLastError() needs to be called immediately after |load_library_api|.
68 error->code = GetLastError();
69 }
70
71 return module;
72 }
73
51 } // namespace 74 } // namespace
52 75
53 std::string NativeLibraryLoadError::ToString() const { 76 std::string NativeLibraryLoadError::ToString() const {
54 return StringPrintf("%u", code); 77 return StringPrintf("%u", code);
55 } 78 }
56 79
57 // static 80 // static
58 NativeLibrary LoadNativeLibraryWithOptions(const FilePath& library_path, 81 NativeLibrary LoadNativeLibraryWithOptions(const FilePath& library_path,
xhwang 2017/03/13 20:47:09 I think base::LoadNativeLIbrary() is calling this
chengx 2017/03/13 22:20:22 I agree with you. I am not seeing LoadNativeLibrar
xhwang 2017/03/14 00:14:31 LoadNativeLibraryDynamically() was added long time
chengx 2017/03/14 02:44:40 Agreed. LoadLibrayExW and LoadLibraryW can be call
59 const NativeLibraryOptions& options, 82 const NativeLibraryOptions& options,
60 NativeLibraryLoadError* error) { 83 NativeLibraryLoadError* error) {
61 return LoadNativeLibraryHelper(library_path, LoadLibraryW, error); 84 return LoadNativeLibraryHelper(library_path, LoadLibraryW, error);
62 } 85 }
63 86
64 NativeLibrary LoadNativeLibraryDynamically(const FilePath& library_path) { 87 NativeLibrary LoadNativeLibraryDynamically(const FilePath& library_path) {
65 typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); 88 HMODULE load_library_module = NULL;
66 89
67 LoadLibraryFunction load_library = reinterpret_cast<LoadLibraryFunction>( 90 enum LoadLibraryResult {
xhwang 2017/03/13 20:47:09 nit: enum class?
xhwang 2017/03/13 20:47:09 Add a comment that combinations of these are used
chengx 2017/03/13 22:20:22 Both should work. Using enum directly rather than
chengx 2017/03/13 22:20:22 The enum is updated, so maybe this comment is no l
xhwang 2017/03/14 00:14:31 We do recommend enum class in new code. How about
chengx 2017/03/14 02:44:40 I understand enum class if preferred over enum. Ho
68 GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW")); 91 LoadLibExW_EXIST = 0,
92 LoadLibExW_NONE = 1 << 0,
93 LoadLibExW_FAIL = 1 << 1,
94 LoadLibW_FAIL = 1 << 2,
xhwang 2017/03/13 20:47:09 nit: You are using 3 bit positions (4 enum values)
chengx 2017/03/13 22:20:22 Agreed and fixed. I was addicted to playing with t
95 // This value is beyond the sum of all bit fields above and
96 // should remain last (shifted by one more than the last value)
97 END = 1 << 3
98 };
69 99
70 return LoadNativeLibraryHelper(library_path, load_library, NULL); 100 // This variable records the library loading result.
101 uint32_t load_library_status = LoadLibraryResult::LoadLibExW_EXIST;
102
103 // The LOAD_LIBRARY_SEARCH_* flags are available on systems that have
104 // KB2533623 installed. To determine whether the flags are available, use
105 // GetProcAddress to get the address of the AddDllDirectory,
106 // RemoveDllDirectory, or SetDefaultDllDirectories function. If GetProcAddress
107 // succeeds, the LOAD_LIBRARY_SEARCH_* flags can be used with LoadLibraryEx.
108 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85). aspx
xhwang 2017/03/13 20:47:09 The link seems to be broken for me...
chengx 2017/03/13 22:20:22 Did you copy the "aspx" in the following line?
xhwang 2017/03/14 00:14:31 I did and I checked... but now I tried it again an
chengx 2017/03/14 02:44:40 Cool!
109 // The LOAD_LIBRARY_SEARCH_* flags are used in LoadNativeLibraryHelperEx
110 // method above.
111 auto add_dll_dir_func = reinterpret_cast<AddDllDirectory>(
112 GetProcAddress(GetModuleHandle(L"kernel32.dll"), "AddDllDirectory"));
xhwang 2017/03/13 20:47:08 nit: Can we move this into a helper function that
chengx 2017/03/13 22:20:22 Now since enum is updated, I need this add_dll_dir
xhwang 2017/03/14 00:14:31 You can always store !!add_dll_dir_func into a boo
chengx 2017/03/14 02:44:40 accepted.
113
114 if (add_dll_dir_func) {
115 LoadLibraryFunctionEx load_library =
116 reinterpret_cast<LoadLibraryFunctionEx>(
117 GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryExW"));
xhwang 2017/03/13 20:47:09 nit for discussion: I don't know what's the value
chengx 2017/03/13 22:20:22 If removing LoadNativeLibraryDynamically and then
118 load_library_module =
119 LoadNativeLibraryHelperEx(library_path, load_library, NULL);
xhwang 2017/03/13 20:47:09 See above that we need to update LoadNativeLibrary
chengx 2017/03/13 22:20:22 Acknowledged.
chengx 2017/03/14 02:44:40 Alright, LoadNativeLibraryWithOptions updated.
120 if (!load_library_module)
121 load_library_status |= LoadLibraryResult::LoadLibExW_FAIL;
122 } else {
123 load_library_status |= LoadLibraryResult::LoadLibExW_NONE;
124 }
125
126 // If LoadLibraryExW API call fails, try LoadLibraryW API.
127 if (!load_library_module) {
128 LoadLibraryFunction load_library = reinterpret_cast<LoadLibraryFunction>(
129 GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW"));
xhwang 2017/03/13 20:47:08 nit: ditto about the possibility of moving this in
chengx 2017/03/13 22:20:22 Acknowledged.
chengx 2017/03/14 02:44:40 Yep, moved into LoadNativeLibraryHelper in the new
130 load_library_module =
131 LoadNativeLibraryHelper(library_path, load_library, NULL);
132 if (!load_library_module)
133 load_library_status |= LoadLibraryResult::LoadLibW_FAIL;
134 }
135
136 UMA_HISTOGRAM_ENUMERATION("LibraryLoader.NativeLibraryDynamicallyLoad",
137 load_library_status, LoadLibraryResult::END);
138 return load_library_module;
71 } 139 }
72 140
73 // static 141 // static
74 void UnloadNativeLibrary(NativeLibrary library) { 142 void UnloadNativeLibrary(NativeLibrary library) {
75 FreeLibrary(library); 143 FreeLibrary(library);
76 } 144 }
77 145
78 // static 146 // static
79 void* GetFunctionPointerFromNativeLibrary(NativeLibrary library, 147 void* GetFunctionPointerFromNativeLibrary(NativeLibrary library,
80 StringPiece name) { 148 StringPiece name) {
81 return GetProcAddress(library, name.data()); 149 return GetProcAddress(library, name.data());
82 } 150 }
83 151
84 // static 152 // static
85 std::string GetNativeLibraryName(StringPiece name) { 153 std::string GetNativeLibraryName(StringPiece name) {
86 DCHECK(IsStringASCII(name)); 154 DCHECK(IsStringASCII(name));
87 return name.as_string() + ".dll"; 155 return name.as_string() + ".dll";
88 } 156 }
89 157
90 } // namespace base 158 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698