Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 |
| OLD | NEW |