adapters/platform_win32.c (211 lines of code) (raw):
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include "azure_c_shared_utility/platform.h"
#include "azure_c_shared_utility/optimize_size.h"
#include "azure_c_shared_utility/xio.h"
#include "azure_c_shared_utility/strings.h"
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/httpapiex.h"
#include "winsock2.h"
#include "minwindef.h"
#include "winnt.h"
#ifdef USE_OPENSSL
#include "azure_c_shared_utility/tlsio_openssl.h"
#endif
#if USE_CYCLONESSL
#include "azure_c_shared_utility/tlsio_cyclonessl.h"
#endif
#if USE_WOLFSSL
#include "azure_c_shared_utility/tlsio_wolfssl.h"
#endif
#if USE_MBEDTLS
#include "azure_c_shared_utility/tlsio_mbedtls.h"
#endif
#if USE_BEARSSL
#include "azure_c_shared_utility/tlsio_bearssl.h"
#endif
#include "azure_c_shared_utility/tlsio_schannel.h"
int platform_init(void)
{
int result;
WSADATA wsaData;
int error_code = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (error_code != 0)
{
LogError("WSAStartup failed: 0x%x", error_code);
result = MU_FAILURE;
}
else
{
result = 0;
#ifndef DONT_USE_UPLOADTOBLOB
if (HTTPAPIEX_Init() == HTTPAPIEX_ERROR)
{
LogError("HTTP for upload to blob failed on initialization.");
result = MU_FAILURE;
}
#endif /* DONT_USE_UPLOADTOBLOB */
#ifdef USE_OPENSSL
if (result == 0)
{
result = tlsio_openssl_init();
}
#endif
}
return result;
}
const IO_INTERFACE_DESCRIPTION* platform_get_default_tlsio(void)
{
#ifdef USE_OPENSSL
return tlsio_openssl_get_interface_description();
#elif USE_CYCLONESSL
return tlsio_cyclonessl_get_interface_description();
#elif USE_WOLFSSL
return tlsio_wolfssl_get_interface_description();
#elif USE_BEARSSL
return tlsio_bearssl_get_interface_description();
#elif USE_MBEDTLS
return tlsio_mbedtls_get_interface_description();
#else
return tlsio_schannel_get_interface_description();
#endif
}
static char* get_win_sqm_info(void)
{
char* result;
LONG openKey;
DWORD options = 0;
HKEY openResult;
HKEY hKey = HKEY_LOCAL_MACHINE;
LPCSTR subKey = "Software\\Microsoft\\SQMClient";
LPCSTR lpValue = "MachineId";
DWORD dwFlags = RRF_RT_ANY;
LONG getRegValue = ERROR_INVALID_HANDLE;
DWORD dataType;
DWORD size = GUID_LENGTH;
PVOID pvData;
// SQM values are guids in the system, we will allocate enough space to hold that
if ((result = (char*)malloc(GUID_LENGTH)) == NULL)
{
LogError("Failure allocating sqm info");
}
else if ((openKey = RegOpenKeyExA(hKey, subKey, options, KEY_READ, &openResult)) != ERROR_SUCCESS)
{
LogError("Failure opening registry key: %d:%s", GetLastError(), subKey);
free(result);
result = NULL;
}
else
{
pvData = result;
if ((getRegValue = RegGetValueA(openResult, NULL, lpValue, dwFlags, &dataType, pvData, &size)) != ERROR_SUCCESS)
{
// Failed to read value, so try opening the 64-bit reg key
// in case this is an x86 binary being run on Windows x64
if ((openKey = RegOpenKeyExA(hKey, subKey, options, KEY_READ | KEY_WOW64_64KEY, &openResult)) != ERROR_SUCCESS)
{
LogError("Failure opening registry sub key: %d:%s", GetLastError(), subKey);
free(result);
result = NULL;
}
else if ((getRegValue = RegGetValueA(openResult, NULL, lpValue, dwFlags, &dataType, pvData, &size)) != ERROR_SUCCESS)
{
LogError("Failure opening registry sub key: %d:%s", GetLastError(), subKey);
free(result);
result = NULL;
}
}
if (getRegValue != ERROR_SUCCESS)
{
LogError("Failure retrieving SQM info Error value: %d", GetLastError());
free(result);
result = NULL;
}
RegCloseKey(openResult);
}
return result;
}
STRING_HANDLE platform_get_platform_info(PLATFORM_INFO_OPTION options)
{
// Expected format: "(<runtime name>; <operating system name>; <platform>)"
STRING_HANDLE result;
SYSTEM_INFO sys_info;
OSVERSIONINFO osvi;
char *arch;
GetSystemInfo(&sys_info);
switch (sys_info.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_AMD64:
arch = "x64";
break;
case PROCESSOR_ARCHITECTURE_ARM:
arch = "ARM";
break;
case PROCESSOR_ARCHITECTURE_IA64:
arch = "IA64";
break;
case PROCESSOR_ARCHITECTURE_INTEL:
arch = "x32";
break;
default:
arch = "UNKNOWN";
break;
}
result = NULL;
memset(&osvi, 0, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
#ifdef _MSC_VER
#pragma warning(disable:4996 28159) // GetVersionEx is deprecated
#endif
if (GetVersionEx(&osvi))
{
DWORD product_type;
if (GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &product_type))
{
result = STRING_construct_sprintf("(native; WindowsProduct:0x%08x %d.%d; %s", product_type, osvi.dwMajorVersion, osvi.dwMinorVersion, arch);
}
}
if (result == NULL)
{
DWORD dwVersion = GetVersion();
result = STRING_construct_sprintf("(native; WindowsProduct:Windows NT %d.%d; %s", LOBYTE(LOWORD(dwVersion)), HIBYTE(LOWORD(dwVersion)), arch);
}
#ifdef _MSC_VER
#pragma warning(default:4996 28159)
#endif
if (result == NULL)
{
LogError("STRING_construct_sprintf failed");
}
else if (options & PLATFORM_INFO_OPTION_RETRIEVE_SQM)
{
// Failure here should continue
char* sqm_info = get_win_sqm_info();
if (sqm_info != NULL)
{
if (STRING_sprintf(result, "; %s)", sqm_info) != 0)
{
LogError("failure concat file");
}
free(sqm_info);
}
else
{
if (STRING_concat(result, ")") != 0)
{
LogError("failure concat file");
}
}
}
else
{
if (STRING_concat(result, ")") != 0)
{
LogError("failure concat file");
}
}
return result;
}
void platform_deinit(void)
{
(void)WSACleanup();
#ifndef DONT_USE_UPLOADTOBLOB
HTTPAPIEX_Deinit();
#endif /* DONT_USE_UPLOADTOBLOB */
#ifdef USE_OPENSSL
tlsio_openssl_deinit();
#endif
}