Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
jlib
Commits
d2da3411
Commit
d2da3411
authored
Sep 30, 2019
by
captainwong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wmi
parent
b657c6e8
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
317 additions
and
1126 deletions
+317
-1126
DeviceUniqueIdentifier.cpp
jlib/win32/DeviceUniqueIdentifier.cpp
+0
-456
DeviceUniqueIdentifier.h
jlib/win32/DeviceUniqueIdentifier.h
+291
-24
DeviceUniqueIdentifierHeaderOnly.h
jlib/win32/DeviceUniqueIdentifierHeaderOnly.h
+0
-412
wmi.h
jlib/win32/wmi.h
+9
-1
test.sln
test/test.sln
+12
-25
test.cpp
test/testDeviceUniqueIdentifier/test.cpp
+0
-37
testDeviceUniqueIdentifier.cpp
...testDeviceUniqueIdentifier/testDeviceUniqueIdentifier.cpp
+1
-1
testDeviceUniqueIdentifier.vcxproj
...DeviceUniqueIdentifier/testDeviceUniqueIdentifier.vcxproj
+3
-7
testDeviceUniqueIdentifier.vcxproj.filters
...iqueIdentifier/testDeviceUniqueIdentifier.vcxproj.filters
+1
-9
testDeviceUniqueIdentifierHeaderOnly.vcxproj
...erHeaderOnly/testDeviceUniqueIdentifierHeaderOnly.vcxproj
+0
-128
testDeviceUniqueIdentifierHeaderOnly.vcxproj.filters
...Only/testDeviceUniqueIdentifierHeaderOnly.vcxproj.filters
+0
-22
testDeviceUniqueIdentifierHeaderOnly.vcxproj.user
...derOnly/testDeviceUniqueIdentifierHeaderOnly.vcxproj.user
+0
-4
No files found.
jlib/win32/DeviceUniqueIdentifier.cpp
deleted
100644 → 0
View file @
b657c6e8
#
include
"DeviceUniqueIdentifier.h"
#include <Windows.h>
#include <algorithm>
#include <math.h>
#include <strsafe.h>
#include <tchar.h>
#include <ntddndis.h>
#include <WbemIdl.h>
#include <comdef.h>
#include <comutil.h>
#include <atlconv.h>
#include <jlib/utf8.h>
#pragma comment (lib, "comsuppw.lib")
#pragma comment (lib, "wbemuuid.lib")
namespace
jlib
{
namespace
win32
{
namespace
DeviceUniqueIdentifier
{
namespace
detail
{
struct
DeviceProperty
{
enum
{
PROPERTY_MAX_LEN
=
128
};
// 属性字段最大长度
wchar_t
szProperty
[
PROPERTY_MAX_LEN
];
};
struct
WQL_QUERY
{
const
wchar_t
*
szSelect
=
nullptr
;
const
wchar_t
*
szProperty
=
nullptr
;
};
inline
WQL_QUERY
getWQLQuery
(
QueryType
queryType
)
{
switch
(
queryType
)
{
case
DeviceUniqueIdentifier
:
:
MAC_ADDR
:
return
// 网卡当前MAC地址
{
L"SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
,
L"MACAddress"
};
case
DeviceUniqueIdentifier
:
:
MAC_ADDR_REAL
:
return
// 网卡原生MAC地址
{
L"SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
,
L"PNPDeviceID"
};
case
DeviceUniqueIdentifier
:
:
HARDDISK_SERIAL
:
return
// 硬盘序列号
{
L"SELECT * FROM Win32_DiskDrive WHERE (SerialNumber IS NOT NULL) AND (MediaType LIKE 'Fixed hard disk%')"
,
L"SerialNumber"
};
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_UUID
:
return
// 主板序列号
{
L"SELECT * FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)"
,
L"SerialNumber"
};
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_MODEL
:
return
// 主板型号
{
L"SELECT * FROM Win32_BaseBoard WHERE (Product IS NOT NULL)"
,
L"Product"
};
case
DeviceUniqueIdentifier
:
:
CPU_ID
:
return
// 处理器ID
{
L"SELECT * FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)"
,
L"ProcessorId"
};
case
DeviceUniqueIdentifier
:
:
BIOS_SERIAL
:
return
// BIOS序列号
{
L"SELECT * FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)"
,
L"SerialNumber"
};
case
DeviceUniqueIdentifier
:
:
WINDOWS_PRODUCT_ID
:
return
// Windows 产品ID
{
L"SELECT * FROM Win32_OperatingSystem WHERE (SerialNumber IS NOT NULL)"
,
L"SerialNumber"
};
default:
return
{
L""
,
L""
};
}
}
static
BOOL
WMI_DoWithHarddiskSerialNumber
(
wchar_t
*
SerialNumber
,
UINT
uSize
)
{
UINT
iLen
;
UINT
i
;
iLen
=
wcslen
(
SerialNumber
);
if
(
iLen
==
40
)
// InterfaceType = "IDE"
{
// 需要将16进制编码串转换为字符串
wchar_t
ch
,
szBuf
[
32
];
BYTE
b
;
for
(
i
=
0
;
i
<
20
;
i
++
)
{
// 将16进制字符转换为高4位
ch
=
SerialNumber
[
i
*
2
];
if
((
ch
>=
'0'
)
&&
(
ch
<=
'9'
))
{
b
=
ch
-
'0'
;
}
else
if
((
ch
>=
'A'
)
&&
(
ch
<=
'F'
))
{
b
=
ch
-
'A'
+
10
;
}
else
if
((
ch
>=
'a'
)
&&
(
ch
<=
'f'
))
{
b
=
ch
-
'a'
+
10
;
}
else
{
// 非法字符
break
;
}
b
<<=
4
;
// 将16进制字符转换为低4位
ch
=
SerialNumber
[
i
*
2
+
1
];
if
((
ch
>=
'0'
)
&&
(
ch
<=
'9'
))
{
b
+=
ch
-
'0'
;
}
else
if
((
ch
>=
'A'
)
&&
(
ch
<=
'F'
))
{
b
+=
ch
-
'A'
+
10
;
}
else
if
((
ch
>=
'a'
)
&&
(
ch
<=
'f'
))
{
b
+=
ch
-
'a'
+
10
;
}
else
{
// 非法字符
break
;
}
szBuf
[
i
]
=
b
;
}
if
(
i
==
20
)
{
// 转换成功
szBuf
[
i
]
=
L'\0'
;
StringCchCopyW
(
SerialNumber
,
uSize
,
szBuf
);
iLen
=
wcslen
(
SerialNumber
);
}
}
// 每2个字符互换位置
for
(
i
=
0
;
i
<
iLen
;
i
+=
2
)
{
std
::
swap
(
SerialNumber
[
i
],
SerialNumber
[
i
+
1
]);
}
// 去掉空格
std
::
remove
(
SerialNumber
,
SerialNumber
+
wcslen
(
SerialNumber
)
+
1
,
L' '
);
return
TRUE
;
}
// 通过“PNPDeviceID”获取网卡原生MAC地址
static
BOOL
WMI_DoWithPNPDeviceID
(
const
wchar_t
*
PNPDeviceID
,
wchar_t
*
MacAddress
,
UINT
uSize
)
{
wchar_t
DevicePath
[
MAX_PATH
];
HANDLE
hDeviceFile
;
BOOL
isOK
=
FALSE
;
// 生成设备路径名
StringCchCopyW
(
DevicePath
,
MAX_PATH
,
L"
\\\\
.
\\
"
);
StringCchCatW
(
DevicePath
,
MAX_PATH
,
PNPDeviceID
);
// {ad498944-762f-11d0-8dcb-00c04fc3358c} is 'Device Interface Name' for 'Network Card'
StringCchCatW
(
DevicePath
,
MAX_PATH
,
L"#{ad498944-762f-11d0-8dcb-00c04fc3358c}"
);
// 将“PNPDeviceID”中的“/”替换成“#”,以获得真正的设备路径名
std
::
replace
(
DevicePath
+
4
,
DevicePath
+
4
+
wcslen
(
PNPDeviceID
),
(
int
)
L'\\'
,
(
int
)
L'#'
);
// 获取设备句柄
hDeviceFile
=
CreateFileW
(
DevicePath
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
if
(
hDeviceFile
!=
INVALID_HANDLE_VALUE
)
{
ULONG
dwID
;
BYTE
ucData
[
8
];
DWORD
dwByteRet
;
// 获取网卡原生MAC地址
dwID
=
OID_802_3_PERMANENT_ADDRESS
;
isOK
=
DeviceIoControl
(
hDeviceFile
,
IOCTL_NDIS_QUERY_GLOBAL_STATS
,
&
dwID
,
sizeof
(
dwID
),
ucData
,
sizeof
(
ucData
),
&
dwByteRet
,
NULL
);
if
(
isOK
)
{
// 将字节数组转换成16进制字符串
for
(
DWORD
i
=
0
;
i
<
dwByteRet
;
i
++
)
{
StringCchPrintfW
(
MacAddress
+
(
i
<<
1
),
uSize
-
(
i
<<
1
),
L"%02X"
,
ucData
[
i
]);
}
MacAddress
[
dwByteRet
<<
1
]
=
L'\0'
;
// 写入字符串结束标记
}
CloseHandle
(
hDeviceFile
);
}
return
isOK
;
}
static
BOOL
WMI_DoWithProperty
(
QueryType
queryType
,
wchar_t
*
szProperty
,
UINT
uSize
)
{
BOOL
isOK
=
TRUE
;
switch
(
queryType
)
{
case
MAC_ADDR_REAL
:
// 网卡原生MAC地址
isOK
=
WMI_DoWithPNPDeviceID
(
szProperty
,
szProperty
,
uSize
);
break
;
case
HARDDISK_SERIAL
:
// 硬盘序列号
isOK
=
WMI_DoWithHarddiskSerialNumber
(
szProperty
,
uSize
);
break
;
case
MAC_ADDR
:
// 网卡当前MAC地址
// 去掉冒号
std
::
remove
(
szProperty
,
szProperty
+
wcslen
(
szProperty
)
+
1
,
L':'
);
break
;
default:
// 去掉空格
std
::
remove
(
szProperty
,
szProperty
+
wcslen
(
szProperty
)
+
1
,
L' '
);
}
return
isOK
;
}
std
::
wstring
getMachineGUID
()
{
std
::
wstring
res
;
/*using namespace winreg;
try {
RegKey key;
key.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography");
res = key.GetStringValue(L"MachineGuid");
} catch (RegException& e) {
res = utf8::a2w(e.what());
} catch (std::exception& e) {
res = utf8::a2w(e.what());
} */
try
{
std
::
wstring
key
=
L"SOFTWARE
\\
Microsoft
\\
Cryptography"
;
std
::
wstring
name
=
L"MachineGuid"
;
HKEY
hKey
;
if
(
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
key
.
c_str
(),
0
,
KEY_READ
|
KEY_WOW64_64KEY
,
&
hKey
)
!=
ERROR_SUCCESS
)
throw
std
::
runtime_error
(
"Could not open registry key"
);
DWORD
type
;
DWORD
cbData
;
if
(
RegQueryValueExW
(
hKey
,
name
.
c_str
(),
NULL
,
&
type
,
NULL
,
&
cbData
)
!=
ERROR_SUCCESS
)
{
RegCloseKey
(
hKey
);
throw
std
::
runtime_error
(
"Could not read registry value"
);
}
if
(
type
!=
REG_SZ
)
{
RegCloseKey
(
hKey
);
throw
"Incorrect registry value type"
;
}
std
::
wstring
value
(
cbData
/
sizeof
(
wchar_t
),
L'\0'
);
if
(
RegQueryValueExW
(
hKey
,
name
.
c_str
(),
NULL
,
NULL
,
reinterpret_cast
<
LPBYTE
>
(
&
value
[
0
]),
&
cbData
)
!=
ERROR_SUCCESS
)
{
RegCloseKey
(
hKey
);
throw
"Could not read registry value"
;
}
res
=
value
;
RegCloseKey
(
hKey
);
}
catch
(
std
::
runtime_error
&
e
)
{
res
=
utf8
::
a2w
(
e
.
what
());
}
return
res
;
}
}
// end of namespace detail
bool
query
(
size_t
queryTypes
,
std
::
vector
<
std
::
wstring
>&
results
)
{
std
::
vector
<
QueryType
>
vec
;
if
(
queryTypes
&
MAC_ADDR
)
{
vec
.
push_back
(
MAC_ADDR
);
}
if
(
queryTypes
&
MAC_ADDR_REAL
)
{
vec
.
push_back
(
MAC_ADDR_REAL
);
}
if
(
queryTypes
&
HARDDISK_SERIAL
)
{
vec
.
push_back
(
HARDDISK_SERIAL
);
}
if
(
queryTypes
&
MOTHERBOARD_UUID
)
{
vec
.
push_back
(
MOTHERBOARD_UUID
);
}
if
(
queryTypes
&
MOTHERBOARD_MODEL
)
{
vec
.
push_back
(
MOTHERBOARD_MODEL
);
}
if
(
queryTypes
&
CPU_ID
)
{
vec
.
push_back
(
CPU_ID
);
}
if
(
queryTypes
&
BIOS_SERIAL
)
{
vec
.
push_back
(
BIOS_SERIAL
);
}
if
(
queryTypes
&
WINDOWS_PRODUCT_ID
)
{
vec
.
push_back
(
WINDOWS_PRODUCT_ID
);
}
auto
ok
=
query
(
vec
,
results
);
if
(
queryTypes
&
WINDOWS_MACHINE_GUID
)
{
results
.
push_back
(
detail
::
getMachineGUID
());
}
return
ok
;
}
// 基于Windows Management Instrumentation(Windows管理规范)
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
std
::
vector
<
std
::
wstring
>&
results
)
{
bool
ok
=
false
;
// 初始化COM
HRESULT
hres
=
CoInitializeEx
(
NULL
,
COINIT_MULTITHREADED
);
if
(
FAILED
(
hres
))
{
return
false
;
}
// 设置COM的安全认证级别
hres
=
CoInitializeSecurity
(
NULL
,
-
1
,
NULL
,
NULL
,
RPC_C_AUTHN_LEVEL_DEFAULT
,
RPC_C_IMP_LEVEL_IMPERSONATE
,
NULL
,
EOAC_NONE
,
NULL
);
if
(
FAILED
(
hres
))
{
CoUninitialize
();
return
false
;
}
// 获得WMI连接COM接口
IWbemLocator
*
pLoc
=
NULL
;
hres
=
CoCreateInstance
(
CLSID_WbemLocator
,
NULL
,
CLSCTX_INPROC_SERVER
,
IID_IWbemLocator
,
reinterpret_cast
<
LPVOID
*>
(
&
pLoc
)
);
if
(
FAILED
(
hres
))
{
CoUninitialize
();
return
false
;
}
// 通过连接接口连接WMI的内核对象名"ROOT//CIMV2"
IWbemServices
*
pSvc
=
NULL
;
hres
=
pLoc
->
ConnectServer
(
_bstr_t
(
L"ROOT
\\
CIMV2"
),
NULL
,
NULL
,
NULL
,
0
,
NULL
,
NULL
,
&
pSvc
);
if
(
FAILED
(
hres
))
{
_com_error
e
(
hres
);
e
.
ErrorMessage
();
pLoc
->
Release
();
CoUninitialize
();
return
false
;
}
// 设置请求代理的安全级别
hres
=
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
(
hres
))
{
pSvc
->
Release
();
pLoc
->
Release
();
CoUninitialize
();
return
false
;
}
for
(
auto
queryType
:
queryTypes
)
{
auto
query
=
detail
::
getWQLQuery
(
queryType
);
// 通过请求代理来向WMI发送请求
IEnumWbemClassObject
*
pEnumerator
=
NULL
;
hres
=
pSvc
->
ExecQuery
(
bstr_t
(
"WQL"
),
bstr_t
(
query
.
szSelect
),
WBEM_FLAG_FORWARD_ONLY
|
WBEM_FLAG_RETURN_IMMEDIATELY
,
NULL
,
&
pEnumerator
);
if
(
FAILED
(
hres
))
{
pSvc
->
Release
();
pLoc
->
Release
();
CoUninitialize
();
continue
;
}
// 循环枚举所有的结果对象
while
(
pEnumerator
)
{
IWbemClassObject
*
pclsObj
=
NULL
;
ULONG
uReturn
=
0
;
pEnumerator
->
Next
(
WBEM_INFINITE
,
1
,
&
pclsObj
,
&
uReturn
);
if
(
uReturn
==
0
)
{
break
;
}
// 获取属性值
{
VARIANT
vtProperty
;
VariantInit
(
&
vtProperty
);
pclsObj
->
Get
(
query
.
szProperty
,
0
,
&
vtProperty
,
NULL
,
NULL
);
detail
::
DeviceProperty
deviceProperty
{};
StringCchCopyW
(
deviceProperty
.
szProperty
,
detail
::
DeviceProperty
::
PROPERTY_MAX_LEN
,
vtProperty
.
bstrVal
);
VariantClear
(
&
vtProperty
);
// 对属性值做进一步的处理
if
(
detail
::
WMI_DoWithProperty
(
queryType
,
deviceProperty
.
szProperty
,
detail
::
DeviceProperty
::
PROPERTY_MAX_LEN
))
{
results
.
push_back
(
deviceProperty
.
szProperty
);
ok
=
true
;
pclsObj
->
Release
();
break
;
}
}
pclsObj
->
Release
();
}
// End While
// 释放资源
pEnumerator
->
Release
();
}
pSvc
->
Release
();
pLoc
->
Release
();
CoUninitialize
();
return
ok
;
}
std
::
wstring
join_result
(
const
std
::
vector
<
std
::
wstring
>&
results
,
const
std
::
wstring
&
conjunction
)
{
std
::
wstring
result
;
auto
itBegin
=
results
.
cbegin
();
auto
itEnd
=
results
.
cend
();
if
(
itBegin
!=
itEnd
)
{
result
=
*
itBegin
++
;
}
for
(;
itBegin
!=
itEnd
;
itBegin
++
)
{
result
+=
conjunction
;
result
+=
*
itBegin
;
}
return
result
;
}
}
}
}
jlib/win32/DeviceUniqueIdentifier.h
View file @
d2da3411
#
pragma
once
#include <string>
#include <vector>
namespace
jlib
{
namespace
win32
{
namespace
DeviceUniqueIdentifier
{
#include "wmi.h"
#include <ntddndis.h> // OID_802_3_PERMANENT_ADDRESS ...
#include <strsafe.h> // StringCch
#include <unordered_map>
#include <algorithm>
#include "../utf8.h"
namespace
jlib
{
namespace
win32
{
namespace
DeviceUniqueIdentifier
{
/*
参考1:
...
...
@@ -48,8 +48,9 @@ enum QueryType : size_t {
更换硬盘后设备ID也必须随之改变, 不然也会影响授权等应用。
因此,很多授权软件没有考虑使用硬盘序列号。
而且,不一定所有的电脑都能获取到硬盘序列号。
因此,采用bootable(唯一)硬盘作为标识
*/
HARDDISK_SERIAL
=
1
<<
2
,
BOOTABLE_
HARDDISK_SERIAL
=
1
<<
2
,
//! 主板序列号
/*
...
...
@@ -100,29 +101,47 @@ enum QueryType : size_t {
WINDOWS_MACHINE_GUID
=
1
<<
8
,
};
static
const
wchar_t
*
queryTypeString
(
QueryType
type
)
{
switch
(
type
)
{
case
QueryType
:
:
MAC_ADDR
:
return
L"MAC_ADDR "
;
case
QueryType
:
:
MAC_ADDR_REAL
:
return
L"MAC_ADDR_REAL "
;
case
QueryType
:
:
BOOTABLE_HARDDISK_SERIAL
:
return
L"BOOTABLE_HARDDISK_SERIAL"
;
case
QueryType
:
:
MOTHERBOARD_UUID
:
return
L"MOTHERBOARD_UUID "
;
case
QueryType
:
:
MOTHERBOARD_MODEL
:
return
L"MOTHERBOARD_MODEL "
;
case
QueryType
:
:
CPU_ID
:
return
L"CPU_ID "
;
case
QueryType
:
:
BIOS_SERIAL
:
return
L"BIOS_SERIAL "
;
case
QueryType
:
:
WINDOWS_PRODUCT_ID
:
return
L"WINDOWS_PRODUCT_ID "
;
case
QueryType
:
:
WINDOWS_MACHINE_GUID
:
return
L"WINDOWS_MACHINE_GUID "
;
default:
return
L"UNKNOWN QueryType "
;
}
}
enum
{
RecommendedQueryTypes
=
WINDOWS_MACHINE_GUID
|
WINDOWS_PRODUCT_ID
|
BIOS_SERIAL
|
CPU_ID
|
MOTHERBOARD_MODEL
RecommendedQueryTypes
=
BOOTABLE_HARDDISK_SERIAL
|
MOTHERBOARD_UUID
|
MOTHERBOARD_MODEL
|
CPU_ID
|
BIOS_SERIAL
|
WINDOWS_PRODUCT_ID
|
WINDOWS_MACHINE_GUID
,
AllQueryTypes
=
RecommendedQueryTypes
|
HARDDISK_SERIAL
|
MAC_ADDR_REAL
|
MAC_ADDR
,
};
typedef
std
::
unordered_map
<
QueryType
,
std
::
wstring
>
QueryResults
;
/**
* @brief 查询信息
* @param[in] queryTypes QueryType集合
* @param[in,out] results 查询结果集合
* @return 成功或失败
*/
bool
query
(
size_t
queryTypes
,
std
::
vector
<
std
::
wstring
>
&
results
);
static
bool
query
(
size_t
queryTypes
,
QueryResults
&
results
);
/**
* @brief 查询信息
...
...
@@ -130,7 +149,7 @@ bool query(size_t queryTypes, std::vector<std::wstring>& results);
* @param[in,out] results 查询结果集合
* @return 成功或失败
*/
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
std
::
vector
<
std
::
wstring
>
&
results
);
static
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
QueryResults
&
results
);
/**
* @brief 连接查询结果为一个字符串
...
...
@@ -138,8 +157,256 @@ bool query(const std::vector<QueryType>& queryTypes, std::vector<std::wstring>&
* @param[in,out] conjunction 连词
* @return 将结果以连词连接起来组成的字符串
*/
std
::
wstring
join_result
(
const
std
::
vector
<
std
::
wstring
>&
results
,
const
std
::
wstring
&
conjunction
);
static
std
::
wstring
join_result
(
const
QueryResults
&
results
,
const
std
::
wstring
&
conjunction
);
// Implementation
namespace
detail
{
inline
const
wchar_t
*
getWQLQuery
(
QueryType
queryType
)
{
switch
(
queryType
)
{
case
DeviceUniqueIdentifier
:
:
MAC_ADDR
:
return
// 网卡当前MAC地址
L"SELECT MACAddress FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
;
case
DeviceUniqueIdentifier
:
:
MAC_ADDR_REAL
:
return
// 网卡原生MAC地址
L"SELECT PNPDeviceID FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
;
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_UUID
:
return
// 主板序列号
L"SELECT SerialNumber FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_MODEL
:
return
// 主板型号
L"SELECT Product FROM Win32_BaseBoard WHERE (Product IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
CPU_ID
:
return
// 处理器ID
L"SELECT ProcessorId FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
BIOS_SERIAL
:
return
// BIOS序列号
L"SELECT SerialNumber FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
WINDOWS_PRODUCT_ID
:
return
// Windows 产品ID
L"SELECT SerialNumber FROM Win32_OperatingSystem WHERE (SerialNumber IS NOT NULL)"
;
case
WINDOWS_MACHINE_GUID
:
return
// 系统UUID
L"SELECT UUID FROM Win32_ComputerSystemProduct"
;
break
;
default
:
return
L""
;
}
}
// 通过“PNPDeviceID”获取网卡原生MAC地址
static
BOOL
parsePNPDeviceID
(
const
wchar_t
*
PNPDeviceID
,
std
::
wstring
&
macAddress
)
{
wchar_t
DevicePath
[
MAX_PATH
];
HANDLE
hDeviceFile
;
BOOL
isOK
=
FALSE
;
// 生成设备路径名
StringCchCopyW
(
DevicePath
,
MAX_PATH
,
L"
\\\\
.
\\
"
);
StringCchCatW
(
DevicePath
,
MAX_PATH
,
PNPDeviceID
);
// {ad498944-762f-11d0-8dcb-00c04fc3358c} is 'Device Interface Name' for 'Network Card'
StringCchCatW
(
DevicePath
,
MAX_PATH
,
L"#{ad498944-762f-11d0-8dcb-00c04fc3358c}"
);
// 将“PNPDeviceID”中的“/”替换成“#”,以获得真正的设备路径名
std
::
replace
(
DevicePath
+
4
,
DevicePath
+
4
+
wcslen
(
PNPDeviceID
),
(
int
)
L'\\'
,
(
int
)
L'#'
);
// 获取设备句柄
hDeviceFile
=
CreateFileW
(
DevicePath
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
if
(
hDeviceFile
!=
INVALID_HANDLE_VALUE
)
{
ULONG
dwID
;
BYTE
ucData
[
8
];
DWORD
dwByteRet
;
// 获取网卡原生MAC地址
dwID
=
OID_802_3_PERMANENT_ADDRESS
;
isOK
=
DeviceIoControl
(
hDeviceFile
,
IOCTL_NDIS_QUERY_GLOBAL_STATS
,
&
dwID
,
sizeof
(
dwID
),
ucData
,
sizeof
(
ucData
),
&
dwByteRet
,
NULL
);
if
(
isOK
)
{
// 将字节数组转换成16进制字符串
macAddress
.
clear
();
for
(
DWORD
i
=
0
;
i
<
dwByteRet
;
i
++
)
{
wchar_t
tmp
[
4
];
swprintf_s
(
tmp
,
4
,
i
==
dwByteRet
-
1
?
L"%02X"
:
L"%02X:"
,
ucData
[
i
]);
macAddress
+=
tmp
;
}
}
CloseHandle
(
hDeviceFile
);
}
return
isOK
;
}
static
std
::
wstring
getMachineGUID
()
{
std
::
wstring
res
;
try
{
std
::
wstring
key
=
L"SOFTWARE
\\
Microsoft
\\
Cryptography"
;
std
::
wstring
name
=
L"MachineGuid"
;
HKEY
hKey
;
if
(
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
key
.
c_str
(),
0
,
KEY_READ
|
KEY_WOW64_64KEY
,
&
hKey
)
!=
ERROR_SUCCESS
)
throw
std
::
runtime_error
(
"Could not open registry key"
);
DWORD
type
;
DWORD
cbData
;
if
(
RegQueryValueExW
(
hKey
,
name
.
c_str
(),
NULL
,
&
type
,
NULL
,
&
cbData
)
!=
ERROR_SUCCESS
)
{
RegCloseKey
(
hKey
);
throw
std
::
runtime_error
(
"Could not read registry value"
);
}
if
(
type
!=
REG_SZ
)
{
RegCloseKey
(
hKey
);
throw
"Incorrect registry value type"
;
}
std
::
wstring
value
(
cbData
/
sizeof
(
wchar_t
),
L'\0'
);
if
(
RegQueryValueExW
(
hKey
,
name
.
c_str
(),
NULL
,
NULL
,
reinterpret_cast
<
LPBYTE
>
(
&
value
[
0
]),
&
cbData
)
!=
ERROR_SUCCESS
)
{
RegCloseKey
(
hKey
);
throw
"Could not read registry value"
;
}
if
(
value
.
back
()
==
L'\0'
)
{
value
.
erase
(
value
.
size
()
-
1
,
1
);
}
res
=
value
;
RegCloseKey
(
hKey
);
}
catch
(
std
::
runtime_error
&
e
)
{
res
=
utf8
::
a2w
(
e
.
what
());
}
return
res
;
}
}
// namespace detail
static
bool
query
(
size_t
queryTypes
,
QueryResults
&
results
)
{
std
::
vector
<
QueryType
>
vec
;
if
(
queryTypes
&
MAC_ADDR
)
{
vec
.
push_back
(
MAC_ADDR
);
}
if
(
queryTypes
&
MAC_ADDR_REAL
)
{
vec
.
push_back
(
MAC_ADDR_REAL
);
}
if
(
queryTypes
&
BOOTABLE_HARDDISK_SERIAL
)
{
vec
.
push_back
(
BOOTABLE_HARDDISK_SERIAL
);
}
if
(
queryTypes
&
MOTHERBOARD_UUID
)
{
vec
.
push_back
(
MOTHERBOARD_UUID
);
}
if
(
queryTypes
&
MOTHERBOARD_MODEL
)
{
vec
.
push_back
(
MOTHERBOARD_MODEL
);
}
if
(
queryTypes
&
CPU_ID
)
{
vec
.
push_back
(
CPU_ID
);
}
if
(
queryTypes
&
BIOS_SERIAL
)
{
vec
.
push_back
(
BIOS_SERIAL
);
}
if
(
queryTypes
&
WINDOWS_PRODUCT_ID
)
{
vec
.
push_back
(
WINDOWS_PRODUCT_ID
);
}
auto
ok
=
query
(
vec
,
results
);
return
ok
;
}
static
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
QueryResults
&
results
)
{
std
::
vector
<
std
::
wstring
>
values
,
errors
;
auto
output
=
[
&
values
](
const
std
::
wstring
&
key
,
const
std
::
wstring
&
value
)
{
values
.
push_back
(
value
);
};
auto
error
=
[
&
errors
](
HRESULT
hr
,
const
std
::
wstring
&
msg
)
{
errors
.
push_back
(
msg
);
};
wmi
::
WmiBase
wmi
(
L"ROOT
\\
CIMV2"
,
output
,
error
);
if
(
!
wmi
.
prepare
())
{
return
false
;
}
for
(
auto
queryType
:
queryTypes
)
{
/*if (queryType == WINDOWS_MACHINE_GUID) {
results[WINDOWS_MACHINE_GUID] = (detail::getMachineGUID());
continue;
} else */
if
(
queryType
==
BOOTABLE_HARDDISK_SERIAL
)
{
auto
sz
=
values
.
size
();
if
(
wmi
.
execute
(
L"SELECT DiskIndex FROM Win32_DiskPartition WHERE Bootable = TRUE"
)
&&
values
.
size
()
==
sz
+
1
)
{
auto
index
=
values
.
back
();
values
.
pop_back
();
if
(
wmi
.
execute
(
L"SELECT SerialNumber FROM Win32_DiskDrive WHERE Index = "
+
index
))
{
results
[
queryType
]
=
values
.
back
();
values
.
pop_back
();
continue
;
}
}
}
else
{
auto
wql
=
detail
::
getWQLQuery
(
queryType
);
auto
sz
=
values
.
size
();
if
(
wmi
.
execute
(
wql
)
&&
values
.
size
()
>
sz
)
{
if
(
queryType
==
MAC_ADDR_REAL
)
{
auto
value
=
values
.
back
();
values
.
pop_back
();
if
(
detail
::
parsePNPDeviceID
(
value
.
data
(),
value
))
{
results
[
queryType
]
=
value
;
}
while
(
values
.
size
()
>
sz
)
{
value
=
values
.
back
();
values
.
pop_back
();
if
(
detail
::
parsePNPDeviceID
(
value
.
data
(),
value
))
{
results
[
queryType
]
+=
L"|"
+
value
;
}
}
}
else
{
results
[
queryType
]
=
values
.
back
();
values
.
pop_back
();
while
(
values
.
size
()
>
sz
)
{
results
[
queryType
]
+=
L"|"
+
values
.
back
();
values
.
pop_back
();
}
}
continue
;
}
}
// error
if
(
!
errors
.
empty
())
{
results
[
queryType
]
=
errors
.
back
();
errors
.
pop_back
();
}
else
{
results
[
queryType
]
=
std
::
wstring
(
L"Get "
)
+
queryTypeString
(
queryType
)
+
L" failed"
;
}
}
return
true
;
}
static
std
::
wstring
join_result
(
const
QueryResults
&
results
,
const
std
::
wstring
&
conjunction
)
{
std
::
wstring
result
;
auto
itBegin
=
results
.
cbegin
();
auto
itEnd
=
results
.
cend
();
if
(
itBegin
!=
itEnd
)
{
result
=
itBegin
->
second
;
itBegin
++
;
}
for
(;
itBegin
!=
itEnd
;
itBegin
++
)
{
result
+=
conjunction
;
result
+=
itBegin
->
second
;
}
return
result
;
}
}
// namespace DeviceUniqueIdentifier
}
// namespace win32
}
// namespace jlib
jlib/win32/DeviceUniqueIdentifierHeaderOnly.h
deleted
100644 → 0
View file @
b657c6e8
#
pragma
once
#include "wmi.h"
#include <atlconv.h>
#include <ntddndis.h>
#include <math.h>
#include <strsafe.h>
#include <unordered_map>
#include <algorithm>
#include "../utf8.h"
#pragma comment (lib, "comsuppw.lib")
#pragma comment (lib, "wbemuuid.lib")
namespace
jlib
{
namespace
win32
{
namespace
DeviceUniqueIdentifier
{
/*
参考1:
《设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识》
http://www.vonwei.com/post/UniqueDeviceIDforWindows.html
参考2:
《通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号》
https://blog.csdn.net/b_h_l/article/details/7764767
*/
enum
QueryType
:
size_t
{
/*
当前网卡MAC
MAC地址可能是最常用的标识方法,但是现在这种方法基本不可靠:
一个电脑可能存在多个网卡,多个MAC地址,
如典型的笔记本可能存在有线、无线、蓝牙等多个MAC地址,
随着不同连接方式的改变,每次MAC地址也会改变。
而且,当安装有虚拟机时,MAC地址会更多。
MAC地址另外一个更加致命的弱点是,MAC地址很容易手动更改。
因此,MAC地址基本不推荐用作设备唯一ID。
*/
MAC_ADDR
=
1
,
/*
当前网卡原生MAC
可以轻易修改网卡MAC,但无法修改原生MAC
*/
MAC_ADDR_REAL
=
1
<<
1
,
/*
硬盘序列号
在Windows系统中通过命令行运行“wmic diskdrive get serialnumber”可以查看。
硬盘序列号作为设备唯一ID存在的问题是,很多机器可能存在多块硬盘,
特别是服务器,而且机器更换硬盘是很可能发生的事情,
更换硬盘后设备ID也必须随之改变, 不然也会影响授权等应用。
因此,很多授权软件没有考虑使用硬盘序列号。
而且,不一定所有的电脑都能获取到硬盘序列号。
因此,采用bootable(唯一)硬盘作为标识
*/
BOOTABLE_HARDDISK_SERIAL
=
1
<<
2
,
//! 主板序列号
/*
在Windows系统中通过命令行运行“wmic csproduct get UUID”可以查看。
主板UUID是很多授权方法和微软官方都比较推崇的方法,
即便重装系统UUID应该也不会变
(笔者没有实测重装,不过在一台机器上安装双系统,获取的主板UUID是一样的,
双系统一个windows一个Linux,Linux下用“dmidecode -s system-uuid”命令可以获取UUID)。
但是这个方法也有缺陷,因为不是所有的厂商都提供一个UUID,
当这种情况发生时,wmic会返回“FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF”,
即一个无效的UUID。
*/
MOTHERBOARD_UUID
=
1
<<
3
,
//! 主板型号
MOTHERBOARD_MODEL
=
1
<<
4
,
/*
CPU ID
在Windows系统中通过命令行运行“wmic cpu get processorid”就可以查看CPU ID。
目前CPU ID也无法唯一标识设备,Intel现在可能同一批次的CPU ID都一样,不再提供唯一的ID。
而且经过实际测试,新购买的同一批次PC的CPU ID很可能一样。
这样作为设备的唯一标识就会存在问题。
*/
CPU_ID
=
1
<<
5
,
//! BIOS序列号
BIOS_SERIAL
=
1
<<
6
,
/*
Windows 产品ID
在“控制面板\系统和安全\系统”的最下面就可以看到激活的Windows产品ID信息,
另外通过注册表“HKEY_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion”也可以看到看到“ProductId”字段。
不过这个产品ID并不唯一,不同系统或者机器重复的概率也比较大。
虚拟机中克隆的系统,使用同一个镜像安装激活的系统,其产品ID就可能一模一样。
经过实测,笔者在两台Thinkpad笔记本上发现其ProductId完全一样。
*/
WINDOWS_PRODUCT_ID
=
1
<<
7
,
/*
Windows MachineGUID
Windows安装时会唯一生成一个GUID,
可以在注册表“HKEY_MACHINE\SOFTWARE\Microsoft\Cryptography”中查看其“MachineGuid”字段。
这个ID作为Windows系统设备的唯一标识不错,不过值得注意的一点是,与硬件ID不一样,
这个ID在重装Windows系统后应该不一样了。
这样授权软件在重装系统后,可能就需要用户重新购买授权。
*/
WINDOWS_MACHINE_GUID
=
1
<<
8
,
};
static
const
wchar_t
*
queryTypeString
(
QueryType
type
)
{
switch
(
type
)
{
case
QueryType
:
:
MAC_ADDR
:
return
L"MAC_ADDR "
;
case
QueryType
:
:
MAC_ADDR_REAL
:
return
L"MAC_ADDR_REAL "
;
case
QueryType
:
:
BOOTABLE_HARDDISK_SERIAL
:
return
L"BOOTABLE_HARDDISK_SERIAL"
;
case
QueryType
:
:
MOTHERBOARD_UUID
:
return
L"MOTHERBOARD_UUID "
;
case
QueryType
:
:
MOTHERBOARD_MODEL
:
return
L"MOTHERBOARD_MODEL "
;
case
QueryType
:
:
CPU_ID
:
return
L"CPU_ID "
;
case
QueryType
:
:
BIOS_SERIAL
:
return
L"BIOS_SERIAL "
;
case
QueryType
:
:
WINDOWS_PRODUCT_ID
:
return
L"WINDOWS_PRODUCT_ID "
;
case
QueryType
:
:
WINDOWS_MACHINE_GUID
:
return
L"WINDOWS_MACHINE_GUID "
;
default:
return
L"UNKNOWN QueryType "
;
}
}
enum
{
RecommendedQueryTypes
=
BOOTABLE_HARDDISK_SERIAL
|
MOTHERBOARD_UUID
|
MOTHERBOARD_MODEL
|
CPU_ID
|
BIOS_SERIAL
|
WINDOWS_PRODUCT_ID
|
WINDOWS_MACHINE_GUID
,
AllQueryTypes
=
RecommendedQueryTypes
|
MAC_ADDR_REAL
|
MAC_ADDR
,
};
typedef
std
::
unordered_map
<
QueryType
,
std
::
wstring
>
QueryResults
;
/**
* @brief 查询信息
* @param[in] queryTypes QueryType集合
* @param[in,out] results 查询结果集合
* @return 成功或失败
*/
static
bool
query
(
size_t
queryTypes
,
QueryResults
&
results
);
/**
* @brief 查询信息
* @param[in] queryTypes QueryType集合
* @param[in,out] results 查询结果集合
* @return 成功或失败
*/
static
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
QueryResults
&
results
);
/**
* @brief 连接查询结果为一个字符串
* @param[in] results 查询结果集合
* @param[in,out] conjunction 连词
* @return 将结果以连词连接起来组成的字符串
*/
static
std
::
wstring
join_result
(
const
QueryResults
&
results
,
const
std
::
wstring
&
conjunction
);
// Implementation
namespace
detail
{
inline
const
wchar_t
*
getWQLQuery
(
QueryType
queryType
)
{
switch
(
queryType
)
{
case
DeviceUniqueIdentifier
:
:
MAC_ADDR
:
return
// 网卡当前MAC地址
L"SELECT MACAddress FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
;
case
DeviceUniqueIdentifier
:
:
MAC_ADDR_REAL
:
return
// 网卡原生MAC地址
L"SELECT PNPDeviceID FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
;
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_UUID
:
return
// 主板序列号
L"SELECT SerialNumber FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_MODEL
:
return
// 主板型号
L"SELECT Product FROM Win32_BaseBoard WHERE (Product IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
CPU_ID
:
return
// 处理器ID
L"SELECT ProcessorId FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
BIOS_SERIAL
:
return
// BIOS序列号
L"SELECT SerialNumber FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)"
;
case
DeviceUniqueIdentifier
:
:
WINDOWS_PRODUCT_ID
:
return
// Windows 产品ID
L"SELECT SerialNumber FROM Win32_OperatingSystem WHERE (SerialNumber IS NOT NULL)"
;
case
WINDOWS_MACHINE_GUID
:
return
// 系统UUID
L"SELECT UUID FROM Win32_ComputerSystemProduct"
;
break
;
default
:
return
L""
;
}
}
// 通过“PNPDeviceID”获取网卡原生MAC地址
static
BOOL
parsePNPDeviceID
(
const
wchar_t
*
PNPDeviceID
,
std
::
wstring
&
macAddress
)
{
wchar_t
DevicePath
[
MAX_PATH
];
HANDLE
hDeviceFile
;
BOOL
isOK
=
FALSE
;
// 生成设备路径名
StringCchCopyW
(
DevicePath
,
MAX_PATH
,
L"
\\\\
.
\\
"
);
StringCchCatW
(
DevicePath
,
MAX_PATH
,
PNPDeviceID
);
// {ad498944-762f-11d0-8dcb-00c04fc3358c} is 'Device Interface Name' for 'Network Card'
StringCchCatW
(
DevicePath
,
MAX_PATH
,
L"#{ad498944-762f-11d0-8dcb-00c04fc3358c}"
);
// 将“PNPDeviceID”中的“/”替换成“#”,以获得真正的设备路径名
std
::
replace
(
DevicePath
+
4
,
DevicePath
+
4
+
wcslen
(
PNPDeviceID
),
(
int
)
L'\\'
,
(
int
)
L'#'
);
// 获取设备句柄
hDeviceFile
=
CreateFileW
(
DevicePath
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
if
(
hDeviceFile
!=
INVALID_HANDLE_VALUE
)
{
ULONG
dwID
;
BYTE
ucData
[
8
];
DWORD
dwByteRet
;
// 获取网卡原生MAC地址
dwID
=
OID_802_3_PERMANENT_ADDRESS
;
isOK
=
DeviceIoControl
(
hDeviceFile
,
IOCTL_NDIS_QUERY_GLOBAL_STATS
,
&
dwID
,
sizeof
(
dwID
),
ucData
,
sizeof
(
ucData
),
&
dwByteRet
,
NULL
);
if
(
isOK
)
{
// 将字节数组转换成16进制字符串
macAddress
.
clear
();
for
(
DWORD
i
=
0
;
i
<
dwByteRet
;
i
++
)
{
wchar_t
tmp
[
4
];
swprintf_s
(
tmp
,
4
,
i
==
dwByteRet
-
1
?
L"%02X"
:
L"%02X:"
,
ucData
[
i
]);
macAddress
+=
tmp
;
}
}
CloseHandle
(
hDeviceFile
);
}
return
isOK
;
}
static
std
::
wstring
getMachineGUID
()
{
std
::
wstring
res
;
try
{
std
::
wstring
key
=
L"SOFTWARE
\\
Microsoft
\\
Cryptography"
;
std
::
wstring
name
=
L"MachineGuid"
;
HKEY
hKey
;
if
(
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
key
.
c_str
(),
0
,
KEY_READ
|
KEY_WOW64_64KEY
,
&
hKey
)
!=
ERROR_SUCCESS
)
throw
std
::
runtime_error
(
"Could not open registry key"
);
DWORD
type
;
DWORD
cbData
;
if
(
RegQueryValueExW
(
hKey
,
name
.
c_str
(),
NULL
,
&
type
,
NULL
,
&
cbData
)
!=
ERROR_SUCCESS
)
{
RegCloseKey
(
hKey
);
throw
std
::
runtime_error
(
"Could not read registry value"
);
}
if
(
type
!=
REG_SZ
)
{
RegCloseKey
(
hKey
);
throw
"Incorrect registry value type"
;
}
std
::
wstring
value
(
cbData
/
sizeof
(
wchar_t
),
L'\0'
);
if
(
RegQueryValueExW
(
hKey
,
name
.
c_str
(),
NULL
,
NULL
,
reinterpret_cast
<
LPBYTE
>
(
&
value
[
0
]),
&
cbData
)
!=
ERROR_SUCCESS
)
{
RegCloseKey
(
hKey
);
throw
"Could not read registry value"
;
}
if
(
value
.
back
()
==
L'\0'
)
{
value
.
erase
(
value
.
size
()
-
1
,
1
);
}
res
=
value
;
RegCloseKey
(
hKey
);
}
catch
(
std
::
runtime_error
&
e
)
{
res
=
utf8
::
a2w
(
e
.
what
());
}
return
res
;
}
}
// namespace detail
static
bool
query
(
size_t
queryTypes
,
QueryResults
&
results
)
{
std
::
vector
<
QueryType
>
vec
;
if
(
queryTypes
&
MAC_ADDR
)
{
vec
.
push_back
(
MAC_ADDR
);
}
if
(
queryTypes
&
MAC_ADDR_REAL
)
{
vec
.
push_back
(
MAC_ADDR_REAL
);
}
if
(
queryTypes
&
BOOTABLE_HARDDISK_SERIAL
)
{
vec
.
push_back
(
BOOTABLE_HARDDISK_SERIAL
);
}
if
(
queryTypes
&
MOTHERBOARD_UUID
)
{
vec
.
push_back
(
MOTHERBOARD_UUID
);
}
if
(
queryTypes
&
MOTHERBOARD_MODEL
)
{
vec
.
push_back
(
MOTHERBOARD_MODEL
);
}
if
(
queryTypes
&
CPU_ID
)
{
vec
.
push_back
(
CPU_ID
);
}
if
(
queryTypes
&
BIOS_SERIAL
)
{
vec
.
push_back
(
BIOS_SERIAL
);
}
if
(
queryTypes
&
WINDOWS_PRODUCT_ID
)
{
vec
.
push_back
(
WINDOWS_PRODUCT_ID
);
}
auto
ok
=
query
(
vec
,
results
);
return
ok
;
}
static
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
QueryResults
&
results
)
{
std
::
vector
<
std
::
wstring
>
values
,
errors
;
auto
output
=
[
&
values
](
const
std
::
wstring
&
key
,
const
std
::
wstring
&
value
)
{
values
.
push_back
(
value
);
};
auto
error
=
[
&
errors
](
HRESULT
hr
,
const
std
::
wstring
&
msg
)
{
errors
.
push_back
(
msg
);
};
wmi
::
WmiBase
wmi
(
L"ROOT
\\
CIMV2"
,
output
,
error
);
wmi
.
prepare
();
for
(
auto
queryType
:
queryTypes
)
{
/*if (queryType == WINDOWS_MACHINE_GUID) {
results[WINDOWS_MACHINE_GUID] = (detail::getMachineGUID());
continue;
} else */
if
(
queryType
==
BOOTABLE_HARDDISK_SERIAL
)
{
auto
sz
=
values
.
size
();
if
(
wmi
.
execute
(
L"SELECT DiskIndex FROM Win32_DiskPartition WHERE Bootable = TRUE"
)
&&
values
.
size
()
==
sz
+
1
)
{
auto
index
=
values
.
back
();
values
.
pop_back
();
if
(
wmi
.
execute
(
L"SELECT SerialNumber FROM Win32_DiskDrive WHERE Index = "
+
index
))
{
results
[
queryType
]
=
values
.
back
();
values
.
pop_back
();
continue
;
}
}
}
else
{
auto
wql
=
detail
::
getWQLQuery
(
queryType
);
auto
sz
=
values
.
size
();
if
(
wmi
.
execute
(
wql
)
&&
values
.
size
()
>
sz
)
{
if
(
queryType
==
MAC_ADDR_REAL
)
{
auto
value
=
values
.
back
();
values
.
pop_back
();
if
(
detail
::
parsePNPDeviceID
(
value
.
data
(),
value
))
{
results
[
queryType
]
=
value
;
}
while
(
values
.
size
()
>
sz
)
{
value
=
values
.
back
();
values
.
pop_back
();
if
(
detail
::
parsePNPDeviceID
(
value
.
data
(),
value
))
{
results
[
queryType
]
+=
L"|"
+
value
;
}
}
}
else
{
results
[
queryType
]
=
values
.
back
();
values
.
pop_back
();
while
(
values
.
size
()
>
sz
)
{
results
[
queryType
]
+=
L"|"
+
values
.
back
();
values
.
pop_back
();
}
}
continue
;
}
}
// error
if
(
!
errors
.
empty
())
{
results
[
queryType
]
=
errors
.
back
();
errors
.
pop_back
();
}
else
{
results
[
queryType
]
=
std
::
wstring
(
L"Get "
)
+
queryTypeString
(
queryType
)
+
L" failed"
;
}
}
return
true
;
}
static
std
::
wstring
join_result
(
const
QueryResults
&
results
,
const
std
::
wstring
&
conjunction
)
{
std
::
wstring
result
;
auto
itBegin
=
results
.
cbegin
();
auto
itEnd
=
results
.
cend
();
if
(
itBegin
!=
itEnd
)
{
result
=
itBegin
->
second
;
itBegin
++
;
}
for
(;
itBegin
!=
itEnd
;
itBegin
++
)
{
result
+=
conjunction
;
result
+=
itBegin
->
second
;
}
return
result
;
}
}
// namespace DeviceUniqueIdentifier
}
// namespace win32
}
// namespace jlib
jlib/win32/wmi.h
View file @
d2da3411
#
pragma
once
/**
* 主要参考了 https://blog.csdn.net/breaksoftware/article/category/9269057
*/
#include <Windows.h>
#include <comdef.h>
#include <WbemIdl.h>
#include <atlbase.h>
#include <atlcom.h>
#include <comdef.h>
#include <string>
#include <functional>
#pragma comment (lib, "comsuppw.lib")
#pragma comment (lib, "wbemuuid.lib")
#if !defined(UNICODE) && !defined(_UNICODE)
#error wmi only works with unicode!
#endif
#define JLIB_CHECK_HR(hr) if (FAILED(hr)) break;
#define JLIB_CHECK_HR2(hr, errorFunc) if (FAILED(hr)) { if (errorFunc) { errorFunc(hr, _com_error(hr).ErrorMessage()); } break; }
#define JLIB_CHECK_WMI_HR(hr) if ((hr) != WBEM_S_NO_ERROR) break;
...
...
test/test.sln
View file @
d2da3411
...
...
@@ -5,10 +5,6 @@ VisualStudioVersion = 16.0.29209.62
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj", "{155F525A-FA2F-471F-A2DF-9B77E7CCCFA5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDeviceUniqueIdentifierHeaderOnly", "testDeviceUniqueIdentifierHeaderOnly\testDeviceUniqueIdentifierHeaderOnly.vcxproj", "{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDeviceUniqueIdentifier", "testDeviceUniqueIdentifier\testDeviceUniqueIdentifier.vcxproj", "{CA7812A3-9E48-4A94-B39A-32EED587E38A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_win32", "test_win32\test_win32.vcxproj", "{A4B1CDB2-7325-4E22-AD0A-1D2907924CDB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_qt", "test_qt\test_qt.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
...
...
@@ -54,9 +50,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "win32", "win32", "{B5D9E71E-2BFE-4D04-A66A-4CB0A103CD77}"
ProjectSection(SolutionItems) = preProject
..\jlib\win32\clipboard.h = ..\jlib\win32\clipboard.h
..\jlib\win32\DeviceUniqueIdentifier.cpp = ..\jlib\win32\DeviceUniqueIdentifier.cpp
..\jlib\win32\DeviceUniqueIdentifier.h = ..\jlib\win32\DeviceUniqueIdentifier.h
..\jlib\win32\deviceuniqueidentifierheaderonly.h = ..\jlib\win32\deviceuniqueidentifierheaderonly.h
..\jlib\win32\deviceuniqueidentifier.h = ..\jlib\win32\deviceuniqueidentifier.h
..\jlib\win32\file_op.h = ..\jlib\win32\file_op.h
..\jlib\win32\memory_micros.h = ..\jlib\win32\memory_micros.h
..\jlib\win32\MyWSAError.h = ..\jlib\win32\MyWSAError.h
...
...
@@ -223,6 +217,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_clipboard", "test_clip
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_wmi", "test_wmi\test_wmi.vcxproj", "{79A2C0A6-B8BB-406F-A732-C6300A611EC8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDeviceUniqueIdentifier", "testDeviceUniqueIdentifier\testDeviceUniqueIdentifier.vcxproj", "{CA7812A3-9E48-4A94-B39A-32EED587E38A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
...
...
@@ -239,22 +235,6 @@ Global
{155F525A-FA2F-471F-A2DF-9B77E7CCCFA5}.Release|x64.Build.0 = Release|x64
{155F525A-FA2F-471F-A2DF-9B77E7CCCFA5}.Release|x86.ActiveCfg = Release|Win32
{155F525A-FA2F-471F-A2DF-9B77E7CCCFA5}.Release|x86.Build.0 = Release|Win32
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Debug|x64.ActiveCfg = Debug|x64
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Debug|x64.Build.0 = Debug|x64
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Debug|x86.ActiveCfg = Debug|Win32
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Debug|x86.Build.0 = Debug|Win32
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Release|x64.ActiveCfg = Release|x64
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Release|x64.Build.0 = Release|x64
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Release|x86.ActiveCfg = Release|Win32
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}.Release|x86.Build.0 = Release|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x64.ActiveCfg = Debug|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x64.Build.0 = Debug|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x86.ActiveCfg = Debug|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x86.Build.0 = Debug|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x64.ActiveCfg = Release|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x64.Build.0 = Release|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x86.ActiveCfg = Release|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x86.Build.0 = Release|Win32
{A4B1CDB2-7325-4E22-AD0A-1D2907924CDB}.Debug|x64.ActiveCfg = Debug|x64
{A4B1CDB2-7325-4E22-AD0A-1D2907924CDB}.Debug|x64.Build.0 = Debug|x64
{A4B1CDB2-7325-4E22-AD0A-1D2907924CDB}.Debug|x86.ActiveCfg = Debug|Win32
...
...
@@ -341,14 +321,20 @@ Global
{79A2C0A6-B8BB-406F-A732-C6300A611EC8}.Release|x64.Build.0 = Release|x64
{79A2C0A6-B8BB-406F-A732-C6300A611EC8}.Release|x86.ActiveCfg = Release|Win32
{79A2C0A6-B8BB-406F-A732-C6300A611EC8}.Release|x86.Build.0 = Release|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x64.ActiveCfg = Debug|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x64.Build.0 = Debug|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x86.ActiveCfg = Debug|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Debug|x86.Build.0 = Debug|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x64.ActiveCfg = Release|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x64.Build.0 = Release|x64
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x86.ActiveCfg = Release|Win32
{CA7812A3-9E48-4A94-B39A-32EED587E38A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{155F525A-FA2F-471F-A2DF-9B77E7CCCFA5} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{CA7812A3-9E48-4A94-B39A-32EED587E38A} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{A4B1CDB2-7325-4E22-AD0A-1D2907924CDB} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{B12702AD-ABFB-343A-A199-8E24837244A3} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{8A39D7AF-50AF-43BD-8CC6-DA20B6349F03} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
...
...
@@ -380,6 +366,7 @@ Global
{16CAD8DD-EF99-4A38-B5AA-BF86FC7A07AB} = {F118E1C9-F461-4CAA-A0F1-75F5A5C8ADF3}
{904EC99B-A012-4134-AE6F-E21635FB602F} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{79A2C0A6-B8BB-406F-A732-C6300A611EC8} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{CA7812A3-9E48-4A94-B39A-32EED587E38A} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A8EBEA58-739C-4DED-99C0-239779F57D5D}
...
...
test/testDeviceUniqueIdentifier/test.cpp
deleted
100644 → 0
View file @
b657c6e8
#include <jlib/win32/DeviceUniqueIdentifier.h>
#include <stdio.h>
#include <algorithm>
#include <locale>
int
main
()
{
std
::
locale
::
global
(
std
::
locale
(
""
));
using
namespace
jlib
::
DeviceUniqueIdentifier
;
std
::
vector
<
std
::
wstring
>
results
;
/*query(RecommendedQueryTypes, results);
auto str = join_result(results, L"\n");
std::wcout << str << std::endl;*/
results
.
clear
();
query
(
AllQueryTypes
,
results
);
std
::
wstring
str
;
std
::
vector
<
std
::
wstring
>
types
=
{
L"MAC_ADDR 网卡MAC地址"
,
L"MAC_ADDR_REAL 网卡原生MAC地址"
,
L"HARDDISK_SERIAL 主硬盘序列号"
,
L"MOTHERBOARD_UUID 主板序列号"
,
L"MOTHERBOARD_MODEL 主板型号"
,
L"CPU_ID 处理器序列号"
,
L"BIOS_SERIAL BIOS序列号"
,
L"WINDOWS_PRODUCT_ID Windows产品ID"
,
L"WINDOWS_MACHINE_GUID Windows机器码"
,
};
for
(
size_t
i
=
0
;
i
<
std
::
min
(
types
.
size
(),
results
.
size
());
i
++
)
{
printf
(
"%ls:
\n
%ls
\n\n
"
,
types
[
i
].
c_str
(),
results
[
i
].
c_str
());
}
//auto str = join_result(results, L"\n");
//std::wcout << std::endl << str << std::endl;
system
(
"pause"
);
}
\ No newline at end of file
test/testDeviceUniqueIdentifier
HeaderOnly/testDeviceUniqueIdentifierHeaderOnly
.cpp
→
test/testDeviceUniqueIdentifier
/testDeviceUniqueIdentifier
.cpp
View file @
d2da3411
#include <jlib/win32/DeviceUniqueIdentifier
HeaderOnly
.h>
#include <jlib/win32/DeviceUniqueIdentifier.h>
#include <stdio.h>
#include <algorithm>
#include <locale.h>
...
...
test/testDeviceUniqueIdentifier/testDeviceUniqueIdentifier.vcxproj
View file @
d2da3411
...
...
@@ -29,14 +29,14 @@
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
true
</UseDebugLibraries>
<PlatformToolset>
v142
</PlatformToolset>
<CharacterSet>
MultiByt
e
</CharacterSet>
<CharacterSet>
Unicod
e
</CharacterSet>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Release|Win32'"
Label=
"Configuration"
>
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
false
</UseDebugLibraries>
<PlatformToolset>
v142
</PlatformToolset>
<WholeProgramOptimization>
true
</WholeProgramOptimization>
<CharacterSet>
MultiByt
e
</CharacterSet>
<CharacterSet>
Unicod
e
</CharacterSet>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Debug|x64'"
Label=
"Configuration"
>
<ConfigurationType>
Application
</ConfigurationType>
...
...
@@ -120,11 +120,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile
Include=
"..\..\jlib\win32\DeviceUniqueIdentifier.cpp"
/>
<ClCompile
Include=
"test.cpp"
/>
</ItemGroup>
<ItemGroup>
<ClInclude
Include=
"..\..\jlib\win32\DeviceUniqueIdentifier.h"
/>
<ClCompile
Include=
"testDeviceUniqueIdentifier.cpp"
/>
</ItemGroup>
<Import
Project=
"$(VCTargetsPath)\Microsoft.Cpp.targets"
/>
<ImportGroup
Label=
"ExtensionTargets"
>
...
...
test/testDeviceUniqueIdentifier/testDeviceUniqueIdentifier.vcxproj.filters
View file @
d2da3411
...
...
@@ -15,16 +15,8 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile
Include=
"
..\..\jlib\win32\
DeviceUniqueIdentifier.cpp"
>
<ClCompile
Include=
"
test
DeviceUniqueIdentifier.cpp"
>
<Filter>
Source Files
</Filter>
</ClCompile>
<ClCompile
Include=
"test.cpp"
>
<Filter>
Source Files
</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude
Include=
"..\..\jlib\win32\DeviceUniqueIdentifier.h"
>
<Filter>
Source Files
</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
test/testDeviceUniqueIdentifierHeaderOnly/testDeviceUniqueIdentifierHeaderOnly.vcxproj
deleted
100644 → 0
View file @
b657c6e8
<?xml version="1.0" encoding="utf-8"?>
<Project
DefaultTargets=
"Build"
ToolsVersion=
"15.0"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<ItemGroup
Label=
"ProjectConfigurations"
>
<ProjectConfiguration
Include=
"Debug|Win32"
>
<Configuration>
Debug
</Configuration>
<Platform>
Win32
</Platform>
</ProjectConfiguration>
<ProjectConfiguration
Include=
"Release|Win32"
>
<Configuration>
Release
</Configuration>
<Platform>
Win32
</Platform>
</ProjectConfiguration>
<ProjectConfiguration
Include=
"Debug|x64"
>
<Configuration>
Debug
</Configuration>
<Platform>
x64
</Platform>
</ProjectConfiguration>
<ProjectConfiguration
Include=
"Release|x64"
>
<Configuration>
Release
</Configuration>
<Platform>
x64
</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup
Label=
"Globals"
>
<VCProjectVersion>
15.0
</VCProjectVersion>
<ProjectGuid>
{1E6D1113-2EDE-4E7E-BF17-A3663101C3AE}
</ProjectGuid>
<RootNamespace>
testDeviceUniqueIdentifierHeaderOnly
</RootNamespace>
<WindowsTargetPlatformVersion>
10.0
</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import
Project=
"$(VCTargetsPath)\Microsoft.Cpp.Default.props"
/>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Debug|Win32'"
Label=
"Configuration"
>
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
true
</UseDebugLibraries>
<PlatformToolset>
v142
</PlatformToolset>
<CharacterSet>
Unicode
</CharacterSet>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Release|Win32'"
Label=
"Configuration"
>
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
false
</UseDebugLibraries>
<PlatformToolset>
v142
</PlatformToolset>
<WholeProgramOptimization>
true
</WholeProgramOptimization>
<CharacterSet>
Unicode
</CharacterSet>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Debug|x64'"
Label=
"Configuration"
>
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
true
</UseDebugLibraries>
<PlatformToolset>
v142
</PlatformToolset>
<CharacterSet>
MultiByte
</CharacterSet>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Release|x64'"
Label=
"Configuration"
>
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
false
</UseDebugLibraries>
<PlatformToolset>
v142
</PlatformToolset>
<WholeProgramOptimization>
true
</WholeProgramOptimization>
<CharacterSet>
MultiByte
</CharacterSet>
</PropertyGroup>
<Import
Project=
"$(VCTargetsPath)\Microsoft.Cpp.props"
/>
<ImportGroup
Label=
"ExtensionSettings"
>
</ImportGroup>
<ImportGroup
Label=
"Shared"
>
</ImportGroup>
<ImportGroup
Label=
"PropertySheets"
Condition=
"'$(Configuration)|$(Platform)'=='Debug|Win32'"
>
<Import
Project=
"$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition=
"exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
Label=
"LocalAppDataPlatform"
/>
</ImportGroup>
<ImportGroup
Label=
"PropertySheets"
Condition=
"'$(Configuration)|$(Platform)'=='Release|Win32'"
>
<Import
Project=
"$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition=
"exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
Label=
"LocalAppDataPlatform"
/>
</ImportGroup>
<ImportGroup
Label=
"PropertySheets"
Condition=
"'$(Configuration)|$(Platform)'=='Debug|x64'"
>
<Import
Project=
"$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition=
"exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
Label=
"LocalAppDataPlatform"
/>
</ImportGroup>
<ImportGroup
Label=
"PropertySheets"
Condition=
"'$(Configuration)|$(Platform)'=='Release|x64'"
>
<Import
Project=
"$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition=
"exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
Label=
"LocalAppDataPlatform"
/>
</ImportGroup>
<PropertyGroup
Label=
"UserMacros"
/>
<PropertyGroup
/>
<ItemDefinitionGroup
Condition=
"'$(Configuration)|$(Platform)'=='Release|Win32'"
>
<ClCompile>
<WarningLevel>
Level3
</WarningLevel>
<Optimization>
MaxSpeed
</Optimization>
<FunctionLevelLinking>
true
</FunctionLevelLinking>
<IntrinsicFunctions>
true
</IntrinsicFunctions>
<SDLCheck>
true
</SDLCheck>
<ConformanceMode>
true
</ConformanceMode>
<AdditionalIncludeDirectories>
$(DEVLIBS)/Global;$(BOOST);%(AdditionalIncludeDirectories)
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>
true
</MultiProcessorCompilation>
</ClCompile>
<Link>
<EnableCOMDATFolding>
true
</EnableCOMDATFolding>
<OptimizeReferences>
true
</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup
Condition=
"'$(Configuration)|$(Platform)'=='Debug|Win32'"
>
<ClCompile>
<WarningLevel>
Level3
</WarningLevel>
<Optimization>
Disabled
</Optimization>
<SDLCheck>
true
</SDLCheck>
<ConformanceMode>
true
</ConformanceMode>
<AdditionalIncludeDirectories>
$(DEVLIBS)/jlib;$(BOOST);%(AdditionalIncludeDirectories)
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>
true
</MultiProcessorCompilation>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup
Condition=
"'$(Configuration)|$(Platform)'=='Debug|x64'"
>
<ClCompile>
<WarningLevel>
Level3
</WarningLevel>
<Optimization>
Disabled
</Optimization>
<SDLCheck>
true
</SDLCheck>
<ConformanceMode>
true
</ConformanceMode>
<AdditionalIncludeDirectories>
$(BOOST);$(DEVLIBS)\jlib;%(AdditionalIncludeDirectories)
</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup
Condition=
"'$(Configuration)|$(Platform)'=='Release|x64'"
>
<ClCompile>
<WarningLevel>
Level3
</WarningLevel>
<Optimization>
MaxSpeed
</Optimization>
<FunctionLevelLinking>
true
</FunctionLevelLinking>
<IntrinsicFunctions>
true
</IntrinsicFunctions>
<SDLCheck>
true
</SDLCheck>
<ConformanceMode>
true
</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>
true
</EnableCOMDATFolding>
<OptimizeReferences>
true
</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile
Include=
"testDeviceUniqueIdentifierHeaderOnly.cpp"
/>
</ItemGroup>
<Import
Project=
"$(VCTargetsPath)\Microsoft.Cpp.targets"
/>
<ImportGroup
Label=
"ExtensionTargets"
>
</ImportGroup>
</Project>
\ No newline at end of file
test/testDeviceUniqueIdentifierHeaderOnly/testDeviceUniqueIdentifierHeaderOnly.vcxproj.filters
deleted
100644 → 0
View file @
b657c6e8
<?xml version="1.0" encoding="utf-8"?>
<Project
ToolsVersion=
"4.0"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<ItemGroup>
<Filter
Include=
"Source Files"
>
<UniqueIdentifier>
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}
</UniqueIdentifier>
<Extensions>
cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
</Extensions>
</Filter>
<Filter
Include=
"Header Files"
>
<UniqueIdentifier>
{93995380-89BD-4b04-88EB-625FBE52EBFB}
</UniqueIdentifier>
<Extensions>
h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
</Extensions>
</Filter>
<Filter
Include=
"Resource Files"
>
<UniqueIdentifier>
{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
</UniqueIdentifier>
<Extensions>
rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile
Include=
"testDeviceUniqueIdentifierHeaderOnly.cpp"
>
<Filter>
Source Files
</Filter>
</ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
test/testDeviceUniqueIdentifierHeaderOnly/testDeviceUniqueIdentifierHeaderOnly.vcxproj.user
deleted
100644 → 0
View file @
b657c6e8
<?xml version="1.0" encoding="utf-8"?>
<Project
ToolsVersion=
"15.0"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<PropertyGroup
/>
</Project>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment