| Index: src/shared/Utils.cpp | 
| diff --git a/src/shared/Utils.cpp b/src/shared/Utils.cpp | 
| index d6f004c524c9bbcd59a7bc77368d0f0f979435cf..7711fd46b2d05fb5529c90a8e10409b77ad689cb 100644 | 
| --- a/src/shared/Utils.cpp | 
| +++ b/src/shared/Utils.cpp | 
| @@ -1,183 +1,196 @@ | 
| -/* | 
| - * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| - * Copyright (C) 2006-2015 Eyeo GmbH | 
| - * | 
| - * Adblock Plus is free software: you can redistribute it and/or modify | 
| - * it under the terms of the GNU General Public License version 3 as | 
| - * published by the Free Software Foundation. | 
| - * | 
| - * Adblock Plus is distributed in the hope that it will be useful, | 
| - * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| - * GNU General Public License for more details. | 
| - * | 
| - * You should have received a copy of the GNU General Public License | 
| - * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| - */ | 
| - | 
| -#include <memory> | 
| -#include <stdexcept> | 
| -#include <vector> | 
| - | 
| -#include <Windows.h> | 
| -#include <ShlObj.h> | 
| - | 
| -#include "Utils.h" | 
| - | 
| -namespace | 
| -{ | 
| -  // See http://blogs.msdn.com/b/oldnewthing/archive/2004/10/25/247180.aspx | 
| -  EXTERN_C IMAGE_DOS_HEADER __ImageBase; | 
| - | 
| -  std::wstring appDataPath; | 
| - | 
| -} | 
| - | 
| -std::unique_ptr<OSVERSIONINFOEX> GetWindowsVersion() | 
| -{ | 
| -  std::unique_ptr<OSVERSIONINFOEX> osvi(new OSVERSIONINFOEX()); | 
| -  osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); | 
| -  GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(osvi.get())); | 
| -  return osvi; | 
| -} | 
| - | 
| -bool IsWindowsVistaOrLater() | 
| -{ | 
| -  std::unique_ptr<OSVERSIONINFOEX> osvi = GetWindowsVersion(); | 
| -  return osvi->dwMajorVersion >= 6; | 
| -} | 
| - | 
| -bool IsWindows8OrLater() | 
| -{ | 
| -  std::unique_ptr<OSVERSIONINFOEX> osvi = GetWindowsVersion(); | 
| -  return (osvi->dwMajorVersion == 6 && osvi->dwMinorVersion >= 2) || osvi->dwMajorVersion > 6; | 
| -} | 
| - | 
| -std::string ToUtf8String(const std::wstring& str) | 
| -{ | 
| -  int length = static_cast<int>(str.size()); | 
| -  if (length == 0) | 
| -    return std::string(); | 
| - | 
| -  int utf8StringLength = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, 0, 0, 0, 0); | 
| -  if (utf8StringLength == 0) | 
| -    throw std::runtime_error("Failed to determine the required buffer size"); | 
| - | 
| -  std::string utf8String(utf8StringLength, '\0'); | 
| -  WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, &utf8String[0], utf8StringLength, 0, 0); | 
| -  return utf8String; | 
| -} | 
| - | 
| -std::wstring ToUtf16String(const std::string& str) | 
| -{ | 
| -  int length = static_cast<int>(str.size()); | 
| -  if (length == 0) | 
| -    return std::wstring(); | 
| - | 
| -  int utf16StringLength = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), length, NULL, 0); | 
| -  if (utf16StringLength == 0) | 
| -    throw std::runtime_error("ToUTF16String failed. Can't determine the length of the buffer needed."); | 
| - | 
| -  std::wstring utf16String(utf16StringLength, L'\0'); | 
| -  MultiByteToWideChar(CP_UTF8, 0, str.c_str(), length, &utf16String[0], utf16StringLength); | 
| -  return utf16String; | 
| -} | 
| - | 
| -std::vector<std::wstring> ToUtf16Strings(const std::vector<std::string>& values) | 
| -{ | 
| -  std::vector<std::wstring> result; | 
| -  result.reserve(values.size()); | 
| -  transform(values.begin(), values.end(), back_inserter(result), ToUtf16String); | 
| -  return result; | 
| -} | 
| - | 
| -std::wstring GetDllDir() | 
| -{ | 
| -  std::vector<WCHAR> path(MAX_PATH); | 
| -  int length = GetModuleFileNameW((HINSTANCE)&__ImageBase, &path[0], static_cast<DWORD>(path.size())); | 
| - | 
| -  while (length == path.size()) | 
| -  { | 
| -    // Buffer too small, double buffer size | 
| -    path.resize(path.size() * 2); | 
| -    length = GetModuleFileNameW((HINSTANCE)&__ImageBase, &path[0], static_cast<DWORD>(path.size())); | 
| -  } | 
| - | 
| -  try | 
| -  { | 
| -    if (length == 0) | 
| -      throw std::runtime_error("Failed determining module path"); | 
| - | 
| -    std::vector<WCHAR>::reverse_iterator it = std::find(path.rbegin(), path.rend(), L'\\'); | 
| -    if (it == path.rend()) | 
| -      throw std::runtime_error("Unexpected plugin path, no backslash found"); | 
| - | 
| -    return std::wstring(path.begin(), it.base()); | 
| -  } | 
| -  catch (const std::exception&) | 
| -  { | 
| -    return std::wstring(); | 
| -  } | 
| -} | 
| - | 
| -std::wstring GetAppDataPath() | 
| -{ | 
| -  if (appDataPath.empty()) | 
| -  { | 
| -    if (IsWindowsVistaOrLater()) | 
| -    { | 
| -      WCHAR* pathBuffer; | 
| -      if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, 0, &pathBuffer))) | 
| -        throw std::runtime_error("Unable to find app data directory"); | 
| -      appDataPath.assign(pathBuffer); | 
| -      CoTaskMemFree(pathBuffer); | 
| -    } | 
| -    else | 
| -    { | 
| -      std::auto_ptr<wchar_t> pathBuffer(new wchar_t[MAX_PATH]); | 
| -      if (!SHGetSpecialFolderPathW(0, pathBuffer.get(), CSIDL_LOCAL_APPDATA, true)) | 
| -        throw std::runtime_error("Unable to find app data directory"); | 
| -      appDataPath.assign(pathBuffer.get()); | 
| -    } | 
| -    appDataPath += L"\\Adblock Plus for IE"; | 
| - | 
| -    // Ignore errors here, this isn't a critical operation | 
| -    ::CreateDirectoryW(appDataPath.c_str(), NULL); | 
| -  } | 
| -  return appDataPath; | 
| -} | 
| - | 
| -void ReplaceString(std::wstring& input, const std::wstring placeholder, const std::wstring replacement) | 
| -{ | 
| -  size_t replaceStart = input.find(placeholder); | 
| -  if (replaceStart != std::string::npos) | 
| -  { | 
| -    input.replace(replaceStart, placeholder.length(), replacement); | 
| -  } | 
| -} | 
| - | 
| -std::wstring GetSchemeAndHierarchicalPart(const std::wstring& url) | 
| -{ | 
| -  auto schemeAndHierarchicalPartEndsAt = url.find(L'?'); | 
| -  if (schemeAndHierarchicalPartEndsAt == std::wstring::npos) | 
| -  { | 
| -    schemeAndHierarchicalPartEndsAt = url.find(L'#'); | 
| -  } | 
| -  return url.substr(0, schemeAndHierarchicalPartEndsAt); | 
| -} | 
| - | 
| -std::wstring GetQueryString(const std::wstring& url) | 
| -{ | 
| -  auto questionSignPos = url.find(L'?'); | 
| -  if (questionSignPos == std::wstring::npos) | 
| -  { | 
| -    return L""; | 
| -  } | 
| -  auto queryStringBeginsAt = questionSignPos + 1; | 
| -  auto endQueryStringPos = url.find(L'#', queryStringBeginsAt); | 
| -  if (endQueryStringPos == std::wstring::npos) | 
| -  { | 
| -    endQueryStringPos = url.length(); | 
| -  } | 
| -  return url.substr(queryStringBeginsAt, endQueryStringPos - queryStringBeginsAt); | 
| -} | 
| +/* | 
| + * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| + * Copyright (C) 2006-2015 Eyeo GmbH | 
| + * | 
| + * Adblock Plus is free software: you can redistribute it and/or modify | 
| + * it under the terms of the GNU General Public License version 3 as | 
| + * published by the Free Software Foundation. | 
| + * | 
| + * Adblock Plus is distributed in the hope that it will be useful, | 
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| + * GNU General Public License for more details. | 
| + * | 
| + * You should have received a copy of the GNU General Public License | 
| + * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| + */ | 
| + | 
| +#include <memory> | 
| +#include <stdexcept> | 
| +#include <vector> | 
| + | 
| +#include <Windows.h> | 
| +#include <ShlObj.h> | 
| + | 
| +#include "Utils.h" | 
| + | 
| +namespace | 
| +{ | 
| +  // See http://blogs.msdn.com/b/oldnewthing/archive/2004/10/25/247180.aspx | 
| +  EXTERN_C IMAGE_DOS_HEADER __ImageBase; | 
| + | 
| +  std::wstring appDataPath; | 
| + | 
| +} | 
| + | 
| +std::unique_ptr<OSVERSIONINFOEX> GetWindowsVersion() | 
| +{ | 
| +  std::unique_ptr<OSVERSIONINFOEX> osvi(new OSVERSIONINFOEX()); | 
| +  osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); | 
| +  GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(osvi.get())); | 
| +  return osvi; | 
| +} | 
| + | 
| +bool IsWindowsVistaOrLater() | 
| +{ | 
| +  std::unique_ptr<OSVERSIONINFOEX> osvi = GetWindowsVersion(); | 
| +  return osvi->dwMajorVersion >= 6; | 
| +} | 
| + | 
| +bool IsWindows8OrLater() | 
| +{ | 
| +  std::unique_ptr<OSVERSIONINFOEX> osvi = GetWindowsVersion(); | 
| +  return (osvi->dwMajorVersion == 6 && osvi->dwMinorVersion >= 2) || osvi->dwMajorVersion > 6; | 
| +} | 
| + | 
| +std::string ToUtf8String(const std::wstring& str) | 
| +{ | 
| +  int length = static_cast<int>(str.size()); | 
| +  if (length == 0) | 
| +    return std::string(); | 
| + | 
| +  int utf8StringLength = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, 0, 0, 0, 0); | 
| +  if (utf8StringLength == 0) | 
| +    throw std::runtime_error("Failed to determine the required buffer size"); | 
| + | 
| +  std::string utf8String(utf8StringLength, '\0'); | 
| +  WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, &utf8String[0], utf8StringLength, 0, 0); | 
| +  return utf8String; | 
| +} | 
| + | 
| +std::wstring ToUtf16String(const std::string& str) | 
| +{ | 
| +  int length = static_cast<int>(str.size()); | 
| +  if (length == 0) | 
| +    return std::wstring(); | 
| + | 
| +  int utf16StringLength = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), length, NULL, 0); | 
| +  if (utf16StringLength == 0) | 
| +    throw std::runtime_error("ToUTF16String failed. Can't determine the length of the buffer needed."); | 
| + | 
| +  std::wstring utf16String(utf16StringLength, L'\0'); | 
| +  MultiByteToWideChar(CP_UTF8, 0, str.c_str(), length, &utf16String[0], utf16StringLength); | 
| +  return utf16String; | 
| +} | 
| + | 
| +std::vector<std::wstring> ToUtf16Strings(const std::vector<std::string>& values) | 
| +{ | 
| +  std::vector<std::wstring> result; | 
| +  result.reserve(values.size()); | 
| +  transform(values.begin(), values.end(), back_inserter(result), ToUtf16String); | 
| +  return result; | 
| +} | 
| + | 
| +namespace | 
| +{ | 
| +  std::wstring GetModulePath(HINSTANCE hInstance) | 
| +  { | 
| +    std::vector<WCHAR> path(MAX_PATH); | 
| +    int length = GetModuleFileNameW(hInstance, &path[0], static_cast<DWORD>(path.size())); | 
| + | 
| +    while (length == path.size()) | 
| +    { | 
| +      // Buffer too small, double buffer size | 
| +      path.resize(path.size() * 2); | 
| +      length = GetModuleFileNameW(hInstance, &path[0], static_cast<DWORD>(path.size())); | 
| +    } | 
| + | 
| +    try | 
| +    { | 
| +      if (length == 0) | 
| +        throw std::runtime_error("Failed determining module path"); | 
| + | 
| +      std::vector<WCHAR>::reverse_iterator it = std::find(path.rbegin(), path.rend(), L'\\'); | 
| +      if (it == path.rend()) | 
| +        throw std::runtime_error("Unexpected plugin path, no backslash found"); | 
| + | 
| +      return std::wstring(path.begin(), it.base()); | 
| +    } | 
| +    catch (const std::exception&) | 
| +    { | 
| +      return std::wstring(); | 
| +    } | 
| +  } | 
| +} | 
| + | 
| +std::wstring GetDllDir() | 
| +{ | 
| +  return GetModulePath((HINSTANCE)&__ImageBase); | 
| +} | 
| + | 
| +std::wstring GetExeDir() | 
| +{ | 
| +  return GetModulePath(nullptr); | 
| +} | 
| + | 
| +std::wstring GetAppDataPath() | 
| +{ | 
| +  if (appDataPath.empty()) | 
| +  { | 
| +    if (IsWindowsVistaOrLater()) | 
| +    { | 
| +      WCHAR* pathBuffer; | 
| +      if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, 0, &pathBuffer))) | 
| +        throw std::runtime_error("Unable to find app data directory"); | 
| +      appDataPath.assign(pathBuffer); | 
| +      CoTaskMemFree(pathBuffer); | 
| +    } | 
| +    else | 
| +    { | 
| +      std::auto_ptr<wchar_t> pathBuffer(new wchar_t[MAX_PATH]); | 
| +      if (!SHGetSpecialFolderPathW(0, pathBuffer.get(), CSIDL_LOCAL_APPDATA, true)) | 
| +        throw std::runtime_error("Unable to find app data directory"); | 
| +      appDataPath.assign(pathBuffer.get()); | 
| +    } | 
| +    appDataPath += L"\\Adblock Plus for IE"; | 
| + | 
| +    // Ignore errors here, this isn't a critical operation | 
| +    ::CreateDirectoryW(appDataPath.c_str(), NULL); | 
| +  } | 
| +  return appDataPath; | 
| +} | 
| + | 
| +void ReplaceString(std::wstring& input, const std::wstring& placeholder, const std::wstring& replacement) | 
| +{ | 
| +  size_t replaceStart = input.find(placeholder); | 
| +  if (replaceStart != std::string::npos) | 
| +  { | 
| +    input.replace(replaceStart, placeholder.length(), replacement); | 
| +  } | 
| +} | 
| + | 
| +std::wstring GetSchemeAndHierarchicalPart(const std::wstring& url) | 
| +{ | 
| +  auto schemeAndHierarchicalPartEndsAt = url.find(L'?'); | 
| +  if (schemeAndHierarchicalPartEndsAt == std::wstring::npos) | 
| +  { | 
| +    schemeAndHierarchicalPartEndsAt = url.find(L'#'); | 
| +  } | 
| +  return url.substr(0, schemeAndHierarchicalPartEndsAt); | 
| +} | 
| + | 
| +std::wstring GetQueryString(const std::wstring& url) | 
| +{ | 
| +  auto questionSignPos = url.find(L'?'); | 
| +  if (questionSignPos == std::wstring::npos) | 
| +  { | 
| +    return L""; | 
| +  } | 
| +  auto queryStringBeginsAt = questionSignPos + 1; | 
| +  auto endQueryStringPos = url.find(L'#', queryStringBeginsAt); | 
| +  if (endQueryStringPos == std::wstring::npos) | 
| +  { | 
| +    endQueryStringPos = url.length(); | 
| +  } | 
| +  return url.substr(queryStringBeginsAt, endQueryStringPos - queryStringBeginsAt); | 
| +} | 
|  |