diff options
| author | Vincent Richard <[email protected]> | 2013-12-29 10:02:12 +0100 |
|---|---|---|
| committer | Vincent Richard <[email protected]> | 2013-12-29 10:02:12 +0100 |
| commit | 152c6bed75598a6ca5efb7914701157270155833 (patch) | |
| tree | 8faced1d75a45c819630323da256248415992ed0 /src/platforms/windows | |
| parent | Merge branch 'master' of https://github.com/kisli/vmime (diff) | |
| download | vmime-152c6bed75598a6ca5efb7914701157270155833.tar.gz vmime-152c6bed75598a6ca5efb7914701157270155833.zip | |
Merged source and header files in directory structure. Got rid of SConstruct build.
Diffstat (limited to 'src/platforms/windows')
| -rw-r--r-- | src/platforms/windows/windowsCriticalSection.cpp | 67 | ||||
| -rw-r--r-- | src/platforms/windows/windowsFile.cpp | 553 | ||||
| -rw-r--r-- | src/platforms/windows/windowsHandler.cpp | 329 | ||||
| -rw-r--r-- | src/platforms/windows/windowsSocket.cpp | 484 |
4 files changed, 0 insertions, 1433 deletions
diff --git a/src/platforms/windows/windowsCriticalSection.cpp b/src/platforms/windows/windowsCriticalSection.cpp deleted file mode 100644 index d6ef0c45..00000000 --- a/src/platforms/windows/windowsCriticalSection.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> -// -// 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 3 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., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Linking this library statically or dynamically with other modules is making -// a combined work based on this library. Thus, the terms and conditions of -// the GNU General Public License cover the whole combination. -// - -#include "vmime/config.hpp" - - -#if VMIME_PLATFORM_IS_WINDOWS - - -#include "vmime/platforms/windows/windowsCriticalSection.hpp" - - -namespace vmime { -namespace platforms { -namespace windows { - - -windowsCriticalSection::windowsCriticalSection() -{ - InitializeCriticalSectionAndSpinCount(&m_cs, 0x400); -} - - -windowsCriticalSection::~windowsCriticalSection() -{ - DeleteCriticalSection(&m_cs); -} - - -void windowsCriticalSection::lock() -{ - EnterCriticalSection(&m_cs); -} - - -void windowsCriticalSection::unlock() -{ - LeaveCriticalSection(&m_cs); -} - - -} // windows -} // platforms -} // vmime - - -#endif // VMIME_PLATFORM_IS_WINDOWS diff --git a/src/platforms/windows/windowsFile.cpp b/src/platforms/windows/windowsFile.cpp deleted file mode 100644 index 6aa0fea8..00000000 --- a/src/platforms/windows/windowsFile.cpp +++ /dev/null @@ -1,553 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> -// -// 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 3 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., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Linking this library statically or dynamically with other modules is making -// a combined work based on this library. Thus, the terms and conditions of -// the GNU General Public License cover the whole combination. -// - -#include "vmime/config.hpp" - - -#if VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_FILESYSTEM_FEATURES - - -#include "vmime/platforms/windows/windowsFile.hpp" - -#include <windows.h> -#include <string.h> - -#include "vmime/exception.hpp" -#include "vmime/utility/stringUtils.hpp" - - -namespace vmime { -namespace platforms { -namespace windows { - - -shared_ptr <vmime::utility::file> windowsFileSystemFactory::create(const vmime::utility::file::path& path) const -{ - return make_shared <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::size_t offset = 0; - vmime::size_t 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); -} - -bool windowsFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const -{ - return isValidPathComponent(comp, false); -} - -bool windowsFileSystemFactory::isValidPathComponent( - const vmime::utility::file::path::component& comp, - bool firstComponent) const -{ - const string& buffer = comp.getBuffer(); - - // If first component, check if component is a drive - if (firstComponent && (buffer.length() == 2) && (buffer[1] == ':')) - { - char drive = tolower(buffer[0]); - if ((drive >= 'a') && (drive <= 'z')) - return true; - } - - // Check for invalid characters - for (size_t i = 0 ; i < buffer.length() ; ++i) - { - const unsigned char c = buffer[i]; - - switch (c) - { - // Reserved characters - case '<': case '>': case ':': - case '"': case '/': case '\\': - case '|': case '$': case '*': - - return false; - - default: - - if (c <= 31) - return false; - } - } - - string upperBuffer = vmime::utility::stringUtils::toUpper(buffer); - - // Check for reserved names - if (upperBuffer.length() == 3) - { - if (upperBuffer == "CON" || buffer == "PRN" || buffer == "AUX" || buffer == "NUL") - return false; - } - else if (upperBuffer.length() == 4) - { - if ((upperBuffer.substr(0, 3) == "COM") && // COM0 to COM9 - (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) - { - return false; - } - else if ((upperBuffer.substr(0, 3) == "LPT") && // LPT0 to LPT9 - (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) - { - return false; - } - } - return true; -} - - -bool windowsFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const -{ - for (int i = 0 ; i < path.getSize() ; ++i) - { - if (!isValidPathComponent(path[i], (i==0))) - 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, - FILE_SHARE_READ | FILE_SHARE_WRITE, - 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); -} - -bool windowsFile::isFile() const -{ - DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str()); - if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) - return false; - return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == 0; -} - -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; -} - -bool windowsFile::canRead() const -{ - HANDLE hFile = CreateFile( - m_nativePath.c_str(), - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - return false; - CloseHandle(hFile); - return true; -} - -bool windowsFile::canWrite() const -{ - HANDLE hFile = CreateFile( - m_nativePath.c_str(), - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - return false; - CloseHandle(hFile); - return true; -} - -windowsFile::length_type windowsFile::getLength() -{ - HANDLE hFile = CreateFile( - m_nativePath.c_str(), - GENERIC_READ, - FILE_SHARE_READ, - 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; -} - -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; -} - -shared_ptr <vmime::utility::file> windowsFile::getParent() const -{ - if (m_path.isEmpty()) - return NULL; - else - return make_shared <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()); -} - -shared_ptr <vmime::utility::fileWriter> windowsFile::getFileWriter() -{ - return make_shared <windowsFileWriter>(m_path, m_nativePath); -} - -shared_ptr <vmime::utility::fileReader> windowsFile::getFileReader() -{ - return make_shared <windowsFileReader>(m_path, m_nativePath); -} - -shared_ptr <vmime::utility::fileIterator> windowsFile::getFiles() const -{ - return make_shared <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); -} - -bool windowsFileIterator::hasMoreElements() const -{ - return m_moreElements; -} - -shared_ptr <vmime::utility::file> windowsFileIterator::nextElement() -{ - shared_ptr <vmime::utility::file> pFile = make_shared <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) -{ -} - -shared_ptr <vmime::utility::inputStream> windowsFileReader::getInputStream() -{ - HANDLE hFile = CreateFile( - m_nativePath.c_str(), - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - windowsFileSystemFactory::reportError(m_path, GetLastError()); - return make_shared <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); -} - -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); -} - -size_t windowsFileReaderInputStream::read(byte_t* const data, const size_t count) -{ - DWORD dwBytesRead; - if (!ReadFile(m_hFile, (LPVOID)data, (DWORD)count, &dwBytesRead, NULL)) - windowsFileSystemFactory::reportError(m_path, GetLastError()); - return dwBytesRead; -} - -size_t windowsFileReaderInputStream::skip(const size_t count) -{ - DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); - DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)count, NULL, FILE_CURRENT); - return (dwNewPos - dwCurPos); -} - -size_t windowsFileReaderInputStream::getPosition() const -{ - DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); - - if (dwCurPos == INVALID_SET_FILE_POINTER) - windowsFileSystemFactory::reportError(m_path, GetLastError()); - - return static_cast <size_t>(dwCurPos); -} - -void windowsFileReaderInputStream::seek(const size_t pos) -{ - DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)pos, NULL, FILE_BEGIN); - - if (dwNewPos == INVALID_SET_FILE_POINTER) - windowsFileSystemFactory::reportError(m_path, GetLastError()); -} - -windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath) -: m_path(path), m_nativePath(nativePath) -{ -} - -shared_ptr <vmime::utility::outputStream> windowsFileWriter::getOutputStream() -{ - HANDLE hFile = CreateFile( - m_nativePath.c_str(), - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - windowsFileSystemFactory::reportError(m_path, GetLastError()); - return make_shared <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::writeImpl(const byte_t* const data, const size_t count) -{ - DWORD dwBytesWritten; - if (!WriteFile(m_hFile, data, (DWORD)count, &dwBytesWritten, NULL)) - windowsFileSystemFactory::reportError(m_path, GetLastError()); -} - - -void windowsFileWriterOutputStream::flush() -{ - // TODO -} - - -} // windows -} // platforms -} // vmime - - -#endif // VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_FILESYSTEM_FEATURES - diff --git a/src/platforms/windows/windowsHandler.cpp b/src/platforms/windows/windowsHandler.cpp deleted file mode 100644 index 9c96b271..00000000 --- a/src/platforms/windows/windowsHandler.cpp +++ /dev/null @@ -1,329 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> -// -// 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 3 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., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Linking this library statically or dynamically with other modules is making -// a combined work based on this library. Thus, the terms and conditions of -// the GNU General Public License cover the whole combination. -// - -#include "vmime/config.hpp" - - -#if VMIME_PLATFORM_IS_WINDOWS - - -#include "vmime/platforms/windows/windowsHandler.hpp" - -#include "vmime/platforms/windows/windowsCriticalSection.hpp" - -#include "vmime/utility/stringUtils.hpp" - -#include <time.h> -#include <locale.h> -#include <process.h> -#include <winsock2.h> // for WSAStartup() -#include <windows.h> // for winnls.h -#include <ws2tcpip.h> -#include <wincrypt.h> - -#if VMIME_HAVE_MLANG -# include <mlang.h> -#endif - - -namespace vmime { -namespace platforms { -namespace windows { - - -windowsHandler::windowsHandler() -{ - WSAData wsaData; - WSAStartup(MAKEWORD(1, 1), &wsaData); - -#if VMIME_HAVE_MESSAGING_FEATURES - m_socketFactory = make_shared <windowsSocketFactory>(); -#endif -#if VMIME_HAVE_FILESYSTEM_FEATURES - m_fileSysFactory = make_shared <windowsFileSystemFactory>(); -#endif -} - - -windowsHandler::~windowsHandler() -{ - WSACleanup(); -} - - -unsigned long windowsHandler::getUnixTime() const -{ - return static_cast <unsigned long>(::time(NULL)); -} - - -const vmime::datetime windowsHandler::getCurrentLocalTime() const -{ - const time_t t(::time(NULL)); - - // Get the local time -#if VMIME_HAVE_LOCALTIME_S - tm local; - ::localtime_s(&local, &t); -#elif VMIME_HAVE_LOCALTIME_R - tm local; - ::localtime_r(&t, &local); -#else - tm local = *::localtime(&t); // WARNING: this is not thread-safe! -#endif - - // Get the UTC time -#if VMIME_HAVE_GMTIME_S - tm gmt; - ::gmtime_s(&gmt, &t); -#elif VMIME_HAVE_GMTIME_R - tm gmt; - ::gmtime_r(&t, &gmt); -#else - tm gmt = *::gmtime(&t); // WARNING: this is not thread-safe! -#endif - - // "A negative value for tm_isdst causes mktime() to attempt - // to determine whether Daylight Saving Time is in effect - // for the specified time." - local.tm_isdst = -1; - gmt.tm_isdst = -1; - - // Calculate the difference (in seconds) - const int diff = (const int)(::mktime(&local) - ::mktime(&gmt)); - - // Return the date - return vmime::datetime(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, - local.tm_hour, local.tm_min, local.tm_sec, diff / 60); // minutes needed -} - - -const vmime::charset windowsHandler::getLocalCharset() const -{ -#if VMIME_HAVE_MLANG - char szCharset[256]; - - CoInitialize(NULL); - { - IMultiLanguage* pMultiLanguage; - CoCreateInstance( - CLSID_CMultiLanguage, - NULL, - CLSCTX_INPROC_SERVER, - IID_IMultiLanguage, - (void**)&pMultiLanguage); - - UINT codePage = GetACP(); - MIMECPINFO cpInfo; - pMultiLanguage->GetCodePageInfo(codePage, &cpInfo); - - int nLengthW = lstrlenW(cpInfo.wszBodyCharset) + 1; - - WideCharToMultiByte(codePage, 0, cpInfo.wszBodyCharset, nLengthW, szCharset, sizeof(szCharset), NULL, NULL ); - - pMultiLanguage->Release(); - - } - CoUninitialize(); - - return vmime::charset(szCharset); -#else // VMIME_HAVE_MLANG - vmime::string ch = vmime::charsets::ISO8859_1; // default - - switch (GetACP()) - { - case 437: ch = vmime::charsets::CP_437; break; - case 737: ch = vmime::charsets::CP_737; break; - case 775: ch = vmime::charsets::CP_775; break; - case 850: ch = vmime::charsets::CP_850; break; - case 852: ch = vmime::charsets::CP_852; break; - case 853: ch = vmime::charsets::CP_853; break; - case 855: ch = vmime::charsets::CP_855; break; - case 857: ch = vmime::charsets::CP_857; break; - case 858: ch = vmime::charsets::CP_858; break; - case 860: ch = vmime::charsets::CP_860; break; - case 861: ch = vmime::charsets::CP_861; break; - case 862: ch = vmime::charsets::CP_862; break; - case 863: ch = vmime::charsets::CP_863; break; - case 864: ch = vmime::charsets::CP_864; break; - case 865: ch = vmime::charsets::CP_865; break; - case 866: ch = vmime::charsets::CP_866; break; - case 869: ch = vmime::charsets::CP_869; break; - case 874: ch = vmime::charsets::CP_874; break; - - case 1125: ch = vmime::charsets::CP_1125; break; - case 1250: ch = vmime::charsets::CP_1250; break; - case 1251: ch = vmime::charsets::CP_1251; break; - case 1252: ch = vmime::charsets::CP_1252; break; - case 1253: ch = vmime::charsets::CP_1253; break; - case 1254: ch = vmime::charsets::CP_1254; break; - case 1255: ch = vmime::charsets::CP_1255; break; - case 1256: ch = vmime::charsets::CP_1256; break; - case 1257: ch = vmime::charsets::CP_1257; break; - - case 28591: ch = vmime::charsets::ISO8859_1; break; - case 28592: ch = vmime::charsets::ISO8859_2; break; - case 28593: ch = vmime::charsets::ISO8859_3; break; - case 28594: ch = vmime::charsets::ISO8859_4; break; - case 28595: ch = vmime::charsets::ISO8859_5; break; - case 28596: ch = vmime::charsets::ISO8859_6; break; - case 28597: ch = vmime::charsets::ISO8859_7; break; - case 28598: ch = vmime::charsets::ISO8859_8; break; - case 28599: ch = vmime::charsets::ISO8859_9; break; - case 28605: ch = vmime::charsets::ISO8859_15; break; - - case 65000: ch = vmime::charsets::UTF_7; break; - case 65001: ch = vmime::charsets::UTF_8; break; - } - - return (vmime::charset(ch)); -#endif -} - - -static inline bool isFQDN(const vmime::string& str) -{ - if (utility::stringUtils::isStringEqualNoCase(str, "localhost", 9)) - return false; - - const vmime::size_t p = str.find_first_of("."); - return p != vmime::string::npos && p > 0 && p != str.length() - 1; -} - - -const vmime::string windowsHandler::getHostName() const -{ - char hostname[256]; - - // Try with 'gethostname' - ::gethostname(hostname, sizeof(hostname)); - hostname[sizeof(hostname) - 1] = '\0'; - - // If this is a Fully-Qualified Domain Name (FQDN), return immediately - if (isFQDN(hostname)) - return hostname; - - if (::strlen(hostname) == 0) - { -#if VMIME_HAVE_STRCPY_S - ::strcpy_s(hostname, "localhost"); -#else - ::strcpy(hostname, "localhost"); -#endif // VMIME_HAVE_STRCPY_S - } - - // Try to get canonical name for the hostname - struct addrinfo hints; - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; // either IPV4 or IPV6 - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_CANONNAME; - - struct addrinfo* info; - - if (getaddrinfo(hostname, "http", &hints, &info) == 0) - { - for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next) - { - if (p->ai_canonname && isFQDN(p->ai_canonname)) - { - const string ret(p->ai_canonname); - freeaddrinfo(info); - return ret; - } - } - - freeaddrinfo(info); - } - - return hostname; -} - - -unsigned int windowsHandler::getProcessId() const -{ - return (static_cast <unsigned int>(::GetCurrentProcessId())); -} - - -unsigned int windowsHandler::getThreadId() const -{ - return static_cast <unsigned int>(::GetCurrentThreadId()); -} - - -#if VMIME_HAVE_MESSAGING_FEATURES - -shared_ptr <vmime::net::socketFactory> windowsHandler::getSocketFactory() -{ - return m_socketFactory; -} - -#endif - - -#if VMIME_HAVE_FILESYSTEM_FEATURES - -shared_ptr <vmime::utility::fileSystemFactory> windowsHandler::getFileSystemFactory() -{ - return m_fileSysFactory; -} - - -shared_ptr <vmime::utility::childProcessFactory> windowsHandler::getChildProcessFactory() -{ - // TODO: Not implemented - return (NULL); -} - -#endif - - -void windowsHandler::wait() const -{ - ::Sleep(100); -} - - -void windowsHandler::generateRandomBytes(unsigned char* buffer, const unsigned int count) -{ - HCRYPTPROV cryptProvider = 0; - CryptAcquireContext(&cryptProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - CryptGenRandom(cryptProvider, static_cast <unsigned long>(count), static_cast <unsigned char*>(buffer)); - CryptReleaseContext(cryptProvider, 0); -} - - -shared_ptr <utility::sync::criticalSection> windowsHandler::createCriticalSection() -{ - return make_shared <windowsCriticalSection>(); -} - - -} // posix -} // platforms -} // vmime - - -#endif // VMIME_PLATFORM_IS_WINDOWS - diff --git a/src/platforms/windows/windowsSocket.cpp b/src/platforms/windows/windowsSocket.cpp deleted file mode 100644 index 40e69363..00000000 --- a/src/platforms/windows/windowsSocket.cpp +++ /dev/null @@ -1,484 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> -// -// 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 3 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., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Linking this library statically or dynamically with other modules is making -// a combined work based on this library. Thus, the terms and conditions of -// the GNU General Public License cover the whole combination. -// - -#include "vmime/config.hpp" - - -#if VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_MESSAGING_FEATURES - - -#pragma warning(disable: 4267) - -#include "vmime/platforms/windows/windowsSocket.hpp" - -#include "vmime/exception.hpp" - -#include <ws2tcpip.h> - - -namespace vmime { -namespace platforms { -namespace windows { - - -// -// windowsSocket -// - -windowsSocket::windowsSocket(shared_ptr <vmime::net::timeoutHandler> th) - : m_timeoutHandler(th), m_desc(INVALID_SOCKET), m_status(0) -{ - WSAData wsaData; - WSAStartup(MAKEWORD(1, 1), &wsaData); -} - - -windowsSocket::~windowsSocket() -{ - if (m_desc != INVALID_SOCKET) - ::closesocket(m_desc); - - WSACleanup(); -} - - -void windowsSocket::connect(const vmime::string& address, const vmime::port_t port) -{ - // Close current connection, if any - if (m_desc != INVALID_SOCKET) - { - ::closesocket(m_desc); - m_desc = INVALID_SOCKET; - } - - // Resolve address - ::sockaddr_in addr; - - memset(&addr, 0, sizeof(addr)); - - addr.sin_family = AF_INET; - addr.sin_port = htons(static_cast <unsigned short>(port)); - addr.sin_addr.s_addr = ::inet_addr(address.c_str()); - - if (addr.sin_addr.s_addr == static_cast <int>(-1)) - { - ::hostent* hostInfo = ::gethostbyname(address.c_str()); - - if (hostInfo == NULL) - { - // Error: cannot resolve address - throw vmime::exceptions::connection_error("Cannot resolve address."); - } - - memcpy(reinterpret_cast <char*>(&addr.sin_addr), hostInfo->h_addr, hostInfo->h_length); - } - - m_serverAddress = address; - - // Get a new socket - m_desc = ::socket(AF_INET, SOCK_STREAM, 0); - - if (m_desc == INVALID_SOCKET) - { - try - { - int err = WSAGetLastError(); - throwSocketError(err); - } - catch (exceptions::socket_exception& e) - { - throw vmime::exceptions::connection_error - ("Error while creating socket.", e); - } - } - - // Start connection - if (::connect(m_desc, reinterpret_cast <sockaddr*>(&addr), sizeof(addr)) == -1) - { - try - { - int err = WSAGetLastError(); - throwSocketError(err); - } - catch (exceptions::socket_exception& e) - { - ::closesocket(m_desc); - m_desc = INVALID_SOCKET; - - // Error - throw vmime::exceptions::connection_error - ("Error while connecting socket.", e); - } - } - - // Set socket to non-blocking - unsigned long non_blocking = 1; - ::ioctlsocket(m_desc, FIONBIO, &non_blocking); -} - - -bool windowsSocket::isConnected() const -{ - if (m_desc == INVALID_SOCKET) - return false; - - char buff; - - return ::recv(m_desc, &buff, 1, MSG_PEEK) != 0; -} - - -void windowsSocket::disconnect() -{ - if (m_desc != INVALID_SOCKET) - { - ::shutdown(m_desc, SD_BOTH); - ::closesocket(m_desc); - - m_desc = INVALID_SOCKET; - } -} - - -static bool isNumericAddress(const char* address) -{ - struct addrinfo hint, *info = NULL; - memset(&hint, 0, sizeof(hint)); - - hint.ai_family = AF_UNSPEC; - hint.ai_flags = AI_NUMERICHOST; - - if (getaddrinfo(address, 0, &hint, &info) == 0) - { - freeaddrinfo(info); - return true; - } - else - { - return false; - } -} - - -const string windowsSocket::getPeerAddress() const -{ - // Get address of connected peer - sockaddr peer; - socklen_t peerLen = sizeof(peer); - - getpeername(m_desc, reinterpret_cast <sockaddr*>(&peer), &peerLen); - - // Convert to numerical presentation format - char host[NI_MAXHOST + 1]; - char service[NI_MAXSERV + 1]; - - if (getnameinfo(reinterpret_cast <sockaddr *>(&peer), peerLen, - host, sizeof(host), service, sizeof(service), - /* flags */ NI_NUMERICHOST) == 0) - { - return string(host); - } - - return ""; // should not happen -} - - -const string windowsSocket::getPeerName() const -{ - // Get address of connected peer - sockaddr peer; - socklen_t peerLen = sizeof(peer); - - getpeername(m_desc, reinterpret_cast <sockaddr*>(&peer), &peerLen); - - // If server address as specified when connecting is a numeric - // address, try to get a host name for it - if (isNumericAddress(m_serverAddress.c_str())) - { - char host[NI_MAXHOST + 1]; - char service[NI_MAXSERV + 1]; - - if (getnameinfo(reinterpret_cast <sockaddr *>(&peer), peerLen, - host, sizeof(host), service, sizeof(service), - /* flags */ NI_NAMEREQD) == 0) - { - return string(host); - } - } - - return m_serverAddress; -} - - -size_t windowsSocket::getBlockSize() const -{ - return 16384; // 16 KB -} - - -void windowsSocket::receive(vmime::string& buffer) -{ - const size_t size = receiveRaw(m_buffer, sizeof(m_buffer)); - buffer = vmime::string(m_buffer, size); -} - - -size_t windowsSocket::receiveRaw(char* buffer, const size_t count) -{ - m_status &= ~STATUS_WOULDBLOCK; - - // Check whether data is available - bool timedout; - waitForData(READ, timedout); - - if (timedout) - { - // No data available at this time - // Check if we are timed out - if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { - // Server did not react within timeout delay - throwSocketError(WSAETIMEDOUT); - } - else - { - // Reset timeout - m_timeoutHandler->resetTimeOut(); - } - } - - // Continue waiting for data - return 0; - } - - // Read available data - int ret = ::recv(m_desc, buffer, count, 0); - - if (ret == SOCKET_ERROR) - { - int err = WSAGetLastError(); - - if (err != WSAEWOULDBLOCK) - throwSocketError(err); - - m_status |= STATUS_WOULDBLOCK; - - // Error or no data - return (0); - } - else if (ret == 0) - { - // Host shutdown - throwSocketError(WSAENOTCONN); - } - else - { - // Data received, reset timeout - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - - return ret; - } -} - - -void windowsSocket::send(const vmime::string& buffer) -{ - sendRaw(reinterpret_cast <const byte_t*>(buffer.data()), buffer.length()); -} - - -void windowsSocket::send(const char* str) -{ - sendRaw(reinterpret_cast <const byte_t*>(str), strlen(str)); -} - - -void windowsSocket::sendRaw(const char* buffer, const size_t count) -{ - m_status &= ~STATUS_WOULDBLOCK; - - size_t size = count; - - while (size > 0) - { - const int ret = ::send(m_desc, buffer, size, 0); - - if (ret == SOCKET_ERROR) - { - int err = WSAGetLastError(); - - if (err != WSAEWOULDBLOCK) - throwSocketError(err); - - bool timedout; - waitForData(WRITE, timedout); - } - else - { - buffer += ret; - size -= ret; - } - } - - // Reset timeout - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); -} - - -size_t windowsSocket::sendRawNonBlocking(const char* buffer, const size_t count) -{ - m_status &= ~STATUS_WOULDBLOCK; - - const int ret = ::send(m_desc, buffer, count, 0); - - if (ret == SOCKET_ERROR) - { - int err = WSAGetLastError(); - - if (err == WSAEWOULDBLOCK) - { - // Check if we are timed out - if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { - // Could not send data within timeout delay - throwSocketError(err); - } - else - { - // Reset timeout - m_timeoutHandler->resetTimeOut(); - } - } - - m_status |= STATUS_WOULDBLOCK; - - // No data can be written at this time - return 0; - } - else - { - throwSocketError(err); - } - } - - // Reset timeout - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - - return ret; -} - - -unsigned int windowsSocket::getStatus() const -{ - return m_status; -} - - -void windowsSocket::throwSocketError(const int err) -{ - std::ostringstream oss; - string msg; - - LPTSTR str; - - if (::FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, err, 0, (LPTSTR) &str, 0, NULL) == 0) - { - // Failed getting message - oss << "Unknown socket error (code " << err << ")"; - } - else - { - oss << str; - ::LocalFree(str); - } - - msg = oss.str(); - - throw exceptions::socket_exception(msg); -} - - -void windowsSocket::waitForData(const WaitOpType t, bool& timedOut) -{ - // Check whether data is available - fd_set fds; - FD_ZERO(&fds); - FD_SET(m_desc, &fds); - - struct timeval tv; - tv.tv_sec = 1; - tv.tv_usec = 0; - - int ret; - - if (t & READ) - ret = ::select(m_desc + 1, &fds, NULL, NULL, &tv); - else if (t & WRITE) - ret = ::select(m_desc + 1, NULL, &fds, NULL, &tv); - else - ret = ::select(m_desc + 1, &fds, &fds, NULL, &tv); - - timedOut = (ret == 0); - - if (ret == SOCKET_ERROR) - { - int err = WSAGetLastError(); - throwSocketError(err); - } -} - - - -// -// posixSocketFactory -// - -shared_ptr <vmime::net::socket> windowsSocketFactory::create() -{ - shared_ptr <vmime::net::timeoutHandler> th = NULL; - return make_shared <windowsSocket>(th); -} - -shared_ptr <vmime::net::socket> windowsSocketFactory::create(shared_ptr <vmime::net::timeoutHandler> th) -{ - return make_shared <windowsSocket>(th); -} - -} // posix -} // platforms -} // vmime - - -#endif // VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_MESSAGING_FEATURES - |
