ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

windows-fs.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #if defined(WIN32)
00024 
00025 // Disable symbol overrides so that we can use system headers.
00026 #define FORBIDDEN_SYMBOL_ALLOW_ALL
00027 
00028 #include "backends/fs/windows/windows-fs.h"
00029 #include "backends/fs/stdiostream.h"
00030 
00031 // F_OK, R_OK and W_OK are not defined under MSVC, so we define them here
00032 // For more information on the modes used by MSVC, check:
00033 // http://msdn2.microsoft.com/en-us/library/1w06ktdy(VS.80).aspx
00034 #ifndef F_OK
00035 #define F_OK 0
00036 #endif
00037 
00038 #ifndef R_OK
00039 #define R_OK 4
00040 #endif
00041 
00042 #ifndef W_OK
00043 #define W_OK 2
00044 #endif
00045 
00046 bool WindowsFilesystemNode::exists() const {
00047     return _access(_path.c_str(), F_OK) == 0;
00048 }
00049 
00050 bool WindowsFilesystemNode::isReadable() const {
00051     return _access(_path.c_str(), R_OK) == 0;
00052 }
00053 
00054 bool WindowsFilesystemNode::isWritable() const {
00055     return _access(_path.c_str(), W_OK) == 0;
00056 }
00057 
00058 void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const char *base, bool hidden, WIN32_FIND_DATA* find_data) {
00059     WindowsFilesystemNode entry;
00060     char *asciiName = toAscii(find_data->cFileName);
00061     bool isDirectory;
00062 
00063     // Skip local directory (.) and parent (..)
00064     if (!strcmp(asciiName, ".") || !strcmp(asciiName, ".."))
00065         return;
00066 
00067     // Skip hidden files if asked
00068     if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) && !hidden)
00069         return;
00070 
00071     isDirectory = (find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? true : false);
00072 
00073     if ((!isDirectory && mode == Common::FSNode::kListDirectoriesOnly) ||
00074         (isDirectory && mode == Common::FSNode::kListFilesOnly))
00075         return;
00076 
00077     entry._isDirectory = isDirectory;
00078     entry._displayName = asciiName;
00079     entry._path = base;
00080     entry._path += asciiName;
00081     if (entry._isDirectory)
00082         entry._path += "\\";
00083     entry._isValid = true;
00084     entry._isPseudoRoot = false;
00085 
00086     list.push_back(new WindowsFilesystemNode(entry));
00087 }
00088 
00089 char* WindowsFilesystemNode::toAscii(TCHAR *str) {
00090 #ifndef UNICODE
00091     return (char *)str;
00092 #else
00093     static char asciiString[MAX_PATH];
00094     WideCharToMultiByte(CP_ACP, 0, str, _tcslen(str) + 1, asciiString, sizeof(asciiString), NULL, NULL);
00095     return asciiString;
00096 #endif
00097 }
00098 
00099 const TCHAR* WindowsFilesystemNode::toUnicode(const char *str) {
00100 #ifndef UNICODE
00101     return (const TCHAR *)str;
00102 #else
00103     static TCHAR unicodeString[MAX_PATH];
00104     MultiByteToWideChar(CP_ACP, 0, str, strlen(str) + 1, unicodeString, sizeof(unicodeString) / sizeof(TCHAR));
00105     return unicodeString;
00106 #endif
00107 }
00108 
00109 WindowsFilesystemNode::WindowsFilesystemNode() {
00110     _isDirectory = true;
00111 #ifndef _WIN32_WCE
00112     // Create a virtual root directory for standard Windows system
00113     _isValid = false;
00114     _path = "";
00115     _isPseudoRoot = true;
00116 #else
00117     _displayName = "Root";
00118     // No need to create a pseudo root directory on Windows CE
00119     _isValid = true;
00120     _path = "\\";
00121     _isPseudoRoot = false;
00122 #endif
00123 }
00124 
00125 WindowsFilesystemNode::WindowsFilesystemNode(const Common::String &p, const bool currentDir) {
00126     if (currentDir) {
00127         char path[MAX_PATH];
00128         GetCurrentDirectory(MAX_PATH, path);
00129         _path = path;
00130     } else {
00131         assert(p.size() > 0);
00132         _path = p;
00133     }
00134 
00135     _displayName = lastPathComponent(_path, '\\');
00136 
00137     // Check whether it is a directory, and whether the file actually exists
00138     DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));
00139 
00140     if (fileAttribs == INVALID_FILE_ATTRIBUTES) {
00141         _isDirectory = false;
00142         _isValid = false;
00143     } else {
00144         _isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
00145         _isValid = true;
00146         // Add a trailing slash, if necessary.
00147         if (_isDirectory && _path.lastChar() != '\\') {
00148             _path += '\\';
00149         }
00150     }
00151     _isPseudoRoot = false;
00152 }
00153 
00154 AbstractFSNode *WindowsFilesystemNode::getChild(const Common::String &n) const {
00155     assert(_isDirectory);
00156 
00157     // Make sure the string contains no slashes
00158     assert(!n.contains('/'));
00159 
00160     Common::String newPath(_path);
00161     if (_path.lastChar() != '\\')
00162         newPath += '\\';
00163     newPath += n;
00164 
00165     return new WindowsFilesystemNode(newPath, false);
00166 }
00167 
00168 bool WindowsFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
00169     assert(_isDirectory);
00170 
00171     if (_isPseudoRoot) {
00172 #ifndef _WIN32_WCE
00173         // Drives enumeration
00174         TCHAR drive_buffer[100];
00175         GetLogicalDriveStrings(sizeof(drive_buffer) / sizeof(TCHAR), drive_buffer);
00176 
00177         for (TCHAR *current_drive = drive_buffer; *current_drive;
00178             current_drive += _tcslen(current_drive) + 1) {
00179                 WindowsFilesystemNode entry;
00180                 char drive_name[2];
00181 
00182                 drive_name[0] = toAscii(current_drive)[0];
00183                 drive_name[1] = '\0';
00184                 entry._displayName = drive_name;
00185                 entry._isDirectory = true;
00186                 entry._isValid = true;
00187                 entry._isPseudoRoot = false;
00188                 entry._path = toAscii(current_drive);
00189                 myList.push_back(new WindowsFilesystemNode(entry));
00190         }
00191 #endif
00192     }
00193     else {
00194         // Files enumeration
00195         WIN32_FIND_DATA desc;
00196         HANDLE handle;
00197         char searchPath[MAX_PATH + 10];
00198 
00199         sprintf(searchPath, "%s*", _path.c_str());
00200 
00201         handle = FindFirstFile(toUnicode(searchPath), &desc);
00202 
00203         if (handle == INVALID_HANDLE_VALUE)
00204             return false;
00205 
00206         addFile(myList, mode, _path.c_str(), hidden, &desc);
00207 
00208         while (FindNextFile(handle, &desc))
00209             addFile(myList, mode, _path.c_str(), hidden, &desc);
00210 
00211         FindClose(handle);
00212     }
00213 
00214     return true;
00215 }
00216 
00217 AbstractFSNode *WindowsFilesystemNode::getParent() const {
00218     assert(_isValid || _isPseudoRoot);
00219 
00220     if (_isPseudoRoot)
00221         return 0;
00222 
00223     WindowsFilesystemNode *p = new WindowsFilesystemNode();
00224     if (_path.size() > 3) {
00225         const char *start = _path.c_str();
00226         const char *end = lastPathComponent(_path, '\\');
00227 
00228         p = new WindowsFilesystemNode();
00229         p->_path = Common::String(start, end - start);
00230         p->_isValid = true;
00231         p->_isDirectory = true;
00232         p->_displayName = lastPathComponent(p->_path, '\\');
00233         p->_isPseudoRoot = false;
00234     }
00235 
00236     return p;
00237 }
00238 
00239 Common::SeekableReadStream *WindowsFilesystemNode::createReadStream() {
00240     return StdioStream::makeFromPath(getPath(), false);
00241 }
00242 
00243 Common::WriteStream *WindowsFilesystemNode::createWriteStream() {
00244     return StdioStream::makeFromPath(getPath(), true);
00245 }
00246 
00247 bool WindowsFilesystemNode::create(bool isDirectoryFlag) {
00248     bool success;
00249 
00250     if (isDirectoryFlag) {
00251         success = CreateDirectory(toUnicode(_path.c_str()), NULL) != 0;
00252     } else {
00253         success = CreateFile(toUnicode(_path.c_str()), GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) != INVALID_HANDLE_VALUE;
00254     }
00255 
00256     if (success) {
00257         //this piece is copied from constructor, it checks that file exists and detects whether it's a directory
00258         DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));
00259         if (fileAttribs != INVALID_FILE_ATTRIBUTES) {
00260             _isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
00261             _isValid = true;
00262             // Add a trailing slash, if necessary.
00263             if (_isDirectory && _path.lastChar() != '\\') {
00264                 _path += '\\';
00265             }
00266 
00267             if (_isDirectory != isDirectoryFlag) warning("failed to create %s: got %s", isDirectoryFlag ? "directory" : "file", _isDirectory ? "directory" : "file");
00268             return _isDirectory == isDirectoryFlag;
00269         }
00270 
00271         warning("WindowsFilesystemNode: Create%s() was a success, but GetFileAttributes() indicates there is no such %s",
00272                 isDirectoryFlag ? "Directory" : "File", isDirectoryFlag ? "directory" : "file");
00273         return false;
00274     }
00275 
00276     return false;
00277 }
00278 
00279 #endif //#ifdef WIN32


Generated on Sat Feb 16 2019 05:01:11 for ResidualVM by doxygen 1.7.1
curved edge   curved edge