diff options
author | alexv-smirnov <alex@ydb.tech> | 2022-12-20 00:50:48 +0300 |
---|---|---|
committer | alexv-smirnov <alex@ydb.tech> | 2022-12-20 00:50:48 +0300 |
commit | 84f2cfa253cc618438ed6e9d68b33fa7c0d88cb9 (patch) | |
tree | f0cf2236e0aafb3e437199f1ac7b559e7fad554a /contrib/libs/aws-sdk-cpp | |
parent | bde6febc1ad3b826e72746de21d7250803e8e0b5 (diff) | |
download | ydb-84f2cfa253cc618438ed6e9d68b33fa7c0d88cb9.tar.gz |
add windows platform to ydb github export
Diffstat (limited to 'contrib/libs/aws-sdk-cpp')
7 files changed, 874 insertions, 0 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/windows/Net.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/windows/Net.cpp new file mode 100644 index 0000000000..b1ec65b5df --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/windows/Net.cpp @@ -0,0 +1,48 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <WinSock2.h> +#include <cassert> +#include <aws/core/utils/logging/LogMacros.h> + +namespace Aws +{ + namespace Net + { + static bool s_globalNetworkInitiated = false; + + bool IsNetworkInitiated() + { + return s_globalNetworkInitiated; + } + + void InitNetwork() + { + if (IsNetworkInitiated()) + { + return; + } + // Initialize Winsock( requires winsock version 2.2) + WSADATA wsaData; + int result = WSAStartup(MAKEWORD(2, 2), &wsaData); + assert(result == NO_ERROR); + if (result != NO_ERROR) + { + AWS_LOGSTREAM_ERROR("WinSock2", "Failed to Initate WinSock2.2"); + s_globalNetworkInitiated = false; + } + else + { + s_globalNetworkInitiated = true; + } + } + + void CleanupNetwork() + { + WSACleanup(); + s_globalNetworkInitiated = false; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/windows/SimpleUDP.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/windows/SimpleUDP.cpp new file mode 100644 index 0000000000..f6e36077ec --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/windows/SimpleUDP.cpp @@ -0,0 +1,263 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <WinSock2.h> +#include <Ws2ipdef.h> +#include <Ws2tcpip.h> +#include <cassert> +#include <aws/core/net/SimpleUDP.h> +#include <aws/core/utils/logging/LogMacros.h> +namespace Aws +{ + namespace Net + { + static const char ALLOC_TAG[] = "SimpleUDP"; + static const char IPV4_LOOP_BACK_ADDRESS[] = "127.0.0.1"; + static const char IPV6_LOOP_BACK_ADDRESS[] = "::1"; + + static inline bool IsValidIPAddress(const char* ip, int addressFamily/*AF_INET or AF_INET6*/) + { + char buffer[128]; + return inet_pton(addressFamily, ip, (void*)buffer) == 1 ?true :false; + } + + static bool GetASockAddrFromHostName(const char* hostName, void* sockAddrBuffer, size_t& addrLength, int& addressFamily) + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + if (getaddrinfo(hostName, nullptr, &hints, &res)) + { + return false; + } + + memcpy(sockAddrBuffer, res->ai_addr, res->ai_addrlen); + addrLength = res->ai_addrlen; + addressFamily = res->ai_family; + freeaddrinfo(res); + return true; + } + + static sockaddr_in BuildAddrInfoIPV4(const char* hostIP, short port) + { + sockaddr_in addrinfo {}; + addrinfo.sin_family = AF_INET; + addrinfo.sin_port = htons(port); + inet_pton(AF_INET, hostIP, &addrinfo.sin_addr); + return addrinfo; + } + + static sockaddr_in6 BuildAddrInfoIPV6(const char* hostIP, short port) + { + sockaddr_in6 addrinfo {}; + addrinfo.sin6_family = AF_INET6; + addrinfo.sin6_port = htons(port); + inet_pton(AF_INET6, hostIP, &addrinfo.sin6_addr); + return addrinfo; + } + + SimpleUDP::SimpleUDP(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking): + m_addressFamily(addressFamily), m_connected(false), m_socket(-1), m_port(0) + { + CreateSocket(addressFamily, sendBufSize, receiveBufSize, nonBlocking); + } + + SimpleUDP::SimpleUDP(bool IPV4, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) : + m_addressFamily(IPV4 ? AF_INET : AF_INET6), m_connected(false), m_socket(-1), m_port(0) + { + CreateSocket(m_addressFamily, sendBufSize, receiveBufSize, nonBlocking); + } + + SimpleUDP::SimpleUDP(const char* host, unsigned short port, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) : + m_addressFamily(AF_INET), m_connected(false), m_socket(-1), m_port(port) + { + if (IsValidIPAddress(host, AF_INET)) + { + m_addressFamily = AF_INET; + m_hostIP = Aws::String(host); + } + else if (IsValidIPAddress(host, AF_INET6)) + { + m_addressFamily = AF_INET6; + m_hostIP = Aws::String(host); + } + else + { + char sockAddrBuffer[100]; + char hostBuffer[100]; + size_t addrLength = 0; + if (GetASockAddrFromHostName(host, (void*)sockAddrBuffer, addrLength, m_addressFamily)) + { + if (m_addressFamily == AF_INET) + { + struct sockaddr_in* sockaddr = reinterpret_cast<struct sockaddr_in*>(sockAddrBuffer); + inet_ntop(m_addressFamily, &(sockaddr->sin_addr), hostBuffer, sizeof(hostBuffer)); + } + else + { + struct sockaddr_in6* sockaddr = reinterpret_cast<struct sockaddr_in6*>(sockAddrBuffer); + inet_ntop(m_addressFamily, &(sockaddr->sin6_addr), hostBuffer, sizeof(hostBuffer)); + } + m_hostIP = Aws::String(hostBuffer); + } + else + { + AWS_LOGSTREAM_ERROR(ALLOC_TAG, "Can't retrieve a valid ip address based on provided host: " << host); + } + } + CreateSocket(m_addressFamily, sendBufSize, receiveBufSize, nonBlocking); + } + + SimpleUDP::~SimpleUDP() + { + closesocket(GetUnderlyingSocket()); + } + + void SimpleUDP::CreateSocket(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) + { + SOCKET sock = socket(addressFamily, SOCK_DGRAM, IPPROTO_UDP); + assert(sock != INVALID_SOCKET); + + // Try to set sock to nonblocking mode. + if (nonBlocking) + { + u_long enable = 1; + ioctlsocket(sock, FIONBIO, &enable); + } + + // if sendBufSize is not zero, try to set send buffer size + if (sendBufSize) + { + int ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char*>(&sendBufSize), sizeof(sendBufSize)); + if (ret) + { + AWS_LOGSTREAM_WARN(ALLOC_TAG, "Failed to set UDP send buffer size to " << sendBufSize << " for socket " << sock << " error code: " << WSAGetLastError()); + } + assert(ret == 0); + } + + // if receiveBufSize is not zero, try to set receive buffer size + if (receiveBufSize) + { + int ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const char*>(&receiveBufSize), sizeof(receiveBufSize)); + if (ret) + { + AWS_LOGSTREAM_WARN(ALLOC_TAG, "Failed to set UDP receive buffer size to " << receiveBufSize << " for socket " << sock << " error code: " << WSAGetLastError()); + } + assert(ret == 0); + } + + SetUnderlyingSocket(static_cast<int>(sock)); + } + + int SimpleUDP::Connect(const sockaddr* address, size_t addressLength) + { + int ret = connect(GetUnderlyingSocket(), address, static_cast<socklen_t>(addressLength)); + m_connected = ret ? false : true; + return ret; + } + + int SimpleUDP::ConnectToHost(const char* hostIP, unsigned short port) const + { + int ret; + if (m_addressFamily == AF_INET6) + { + sockaddr_in6 addrinfo = BuildAddrInfoIPV6(hostIP, port); + ret = connect(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); + } + else + { + sockaddr_in addrinfo = BuildAddrInfoIPV4(hostIP, port); + ret = connect(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); + } + m_connected = ret ? false : true; + return ret; + } + + int SimpleUDP::ConnectToLocalHost(unsigned short port) const + { + if (m_addressFamily == AF_INET6) + { + return ConnectToHost(IPV6_LOOP_BACK_ADDRESS, port); + } + else + { + return ConnectToHost(IPV4_LOOP_BACK_ADDRESS, port); + } + } + + int SimpleUDP::Bind(const sockaddr* address, size_t addressLength) const + { + return bind(GetUnderlyingSocket(), address, static_cast<socklen_t>(addressLength)); + } + + int SimpleUDP::BindToLocalHost(unsigned short port) const + { + if (m_addressFamily == AF_INET6) + { + sockaddr_in6 addrinfo = BuildAddrInfoIPV6(IPV6_LOOP_BACK_ADDRESS, port); + return bind(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); + } + else + { + sockaddr_in addrinfo = BuildAddrInfoIPV4(IPV4_LOOP_BACK_ADDRESS, port); + return bind(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); + } + } + + int SimpleUDP::SendData(const uint8_t* data, size_t dataLen) const + { + if (!m_connected) + { + ConnectToHost(m_hostIP.c_str(), m_port); + } + return send(GetUnderlyingSocket(), reinterpret_cast<const char*>(data), static_cast<int>(dataLen), 0); + } + + int SimpleUDP::SendDataTo(const sockaddr* address, size_t addressLength, const uint8_t* data, size_t dataLen) const + { + if (m_connected) + { + return send(GetUnderlyingSocket(), reinterpret_cast<const char*>(data), static_cast<int>(dataLen), 0); + } + else + { + return sendto(GetUnderlyingSocket(), reinterpret_cast<const char*>(data), static_cast<int>(dataLen), 0, address, static_cast<socklen_t>(addressLength)); + } + } + + int SimpleUDP::SendDataToLocalHost(const uint8_t* data, size_t dataLen, unsigned short port) const + { + if (m_connected) + { + return send(GetUnderlyingSocket(), reinterpret_cast<const char*>(data), static_cast<int>(dataLen), 0); + } + else if (m_addressFamily == AF_INET6) + { + sockaddr_in6 addrinfo = BuildAddrInfoIPV6(IPV6_LOOP_BACK_ADDRESS, port); + return sendto(GetUnderlyingSocket(), reinterpret_cast<const char*>(data), static_cast<int>(dataLen), 0, reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); + } + else + { + sockaddr_in addrinfo = BuildAddrInfoIPV4(IPV4_LOOP_BACK_ADDRESS, port); + return sendto(GetUnderlyingSocket(), reinterpret_cast<const char*>(data), static_cast<int>(dataLen), 0, reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); + } + } + + int SimpleUDP::ReceiveData(uint8_t* buffer, size_t bufferLen) const + { + return recv(GetUnderlyingSocket(), reinterpret_cast<char*>(buffer), static_cast<int>(bufferLen), 0); + } + + + int SimpleUDP::ReceiveDataFrom(sockaddr* address, size_t* addressLength, uint8_t* buffer, size_t bufferLen) const + { + return recvfrom(GetUnderlyingSocket(), reinterpret_cast<char*>(buffer), static_cast<int>(bufferLen), 0, address, reinterpret_cast<socklen_t*>(addressLength)); + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Environment.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Environment.cpp new file mode 100644 index 0000000000..d8b5403123 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Environment.cpp @@ -0,0 +1,37 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/platform/Environment.h> + +#include <stdio.h> +#include <utility> + +namespace Aws +{ +namespace Environment +{ + +/* +using std::getenv generates a warning on windows so we use _dupenv_s instead. The character array returned by this function is our responsibility to clean up, so rather than returning raw strings +that would need to be manually freed in all the client functions, just copy it into a Aws::String instead, freeing it here. +*/ +Aws::String GetEnv(const char *variableName) +{ + char* variableValue = nullptr; + std::size_t valueSize = 0; + auto queryResult = _dupenv_s(&variableValue, &valueSize, variableName); + + Aws::String result; + if(queryResult == 0 && variableValue != nullptr && valueSize > 0) + { + result.assign(variableValue, valueSize - 1); // don't copy the c-string terminator byte + free(variableValue); + } + + return result; +} + +} // namespace Environment +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/FileSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/FileSystem.cpp new file mode 100644 index 0000000000..2ea82de6f8 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/FileSystem.cpp @@ -0,0 +1,336 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/core/platform/FileSystem.h> + +#include <aws/core/platform/Environment.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/StringUtils.h> +#include <cassert> +#include <iostream> +#include <Userenv.h> + +#pragma warning( disable : 4996) + +using namespace Aws::Utils; +namespace Aws +{ +namespace FileSystem +{ + +static const char* FILE_SYSTEM_UTILS_LOG_TAG = "FileSystem"; + +/** + * See + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx + * to understand how could we pass long path (over 260 chars) to WinAPI + */ +static inline Aws::WString ToLongPath(const Aws::WString& path) +{ + if (path.size() > MAX_PATH - 12/*8.3 file name*/) + { + return L"\\\\?\\" + path; + } + return path; +} + +class User32Directory : public Directory +{ +public: + User32Directory(const Aws::String& path, const Aws::String& relativePath) : Directory(path, relativePath), m_find(INVALID_HANDLE_VALUE), m_lastError(0) + { + WIN32_FIND_DATAW ffd; + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Entering directory " << m_directoryEntry.path); + + m_find = FindFirstFileW(ToLongPath(Aws::Utils::StringUtils::ToWString(m_directoryEntry.path.c_str())).c_str(), &ffd); + if (m_find != INVALID_HANDLE_VALUE) + { + m_directoryEntry = ParseFileInfo(ffd, false); + FindClose(m_find); + auto seachPath = Join(m_directoryEntry.path, "*"); + m_find = FindFirstFileW(ToLongPath(Aws::Utils::StringUtils::ToWString(seachPath.c_str())).c_str(), &m_ffd); + } + else + { + AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Could not load directory " << m_directoryEntry.path << " with error code " << GetLastError()); + } + } + + ~User32Directory() + { + if (m_find != INVALID_HANDLE_VALUE) + { + FindClose(m_find); + } + } + + operator bool() const override { return m_directoryEntry.operator bool() && m_find != INVALID_HANDLE_VALUE; } + + DirectoryEntry Next() override + { + assert(m_find != INVALID_HANDLE_VALUE); + DirectoryEntry entry; + bool invalidEntry = true; + + while(invalidEntry && !m_lastError) + { + //due to the way the FindFirstFile api works, + //the first entry will already be loaded by the time we get here. + entry = ParseFileInfo(m_ffd, true); + + Aws::String fileName = Aws::Utils::StringUtils::FromWString(m_ffd.cFileName); + if (fileName != ".." && fileName != ".") + { + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Found entry " << entry.path); + invalidEntry = false; + } + else + { + entry.fileType = FileType::None; + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Skipping . or .. entries."); + } + + if(!FindNextFileW(m_find, &m_ffd)) + { + m_lastError = GetLastError(); + AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Could not fetch next entry from " << m_directoryEntry.path << " with error code " << m_lastError); + break; + } + } + + return entry; + } + +private: + DirectoryEntry ParseFileInfo(WIN32_FIND_DATAW& ffd, bool computePath) + { + DirectoryEntry entry; + LARGE_INTEGER fileSize; + fileSize.HighPart = ffd.nFileSizeHigh; + fileSize.LowPart = ffd.nFileSizeLow; + entry.fileSize = static_cast<int64_t>(fileSize.QuadPart); + + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + entry.fileType = FileType::Directory; + } + else + { + entry.fileType = FileType::File; + } + + if(computePath) + { + entry.path = Join(m_directoryEntry.path, Aws::Utils::StringUtils::FromWString(ffd.cFileName)); + entry.relativePath = m_directoryEntry.relativePath.empty() ? Aws::Utils::StringUtils::FromWString(ffd.cFileName) : Join(m_directoryEntry.relativePath, Aws::Utils::StringUtils::FromWString(ffd.cFileName)); + } + else + { + entry.path = m_directoryEntry.path; + entry.relativePath = m_directoryEntry.relativePath; + } + + return entry; + } + + HANDLE m_find; + WIN32_FIND_DATAW m_ffd; + DWORD m_lastError; +}; + +Aws::String GetHomeDirectory() +{ + static const char* HOME_DIR_ENV_VAR = "USERPROFILE"; + + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Checking " << HOME_DIR_ENV_VAR << " for the home directory."); + Aws::String homeDir = Aws::Environment::GetEnv(HOME_DIR_ENV_VAR); + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Environment value for variable " << HOME_DIR_ENV_VAR << " is " << homeDir); + if(homeDir.empty()) + { + AWS_LOGSTREAM_WARN(FILE_SYSTEM_UTILS_LOG_TAG, "Home dir not stored in environment, trying to fetch manually from the OS."); + HANDLE hToken; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) + { + DWORD len = MAX_PATH; + WCHAR path[MAX_PATH]; + if (GetUserProfileDirectoryW(hToken, path, &len)) + { + homeDir = Aws::Utils::StringUtils::FromWString(path); + } + CloseHandle(hToken); + } + + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Pulled " << homeDir << " as home directory from the OS."); + } + + Aws::String retVal = (homeDir.size() > 0) ? Aws::Utils::StringUtils::Trim(homeDir.c_str()) : ""; + + if (!retVal.empty()) + { + if (retVal.at(retVal.length() - 1) != Aws::FileSystem::PATH_DELIM) + { + retVal += Aws::FileSystem::PATH_DELIM; + } + } + + return retVal; +} + +Aws::String GetExecutableDirectory() +{ + static const unsigned long long bufferSize = 256; + WCHAR buffer[bufferSize]; + + memset(buffer, 0, sizeof(buffer)); + + if (GetModuleFileNameW(nullptr, buffer, static_cast<DWORD>(sizeof(buffer)))) + { + Aws::String bufferStr(Aws::Utils::StringUtils::FromWString(buffer)); + auto fileNameStart = bufferStr.find_last_of(PATH_DELIM); + if (fileNameStart != std::string::npos) + { + bufferStr = bufferStr.substr(0, fileNameStart); + } + + return bufferStr; + } + + return ""; +} + +bool CreateDirectoryIfNotExists(const char* path, bool createParentDirs) +{ + Aws::String directoryName = path; + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Creating directory " << directoryName); + + // Create intermediate directories or create the target directory once. + for (size_t i = createParentDirs ? 0 : directoryName.size() - 1; i < directoryName.size(); i++) + { + // Create the intermediate directory if we find a delimiter and the delimiter is not the first char, or if this is the target directory. + if (i != 0 && (directoryName[i] == FileSystem::PATH_DELIM || i == directoryName.size() - 1)) + { + // the last delimeter can be removed safely. + if (directoryName[i] == FileSystem::PATH_DELIM) + { + directoryName[i] = '\0'; + } + if (CreateDirectoryW(ToLongPath(StringUtils::ToWString(directoryName.c_str())).c_str(), nullptr)) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Creation of directory " << directoryName.c_str() << " succeeded."); + } + else + { + DWORD errorCode = GetLastError(); + if (errorCode != ERROR_ALREADY_EXISTS && errorCode != NO_ERROR) // in vs2013 the errorCode is NO_ERROR + { + AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, " Creation of directory " << directoryName.c_str() << " returned code: " << errorCode); + return false; + } + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, " Creation of directory " << directoryName.c_str() << " returned code: " << errorCode); + } + // Restore the path. We are good even if we didn't change that char to '\0', because we are ready to return. + directoryName[i] = FileSystem::PATH_DELIM; + } + } + return true; +} + +bool RemoveFileIfExists(const char* path) +{ + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Deleting file: " << path); + + if (DeleteFileW(ToLongPath(Aws::Utils::StringUtils::ToWString(path)).c_str())) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Successfully deleted file: " << path); + return true; + } + else + { + DWORD errorCode = GetLastError(); + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Deletion of file: " << path << " Returned error code: " << errorCode); + return errorCode == ERROR_FILE_NOT_FOUND; + } +} + +bool RelocateFileOrDirectory(const char* from, const char* to) +{ + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Moving file at " << from << " to " << to); + + if(MoveFileW(ToLongPath(Aws::Utils::StringUtils::ToWString(from)).c_str(), Aws::Utils::StringUtils::ToWString(to).c_str())) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The moving operation of file at " << from << " to " << to << " Succeeded."); + return true; + } + else + { + int errorCode = GetLastError(); + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The moving operation of file at " << from << " to " << to << " Returned error code of " << errorCode); + return false; + } +} + +bool RemoveDirectoryIfExists(const char* path) +{ + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Removing directory at " << path); + + if(RemoveDirectoryW(ToLongPath(Aws::Utils::StringUtils::ToWString(path)).c_str())) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The remove operation of file at " << path << " Succeeded."); + return true; + } + else + { + int errorCode = GetLastError(); + if (errorCode == ERROR_DIR_NOT_EMPTY) + { + AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "The remove operation of file at " << path << " failed. with error code because it was not empty."); + } + + else if(errorCode == ERROR_DIRECTORY) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The deletion of directory at " << path << " failed because it doesn't exist."); + return true; + + } + + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The remove operation of file at " << path << " failed. with error code " << errorCode); + return false; + } +} + +Aws::String CreateTempFilePath() +{ +#ifdef _MSC_VER +#pragma warning(disable: 4996) // _CRT_SECURE_NO_WARNINGS +#endif + char s_tempName[L_tmpnam_s+1]; + + /* + Prior to VS 2014, tmpnam/tmpnam_s generated root level files ("\filename") which were not appropriate for our usage, so for the windows version, we prepended a '.' to make it a + tempfile in the current directory. Starting with VS2014, the behavior of tmpnam/tmpnam_s was changed to be a full, valid filepath based on the + current user ("C:\Users\username\AppData\Local\Temp\..."). + + See the tmpnam section in http://blogs.msdn.com/b/vcblog/archive/2014/06/18/crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1.aspx + for more details. + */ + +#if _MSC_VER >= 1900 + tmpnam_s(s_tempName, L_tmpnam_s); +#else + s_tempName[0] = '.'; + tmpnam_s(s_tempName + 1, L_tmpnam_s); +#endif // _MSC_VER + + + return s_tempName; +} + +Aws::UniquePtr<Directory> OpenDirectory(const Aws::String& path, const Aws::String& relativePath) +{ + return Aws::MakeUnique<User32Directory>(FILE_SYSTEM_UTILS_LOG_TAG, path, relativePath); +} + +} // namespace FileSystem +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/OSVersionInfo.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/OSVersionInfo.cpp new file mode 100644 index 0000000000..0180f7fbf6 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/OSVersionInfo.cpp @@ -0,0 +1,138 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/platform/OSVersionInfo.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + +#include <iomanip> + +#pragma warning(disable: 4996) +#include <windows.h> +#include <stdio.h> +namespace Aws +{ +namespace OSVersionInfo +{ + +Aws::String GetSysCommandOutput(const char* command) +{ + Aws::String outputStr; + FILE* outputStream; + const int maxBufferSize = 256; + char outputBuffer[maxBufferSize]; + + outputStream = _popen(command, "r"); + + if (outputStream) + { + while (!feof(outputStream)) + { + if (fgets(outputBuffer, maxBufferSize, outputStream) != nullptr) + { + outputStr.append(outputBuffer); + } + } + + _pclose(outputStream); + + return Aws::Utils::StringUtils::Trim(outputStr.c_str()); + } + + return {}; +} + +Aws::String ComputeOSVersionString() +{ + // With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version. + // The value returned by the GetVersionEx function now depends on how the application is manifested. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 + // + // This only works when the application is manifested for Windows 8.1 or 10, which we don't actually care about. + // Also, this will cause build headaches for folks not building with VS2015, and is overall an unusable API for us. + // The following is the least painful but most reliable hack I can come up with. + // + // From this article: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724429.aspx + // we will do the following: + // + // To obtain the full version number for the operating system, call the GetFileVersionInfo function on one of the system DLLs, such as Kernel32.dll, + // then call VerQueryValue to obtain the \\StringFileInfo\\<lang><codepage>\\ProductVersion subblock of the file version information. + // + Aws::StringStream ss; + ss << "Windows/"; + + DWORD uselessParameter(0); + static const char* FILE_TO_CHECK = "Kernel32.dll"; + DWORD fileVersionSize = GetFileVersionInfoSizeA(FILE_TO_CHECK, &uselessParameter); + void* blob = Aws::Malloc("OSVersionInfo", static_cast<size_t>(fileVersionSize)); + bool versionFound(false); + + if (GetFileVersionInfoA(FILE_TO_CHECK, 0, fileVersionSize, blob)) + { + struct LANGANDCODEPAGE { + WORD wLanguage; + WORD wCodePage; + } *lpTranslate; + + UINT sizeOfCodePage(0); + + if (VerQueryValueA(blob, "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &sizeOfCodePage)) + { + //we don't actually care which language pack we get, they should all have the same windows version attached. + Aws::StringStream codePageSS; + codePageSS << "\\StringFileInfo\\"; + codePageSS << std::setfill('0') << std::setw(4) << std::nouppercase << std::hex << lpTranslate[0].wLanguage; + codePageSS << std::setfill('0') << std::setw(4) << std::nouppercase << std::hex << lpTranslate[0].wCodePage; + codePageSS << "\\ProductVersion"; + + void* subBlock(nullptr); + UINT subBlockSize(0); + + if (VerQueryValueA(blob, codePageSS.str().c_str(), &subBlock, &subBlockSize)) + { + ss << static_cast<const char*>(subBlock); + versionFound = true; + } + } + } + + Aws::Free(blob); + + if (!versionFound) + { + ss << "Unknown Version"; + } + + + + SYSTEM_INFO sysInfo; + ZeroMemory(&sysInfo, sizeof(SYSTEM_INFO)); + GetSystemInfo(&sysInfo); + + switch (sysInfo.wProcessorArchitecture) + { + //PROCESSOR_ARCHITECTURE_AMD64 + case 0x09: + ss << " AMD64"; + break; + //PROCESSOR_ARCHITECTURE_IA64 + case 0x06: + ss << " IA64"; + break; + //PROCESSOR_ARCHITECTURE_INTEL + case 0x00: + ss << " x86"; + break; + default: + ss << " Unknown Processor Architecture"; + break; + } + + return ss.str(); +} + + +} // namespace OSVersionInfo +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Security.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Security.cpp new file mode 100644 index 0000000000..fbf9a4e679 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Security.cpp @@ -0,0 +1,21 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/platform/Security.h> + +#include <windows.h> + +namespace Aws +{ +namespace Security +{ + +void SecureMemClear(unsigned char *data, size_t length) +{ + SecureZeroMemory(data, length); +} + +} // namespace Security +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Time.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Time.cpp new file mode 100644 index 0000000000..e186d21c81 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/windows/Time.cpp @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/platform/Time.h> + +#include <time.h> + +namespace Aws +{ +namespace Time +{ + +time_t TimeGM(struct tm* const t) +{ + return _mkgmtime(t); +} + +void LocalTime(tm* t, std::time_t time) +{ + localtime_s(t, &time); +} + +void GMTime(tm* t, std::time_t time) +{ + gmtime_s(t, &time); +} + +} // namespace Time +} // namespace Aws |