15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/native_library.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_util.h" 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/strings/stringprintf.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace { 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path, 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LoadLibraryFunction load_library_api, 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NativeLibraryLoadError* error) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LoadLibrary() opens the file off disk. 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ThreadRestrictions::AssertIOAllowed(); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Switch the current directory to the library directory as the library 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may have dependencies on DLLs in this directory. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool restore_directory = false; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath current_directory; 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (GetCurrentDirectory(¤t_directory)) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath plugin_path = library_path.DirName(); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!plugin_path.empty()) { 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetCurrentDirectory(plugin_path); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_directory = true; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE module = (*load_library_api)(library_path.value().c_str()); 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!module && error) { 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // GetLastError() needs to be called immediately after |load_library_api|. 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch error->code = GetLastError(); 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restore_directory) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetCurrentDirectory(current_directory); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return module; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstd::string NativeLibraryLoadError::ToString() const { 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return StringPrintf("%u", code); 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeLibrary LoadNativeLibrary(const FilePath& library_path, 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NativeLibraryLoadError* error) { 5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return LoadNativeLibraryHelper(library_path, LoadLibraryW, error); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeLibrary LoadNativeLibraryDynamically(const FilePath& library_path) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadLibraryFunction load_library; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_library = reinterpret_cast<LoadLibraryFunction>( 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW")); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return LoadNativeLibraryHelper(library_path, load_library, NULL); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnloadNativeLibrary(NativeLibrary library) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreeLibrary(library); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* GetFunctionPointerFromNativeLibrary(NativeLibrary library, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetProcAddress(library, name); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 GetNativeLibraryName(const string16& name) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name + ASCIIToUTF16(".dll"); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 89