forked from OSGeo/gdal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpl_aws_win32.cpp
145 lines (126 loc) · 4.5 KB
/
cpl_aws_win32.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**********************************************************************
*
* Project: CPL - Common Portability Library
* Purpose: Fetch Windows UUID using WMI COM interface.
* Author: [email protected]
*
**********************************************************************
* Copyright (c) 2020, Robin Princeley <[email protected]>
*
* SPDX-License-Identifier: MIT
****************************************************************************/
#include "cpl_port.h"
#if defined(HAVE_ATLBASE_H)
#define _WIN32_DCOM
#include <iostream>
#include <mutex>
#include <comdef.h>
#include <Wbemidl.h>
#include <windows.h>
#include <comutil.h>
#include <atlbase.h>
#include "cpl_string.h"
#include "cpl_multiproc.h"
static std::string osWindowsProductUUID;
static void FetchUUIDFunc(void *)
{
HRESULT hResult = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hResult))
{
CPLError(CE_Failure, CPLE_AppDefined,
"Failed to initialize COM library, HRESULT = %d", hResult);
return;
}
else
{
CComPtr<IWbemLocator> poLocator;
hResult = poLocator.CoCreateInstance(CLSID_WbemLocator, NULL,
CLSCTX_INPROC_SERVER);
if (FAILED(hResult))
{
CPLError(CE_Failure, CPLE_AppDefined,
"Failed to create instance of IWbemLocator, HRESULT = %d",
hResult);
goto com_cleanup;
}
CComPtr<IWbemServices> pSvc;
hResult = poLocator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL,
0, NULL, 0, 0, &pSvc);
if (FAILED(hResult))
{
CPLError(CE_Failure, CPLE_AppDefined,
"Failed to create connect to WMI server, HRESULT = %d",
hResult);
goto com_cleanup;
}
CPLDebug("CPLFetchWindowsProductUUID",
"Connected to ROOT\\CIMV2 WMI namespace");
hResult =
CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (FAILED(hResult))
{
CPLError(CE_Failure, CPLE_AppDefined,
"Failed to set proxy blanket, HRESULT = %d", hResult);
goto com_cleanup;
}
CComPtr<IEnumWbemClassObject> pEnumerator;
hResult = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT UUID FROM Win32_ComputerSystemProduct"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL,
&pEnumerator);
if (FAILED(hResult))
{
CPLError(CE_Failure, CPLE_AppDefined,
"Query for UUID in Win32_ComputerSystemProduct failed, "
"HRESULT = %d",
hResult);
goto com_cleanup;
}
if (pEnumerator)
{
CComPtr<IWbemClassObject> poClassObject;
ULONG uReturn = 0;
hResult =
pEnumerator->Next(WBEM_INFINITE, 1, &poClassObject, &uReturn);
if (SUCCEEDED(hResult) && uReturn)
{
CComVariant poVariant;
hResult = poClassObject->Get(L"UUID", 0, &poVariant, 0, 0);
if (SUCCEEDED(hResult))
{
bstr_t bString(poVariant.bstrVal);
if (bString.length())
osWindowsProductUUID =
static_cast<const char *>(bString);
}
}
}
}
if (!osWindowsProductUUID.empty())
CPLDebug("CPLFetchWindowsProductUUID",
"Succeeded in querying UUID from WMI.");
com_cleanup:
CoUninitialize();
}
bool CPLFetchWindowsProductUUID(std::string &osStr);
bool CPLFetchWindowsProductUUID(std::string &osStr)
{
static std::mutex gMutex;
std::lock_guard<std::mutex> oGuard(gMutex);
static bool bAttemptedGUID = false;
if (!bAttemptedGUID)
{
// All COM work is in a different thread to avoid potential problems:
// the calling thread may or may not have already initialized COM,
// and the threading model may differ.
auto pThread = CPLCreateJoinableThread(FetchUUIDFunc, nullptr);
CPLJoinThread(pThread);
bAttemptedGUID = true;
}
osStr = osWindowsProductUUID;
return !osWindowsProductUUID.empty();
}
#endif /* defined(HAVE_ATLBASE_H) */