diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/app_base.gypi | 6 | ||||
-rw-r--r-- | app/win/iat_patch_function.cc | 278 | ||||
-rw-r--r-- | app/win/iat_patch_function.h | 72 | ||||
-rw-r--r-- | app/win/scoped_co_mem.h | 49 | ||||
-rw-r--r-- | app/win/scoped_com_initializer.h | 60 | ||||
-rw-r--r-- | app/win/shell.cc | 112 | ||||
-rw-r--r-- | app/win/shell.h | 41 |
7 files changed, 0 insertions, 618 deletions
diff --git a/app/app_base.gypi b/app/app_base.gypi index 5794c7d..05c5696 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -36,12 +36,6 @@ 'sql/statement.h', 'sql/transaction.cc', 'sql/transaction.h', - 'win/iat_patch_function.cc', - 'win/iat_patch_function.h', - 'win/scoped_co_mem.h', - 'win/scoped_com_initializer.h', - 'win/shell.cc', - 'win/shell.h', ], }, ], diff --git a/app/win/iat_patch_function.cc b/app/win/iat_patch_function.cc deleted file mode 100644 index 9abd6f2..0000000 --- a/app/win/iat_patch_function.cc +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2011 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. - -#include "app/win/iat_patch_function.h" - -#include "base/logging.h" -#include "base/win/pe_image.h" - -namespace app { -namespace win { - -namespace { - -struct InterceptFunctionInformation { - bool finished_operation; - const char* imported_from_module; - const char* function_name; - void* new_function; - void** old_function; - IMAGE_THUNK_DATA** iat_thunk; - DWORD return_code; -}; - -void* GetIATFunction(IMAGE_THUNK_DATA* iat_thunk) { - if (NULL == iat_thunk) { - NOTREACHED(); - return NULL; - } - - // Works around the 64 bit portability warning: - // The Function member inside IMAGE_THUNK_DATA is really a pointer - // to the IAT function. IMAGE_THUNK_DATA correctly maps to IMAGE_THUNK_DATA32 - // or IMAGE_THUNK_DATA64 for correct pointer size. - union FunctionThunk { - IMAGE_THUNK_DATA thunk; - void* pointer; - } iat_function; - - iat_function.thunk = *iat_thunk; - return iat_function.pointer; -} -// Change the page protection (of code pages) to writable and copy -// the data at the specified location -// -// Arguments: -// old_code Target location to copy -// new_code Source -// length Number of bytes to copy -// -// Returns: Windows error code (winerror.h). NO_ERROR if successful -DWORD ModifyCode(void* old_code, void* new_code, int length) { - if ((NULL == old_code) || (NULL == new_code) || (0 == length)) { - NOTREACHED(); - return ERROR_INVALID_PARAMETER; - } - - // Change the page protection so that we can write. - DWORD error = NO_ERROR; - DWORD old_page_protection = 0; - if (VirtualProtect(old_code, - length, - PAGE_READWRITE, - &old_page_protection)) { - - // Write the data. - CopyMemory(old_code, new_code, length); - - // Restore the old page protection. - error = ERROR_SUCCESS; - VirtualProtect(old_code, - length, - old_page_protection, - &old_page_protection); - } else { - error = GetLastError(); - NOTREACHED(); - } - - return error; -} - -bool InterceptEnumCallback(const base::win::PEImage& image, const char* module, - DWORD ordinal, const char* name, DWORD hint, - IMAGE_THUNK_DATA* iat, void* cookie) { - InterceptFunctionInformation* intercept_information = - reinterpret_cast<InterceptFunctionInformation*>(cookie); - - if (NULL == intercept_information) { - NOTREACHED(); - return false; - } - - DCHECK(module); - - if ((0 == lstrcmpiA(module, intercept_information->imported_from_module)) && - (NULL != name) && - (0 == lstrcmpiA(name, intercept_information->function_name))) { - // Save the old pointer. - if (NULL != intercept_information->old_function) { - *(intercept_information->old_function) = GetIATFunction(iat); - } - - if (NULL != intercept_information->iat_thunk) { - *(intercept_information->iat_thunk) = iat; - } - - // portability check - COMPILE_ASSERT(sizeof(iat->u1.Function) == - sizeof(intercept_information->new_function), unknown_IAT_thunk_format); - - // Patch the function. - intercept_information->return_code = - ModifyCode(&(iat->u1.Function), - &(intercept_information->new_function), - sizeof(intercept_information->new_function)); - - // Terminate further enumeration. - intercept_information->finished_operation = true; - return false; - } - - return true; -} - -// Helper to intercept a function in an import table of a specific -// module. -// -// Arguments: -// module_handle Module to be intercepted -// imported_from_module Module that exports the symbol -// function_name Name of the API to be intercepted -// new_function Interceptor function -// old_function Receives the original function pointer -// iat_thunk Receives pointer to IAT_THUNK_DATA -// for the API from the import table. -// -// Returns: Returns NO_ERROR on success or Windows error code -// as defined in winerror.h -DWORD InterceptImportedFunction(HMODULE module_handle, - const char* imported_from_module, - const char* function_name, void* new_function, - void** old_function, - IMAGE_THUNK_DATA** iat_thunk) { - if ((NULL == module_handle) || (NULL == imported_from_module) || - (NULL == function_name) || (NULL == new_function)) { - NOTREACHED(); - return ERROR_INVALID_PARAMETER; - } - - base::win::PEImage target_image(module_handle); - if (!target_image.VerifyMagic()) { - NOTREACHED(); - return ERROR_INVALID_PARAMETER; - } - - InterceptFunctionInformation intercept_information = { - false, - imported_from_module, - function_name, - new_function, - old_function, - iat_thunk, - ERROR_GEN_FAILURE}; - - // First go through the IAT. If we don't find the import we are looking - // for in IAT, search delay import table. - target_image.EnumAllImports(InterceptEnumCallback, &intercept_information); - if (!intercept_information.finished_operation) { - target_image.EnumAllDelayImports(InterceptEnumCallback, - &intercept_information); - } - - return intercept_information.return_code; -} - -// Restore intercepted IAT entry with the original function. -// -// Arguments: -// intercept_function Interceptor function -// original_function Receives the original function pointer -// -// Returns: Returns NO_ERROR on success or Windows error code -// as defined in winerror.h -DWORD RestoreImportedFunction(void* intercept_function, - void* original_function, - IMAGE_THUNK_DATA* iat_thunk) { - if ((NULL == intercept_function) || (NULL == original_function) || - (NULL == iat_thunk)) { - NOTREACHED(); - return ERROR_INVALID_PARAMETER; - } - - if (GetIATFunction(iat_thunk) != intercept_function) { - // Check if someone else has intercepted on top of us. - // We cannot unpatch in this case, just raise a red flag. - NOTREACHED(); - return ERROR_INVALID_FUNCTION; - } - - return ModifyCode(&(iat_thunk->u1.Function), - &original_function, - sizeof(original_function)); -} - -} // namespace - -IATPatchFunction::IATPatchFunction() - : module_handle_(NULL), - original_function_(NULL), - iat_thunk_(NULL), - intercept_function_(NULL) { -} - -IATPatchFunction::~IATPatchFunction() { - if (NULL != intercept_function_) { - DWORD error = Unpatch(); - DCHECK_EQ(static_cast<DWORD>(NO_ERROR), error); - } -} - -DWORD IATPatchFunction::Patch(const wchar_t* module, - const char* imported_from_module, - const char* function_name, - void* new_function) { - DCHECK_EQ(static_cast<void*>(NULL), original_function_); - DCHECK_EQ(static_cast<IMAGE_THUNK_DATA*>(NULL), iat_thunk_); - DCHECK_EQ(static_cast<void*>(NULL), intercept_function_); - - HMODULE module_handle = LoadLibraryW(module); - - if (module_handle == NULL) { - NOTREACHED(); - return GetLastError(); - } - - DWORD error = InterceptImportedFunction(module_handle, - imported_from_module, - function_name, - new_function, - &original_function_, - &iat_thunk_); - - if (NO_ERROR == error) { - DCHECK_NE(original_function_, intercept_function_); - module_handle_ = module_handle; - intercept_function_ = new_function; - } else { - FreeLibrary(module_handle); - } - - return error; -} - -DWORD IATPatchFunction::Unpatch() { - DWORD error = RestoreImportedFunction(intercept_function_, - original_function_, - iat_thunk_); - DCHECK_EQ(static_cast<DWORD>(NO_ERROR), error); - - // Hands off the intercept if we fail to unpatch. - // If IATPatchFunction::Unpatch fails during RestoreImportedFunction - // it means that we cannot safely unpatch the import address table - // patch. In this case its better to be hands off the intercept as - // trying to unpatch again in the destructor of IATPatchFunction is - // not going to be any safer - if (module_handle_) - FreeLibrary(module_handle_); - module_handle_ = NULL; - intercept_function_ = NULL; - original_function_ = NULL; - iat_thunk_ = NULL; - - return error; -} - -} // namespace win -} // namespace app diff --git a/app/win/iat_patch_function.h b/app/win/iat_patch_function.h deleted file mode 100644 index 4a2aa0c..0000000 --- a/app/win/iat_patch_function.h +++ /dev/null @@ -1,72 +0,0 @@ -// 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 APP_WIN_IAT_PATCH_FUNCTION_H_ -#define APP_WIN_IAT_PATCH_FUNCTION_H_ -#pragma once - -#include <windows.h> - -#include "base/basictypes.h" - -namespace app { -namespace win { - -// A class that encapsulates Import Address Table patching helpers and restores -// the original function in the destructor. -// -// It will intercept functions for a specific DLL imported from another DLL. -// This is the case when, for example, we want to intercept -// CertDuplicateCertificateContext function (exported from crypt32.dll) called -// by wininet.dll. -class IATPatchFunction { - public: - IATPatchFunction(); - ~IATPatchFunction(); - - // Intercept a function in an import table of a specific - // module. Save the original function and the import - // table address. These values will be used later - // during Unpatch - // - // Arguments: - // module Module to be intercepted - // imported_from_module Module that exports the 'function_name' - // function_name Name of the API to be intercepted - // - // Returns: Windows error code (winerror.h). NO_ERROR if successful - // - // Note: Patching a function will make the IAT patch take some "ownership" on - // |module|. It will LoadLibrary(module) to keep the DLL alive until a call - // to Unpatch(), which will call FreeLibrary() and allow the module to be - // unloaded. The idea is to help prevent the DLL from going away while a - // patch is still active. - DWORD Patch(const wchar_t* module, - const char* imported_from_module, - const char* function_name, - void* new_function); - - // Unpatch the IAT entry using internally saved original - // function. - // - // Returns: Windows error code (winerror.h). NO_ERROR if successful - DWORD Unpatch(); - - bool is_patched() const { - return (NULL != intercept_function_); - } - - private: - HMODULE module_handle_; - void* intercept_function_; - void* original_function_; - IMAGE_THUNK_DATA* iat_thunk_; - - DISALLOW_COPY_AND_ASSIGN(IATPatchFunction); -}; - -} // namespace win -} // namespace app - -#endif // APP_WIN_IAT_PATCH_FUNCTION_H_ diff --git a/app/win/scoped_co_mem.h b/app/win/scoped_co_mem.h deleted file mode 100644 index a6017fa..0000000 --- a/app/win/scoped_co_mem.h +++ /dev/null @@ -1,49 +0,0 @@ -// 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 APP_WIN_SCOPED_CO_MEM_H_ -#define APP_WIN_SCOPED_CO_MEM_H_ -#pragma once - -#include <objbase.h> - -#include "base/basictypes.h" - -namespace app { -namespace win { - -// Simple scoped memory releaser class for COM allocated memory. -// Example: -// app::win::ScopedCoMem<ITEMIDLIST> file_item; -// SHGetSomeInfo(&file_item, ...); -// ... -// return; <-- memory released -template<typename T> -class ScopedCoMem { - public: - explicit ScopedCoMem() : mem_ptr_(NULL) {} - - ~ScopedCoMem() { - if (mem_ptr_) - CoTaskMemFree(mem_ptr_); - } - - T** operator&() { // NOLINT - return &mem_ptr_; - } - - operator T*() { - return mem_ptr_; - } - - private: - T* mem_ptr_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCoMem); -}; - -} // namespace win -} // namespace app - -#endif // APP_WIN_SCOPED_CO_MEM_H_ diff --git a/app/win/scoped_com_initializer.h b/app/win/scoped_com_initializer.h deleted file mode 100644 index 3a2cf55..0000000 --- a/app/win/scoped_com_initializer.h +++ /dev/null @@ -1,60 +0,0 @@ -// 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 APP_WIN_SCOPED_COM_INITIALIZER_H_ -#define APP_WIN_SCOPED_COM_INITIALIZER_H_ -#pragma once - -#include "base/basictypes.h" -#include "build/build_config.h" - -#if defined(OS_WIN) - -#include <objbase.h> - -namespace app { -namespace win { - -// Initializes COM in the constructor (STA), and uninitializes COM in the -// destructor. -class ScopedCOMInitializer { - public: - ScopedCOMInitializer() : hr_(CoInitialize(NULL)) { - } - - ScopedCOMInitializer::~ScopedCOMInitializer() { - if (SUCCEEDED(hr_)) - CoUninitialize(); - } - - private: - HRESULT hr_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCOMInitializer); -}; - -} // namespace win -} // namespace app - -#else - -namespace app { -namespace win { - -// Do-nothing class for other platforms. -class ScopedCOMInitializer { - public: - ScopedCOMInitializer() {} - ~ScopedCOMInitializer() {} - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedCOMInitializer); -}; - -} // namespace win -} // namespace app - -#endif - -#endif // APP_WIN_SCOPED_COM_INITIALIZER_H_ diff --git a/app/win/shell.cc b/app/win/shell.cc deleted file mode 100644 index cf47387..0000000 --- a/app/win/shell.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2011 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. - -#include "app/win/shell.h" - -#include <shellapi.h> -#include <shlobj.h> - -#include "base/file_path.h" -#include "base/native_library.h" -#include "base/string_util.h" -#include "base/win/scoped_comptr.h" -#include "base/win/win_util.h" -#include "base/win/windows_version.h" - -namespace app { -namespace win { - -namespace { - -const wchar_t kShell32[] = L"shell32.dll"; -const char kSHGetPropertyStoreForWindow[] = "SHGetPropertyStoreForWindow"; - -// Define the type of SHGetPropertyStoreForWindow is SHGPSFW. -typedef DECLSPEC_IMPORT HRESULT (STDAPICALLTYPE *SHGPSFW)(HWND hwnd, - REFIID riid, - void** ppv); - -} // namespace - -// Open an item via a shell execute command. Error code checking and casting -// explanation: http://msdn2.microsoft.com/en-us/library/ms647732.aspx -bool OpenItemViaShell(const FilePath& full_path) { - HINSTANCE h = ::ShellExecuteW( - NULL, NULL, full_path.value().c_str(), NULL, - full_path.DirName().value().c_str(), SW_SHOWNORMAL); - - LONG_PTR error = reinterpret_cast<LONG_PTR>(h); - if (error > 32) - return true; - - if ((error == SE_ERR_NOASSOC)) - return OpenItemWithExternalApp(full_path.value()); - - return false; -} - -bool OpenItemViaShellNoZoneCheck(const FilePath& full_path) { - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.fMask = SEE_MASK_NOZONECHECKS | SEE_MASK_FLAG_DDEWAIT; - sei.nShow = SW_SHOWNORMAL; - sei.lpVerb = NULL; - sei.lpFile = full_path.value().c_str(); - if (::ShellExecuteExW(&sei)) - return true; - LONG_PTR error = reinterpret_cast<LONG_PTR>(sei.hInstApp); - if ((error == SE_ERR_NOASSOC)) - return OpenItemWithExternalApp(full_path.value()); - return false; -} - -// Show the Windows "Open With" dialog box to ask the user to pick an app to -// open the file with. -bool OpenItemWithExternalApp(const string16& full_path) { - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.fMask = SEE_MASK_FLAG_DDEWAIT; - sei.nShow = SW_SHOWNORMAL; - sei.lpVerb = L"openas"; - sei.lpFile = full_path.c_str(); - return (TRUE == ::ShellExecuteExW(&sei)); -} - -void SetAppIdForWindow(const string16& app_id, HWND hwnd) { - // This functionality is only available on Win7+. - if (base::win::GetVersion() < base::win::VERSION_WIN7) - return; - - // Load Shell32.dll into memory. - // TODO(brg): Remove this mechanism when the Win7 SDK is available in trunk. - std::wstring shell32_filename(kShell32); - FilePath shell32_filepath(shell32_filename); - base::NativeLibrary shell32_library = base::LoadNativeLibrary( - shell32_filepath, NULL); - - if (!shell32_library) - return; - - // Get the function pointer for SHGetPropertyStoreForWindow. - void* function = base::GetFunctionPointerFromNativeLibrary( - shell32_library, - kSHGetPropertyStoreForWindow); - - if (!function) { - base::UnloadNativeLibrary(shell32_library); - return; - } - - // Set the application's name. - base::win::ScopedComPtr<IPropertyStore> pps; - SHGPSFW SHGetPropertyStoreForWindow = static_cast<SHGPSFW>(function); - HRESULT result = SHGetPropertyStoreForWindow( - hwnd, __uuidof(*pps), reinterpret_cast<void**>(pps.Receive())); - if (S_OK == result) - base::win::SetAppIdForPropertyStore(pps, app_id.c_str()); - - // Cleanup. - base::UnloadNativeLibrary(shell32_library); -} - -} // namespace win -} // namespace app diff --git a/app/win/shell.h b/app/win/shell.h deleted file mode 100644 index 44ee3ba7..0000000 --- a/app/win/shell.h +++ /dev/null @@ -1,41 +0,0 @@ -// 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 APP_WIN_SHELL_H_ -#define APP_WIN_SHELL_H_ - -#include <windows.h> - -#include "base/string16.h" - -class FilePath; - -namespace app { -namespace win { - -// Open or run a file via the Windows shell. In the event that there is no -// default application registered for the file specified by 'full_path', -// ask the user, via the Windows "Open With" dialog. -// Returns 'true' on successful open, 'false' otherwise. -bool OpenItemViaShell(const FilePath& full_path); - -// The download manager now writes the alternate data stream with the -// zone on all downloads. This function is equivalent to OpenItemViaShell -// without showing the zone warning dialog. -bool OpenItemViaShellNoZoneCheck(const FilePath& full_path); - -// Ask the user, via the Windows "Open With" dialog, for an application to use -// to open the file specified by 'full_path'. -// Returns 'true' on successful open, 'false' otherwise. -bool OpenItemWithExternalApp(const string16& full_path); - -// Sets the application id given as the Application Model ID for the window -// specified. This method is used to insure that different web applications -// do not group together on the Win7 task bar. -void SetAppIdForWindow(const string16& app_id, HWND hwnd); - -} // namespace win -} // namespace app - -#endif // APP_WIN_SHELL_H_ |