2005-03-27 18:26:25 +00:00
|
|
|
//
|
2013-01-10 16:30:31 +00:00
|
|
|
// VMime library (http://www.vmime.org)
|
|
|
|
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
2005-03-27 18:26:25 +00:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
2009-09-06 12:02:10 +00:00
|
|
|
// published by the Free Software Foundation; either version 3 of
|
2005-03-27 18:26:25 +00:00
|
|
|
// 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.
|
|
|
|
//
|
2005-09-17 10:10:29 +00:00
|
|
|
// 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.
|
2005-03-27 18:26:25 +00:00
|
|
|
//
|
|
|
|
|
2005-04-18 19:55:58 +00:00
|
|
|
#include "vmime/config.hpp"
|
2005-03-27 18:26:25 +00:00
|
|
|
|
2012-11-01 17:20:06 +00:00
|
|
|
|
|
|
|
#if VMIME_PLATFORM_IS_WINDOWS
|
|
|
|
|
|
|
|
|
|
|
|
#include "vmime/platforms/windows/windowsHandler.hpp"
|
|
|
|
|
2012-11-03 08:27:12 +00:00
|
|
|
#include "vmime/platforms/windows/windowsCriticalSection.hpp"
|
|
|
|
|
2013-02-11 08:37:32 +00:00
|
|
|
#include "vmime/utility/stringUtils.hpp"
|
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
#include <time.h>
|
|
|
|
#include <locale.h>
|
|
|
|
#include <process.h>
|
2005-04-18 19:55:58 +00:00
|
|
|
#include <windows.h> // for winnls.h
|
2007-10-16 18:13:47 +00:00
|
|
|
#include <winsock2.h> // for WSAStartup()
|
2013-02-24 14:36:53 +00:00
|
|
|
#include <ws2tcpip.h>
|
2012-11-12 11:22:03 +00:00
|
|
|
#include <wincrypt.h>
|
2005-04-18 19:55:58 +00:00
|
|
|
|
2013-02-10 20:12:41 +00:00
|
|
|
#if VMIME_HAVE_MLANG
|
2005-04-18 19:55:58 +00:00
|
|
|
# include <mlang.h>
|
|
|
|
#endif
|
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
|
|
|
|
namespace vmime {
|
|
|
|
namespace platforms {
|
|
|
|
namespace windows {
|
|
|
|
|
|
|
|
|
|
|
|
windowsHandler::windowsHandler()
|
|
|
|
{
|
2007-10-16 18:13:47 +00:00
|
|
|
WSAData wsaData;
|
|
|
|
WSAStartup(MAKEWORD(1, 1), &wsaData);
|
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
#if VMIME_HAVE_MESSAGING_FEATURES
|
2005-10-04 18:34:25 +00:00
|
|
|
m_socketFactory = vmime::create <windowsSocketFactory>();
|
2005-03-27 18:26:25 +00:00
|
|
|
#endif
|
|
|
|
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
2009-12-08 10:03:34 +00:00
|
|
|
m_fileSysFactory = vmime::create <windowsFileSystemFactory>();
|
2005-03-27 18:26:25 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
windowsHandler::~windowsHandler()
|
|
|
|
{
|
2007-10-16 18:13:47 +00:00
|
|
|
WSACleanup();
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-12 10:05:28 +00:00
|
|
|
unsigned int windowsHandler::getUnixTime() const
|
2005-03-27 18:26:25 +00:00
|
|
|
{
|
2005-05-14 15:57:06 +00:00
|
|
|
return static_cast <unsigned int>(::time(NULL));
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const vmime::datetime windowsHandler::getCurrentLocalTime() const
|
|
|
|
{
|
|
|
|
const time_t t(::time(NULL));
|
|
|
|
|
|
|
|
// Get the local time
|
2013-02-05 13:21:21 +00:00
|
|
|
#if VMIME_HAVE_LOCALTIME_S
|
|
|
|
tm local;
|
|
|
|
::localtime_s(&local, &t);
|
|
|
|
#elif VMIME_HAVE_LOCALTIME_R
|
2005-03-27 18:26:25 +00:00
|
|
|
tm local;
|
|
|
|
::localtime_r(&t, &local);
|
|
|
|
#else
|
|
|
|
tm local = *::localtime(&t); // WARNING: this is not thread-safe!
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Get the UTC time
|
2013-02-05 13:21:21 +00:00
|
|
|
#if VMIME_HAVE_GMTIME_S
|
|
|
|
tm gmt;
|
|
|
|
::gmtime_s(&gmt, &t);
|
|
|
|
#elif VMIME_HAVE_GMTIME_R
|
2005-03-27 18:26:25 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-25 12:10:15 +00:00
|
|
|
const vmime::charset windowsHandler::getLocalCharset() const
|
2005-03-27 18:26:25 +00:00
|
|
|
{
|
2013-02-10 20:12:41 +00:00
|
|
|
#if VMIME_HAVE_MLANG
|
2005-03-27 18:26:25 +00:00
|
|
|
char szCharset[256];
|
2005-04-18 19:55:58 +00:00
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
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;
|
2005-04-18 19:55:58 +00:00
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
WideCharToMultiByte(codePage, 0, cpInfo.wszBodyCharset, nLengthW, szCharset, sizeof(szCharset), NULL, NULL );
|
2005-04-18 19:55:58 +00:00
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
pMultiLanguage->Release();
|
|
|
|
|
2005-04-18 19:55:58 +00:00
|
|
|
}
|
2005-03-27 18:26:25 +00:00
|
|
|
CoUninitialize();
|
|
|
|
|
|
|
|
return vmime::charset(szCharset);
|
2013-02-10 20:12:41 +00:00
|
|
|
#else // VMIME_HAVE_MLANG
|
2005-04-18 19:55:58 +00:00
|
|
|
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
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
static inline bool isFQDN(const vmime::string& str)
|
|
|
|
{
|
|
|
|
if (utility::stringUtils::isStringEqualNoCase(str, "localhost", 9))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const vmime::string::size_type p = str.find_first_of(".");
|
|
|
|
return p != vmime::string::npos && p > 0 && p != str.length() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
const vmime::string windowsHandler::getHostName() const
|
|
|
|
{
|
2013-02-10 19:59:14 +00:00
|
|
|
char hostname[256];
|
2005-03-27 18:26:25 +00:00
|
|
|
|
|
|
|
// Try with 'gethostname'
|
2013-02-10 19:59:14 +00:00
|
|
|
::gethostname(hostname, sizeof(hostname));
|
|
|
|
hostname[sizeof(hostname) - 1] = '\0';
|
2005-03-27 18:26:25 +00:00
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
// If this is a Fully-Qualified Domain Name (FQDN), return immediately
|
|
|
|
if (isFQDN(hostname))
|
|
|
|
return hostname;
|
2005-03-27 18:26:25 +00:00
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
if (::strlen(hostname) == 0)
|
2013-02-28 08:16:40 +00:00
|
|
|
{
|
|
|
|
#if VMIME_HAVE_STRCPY_S
|
2013-02-26 16:51:44 +00:00
|
|
|
::strcpy_s(hostname, "localhost");
|
2013-02-28 08:16:40 +00:00
|
|
|
#else
|
|
|
|
::strcpy(hostname, "localhost");
|
|
|
|
#endif // VMIME_HAVE_STRCPY_S
|
|
|
|
}
|
2005-03-27 18:26:25 +00:00
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
// 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;
|
2005-03-27 18:26:25 +00:00
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
struct addrinfo* info;
|
2005-03-27 18:26:25 +00:00
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
if (getaddrinfo(hostname, "http", &hints, &info) == 0)
|
|
|
|
{
|
|
|
|
for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next)
|
2005-03-27 18:26:25 +00:00
|
|
|
{
|
2013-02-10 19:59:14 +00:00
|
|
|
if (isFQDN(p->ai_canonname))
|
|
|
|
{
|
2013-02-11 20:10:19 +00:00
|
|
|
const string ret(p->ai_canonname);
|
2013-02-10 19:59:14 +00:00
|
|
|
freeaddrinfo(info);
|
2013-02-11 20:10:19 +00:00
|
|
|
return ret;
|
2013-02-10 19:59:14 +00:00
|
|
|
}
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
freeaddrinfo(info);
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
2013-02-10 19:59:14 +00:00
|
|
|
return hostname;
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-12 10:05:28 +00:00
|
|
|
unsigned int windowsHandler::getProcessId() const
|
2005-03-27 18:26:25 +00:00
|
|
|
{
|
2005-05-14 16:39:33 +00:00
|
|
|
return (static_cast <unsigned int>(::GetCurrentProcessId()));
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-06 15:05:24 +00:00
|
|
|
unsigned int windowsHandler::getThreadId() const
|
2012-11-03 08:27:12 +00:00
|
|
|
{
|
|
|
|
return static_cast <unsigned int>(::GetCurrentThreadId());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
#if VMIME_HAVE_MESSAGING_FEATURES
|
|
|
|
|
2009-12-08 10:03:34 +00:00
|
|
|
ref <vmime::net::socketFactory> windowsHandler::getSocketFactory()
|
2005-03-27 18:26:25 +00:00
|
|
|
{
|
2009-12-08 10:03:34 +00:00
|
|
|
return m_socketFactory;
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
|
|
|
|
2009-12-08 10:03:34 +00:00
|
|
|
ref <vmime::utility::fileSystemFactory> windowsHandler::getFileSystemFactory()
|
2005-03-27 18:26:25 +00:00
|
|
|
{
|
2009-12-08 10:03:34 +00:00
|
|
|
return m_fileSysFactory;
|
2005-03-27 18:26:25 +00:00
|
|
|
}
|
|
|
|
|
2005-04-30 08:19:56 +00:00
|
|
|
|
2009-12-08 10:03:34 +00:00
|
|
|
ref <vmime::utility::childProcessFactory> windowsHandler::getChildProcessFactory()
|
2005-04-30 08:19:56 +00:00
|
|
|
{
|
|
|
|
// TODO: Not implemented
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
void windowsHandler::wait() const
|
|
|
|
{
|
|
|
|
::Sleep(1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-03 08:27:12 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-06 15:05:24 +00:00
|
|
|
ref <utility::sync::criticalSection> windowsHandler::createCriticalSection()
|
2012-11-03 08:27:12 +00:00
|
|
|
{
|
|
|
|
return vmime::create <windowsCriticalSection>();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-27 18:26:25 +00:00
|
|
|
} // posix
|
|
|
|
} // platforms
|
|
|
|
} // vmime
|
2012-11-01 17:20:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
#endif // VMIME_PLATFORM_IS_WINDOWS
|
|
|
|
|