Merge pull request #26386 from ksooo/guiinfo-fix-listitem-filenamenoextension
[xbmc.git] / lib / libUPnP / Neptune / Source / System / WinRT / NptWinRtFile.cpp
bloba9c76f12283b2621aba0359a5c22222097b8c181
1 /*****************************************************************
3 | Neptune - Files :: WinRT Implementation
5 | (c) 2001-2013 Gilles Boccon-Gibod
6 | Author: Gilles Boccon-Gibod (bok@bok.net)
8 ****************************************************************/
10 /*----------------------------------------------------------------------
11 | includes
12 +---------------------------------------------------------------------*/
13 #include "NptWinRtPch.h"
15 #include "NptConfig.h"
16 #include "NptUtils.h"
17 #include "NptFile.h"
18 #include "NptStrings.h"
19 #include "NptDebug.h"
20 #include "NptWinRtUtils.h"
22 /*----------------------------------------------------------------------
23 | MapError
24 +---------------------------------------------------------------------*/
25 static NPT_Result
26 MapError(DWORD err) {
27 switch (err) {
28 case ERROR_ALREADY_EXISTS: return NPT_ERROR_FILE_ALREADY_EXISTS;
29 case ERROR_PATH_NOT_FOUND:
30 case ERROR_FILE_NOT_FOUND:
31 case ERROR_INVALID_DRIVE:
32 case ERROR_BAD_PATHNAME:
33 case ERROR_BAD_NET_NAME:
34 case ERROR_FILENAME_EXCED_RANGE:
35 case ERROR_NO_MORE_FILES:
36 case ERROR_BAD_NETPATH: return NPT_ERROR_NO_SUCH_FILE;
37 case ERROR_LOCK_VIOLATION:
38 case ERROR_SEEK_ON_DEVICE:
39 case ERROR_CURRENT_DIRECTORY:
40 case ERROR_CANNOT_MAKE:
41 case ERROR_FAIL_I24:
42 case ERROR_NETWORK_ACCESS_DENIED:
43 case ERROR_DRIVE_LOCKED:
44 case ERROR_ACCESS_DENIED: return NPT_ERROR_PERMISSION_DENIED;
45 case ERROR_NOT_LOCKED:
46 case ERROR_LOCK_FAILED:
47 case ERROR_SHARING_VIOLATION: return NPT_ERROR_FILE_BUSY;
48 case ERROR_INVALID_FUNCTION: return NPT_ERROR_INTERNAL;
49 case ERROR_NOT_ENOUGH_QUOTA: return NPT_ERROR_OUT_OF_MEMORY;
50 case ERROR_ARENA_TRASHED:
51 case ERROR_NOT_ENOUGH_MEMORY:
52 case ERROR_INVALID_BLOCK: return NPT_ERROR_OUT_OF_MEMORY;
53 case ERROR_DISK_FULL: return NPT_ERROR_FILE_NOT_ENOUGH_SPACE;
54 case ERROR_TOO_MANY_OPEN_FILES: return NPT_ERROR_OUT_OF_RESOURCES;
55 case ERROR_INVALID_HANDLE:
56 case ERROR_INVALID_ACCESS:
57 case ERROR_INVALID_DATA: return NPT_ERROR_INVALID_PARAMETERS;
58 case ERROR_DIR_NOT_EMPTY: return NPT_ERROR_DIRECTORY_NOT_EMPTY;
59 case ERROR_NEGATIVE_SEEK: return NPT_ERROR_OUT_OF_RANGE;
60 default: return NPT_FAILURE;
64 #include <sys/stat.h>
65 #include <direct.h>
67 /*----------------------------------------------------------------------
68 | NPT_stat_utf8
69 +---------------------------------------------------------------------*/
70 int
71 NPT_stat_utf8(const char* path, struct __stat64* info)
73 NPT_WINRT_USE_CHAR_CONVERSION;
74 return _wstat64(NPT_WINRT_A2W(path), info);
77 /*----------------------------------------------------------------------
78 | NPT_fsopen_utf8
79 +---------------------------------------------------------------------*/
80 FILE*
81 NPT_fsopen_utf8(const char* path, const char* mode, int sh_flags)
83 NPT_WINRT_USE_CHAR_CONVERSION;
84 return _wfsopen(NPT_WINRT_A2W(path), NPT_WINRT_A2W(mode), sh_flags);
87 /*----------------------------------------------------------------------
88 | NPT_FilePath::Separator
89 +---------------------------------------------------------------------*/
90 const char* const NPT_FilePath::Separator = "\\";
92 /*----------------------------------------------------------------------
93 | NPT_File::GetRoots
94 +---------------------------------------------------------------------*/
95 NPT_Result
96 NPT_File::GetRoots(NPT_List<NPT_String>& roots)
98 roots.Clear();
99 return NPT_ERROR_NOT_IMPLEMENTED;
102 /*----------------------------------------------------------------------
103 | NPT_File::GetWorkingDir
104 +---------------------------------------------------------------------*/
105 NPT_Result
106 NPT_File::GetWorkingDir(NPT_String& path)
108 path.SetLength(0);
109 return NPT_ERROR_NOT_IMPLEMENTED;
112 /*----------------------------------------------------------------------
113 | NPT_File::GetInfo
114 +---------------------------------------------------------------------*/
115 NPT_Result
116 NPT_File::GetInfo(const char* path, NPT_FileInfo* info)
118 DWORD attributes = 0;
119 WIN32_FILE_ATTRIBUTE_DATA attribute_data;
121 NPT_WINRT_USE_CHAR_CONVERSION;
123 if (0 == GetFileAttributesEx(
124 NPT_WINRT_A2W(path),
125 GetFileExInfoStandard,
126 &attribute_data)) {
127 DWORD error_code = GetLastError();
128 return NPT_FAILURE;
130 attributes = attribute_data.dwFileAttributes;
131 if (attributes == INVALID_FILE_ATTRIBUTES) {
132 return NPT_FAILURE;
135 if (info != NULL) {
136 // (prasad) FIXME - fill in the attribute values in return value
139 return NPT_SUCCESS;
142 /*----------------------------------------------------------------------
143 | NPT_File::CreateDir
144 +---------------------------------------------------------------------*/
145 NPT_Result
146 NPT_File::CreateDir(const char* path)
148 NPT_WINRT_USE_CHAR_CONVERSION;
149 BOOL result = ::CreateDirectoryW(NPT_WINRT_A2W(path), NULL);
150 if (result == 0) {
151 return MapError(GetLastError());
153 return NPT_SUCCESS;
156 /*----------------------------------------------------------------------
157 | NPT_File::RemoveFile
158 +---------------------------------------------------------------------*/
159 NPT_Result
160 NPT_File::RemoveFile(const char* path)
162 NPT_WINRT_USE_CHAR_CONVERSION;
163 BOOL result = ::DeleteFileW(NPT_WINRT_A2W(path));
164 if (result == 0) {
165 return MapError(GetLastError());
167 return NPT_SUCCESS;
170 /*----------------------------------------------------------------------
171 | NPT_File::RemoveDir
172 +---------------------------------------------------------------------*/
173 NPT_Result
174 NPT_File::RemoveDir(const char* path)
176 NPT_WINRT_USE_CHAR_CONVERSION;
177 BOOL result = ::RemoveDirectoryW(NPT_WINRT_A2W(path));
178 if (result == 0) {
179 return MapError(GetLastError());
181 return NPT_SUCCESS;
184 /*----------------------------------------------------------------------
185 | NPT_File::Rename
186 +---------------------------------------------------------------------*/
187 NPT_Result
188 NPT_File::Rename(const char* from_path, const char* to_path)
190 NPT_WINRT_USE_CHAR_CONVERSION;
191 BOOL result = MoveFileEx(NPT_WINRT_A2W(from_path),
192 NPT_WINRT_A2W(to_path),
193 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH);
194 if (result == 0) {
195 return MapError(GetLastError());
197 return NPT_SUCCESS;
200 /*----------------------------------------------------------------------
201 | NPT_File_ProcessFindData
202 +---------------------------------------------------------------------*/
203 static bool
204 NPT_File_ProcessFindData(WIN32_FIND_DATAW* find_data)
206 NPT_WINRT_USE_CHAR_CONVERSION;
208 // discard system specific files/shortcuts
209 if (NPT_StringsEqual(NPT_WINRT_W2A(find_data->cFileName), ".") ||
210 NPT_StringsEqual(NPT_WINRT_W2A(find_data->cFileName), "..")) {
211 return false;
214 return true;
217 /*----------------------------------------------------------------------
218 | NPT_File::ListDir
219 +---------------------------------------------------------------------*/
220 NPT_Result
221 NPT_File::ListDir(const char* path,
222 NPT_List<NPT_String>& entries,
223 NPT_Ordinal start /* = 0 */,
224 NPT_Cardinal max /* = 0 */)
226 NPT_WINRT_USE_CHAR_CONVERSION;
228 // default return value
229 entries.Clear();
231 // check the arguments
232 if (path == NULL || path[0] == '\0') return NPT_ERROR_INVALID_PARAMETERS;
234 // construct a path name with a \* wildcard at the end
235 NPT_String path_pattern = path;
236 if (path_pattern.EndsWith("\\") || path_pattern.EndsWith("/")) {
237 path_pattern += "*";
238 } else {
239 path_pattern += "\\*";
242 // list the entries
243 WIN32_FIND_DATAW find_data;
244 HANDLE find_handle = FindFirstFileEx(NPT_WINRT_A2W(path_pattern.GetChars()),
245 FindExInfoStandard,
246 &find_data,
247 FindExSearchNameMatch,
248 NULL,
250 if (find_handle == INVALID_HANDLE_VALUE) return MapError(GetLastError());
251 NPT_Cardinal count = 0;
252 do {
253 if (NPT_File_ProcessFindData(&find_data)) {
254 // continue if we still have entries to skip
255 if (start > 0) {
256 --start;
257 continue;
259 entries.Add(NPT_WINRT_W2A(find_data.cFileName));
261 // stop when we have reached the maximum requested
262 if (max && ++count == max) return NPT_SUCCESS;
264 } while (FindNextFileW(find_handle, &find_data));
265 DWORD last_error = GetLastError();
266 FindClose(find_handle);
267 if (last_error != ERROR_NO_MORE_FILES) return MapError(last_error);
269 return NPT_SUCCESS;