2626#include < algorithm>
2727#include < CommDlg.h>
2828#include < ShlObj.h>
29+ #include < Shlwapi.h>
30+ #include < stdio.h>
31+ #include < sys/stat.h>
2932
3033// Forward declarations for functions at the bottom of this file
31- void FixFilename (ExtensionString& filename);
34+ void ConvertToNativePath (ExtensionString& filename);
35+ void ConvertToUnixPath (ExtensionString& filename);
3236int ConvertErrnoCode (int errorCode, bool isReading = true );
3337int ConvertWinErrorCode (int errorCode, bool isReading = true );
3438
@@ -52,8 +56,6 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
5256 wchar_t szFile[MAX_PATH];
5357 szFile[0 ] = 0 ;
5458
55- FixFilename (initialDirectory);
56-
5759 // TODO (issue #64) - This method should be using IFileDialog instead of the
5860 /* outdated SHGetPathFromIDList and GetOpenFileName.
5961
@@ -103,8 +105,6 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
103105 ofn.lpstrFile = szFile;
104106 ofn.nMaxFile = MAX_PATH;
105107
106- allowMulitpleSelection = false ; // TODO: Raymond, please implement.
107-
108108 // TODO (issue #65) - Use passed in file types. Note, when fileTypesStr is null, all files should be shown
109109 /* findAndReplaceString( fileTypesStr, std::string(" "), std::string(";*."));
110110 LPCWSTR allFilesFilter = L"All Files\0*.*\0\0";*/
@@ -119,23 +119,21 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
119119 if (GetOpenFileName (&ofn)) {
120120 if (allowMulitpleSelection) {
121121 // Multiple selection encodes the files differently
122- /*
122+
123123 // If multiple files are selected, the first null terminator
124124 // signals end of directory that the files are all in
125125 std::wstring dir (szFile);
126126
127127 // Check for two null terminators, which signal that only one file
128128 // was selected
129129 if (szFile[dir.length () + 1 ] == ' \0 ' ) {
130- // Escape the single file path and add it to the JSON array
131- std::wstring escaped;
132- EscapeJSONString(dir, escaped);
133- results += L"\"" + escaped + L"\"";
130+ ExtensionString filePath (dir);
131+ ConvertToUnixPath (filePath);
132+ selectedFiles->SetString (0 , filePath);
134133 } else {
135134 // Multiple files are selected
136135 wchar_t fullPath[MAX_PATH];
137- bool firstFile = true;
138- for (int i = dir.length() + 1;;) {
136+ for (int i = (dir.length () + 1 ), fileIndex = 0 ; ; fileIndex++) {
139137 // Get the next file name
140138 std::wstring file (&szFile[i]);
141139
@@ -145,25 +143,17 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
145143
146144 // The filename is relative to the directory that was specified as
147145 // the first string
148- if (PathCombine(fullPath, dir.c_str(), file.c_str()) != NULL)
149- {
150- // Append a comma separator if it is not the first file in the list
151- if (firstFile)
152- firstFile = false;
153- else
154- results += L",";
155-
156- // Escape the path and add it to the list
157- std::wstring escaped;
158- EscapeJSONString(std::wstring(fullPath), escaped);
159- results += L"\"" + escaped + L"\"";
160- }
146+ if (PathCombine (fullPath, dir.c_str (), file.c_str ()) != NULL ) {
147+ ExtensionString filePath (fullPath);
148+ ConvertToUnixPath (filePath);
149+ selectedFiles->SetString (fileIndex, filePath);
150+ }
161151
162152 // Go to the start of the next file name
163153 i += file.length () + 1 ;
164154 }
165155 }
166- */
156+
167157 } else {
168158 // If multiple files are not allowed, add the single file
169159 selectedFiles->SetString (0 , szFile);
@@ -176,9 +166,10 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
176166
177167int32 ReadDir (ExtensionString path, CefRefPtr<CefListValue>& directoryContents)
178168{
179- FixFilename (path);
169+ if (path.length () && path[path.length () - 1 ] != ' /' )
170+ path += ' /' ;
180171
181- path += L" \\ * " ;
172+ path += ' * ' ;
182173
183174 WIN32_FIND_DATA ffd;
184175 HANDLE hFind = FindFirstFile (path.c_str (), &ffd);
@@ -219,8 +210,6 @@ int32 ReadDir(ExtensionString path, CefRefPtr<CefListValue>& directoryContents)
219210
220211int32 GetFileModificationTime (ExtensionString filename, uint32& modtime, bool & isDir)
221212{
222- FixFilename (filename);
223-
224213 DWORD dwAttr = GetFileAttributes (filename.c_str ());
225214
226215 if (dwAttr == INVALID_FILE_ATTRIBUTES) {
@@ -229,6 +218,11 @@ int32 GetFileModificationTime(ExtensionString filename, uint32& modtime, bool& i
229218
230219 isDir = ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) != 0 );
231220
221+ // Remove trailing "/", if present. _wstat will fail with a "file not found"
222+ // error if a directory has a trailing '/' in the name.
223+ if (filename[filename.length () - 1 ] == ' /' )
224+ filename[filename.length () - 1 ] = 0 ;
225+
232226 struct _stat buffer;
233227 if (_wstat (filename.c_str (), &buffer) == -1 ) {
234228 return ConvertErrnoCode (errno);
@@ -241,8 +235,6 @@ int32 GetFileModificationTime(ExtensionString filename, uint32& modtime, bool& i
241235
242236int32 ReadFile (ExtensionString filename, ExtensionString encoding, std::string& contents)
243237{
244- FixFilename (filename);
245-
246238 if (encoding != L" utf8" )
247239 return ERR_UNSUPPORTED_ENCODING;
248240
@@ -282,8 +274,6 @@ int32 ReadFile(ExtensionString filename, ExtensionString encoding, std::string&
282274
283275int32 WriteFile (ExtensionString filename, std::string contents, ExtensionString encoding)
284276{
285- FixFilename (filename);
286-
287277 if (encoding != L" utf8" )
288278 return ERR_UNSUPPORTED_ENCODING;
289279
@@ -306,22 +296,45 @@ int32 WriteFile(ExtensionString filename, std::string contents, ExtensionString
306296
307297int32 SetPosixPermissions (ExtensionString filename, int32 mode)
308298{
309- // TODO: Raymond, please implement
299+ DWORD dwAttr = GetFileAttributes (filename.c_str ());
300+
301+ if (dwAttr == INVALID_FILE_ATTRIBUTES)
302+ return ERR_NOT_FOUND;
303+
304+ if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) != 0 )
305+ return NO_ERROR;
306+
307+ bool write = (mode & 0200 ) != 0 ;
308+ bool read = (mode & 0400 ) != 0 ;
309+ int mask = (write ? _S_IWRITE : 0 ) | (read ? _S_IREAD : 0 );
310+
311+ if (_wchmod (filename.c_str (), mask) == -1 ) {
312+ return ConvertErrnoCode (errno);
313+ }
314+
310315 return NO_ERROR;
311316}
312317
313318int32 DeleteFileOrDirectory (ExtensionString filename)
314319{
315- // TODO: Raymond, please implement
320+ if (!DeleteFile (filename.c_str ()))
321+ return ConvertWinErrorCode (GetLastError ());
322+
316323 return NO_ERROR;
317324}
318325
319- void FixFilename (ExtensionString& filename)
326+ void ConvertToNativePath (ExtensionString& filename)
320327{
321328 // Convert '/' to '\'
322329 replace (filename.begin (), filename.end (), ' /' , ' \\ ' );
323330}
324331
332+ void ConvertToUnixPath (ExtensionString& filename)
333+ {
334+ // Convert '\\' to '/'
335+ replace (filename.begin (), filename.end (), ' \\ ' , ' /' );
336+ }
337+
325338// Maps errors from errno.h to the brackets error codes
326339// found in brackets_extensions.js
327340int ConvertErrnoCode (int errorCode, bool isReading)
0 commit comments