File_WIN32.cpp
Go to the documentation of this file.
00001 //
00002 // File_WIN32.cpp
00003 //
00004 // $Id: //poco/1.3/Foundation/src/File_WIN32.cpp#9 $
00005 //
00006 // Library: Foundation
00007 // Package: Filesystem
00008 // Module:  File
00009 //
00010 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
00011 // and Contributors.
00012 //
00013 // Permission is hereby granted, free of charge, to any person or organization
00014 // obtaining a copy of the software and accompanying documentation covered by
00015 // this license (the "Software") to use, reproduce, display, distribute,
00016 // execute, and transmit the Software, and to prepare derivative works of the
00017 // Software, and to permit third-parties to whom the Software is furnished to
00018 // do so, all subject to the following:
00019 // 
00020 // The copyright notices in the Software and this entire statement, including
00021 // the above license grant, this restriction and the following disclaimer,
00022 // must be included in all copies of the Software, in whole or in part, and
00023 // all derivative works of the Software, unless such copies or derivative
00024 // works are solely in the form of machine-executable object code generated by
00025 // a source language processor.
00026 // 
00027 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00028 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00029 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
00030 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
00031 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
00032 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00033 // DEALINGS IN THE SOFTWARE.
00034 //
00035 
00036 
00037 #include "Poco/File_WIN32.h"
00038 #include "Poco/Exception.h"
00039 #include "Poco/String.h"
00040 #include "Poco/UnWindows.h"
00041 
00042 
00043 namespace Poco {
00044 
00045 
00046 class FileHandle
00047 {
00048 public:
00049         FileHandle(const std::string& path, DWORD access, DWORD share, DWORD disp)
00050         {
00051                 _h = CreateFileA(path.c_str(), access, share, 0, disp, 0, 0);
00052                 if (!_h) FileImpl::handleLastErrorImpl(path);
00053         }
00054         
00055         ~FileHandle()
00056         {
00057                 if (_h) CloseHandle(_h);
00058         }
00059         
00060         HANDLE get() const
00061         {
00062                 return _h;
00063         }
00064         
00065 private:
00066         HANDLE _h;
00067 };
00068 
00069 
00070 FileImpl::FileImpl()
00071 {
00072 }
00073 
00074 
00075 FileImpl::FileImpl(const std::string& path): _path(path)
00076 {
00077         std::string::size_type n = _path.size();
00078         if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
00079         {
00080                 _path.resize(n - 1);
00081         }
00082 }
00083 
00084 
00085 FileImpl::~FileImpl()
00086 {
00087 }
00088 
00089 
00090 void FileImpl::swapImpl(FileImpl& file)
00091 {
00092         std::swap(_path, file._path);
00093 }
00094 
00095 
00096 void FileImpl::setPathImpl(const std::string& path)
00097 {
00098         _path = path;
00099         std::string::size_type n = _path.size();
00100         if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
00101         {
00102                 _path.resize(n - 1);
00103         }
00104 }
00105 
00106 
00107 bool FileImpl::existsImpl() const
00108 {
00109         poco_assert (!_path.empty());
00110 
00111         DWORD attr = GetFileAttributes(_path.c_str());
00112         if (attr == 0xFFFFFFFF)
00113         {
00114                 switch (GetLastError())
00115                 {
00116                 case ERROR_FILE_NOT_FOUND:
00117                 case ERROR_PATH_NOT_FOUND:
00118                 case ERROR_NOT_READY:
00119                 case ERROR_INVALID_DRIVE:
00120                         return false;
00121                 default:
00122                         handleLastErrorImpl(_path);
00123                 }
00124         }
00125         return true;
00126 }
00127 
00128 
00129 bool FileImpl::canReadImpl() const
00130 {
00131         poco_assert (!_path.empty());
00132         
00133         DWORD attr = GetFileAttributes(_path.c_str());
00134         if (attr == 0xFFFFFFFF)
00135         {
00136                 switch (GetLastError())
00137                 {
00138                 case ERROR_ACCESS_DENIED:
00139                         return false;
00140                 default:
00141                         handleLastErrorImpl(_path);
00142                 }
00143         }
00144         return true;
00145 }
00146 
00147 
00148 bool FileImpl::canWriteImpl() const
00149 {
00150         poco_assert (!_path.empty());
00151         
00152         DWORD attr = GetFileAttributes(_path.c_str());
00153         if (attr == 0xFFFFFFFF)
00154                 handleLastErrorImpl(_path);
00155         return (attr & FILE_ATTRIBUTE_READONLY) == 0;
00156 }
00157 
00158 
00159 bool FileImpl::canExecuteImpl() const
00160 {
00161         Path p(_path);
00162         return icompare(p.getExtension(), "exe") == 0;
00163 }
00164 
00165 
00166 bool FileImpl::isFileImpl() const
00167 {
00168         return !isDirectoryImpl() && !isDeviceImpl();
00169 }
00170 
00171 
00172 bool FileImpl::isDirectoryImpl() const
00173 {
00174         poco_assert (!_path.empty());
00175 
00176         DWORD attr = GetFileAttributes(_path.c_str());
00177         if (attr == 0xFFFFFFFF)
00178                 handleLastErrorImpl(_path);
00179         return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
00180 }
00181 
00182 
00183 bool FileImpl::isLinkImpl() const
00184 {
00185         return false;
00186 }
00187 
00188 
00189 bool FileImpl::isDeviceImpl() const
00190 {
00191         poco_assert (!_path.empty());
00192 
00193         FileHandle fh(_path, GENERIC_READ, 0, OPEN_EXISTING);
00194         DWORD type = GetFileType(fh.get());
00195         if (type == FILE_TYPE_CHAR)
00196                 return true;
00197         else if (type == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR)
00198                 handleLastErrorImpl(_path);
00199         return false;
00200 }
00201 
00202 
00203 bool FileImpl::isHiddenImpl() const
00204 {
00205         poco_assert (!_path.empty());
00206 
00207         DWORD attr = GetFileAttributes(_path.c_str());
00208         if (attr == 0xFFFFFFFF)
00209                 handleLastErrorImpl(_path);
00210         return (attr & FILE_ATTRIBUTE_HIDDEN) != 0;
00211 }
00212 
00213 
00214 Timestamp FileImpl::createdImpl() const
00215 {
00216         poco_assert (!_path.empty());
00217 
00218         WIN32_FILE_ATTRIBUTE_DATA fad;
00219         if (GetFileAttributesEx(_path.c_str(), GetFileExInfoStandard, &fad) == 0) 
00220                 handleLastErrorImpl(_path);
00221         return Timestamp::fromFileTimeNP(fad.ftCreationTime.dwLowDateTime, fad.ftCreationTime.dwHighDateTime);
00222 }
00223 
00224 
00225 Timestamp FileImpl::getLastModifiedImpl() const
00226 {
00227         poco_assert (!_path.empty());
00228 
00229         WIN32_FILE_ATTRIBUTE_DATA fad;
00230         if (GetFileAttributesEx(_path.c_str(), GetFileExInfoStandard, &fad) == 0) 
00231                 handleLastErrorImpl(_path);
00232         return Timestamp::fromFileTimeNP(fad.ftLastWriteTime.dwLowDateTime, fad.ftLastWriteTime.dwHighDateTime);
00233 }
00234 
00235 
00236 void FileImpl::setLastModifiedImpl(const Timestamp& ts)
00237 {
00238         poco_assert (!_path.empty());
00239 
00240         UInt32 low;
00241         UInt32 high;
00242         ts.toFileTimeNP(low, high);
00243         FILETIME ft;
00244         ft.dwLowDateTime  = low;
00245         ft.dwHighDateTime = high;
00246         FileHandle fh(_path, FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
00247         if (SetFileTime(fh.get(), 0, &ft, &ft) == 0)
00248                 handleLastErrorImpl(_path);
00249 }
00250 
00251 
00252 FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
00253 {
00254         poco_assert (!_path.empty());
00255 
00256         WIN32_FILE_ATTRIBUTE_DATA fad;
00257         if (GetFileAttributesEx(_path.c_str(), GetFileExInfoStandard, &fad) == 0) 
00258                 handleLastErrorImpl(_path);
00259         LARGE_INTEGER li;
00260         li.LowPart  = fad.nFileSizeLow;
00261         li.HighPart = fad.nFileSizeHigh;
00262         return li.QuadPart;
00263 }
00264 
00265 
00266 void FileImpl::setSizeImpl(FileSizeImpl size)
00267 {
00268         poco_assert (!_path.empty());
00269 
00270         FileHandle fh(_path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
00271         LARGE_INTEGER li;
00272         li.QuadPart = size;
00273         if (SetFilePointer(fh.get(), li.LowPart, &li.HighPart, FILE_BEGIN) == -1)
00274                 handleLastErrorImpl(_path);
00275         if (SetEndOfFile(fh.get()) == 0) 
00276                 handleLastErrorImpl(_path);
00277 }
00278 
00279 
00280 void FileImpl::setWriteableImpl(bool flag)
00281 {
00282         poco_assert (!_path.empty());
00283 
00284         DWORD attr = GetFileAttributes(_path.c_str());
00285         if (attr == -1)
00286                 handleLastErrorImpl(_path);
00287         if (flag)
00288                 attr &= ~FILE_ATTRIBUTE_READONLY;
00289         else
00290                 attr |= FILE_ATTRIBUTE_READONLY;
00291         if (SetFileAttributes(_path.c_str(), attr) == 0)
00292                 handleLastErrorImpl(_path);
00293 }
00294 
00295 
00296 void FileImpl::setExecutableImpl(bool flag)
00297 {
00298         // not supported
00299 }
00300 
00301 
00302 void FileImpl::copyToImpl(const std::string& path) const
00303 {
00304         poco_assert (!_path.empty());
00305 
00306         if (CopyFileA(_path.c_str(), path.c_str(), FALSE) != 0) 
00307         {
00308                 FileImpl copy(path);
00309                 copy.setWriteableImpl(true);
00310         }
00311         else handleLastErrorImpl(_path);
00312 }
00313 
00314 
00315 void FileImpl::renameToImpl(const std::string& path)
00316 {
00317         poco_assert (!_path.empty());
00318 
00319         if (MoveFileA(_path.c_str(), path.c_str()) == 0) 
00320                 handleLastErrorImpl(_path);
00321 }
00322 
00323 
00324 void FileImpl::removeImpl()
00325 {
00326         poco_assert (!_path.empty());
00327 
00328         if (isDirectoryImpl())
00329         {
00330                 if (RemoveDirectoryA(_path.c_str()) == 0) 
00331                         handleLastErrorImpl(_path);
00332         }
00333         else
00334         {
00335                 if (DeleteFileA(_path.c_str()) == 0)
00336                         handleLastErrorImpl(_path);
00337         }
00338 }
00339 
00340 
00341 bool FileImpl::createFileImpl()
00342 {
00343         poco_assert (!_path.empty());
00344 
00345         HANDLE hFile = CreateFileA(_path.c_str(), GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0);
00346         if (hFile != INVALID_HANDLE_VALUE)
00347         {
00348                 CloseHandle(hFile);
00349                 return true;
00350         }
00351         else if (GetLastError() == ERROR_FILE_EXISTS)
00352                 return false;
00353         else
00354                 handleLastErrorImpl(_path);
00355         return false;
00356 }
00357 
00358 
00359 bool FileImpl::createDirectoryImpl()
00360 {
00361         poco_assert (!_path.empty());
00362         
00363         if (existsImpl() && isDirectoryImpl())
00364                 return false;
00365         if (CreateDirectoryA(_path.c_str(), 0) == 0)
00366                 handleLastErrorImpl(_path);
00367         return true;
00368 }
00369 
00370 
00371 void FileImpl::handleLastErrorImpl(const std::string& path)
00372 {
00373         switch (GetLastError())
00374         {
00375         case ERROR_FILE_NOT_FOUND:
00376                 throw FileNotFoundException(path);
00377         case ERROR_PATH_NOT_FOUND:
00378         case ERROR_BAD_NETPATH:
00379         case ERROR_CANT_RESOLVE_FILENAME:
00380         case ERROR_INVALID_DRIVE:
00381                 throw PathNotFoundException(path);
00382         case ERROR_ACCESS_DENIED:
00383                 throw FileAccessDeniedException(path);
00384         case ERROR_ALREADY_EXISTS:
00385         case ERROR_FILE_EXISTS:
00386                 throw FileExistsException(path);
00387         case ERROR_INVALID_NAME:
00388         case ERROR_DIRECTORY:
00389         case ERROR_FILENAME_EXCED_RANGE:
00390         case ERROR_BAD_PATHNAME:
00391                 throw PathSyntaxException(path);
00392         case ERROR_FILE_READ_ONLY:
00393                 throw FileReadOnlyException(path);
00394         case ERROR_CANNOT_MAKE:
00395                 throw CreateFileException(path);
00396         case ERROR_DIR_NOT_EMPTY:
00397                 throw FileException("directory not empty", path);
00398         case ERROR_WRITE_FAULT:
00399                 throw WriteFileException(path);
00400         case ERROR_READ_FAULT:
00401                 throw ReadFileException(path);
00402         case ERROR_SHARING_VIOLATION:
00403                 throw FileException("sharing violation", path);
00404         case ERROR_LOCK_VIOLATION:
00405                 throw FileException("lock violation", path);
00406         case ERROR_HANDLE_EOF:
00407                 throw ReadFileException("EOF reached", path);
00408         case ERROR_HANDLE_DISK_FULL:
00409         case ERROR_DISK_FULL:
00410                 throw WriteFileException("disk is full", path);
00411         case ERROR_NEGATIVE_SEEK:
00412                 throw FileException("negative seek", path);
00413         default:
00414                 throw FileException(path);
00415         }
00416 }
00417 
00418 
00419 } // namespace Poco


pluginlib
Author(s): Tully Foote and Eitan Marder-Eppstein
autogenerated on Sat Dec 28 2013 17:20:19