// // VMime library (http://www.vmime.org) // Copyright (C) 2002 Vincent Richard // // 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 #include #include #include // for WSAStartup() #include // for winnls.h #include #include #if VMIME_HAVE_MLANG # include #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 (); #endif #if VMIME_HAVE_FILESYSTEM_FEATURES m_fileSysFactory = make_shared (); #endif } windowsHandler::~windowsHandler() { WSACleanup(); } unsigned long windowsHandler::getUnixTime() const { return static_cast (::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 } const vmime::string windowsHandler::getHostName() const { char hostname[1024]; DWORD hostnameLen; // First, try to get a Fully-Qualified Domain Name (FQDN) for (int cnf = ComputerNameDnsHostname ; cnf <= ComputerNameDnsFullyQualified ; ++cnf) { hostnameLen = sizeof(hostname); if (GetComputerNameEx((COMPUTER_NAME_FORMAT) cnf, hostname, &hostnameLen)) { const vmime::string hostnameStr(hostname); if (utility::stringUtils::isValidFQDN(hostnameStr)) { return hostnameStr; } } } // Anything else will be OK, as long as it is a valid hostname for (int cnf = 0 ; cnf < ComputerNameMax ; ++cnf) { hostnameLen = sizeof(hostname); if (GetComputerNameEx((COMPUTER_NAME_FORMAT) cnf, hostname, &hostnameLen)) { const vmime::string hostnameStr(hostname); if (utility::stringUtils::isValidHostname(hostnameStr)) { return hostnameStr; } } } return "localhost.localdomain"; } unsigned int windowsHandler::getProcessId() const { return static_cast (::GetCurrentProcessId()); } unsigned int windowsHandler::getThreadId() const { return static_cast (::GetCurrentThreadId()); } #if VMIME_HAVE_MESSAGING_FEATURES shared_ptr windowsHandler::getSocketFactory() { return m_socketFactory; } #endif #if VMIME_HAVE_FILESYSTEM_FEATURES shared_ptr windowsHandler::getFileSystemFactory() { return m_fileSysFactory; } shared_ptr windowsHandler::getChildProcessFactory() { // TODO: Not implemented return null; } #endif 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 (count), static_cast (buffer)); CryptReleaseContext(cryptProvider, 0); } shared_ptr windowsHandler::createCriticalSection() { return make_shared (); } } // posix } // platforms } // vmime #endif // VMIME_PLATFORM_IS_WINDOWS