FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
SystemHelpersWin.cpp
1 /**********************************************************\
2 Original Author: Richard Bateman (taxilian)
3 
4 Created: Sep 27, 2011
5 License: Dual license model; choose one of two:
6  New BSD License
7  http://www.opensource.org/licenses/bsd-license.php
8  - or -
9  GNU Lesser General Public License, version 2.1
10  http://www.gnu.org/licenses/lgpl-2.1.html
11 
12 Copyright 2011 GradeCam, Inc and the Firebreath development team
13 \**********************************************************/
14 
15 #include "../SystemHelpers.h"
16 #include "shlobj.h"
17 #include <cassert>
18 #include "utf8_tools.h"
19 
20 #ifndef REFKNOWNFOLDERID
21 typedef GUID KNOWNFOLDERID;
22 #define REFKNOWNFOLDERID const KNOWNFOLDERID &
23 #endif
24 
25 #ifndef DEFINE_KNOWN_FOLDER
26 #define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
27  EXTERN_C const GUID DECLSPEC_SELECTANY name \
28  = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
29 DEFINE_KNOWN_FOLDER(FOLDERID_LocalAppDataLow, 0xA520A1A4, 0x1780, 0x4FF6, 0xBD, 0x18, 0x16, 0x73, 0x43, 0xC5, 0xAF, 0x16);
30 #undef DEFINE_KNOWN_FOLDER
31 #endif
32 
33 using std::string;
34 
35 typedef HRESULT (WINAPI*GetKnownFolderPathFunc)(REFKNOWNFOLDERID, DWORD, HANDLE hToken, PWSTR *ppszPath); // free *ppszPath with CoTaskMemFree
36 
37 static bool useNewAPI(false);
38 static HMODULE library(NULL);
39 static GetKnownFolderPathFunc getKnownFolderPath(NULL);
40 
41 namespace {
42  void initLibrary() {
43  library = LoadLibraryA("shell32.dll");
44  assert(library != NULL);
45  getKnownFolderPath = (GetKnownFolderPathFunc)GetProcAddress(library, "SHGetKnownFolderPath");
46  useNewAPI = getKnownFolderPath != NULL;
47  }
48 
49  std::string getFolderNew(REFKNOWNFOLDERID folder) {
50  PWSTR pszPath;
51  HRESULT hr = (*getKnownFolderPath)(folder, 0, NULL, &pszPath);
52  if (FAILED(hr)) {
53  throw std::runtime_error("Could not find path");
54  }
55 
56  std::wstring path(pszPath);
57  CoTaskMemFree(pszPath);
58  return FB::wstring_to_utf8(path);
59  }
60 
61  std::string getFolderStd(int csIDL) {
62  wchar_t rawPath[MAX_PATH];
63 
64  if (SHGetSpecialFolderPathW(NULL, rawPath, csIDL, FALSE)) {
65  return FB::wstring_to_utf8(rawPath);
66  } else {
67  throw std::runtime_error("Could not find path");
68  }
69  }
70 
71  void closeLibrary() {
72  FreeLibrary(library);
73  library = NULL;
74  getKnownFolderPath = NULL;
75  }
76 };
77 
78 string FB::System::getHomeDirPath()
79 {
80  return getFolderStd(CSIDL_PROFILE);
81 }
82 
83 string FB::System::getAppDataPath(const string& appName)
84 {
85  std::string out;
86  out = getFolderStd(CSIDL_APPDATA);
87  return out + "\\" + appName;
88 }
89 
90 string FB::System::getLocalAppDataPath(const string& appName)
91 {
92  std::string out;
93  initLibrary();
94  if (useNewAPI) {
95  out = getFolderNew(FOLDERID_LocalAppDataLow);
96  } else {
97  out = getFolderStd(CSIDL_LOCAL_APPDATA);
98  }
99  closeLibrary();
100  return out + "\\" + appName;
101 }
102 
103 string FB::System::getTempPath()
104 {
105  wchar_t path[MAX_PATH];
106  DWORD len;
107  len = GetTempPathW(MAX_PATH, path);
108  if (len > 0) {
109  return FB::wstring_to_utf8(std::wstring(path, len));
110  } else {
111  throw std::runtime_error("Could not find path");
112  }
113 }
std::string wstring_to_utf8(const std::wstring &src)
Accepts a std::wstring and returns a UTF8-encoded std::string.
Definition: utf8_tools.cpp:37