461 lines
11 KiB
C++
461 lines
11 KiB
C++
//
|
|
// VMime library (http://vmime.sourceforge.net)
|
|
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as
|
|
// published by the Free Software Foundation; either version 2 of
|
|
// the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
//
|
|
|
|
#include "vmime/platforms/windows/windowsFile.hpp"
|
|
|
|
#include <windows.h>
|
|
#include <string.h>
|
|
|
|
#include "vmime/exception.hpp"
|
|
|
|
|
|
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
|
|
|
|
|
namespace vmime {
|
|
namespace platforms {
|
|
namespace windows {
|
|
|
|
|
|
vmime::utility::file* windowsFileSystemFactory::create(const vmime::utility::file::path& path) const
|
|
{
|
|
return new windowsFile(path);
|
|
}
|
|
|
|
|
|
const vmime::utility::file::path windowsFileSystemFactory::stringToPath(const vmime::string& str) const
|
|
{
|
|
return (stringToPathImpl(str));
|
|
}
|
|
|
|
|
|
const vmime::string windowsFileSystemFactory::pathToString(const vmime::utility::file::path& path) const
|
|
{
|
|
return (pathToStringImpl(path));
|
|
}
|
|
|
|
|
|
const vmime::utility::file::path windowsFileSystemFactory::stringToPathImpl(const vmime::string& str)
|
|
{
|
|
vmime::string::size_type offset = 0;
|
|
vmime::string::size_type prev = 0;
|
|
|
|
vmime::utility::file::path path;
|
|
|
|
while ((offset = str.find_first_of("\\", offset)) != vmime::string::npos)
|
|
{
|
|
if (offset != prev)
|
|
path.appendComponent(vmime::string(str.begin() + prev, str.begin() + offset));
|
|
|
|
prev = offset + 1;
|
|
offset++;
|
|
}
|
|
|
|
if (prev < str.length())
|
|
path.appendComponent(vmime::string(str.begin() + prev, str.end()));
|
|
|
|
return (path);
|
|
}
|
|
|
|
|
|
const vmime::string windowsFileSystemFactory::pathToStringImpl(const vmime::utility::file::path& path)
|
|
{
|
|
vmime::string native = "";
|
|
|
|
for (int i = 0 ; i < path.getSize() ; ++i)
|
|
{
|
|
if (i > 0)
|
|
native += "\\";
|
|
|
|
native += path[i].getBuffer();
|
|
}
|
|
|
|
return (native);
|
|
}
|
|
|
|
|
|
const bool windowsFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const
|
|
{
|
|
return (comp.getBuffer().find_first_of("\\*") == vmime::string::npos);
|
|
}
|
|
|
|
|
|
const bool windowsFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const
|
|
{
|
|
for (int i = 0 ; i < path.getSize() ; ++i)
|
|
{
|
|
if (!isValidPathComponent(path[i]))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void windowsFileSystemFactory::reportError(const vmime::utility::path& path, const int err)
|
|
{
|
|
vmime::string desc;
|
|
|
|
LPVOID lpMsgBuf;
|
|
if (FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
err,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPTSTR) &lpMsgBuf,
|
|
0,
|
|
NULL ))
|
|
{
|
|
desc = (char*)lpMsgBuf;
|
|
LocalFree( lpMsgBuf );
|
|
}
|
|
|
|
throw vmime::exceptions::filesystem_exception(desc, path);
|
|
}
|
|
|
|
windowsFile::windowsFile(const vmime::utility::file::path& path)
|
|
: m_path(path), m_nativePath(windowsFileSystemFactory::pathToStringImpl(path))
|
|
{
|
|
}
|
|
|
|
void windowsFile::createFile()
|
|
{
|
|
HANDLE hFile = CreateFile(
|
|
m_nativePath.c_str(),
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
|
|
CloseHandle(hFile);
|
|
}
|
|
|
|
void windowsFile::createDirectory(const bool createAll)
|
|
{
|
|
createDirectoryImpl(m_path, m_path, createAll);
|
|
}
|
|
|
|
const bool windowsFile::isFile() const
|
|
{
|
|
DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str());
|
|
if (dwFileAttribute == INVALID_FILE_ATTRIBUTES)
|
|
return false;
|
|
return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
|
}
|
|
|
|
const bool windowsFile::isDirectory() const
|
|
{
|
|
DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str());
|
|
if (dwFileAttribute == INVALID_FILE_ATTRIBUTES)
|
|
return false;
|
|
return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
|
|
}
|
|
|
|
const bool windowsFile::canRead() const
|
|
{
|
|
HANDLE hFile = CreateFile(
|
|
m_nativePath.c_str(),
|
|
GENERIC_READ,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
return false;
|
|
CloseHandle(hFile);
|
|
return true;
|
|
}
|
|
|
|
const bool windowsFile::canWrite() const
|
|
{
|
|
HANDLE hFile = CreateFile(
|
|
m_nativePath.c_str(),
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
return false;
|
|
CloseHandle(hFile);
|
|
return true;
|
|
}
|
|
|
|
const windowsFile::length_type windowsFile::getLength()
|
|
{
|
|
HANDLE hFile = CreateFile(
|
|
m_nativePath.c_str(),
|
|
GENERIC_READ,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
|
|
DWORD dwSize = GetFileSize(hFile, NULL);
|
|
CloseHandle(hFile);
|
|
|
|
return dwSize;
|
|
}
|
|
|
|
const vmime::utility::path& windowsFile::getFullPath() const
|
|
{
|
|
return m_path;
|
|
}
|
|
|
|
const bool windowsFile::exists() const
|
|
{
|
|
WIN32_FIND_DATA findData;
|
|
HANDLE hFind = FindFirstFile(m_nativePath.c_str(), &findData);
|
|
if (hFind != INVALID_HANDLE_VALUE)
|
|
{
|
|
FindClose(hFind);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const vmime::utility::file* windowsFile::getParent() const
|
|
{
|
|
if (m_path.isEmpty())
|
|
return NULL;
|
|
else
|
|
return new windowsFile(m_path.getParent());
|
|
}
|
|
|
|
void windowsFile::rename(const path& newName)
|
|
{
|
|
const vmime::string newNativeName = windowsFileSystemFactory::pathToStringImpl(newName);
|
|
if (MoveFile(m_nativePath.c_str(), newNativeName.c_str()))
|
|
{
|
|
m_path = newName;
|
|
m_nativePath = newNativeName;
|
|
}
|
|
else
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
}
|
|
|
|
void windowsFile::remove()
|
|
{
|
|
if (!DeleteFile(m_nativePath.c_str()))
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
}
|
|
|
|
vmime::utility::fileWriter* windowsFile::getFileWriter()
|
|
{
|
|
return new windowsFileWriter(m_path, m_nativePath);
|
|
}
|
|
|
|
vmime::utility::fileReader* windowsFile::getFileReader()
|
|
{
|
|
return new windowsFileReader(m_path, m_nativePath);
|
|
}
|
|
|
|
vmime::utility::fileIterator* windowsFile::getFiles() const
|
|
{
|
|
return new windowsFileIterator(m_path, m_nativePath);
|
|
}
|
|
|
|
void windowsFile::createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive)
|
|
{
|
|
const vmime::string nativePath = windowsFileSystemFactory::pathToStringImpl(path);
|
|
|
|
windowsFile tmp(fullPath);
|
|
if (tmp.isDirectory())
|
|
return;
|
|
|
|
if (!path.isEmpty() && recursive)
|
|
createDirectoryImpl(fullPath, path.getParent(), true);
|
|
|
|
if (!CreateDirectory(nativePath.c_str(), NULL))
|
|
windowsFileSystemFactory::reportError(fullPath, GetLastError());
|
|
}
|
|
|
|
windowsFileIterator::windowsFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath)
|
|
: m_path(path), m_nativePath(nativePath), m_moreElements(false), m_hFind(INVALID_HANDLE_VALUE)
|
|
{
|
|
findFirst();
|
|
}
|
|
|
|
windowsFileIterator::~windowsFileIterator()
|
|
{
|
|
if (m_hFind != INVALID_HANDLE_VALUE)
|
|
FindClose(m_hFind);
|
|
}
|
|
|
|
const bool windowsFileIterator::hasMoreElements() const
|
|
{
|
|
return m_moreElements;
|
|
}
|
|
|
|
vmime::utility::file* windowsFileIterator::nextElement()
|
|
{
|
|
vmime::utility::file* pFile = new windowsFile(m_path / vmime::utility::file::path::component(m_findData.cFileName));
|
|
|
|
findNext();
|
|
|
|
return pFile;
|
|
}
|
|
|
|
void windowsFileIterator::findFirst()
|
|
{
|
|
m_hFind = FindFirstFile(m_nativePath.c_str(), &m_findData);
|
|
if (m_hFind == INVALID_HANDLE_VALUE)
|
|
{
|
|
m_moreElements = false;
|
|
return;
|
|
}
|
|
|
|
m_moreElements = true;
|
|
if (isCurrentOrParentDir())
|
|
findNext();
|
|
}
|
|
|
|
void windowsFileIterator::findNext()
|
|
{
|
|
do
|
|
{
|
|
if (!FindNextFile(m_hFind, &m_findData))
|
|
{
|
|
m_moreElements = false;
|
|
return;
|
|
}
|
|
}
|
|
while (isCurrentOrParentDir());
|
|
}
|
|
|
|
bool windowsFileIterator::isCurrentOrParentDir() const
|
|
{
|
|
vmime::string s(m_findData.cFileName);
|
|
if ((s == ".") || (s == ".."))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
windowsFileReader::windowsFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath)
|
|
: m_path(path), m_nativePath(nativePath)
|
|
{
|
|
}
|
|
|
|
vmime::utility::inputStream* windowsFileReader::getInputStream()
|
|
{
|
|
HANDLE hFile = CreateFile(
|
|
m_nativePath.c_str(),
|
|
GENERIC_READ,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
return new windowsFileReaderInputStream(m_path, hFile);
|
|
}
|
|
|
|
windowsFileReaderInputStream::windowsFileReaderInputStream(const vmime::utility::file::path& path, HANDLE hFile)
|
|
: m_path(path), m_hFile(hFile)
|
|
{
|
|
}
|
|
|
|
windowsFileReaderInputStream::~windowsFileReaderInputStream()
|
|
{
|
|
CloseHandle(m_hFile);
|
|
}
|
|
|
|
const bool windowsFileReaderInputStream::eof() const
|
|
{
|
|
DWORD dwSize = GetFileSize(m_hFile, NULL);
|
|
DWORD dwPosition = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT);
|
|
return (dwSize == dwPosition);
|
|
}
|
|
|
|
void windowsFileReaderInputStream::reset()
|
|
{
|
|
SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN);
|
|
}
|
|
|
|
const vmime::utility::stream::size_type windowsFileReaderInputStream::read(value_type* const data, const size_type count)
|
|
{
|
|
DWORD dwBytesRead;
|
|
if (!ReadFile(m_hFile, (LPVOID)data, (DWORD)count, &dwBytesRead, NULL))
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
return dwBytesRead;
|
|
}
|
|
|
|
const vmime::utility::stream::size_type windowsFileReaderInputStream::skip(const size_type count)
|
|
{
|
|
DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT);
|
|
DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)count, NULL, FILE_CURRENT);
|
|
return (dwNewPos - dwCurPos);
|
|
}
|
|
|
|
windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath)
|
|
: m_path(path), m_nativePath(nativePath)
|
|
{
|
|
}
|
|
|
|
vmime::utility::outputStream* windowsFileWriter::getOutputStream()
|
|
{
|
|
HANDLE hFile = CreateFile(
|
|
m_nativePath.c_str(),
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
return new windowsFileWriterOutputStream(m_path, hFile);
|
|
}
|
|
|
|
windowsFileWriterOutputStream::windowsFileWriterOutputStream(const vmime::utility::file::path& path, HANDLE hFile)
|
|
: m_path(path), m_hFile(hFile)
|
|
{
|
|
}
|
|
|
|
windowsFileWriterOutputStream::~windowsFileWriterOutputStream()
|
|
{
|
|
CloseHandle(m_hFile);
|
|
}
|
|
|
|
void windowsFileWriterOutputStream::write(const value_type* const data, const size_type count)
|
|
{
|
|
DWORD dwBytesWritten;
|
|
if (!WriteFile(m_hFile, data, (DWORD)count, &dwBytesWritten, NULL))
|
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
}
|
|
|
|
} // windows
|
|
} // platforms
|
|
} // vmime
|
|
|
|
|
|
#endif // VMIME_HAVE_FILESYSTEM_FEATURES
|