Chromium Code Reviews| Index: base/native_library_win.cc |
| diff --git a/base/native_library_win.cc b/base/native_library_win.cc |
| index 64c7380f173247c28b78e1f339b963d7374cf83f..4171a2a5ea9de2afe6132e8c19c8a3bef13bd64a 100644 |
| --- a/base/native_library_win.cc |
| +++ b/base/native_library_win.cc |
| @@ -7,6 +7,7 @@ |
| #include <windows.h> |
| #include "base/files/file_util.h" |
| +#include "base/metrics/histogram_macros.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| @@ -14,10 +15,14 @@ |
| namespace base { |
| +typedef HMODULE(WINAPI* AddDllDirectory)(PCWSTR NewDirectory); |
| typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); |
| +typedef HMODULE(WINAPI* LoadLibraryFunctionEx)(const wchar_t* file_name, |
| + HANDLE hFile, |
| + 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.
|
| namespace { |
| - |
| +// This helper method uses LoadLibrary() WinAPI. |
| NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path, |
| LoadLibraryFunction load_library_api, |
| NativeLibraryLoadError* error) { |
| @@ -48,6 +53,24 @@ NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path, |
| return module; |
| } |
| +// This helper method uses LoadLibraryEx() WinAPI. |
| +NativeLibrary LoadNativeLibraryHelperEx(const FilePath& library_path, |
| + LoadLibraryFunctionEx load_library_api, |
| + NativeLibraryLoadError* error) { |
| + // LoadLibraryEx() opens the file off disk. |
| + ThreadRestrictions::AssertIOAllowed(); |
| + |
| + HMODULE module = (*load_library_api)( |
| + 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.
|
| + 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.
|
| + if (!module && error) { |
| + // GetLastError() needs to be called immediately after |load_library_api|. |
| + error->code = GetLastError(); |
| + } |
| + |
| + return module; |
| +} |
| + |
| } // namespace |
| std::string NativeLibraryLoadError::ToString() const { |
| @@ -62,12 +85,57 @@ NativeLibrary LoadNativeLibraryWithOptions(const FilePath& library_path, |
| } |
| NativeLibrary LoadNativeLibraryDynamically(const FilePath& library_path) { |
| - typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); |
| + HMODULE load_library_module = NULL; |
| + |
| + 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
|
| + LoadLibExW_EXIST = 0, |
| + LoadLibExW_NONE = 1 << 0, |
| + LoadLibExW_FAIL = 1 << 1, |
| + 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
|
| + // This value is beyond the sum of all bit fields above and |
| + // should remain last (shifted by one more than the last value) |
| + END = 1 << 3 |
| + }; |
| + |
| + // This variable records the library loading result. |
| + uint32_t load_library_status = LoadLibraryResult::LoadLibExW_EXIST; |
| + |
| + // The LOAD_LIBRARY_SEARCH_* flags are available on systems that have |
| + // KB2533623 installed. To determine whether the flags are available, use |
| + // GetProcAddress to get the address of the AddDllDirectory, |
| + // RemoveDllDirectory, or SetDefaultDllDirectories function. If GetProcAddress |
| + // succeeds, the LOAD_LIBRARY_SEARCH_* flags can be used with LoadLibraryEx. |
| + // 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!
|
| + // The LOAD_LIBRARY_SEARCH_* flags are used in LoadNativeLibraryHelperEx |
| + // method above. |
| + auto add_dll_dir_func = reinterpret_cast<AddDllDirectory>( |
| + 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.
|
| + |
| + if (add_dll_dir_func) { |
| + LoadLibraryFunctionEx load_library = |
| + reinterpret_cast<LoadLibraryFunctionEx>( |
| + 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
|
| + load_library_module = |
| + 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.
|
| + if (!load_library_module) |
| + load_library_status |= LoadLibraryResult::LoadLibExW_FAIL; |
| + } else { |
| + load_library_status |= LoadLibraryResult::LoadLibExW_NONE; |
| + } |
| - LoadLibraryFunction load_library = reinterpret_cast<LoadLibraryFunction>( |
| - GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW")); |
| + // If LoadLibraryExW API call fails, try LoadLibraryW API. |
| + if (!load_library_module) { |
| + LoadLibraryFunction load_library = reinterpret_cast<LoadLibraryFunction>( |
| + 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
|
| + load_library_module = |
| + LoadNativeLibraryHelper(library_path, load_library, NULL); |
| + if (!load_library_module) |
| + load_library_status |= LoadLibraryResult::LoadLibW_FAIL; |
| + } |
| - return LoadNativeLibraryHelper(library_path, load_library, NULL); |
| + UMA_HISTOGRAM_ENUMERATION("LibraryLoader.NativeLibraryDynamicallyLoad", |
| + load_library_status, LoadLibraryResult::END); |
| + return load_library_module; |
| } |
| // static |