| OLD | NEW |
| 1 #include <memory> | 1 #include <memory> |
| 2 #include <stdexcept> | 2 #include <stdexcept> |
| 3 #include <vector> |
| 3 | 4 |
| 4 #include <Windows.h> | 5 #include <Windows.h> |
| 5 #include <ShlObj.h> | 6 #include <ShlObj.h> |
| 6 | 7 |
| 7 #include "Utils.h" | 8 #include "Utils.h" |
| 8 | 9 |
| 9 namespace | 10 namespace |
| 10 { | 11 { |
| 12 // See http://blogs.msdn.com/b/oldnewthing/archive/2004/10/25/247180.aspx |
| 13 EXTERN_C IMAGE_DOS_HEADER __ImageBase; |
| 14 |
| 11 std::wstring appDataPath; | 15 std::wstring appDataPath; |
| 12 | 16 |
| 13 bool IsWindowsVistaOrLater() | 17 bool IsWindowsVistaOrLater() |
| 14 { | 18 { |
| 15 OSVERSIONINFOEX osvi; | 19 OSVERSIONINFOEX osvi; |
| 16 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); | 20 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); |
| 17 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); | 21 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); |
| 18 GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osvi)); | 22 GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osvi)); |
| 19 return osvi.dwMajorVersion >= 6; | 23 return osvi.dwMajorVersion >= 6; |
| 20 } | 24 } |
| 21 } | 25 } |
| 22 | 26 |
| 23 std::string ToUtf8String(std::wstring str) | 27 std::string ToUtf8String(const std::wstring& str) |
| 24 { | 28 { |
| 25 size_t length = str.size(); | 29 size_t length = str.size(); |
| 26 if (length == 0) | 30 if (length == 0) |
| 27 return std::string(); | 31 return std::string(); |
| 28 | 32 |
| 29 DWORD utf8StringLength = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length,
0, 0, 0, 0); | 33 DWORD utf8StringLength = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length,
0, 0, 0, 0); |
| 30 if (utf8StringLength == 0) | 34 if (utf8StringLength == 0) |
| 31 throw std::runtime_error("Failed to determine the required buffer size"); | 35 throw std::runtime_error("Failed to determine the required buffer size"); |
| 32 | 36 |
| 33 std::string utf8String(utf8StringLength, '\0'); | 37 std::string utf8String(utf8StringLength, '\0'); |
| 34 WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, &utf8String[0], utf8Strin
gLength, 0, 0); | 38 WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, &utf8String[0], utf8Strin
gLength, 0, 0); |
| 35 return utf8String; | 39 return utf8String; |
| 36 } | 40 } |
| 37 | 41 |
| 42 std::wstring ToUtf16String(const std::string& str) |
| 43 { |
| 44 size_t length = str.size(); |
| 45 if (length == 0) |
| 46 return std::wstring(); |
| 47 |
| 48 DWORD utf16StringLength = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), length,
NULL, 0); |
| 49 if (utf16StringLength == 0) |
| 50 throw std::runtime_error("ToUTF16String failed. Can't determine the length o
f the buffer needed."); |
| 51 |
| 52 std::wstring utf16String(utf16StringLength, L'\0'); |
| 53 MultiByteToWideChar(CP_UTF8, 0, str.c_str(), length, &utf16String[0], utf16Str
ingLength); |
| 54 return utf16String; |
| 55 } |
| 56 |
| 57 std::wstring GetDllDir() |
| 58 { |
| 59 std::vector<WCHAR> path(MAX_PATH); |
| 60 DWORD length = GetModuleFileNameW((HINSTANCE)&__ImageBase, &path[0], path.size
()); |
| 61 |
| 62 while (length == path.size()) |
| 63 { |
| 64 // Buffer too small, double buffer size |
| 65 path.resize(path.size() * 2); |
| 66 length = GetModuleFileNameW((HINSTANCE)&__ImageBase, &path[0], path.size()); |
| 67 } |
| 68 |
| 69 try |
| 70 { |
| 71 if (length == 0) |
| 72 throw std::runtime_error("Failed determining module path"); |
| 73 |
| 74 std::vector<WCHAR>::reverse_iterator it = std::find(path.rbegin(), path.rend
(), L'\\'); |
| 75 if (it == path.rend()) |
| 76 throw std::runtime_error("Unexpected plugin path, no backslash found"); |
| 77 |
| 78 return std::wstring(path.begin(), it.base()); |
| 79 } |
| 80 catch (const std::exception&) |
| 81 { |
| 82 return std::wstring(); |
| 83 } |
| 84 } |
| 85 |
| 38 std::wstring GetAppDataPath() | 86 std::wstring GetAppDataPath() |
| 39 { | 87 { |
| 40 if (appDataPath.empty()) | 88 if (appDataPath.empty()) |
| 41 { | 89 { |
| 42 if (IsWindowsVistaOrLater()) | 90 if (IsWindowsVistaOrLater()) |
| 43 { | 91 { |
| 44 WCHAR* pathBuffer; | 92 WCHAR* pathBuffer; |
| 45 if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, 0, &pathBuffe
r))) | 93 if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, 0, &pathBuffe
r))) |
| 46 throw std::runtime_error("Unable to find app data directory"); | 94 throw std::runtime_error("Unable to find app data directory"); |
| 47 appDataPath.assign(pathBuffer); | 95 appDataPath.assign(pathBuffer); |
| 48 CoTaskMemFree(pathBuffer); | 96 CoTaskMemFree(pathBuffer); |
| 49 } | 97 } |
| 50 else | 98 else |
| 51 { | 99 { |
| 52 std::auto_ptr<wchar_t> pathBuffer(new wchar_t[MAX_PATH]); | 100 std::auto_ptr<wchar_t> pathBuffer(new wchar_t[MAX_PATH]); |
| 53 if (!SHGetSpecialFolderPath(0, pathBuffer.get(), CSIDL_LOCAL_APPDATA, true
)) | 101 if (!SHGetSpecialFolderPathW(0, pathBuffer.get(), CSIDL_LOCAL_APPDATA, tru
e)) |
| 54 throw std::runtime_error("Unable to find app data directory"); | 102 throw std::runtime_error("Unable to find app data directory"); |
| 55 appDataPath.assign(pathBuffer.get()); | 103 appDataPath.assign(pathBuffer.get()); |
| 56 } | 104 } |
| 57 appDataPath += L"\\Adblock Plus for IE"; | 105 appDataPath += L"\\Adblock Plus for IE"; |
| 58 | 106 |
| 59 // Ignore errors here, this isn't a critical operation | 107 // Ignore errors here, this isn't a critical operation |
| 60 ::CreateDirectoryW(appDataPath.c_str(), NULL); | 108 ::CreateDirectoryW(appDataPath.c_str(), NULL); |
| 61 } | 109 } |
| 62 return appDataPath; | 110 return appDataPath; |
| 63 } | 111 } |
| OLD | NEW |