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 |