SDL  2.0
SDL_sysfilesystem.cpp
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 /* TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all
24 */
25 
26 #ifdef __WINRT__
27 
28 extern "C" {
29 #include "SDL_filesystem.h"
30 #include "SDL_error.h"
31 #include "SDL_hints.h"
32 #include "SDL_stdinc.h"
33 #include "SDL_system.h"
34 #include "../../core/windows/SDL_windows.h"
35 }
36 
37 #include <string>
38 #include <unordered_map>
39 
40 using namespace std;
41 using namespace Windows::Storage;
42 
43 extern "C" const wchar_t *
44 SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType)
45 {
46  switch (pathType) {
47  case SDL_WINRT_PATH_INSTALLED_LOCATION:
48  {
49  static wstring path;
50  if (path.empty()) {
51  path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
52  }
53  return path.c_str();
54  }
55 
56  case SDL_WINRT_PATH_LOCAL_FOLDER:
57  {
58  static wstring path;
59  if (path.empty()) {
60  path = ApplicationData::Current->LocalFolder->Path->Data();
61  }
62  return path.c_str();
63  }
64 
65 #if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
66  case SDL_WINRT_PATH_ROAMING_FOLDER:
67  {
68  static wstring path;
69  if (path.empty()) {
70  path = ApplicationData::Current->RoamingFolder->Path->Data();
71  }
72  return path.c_str();
73  }
74 
75  case SDL_WINRT_PATH_TEMP_FOLDER:
76  {
77  static wstring path;
78  if (path.empty()) {
79  path = ApplicationData::Current->TemporaryFolder->Path->Data();
80  }
81  return path.c_str();
82  }
83 #endif
84 
85  default:
86  break;
87  }
88 
90  return NULL;
91 }
92 
93 extern "C" const char *
94 SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType)
95 {
96  typedef unordered_map<SDL_WinRT_Path, string> UTF8PathMap;
97  static UTF8PathMap utf8Paths;
98 
99  UTF8PathMap::iterator searchResult = utf8Paths.find(pathType);
100  if (searchResult != utf8Paths.end()) {
101  return searchResult->second.c_str();
102  }
103 
104  const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType);
105  if (!ucs2Path) {
106  return NULL;
107  }
108 
109  char * utf8Path = WIN_StringToUTF8(ucs2Path);
110  utf8Paths[pathType] = utf8Path;
111  SDL_free(utf8Path);
112  return utf8Paths[pathType].c_str();
113 }
114 
115 extern "C" char *
116 SDL_GetBasePath(void)
117 {
118  const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION);
119  size_t destPathLen;
120  char * destPath = NULL;
121 
122  if (!srcPath) {
123  SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError());
124  return NULL;
125  }
126 
127  destPathLen = SDL_strlen(srcPath) + 2;
128  destPath = (char *) SDL_malloc(destPathLen);
129  if (!destPath) {
130  SDL_OutOfMemory();
131  return NULL;
132  }
133 
134  SDL_snprintf(destPath, destPathLen, "%s\\", srcPath);
135  return destPath;
136 }
137 
138 extern "C" char *
139 SDL_GetPrefPath(const char *org, const char *app)
140 {
141  /* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and
142  * earlier is not available on WinRT or Windows Phone. WinRT provides
143  * a similar API, but SHGetFolderPath can't be called, at least not
144  * without violating Microsoft's app-store requirements.
145  */
146 
147  const WCHAR * srcPath = NULL;
148  WCHAR path[MAX_PATH];
149  char *retval = NULL;
150  WCHAR* worg = NULL;
151  WCHAR* wapp = NULL;
152  size_t new_wpath_len = 0;
153  BOOL api_result = FALSE;
154 
155  srcPath = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_LOCAL_FOLDER);
156  if ( ! srcPath) {
157  SDL_SetError("Unable to find a source path");
158  return NULL;
159  }
160 
161  if (SDL_wcslen(srcPath) >= MAX_PATH) {
162  SDL_SetError("Path too long.");
163  return NULL;
164  }
165  SDL_wcslcpy(path, srcPath, SDL_arraysize(path));
166 
167  worg = WIN_UTF8ToString(org);
168  if (worg == NULL) {
169  SDL_OutOfMemory();
170  return NULL;
171  }
172 
173  wapp = WIN_UTF8ToString(app);
174  if (wapp == NULL) {
175  SDL_free(worg);
176  SDL_OutOfMemory();
177  return NULL;
178  }
179 
180  new_wpath_len = SDL_wcslen(worg) + SDL_wcslen(wapp) + SDL_wcslen(path) + 3;
181 
182  if ((new_wpath_len + 1) > MAX_PATH) {
183  SDL_free(worg);
184  SDL_free(wapp);
185  SDL_SetError("Path too long.");
186  return NULL;
187  }
188 
189  SDL_wcslcat(path, L"\\", new_wpath_len + 1);
190  SDL_wcslcat(path, worg, new_wpath_len + 1);
191  SDL_free(worg);
192 
193  api_result = CreateDirectoryW(path, NULL);
194  if (api_result == FALSE) {
195  if (GetLastError() != ERROR_ALREADY_EXISTS) {
196  SDL_free(wapp);
197  WIN_SetError("Couldn't create a prefpath.");
198  return NULL;
199  }
200  }
201 
202  SDL_wcslcat(path, L"\\", new_wpath_len + 1);
203  SDL_wcslcat(path, wapp, new_wpath_len + 1);
204  SDL_free(wapp);
205 
206  api_result = CreateDirectoryW(path, NULL);
207  if (api_result == FALSE) {
208  if (GetLastError() != ERROR_ALREADY_EXISTS) {
209  WIN_SetError("Couldn't create a prefpath.");
210  return NULL;
211  }
212  }
213 
214  SDL_wcslcat(path, L"\\", new_wpath_len + 1);
215 
216  retval = WIN_StringToUTF8(path);
217 
218  return retval;
219 }
220 
221 #endif /* __WINRT__ */
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:46
GLuint srcPath
#define SDL_GetError
STL namespace.
SDL_bool retval
#define SDL_wcslen
void SDL_free(void *mem)
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:45
#define SDL_wcslcat
#define SDL_wcslcpy
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
int WIN_SetError(const char *prefix)
#define SDL_SetError
#define SDL_strlen
#define SDL_GetPrefPath
Include file for filesystem SDL API functions.
#define SDL_WinRTGetFSPathUTF8
#define SDL_snprintf
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:90
#define SDL_malloc
GLsizei const GLchar *const * path
#define SDL_WinRTGetFSPathUNICODE
#define FALSE
Definition: edid-parse.c:34
char * SDL_GetBasePath(void)
Get the path where the application resides.
#define SDL_Unsupported()
Definition: SDL_error.h:53