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
b657c6e8
Commit
b657c6e8
authored
Sep 30, 2019
by
captainwong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update device unique identifire
parent
bef40403
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
155 additions
and
409 deletions
+155
-409
DeviceUniqueIdentifierHeaderOnly.h
jlib/win32/DeviceUniqueIdentifierHeaderOnly.h
+95
-346
wmi.h
jlib/win32/wmi.h
+60
-63
No files found.
jlib/win32/DeviceUniqueIdentifierHeaderOnly.h
View file @
b657c6e8
#
pragma
once
#
pragma
once
#include <Windows.h>
#include "wmi.h"
#include <winioctl.h>
#include <WbemIdl.h>
#include <ntddndis.h>
#include <comdef.h>
#include <comutil.h>
#include <atlconv.h>
#include <atlconv.h>
#include <ntddndis.h>
#include <math.h>
#include <math.h>
#include <strsafe.h>
#include <strsafe.h>
#include <tchar.h>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_map>
#include <algorithm>
#include <algorithm>
#include "../utf8.h"
#include "../utf8.h"
...
@@ -60,8 +53,9 @@ enum QueryType : size_t {
...
@@ -60,8 +53,9 @@ enum QueryType : size_t {
更换硬盘后设备ID也必须随之改变, 不然也会影响授权等应用。
更换硬盘后设备ID也必须随之改变, 不然也会影响授权等应用。
因此,很多授权软件没有考虑使用硬盘序列号。
因此,很多授权软件没有考虑使用硬盘序列号。
而且,不一定所有的电脑都能获取到硬盘序列号。
而且,不一定所有的电脑都能获取到硬盘序列号。
因此,采用bootable(唯一)硬盘作为标识
*/
*/
HARDDISK_SERIAL
=
1
<<
2
,
BOOTABLE_
HARDDISK_SERIAL
=
1
<<
2
,
//! 主板序列号
//! 主板序列号
/*
/*
...
@@ -117,28 +111,28 @@ static const wchar_t* queryTypeString(QueryType type)
...
@@ -117,28 +111,28 @@ static const wchar_t* queryTypeString(QueryType type)
switch
(
type
)
{
switch
(
type
)
{
case
QueryType
:
:
MAC_ADDR
:
return
L"MAC_ADDR "
;
case
QueryType
:
:
MAC_ADDR
:
return
L"MAC_ADDR "
;
case
QueryType
:
:
MAC_ADDR_REAL
:
return
L"MAC_ADDR_REAL "
;
case
QueryType
:
:
MAC_ADDR_REAL
:
return
L"MAC_ADDR_REAL "
;
case
QueryType
:
:
HARDDISK_SERIAL
:
return
L"HARDDISK_SERIAL
"
;
case
QueryType
:
:
BOOTABLE_HARDDISK_SERIAL
:
return
L"BOOTABLE_HARDDISK_SERIAL
"
;
case
QueryType
:
:
MOTHERBOARD_UUID
:
return
L"MOTHERBOARD_UUID "
;
case
QueryType
:
:
MOTHERBOARD_UUID
:
return
L"MOTHERBOARD_UUID "
;
case
QueryType
:
:
MOTHERBOARD_MODEL
:
return
L"MOTHERBOARD_MODEL "
;
case
QueryType
:
:
MOTHERBOARD_MODEL
:
return
L"MOTHERBOARD_MODEL "
;
case
QueryType
:
:
CPU_ID
:
return
L"CPU_ID "
;
case
QueryType
:
:
CPU_ID
:
return
L"CPU_ID "
;
case
QueryType
:
:
BIOS_SERIAL
:
return
L"BIOS_SERIAL "
;
case
QueryType
:
:
BIOS_SERIAL
:
return
L"BIOS_SERIAL "
;
case
QueryType
:
:
WINDOWS_PRODUCT_ID
:
return
L"WINDOWS_PRODUCT_ID "
;
case
QueryType
:
:
WINDOWS_PRODUCT_ID
:
return
L"WINDOWS_PRODUCT_ID "
;
case
QueryType
:
:
WINDOWS_MACHINE_GUID
:
return
L"WINDOWS_MACHINE_GUID
"
;
case
QueryType
:
:
WINDOWS_MACHINE_GUID
:
return
L"WINDOWS_MACHINE_GUID
"
;
default:
return
L"UNKNOWN QueryType "
;
default:
return
L"UNKNOWN QueryType "
;
}
}
}
}
enum
{
enum
{
RecommendedQueryTypes
=
WINDOWS_MACHINE_GUID
RecommendedQueryTypes
=
BOOTABLE_HARDDISK_SERIAL
|
WINDOWS_PRODUCT_ID
|
BIOS_SERIAL
|
CPU_ID
|
MOTHERBOARD_MODEL
|
MOTHERBOARD_UUID
|
MOTHERBOARD_UUID
|
MOTHERBOARD_MODEL
|
CPU_ID
|
BIOS_SERIAL
|
WINDOWS_PRODUCT_ID
|
WINDOWS_MACHINE_GUID
,
,
AllQueryTypes
=
RecommendedQueryTypes
AllQueryTypes
=
RecommendedQueryTypes
|
HARDDISK_SERIAL
|
MAC_ADDR_REAL
|
MAC_ADDR_REAL
|
MAC_ADDR
|
MAC_ADDR
,
,
...
@@ -176,115 +170,40 @@ static std::wstring join_result(const QueryResults& results, const std::wstring&
...
@@ -176,115 +170,40 @@ static std::wstring join_result(const QueryResults& results, const std::wstring&
namespace
detail
namespace
detail
{
{
struct
DeviceProperty
{
inline
const
wchar_t
*
getWQLQuery
(
QueryType
queryType
)
{
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
)
{
switch
(
queryType
)
{
case
DeviceUniqueIdentifier
:
:
MAC_ADDR
:
case
DeviceUniqueIdentifier
:
:
MAC_ADDR
:
return
// 网卡当前MAC地址
return
// 网卡当前MAC地址
{
L"SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
,
L"SELECT MACAddress FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
;
L"MACAddress"
};
case
DeviceUniqueIdentifier
:
:
MAC_ADDR_REAL
:
case
DeviceUniqueIdentifier
:
:
MAC_ADDR_REAL
:
return
// 网卡原生MAC地址
return
// 网卡原生MAC地址
{
L"SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
,
L"SELECT PNPDeviceID 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
:
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_UUID
:
return
// 主板序列号
return
// 主板序列号
{
L"SELECT * FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)"
,
L"SELECT SerialNumber FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)"
;
L"SerialNumber"
};
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_MODEL
:
case
DeviceUniqueIdentifier
:
:
MOTHERBOARD_MODEL
:
return
// 主板型号
return
// 主板型号
{
L"SELECT * FROM Win32_BaseBoard WHERE (Product IS NOT NULL)"
,
L"SELECT Product FROM Win32_BaseBoard WHERE (Product IS NOT NULL)"
;
L"Product"
};
case
DeviceUniqueIdentifier
:
:
CPU_ID
:
case
DeviceUniqueIdentifier
:
:
CPU_ID
:
return
// 处理器ID
return
// 处理器ID
{
L"SELECT * FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)"
,
L"SELECT ProcessorId FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)"
;
L"ProcessorId"
};
case
DeviceUniqueIdentifier
:
:
BIOS_SERIAL
:
case
DeviceUniqueIdentifier
:
:
BIOS_SERIAL
:
return
// BIOS序列号
return
// BIOS序列号
{
L"SELECT * FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)"
,
L"SELECT SerialNumber FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)"
;
L"SerialNumber"
};
case
DeviceUniqueIdentifier
:
:
WINDOWS_PRODUCT_ID
:
case
DeviceUniqueIdentifier
:
:
WINDOWS_PRODUCT_ID
:
return
// Windows 产品ID
return
// Windows 产品ID
{
L"SELECT * FROM Win32_OperatingSystem WHERE (SerialNumber IS NOT NULL)"
,
L"SELECT SerialNumber FROM Win32_OperatingSystem WHERE (SerialNumber IS NOT NULL)"
;
L"SerialNumber"
};
case
WINDOWS_MACHINE_GUID
:
default:
return
// 系统UUID
return
{
L""
,
L""
};
L"SELECT UUID FROM Win32_ComputerSystemProduct"
;
}
}
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
;
break
;
default
:
return
L""
;
}
}
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地址
// 通过“PNPDeviceID”获取网卡原生MAC地址
static
BOOL
WMI_DoWithPNPDeviceID
(
const
wchar_t
*
PNPDeviceID
,
wchar_t
*
MacAddress
,
UINT
uSize
)
static
BOOL
parsePNPDeviceID
(
const
wchar_t
*
PNPDeviceID
,
std
::
wstring
&
macAddress
)
{
{
wchar_t
DevicePath
[
MAX_PATH
];
wchar_t
DevicePath
[
MAX_PATH
];
HANDLE
hDeviceFile
;
HANDLE
hDeviceFile
;
...
@@ -317,56 +236,23 @@ static BOOL WMI_DoWithPNPDeviceID(const wchar_t* PNPDeviceID, wchar_t* MacAddres
...
@@ -317,56 +236,23 @@ static BOOL WMI_DoWithPNPDeviceID(const wchar_t* PNPDeviceID, wchar_t* MacAddres
dwID
=
OID_802_3_PERMANENT_ADDRESS
;
dwID
=
OID_802_3_PERMANENT_ADDRESS
;
isOK
=
DeviceIoControl
(
hDeviceFile
,
IOCTL_NDIS_QUERY_GLOBAL_STATS
,
&
dwID
,
sizeof
(
dwID
),
ucData
,
sizeof
(
ucData
),
&
dwByteRet
,
NULL
);
isOK
=
DeviceIoControl
(
hDeviceFile
,
IOCTL_NDIS_QUERY_GLOBAL_STATS
,
&
dwID
,
sizeof
(
dwID
),
ucData
,
sizeof
(
ucData
),
&
dwByteRet
,
NULL
);
if
(
isOK
)
{
// 将字节数组转换成16进制字符串
if
(
isOK
)
{
// 将字节数组转换成16进制字符串
macAddress
.
clear
();
for
(
DWORD
i
=
0
;
i
<
dwByteRet
;
i
++
)
{
for
(
DWORD
i
=
0
;
i
<
dwByteRet
;
i
++
)
{
StringCchPrintfW
(
MacAddress
+
(
i
<<
1
),
uSize
-
(
i
<<
1
),
L"%02X"
,
ucData
[
i
]);
wchar_t
tmp
[
4
];
swprintf_s
(
tmp
,
4
,
i
==
dwByteRet
-
1
?
L"%02X"
:
L"%02X:"
,
ucData
[
i
]);
macAddress
+=
tmp
;
}
}
MacAddress
[
dwByteRet
<<
1
]
=
L'\0'
;
// 写入字符串结束标记
}
}
CloseHandle
(
hDeviceFile
);
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
;
return
isOK
;
}
}
static
std
::
wstring
getMachineGUID
()
static
std
::
wstring
getMachineGUID
()
{
{
std
::
wstring
res
;
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
{
try
{
std
::
wstring
key
=
L"SOFTWARE
\\
Microsoft
\\
Cryptography"
;
std
::
wstring
key
=
L"SOFTWARE
\\
Microsoft
\\
Cryptography"
;
std
::
wstring
name
=
L"MachineGuid"
;
std
::
wstring
name
=
L"MachineGuid"
;
...
@@ -396,6 +282,7 @@ static std::wstring getMachineGUID()
...
@@ -396,6 +282,7 @@ static std::wstring getMachineGUID()
if
(
value
.
back
()
==
L'\0'
)
{
if
(
value
.
back
()
==
L'\0'
)
{
value
.
erase
(
value
.
size
()
-
1
,
1
);
value
.
erase
(
value
.
size
()
-
1
,
1
);
}
}
res
=
value
;
res
=
value
;
RegCloseKey
(
hKey
);
RegCloseKey
(
hKey
);
...
@@ -418,8 +305,8 @@ static bool query(size_t queryTypes, QueryResults& results)
...
@@ -418,8 +305,8 @@ static bool query(size_t queryTypes, QueryResults& results)
if
(
queryTypes
&
MAC_ADDR_REAL
)
{
if
(
queryTypes
&
MAC_ADDR_REAL
)
{
vec
.
push_back
(
MAC_ADDR_REAL
);
vec
.
push_back
(
MAC_ADDR_REAL
);
}
}
if
(
queryTypes
&
HARDDISK_SERIAL
)
{
if
(
queryTypes
&
BOOTABLE_
HARDDISK_SERIAL
)
{
vec
.
push_back
(
HARDDISK_SERIAL
);
vec
.
push_back
(
BOOTABLE_
HARDDISK_SERIAL
);
}
}
if
(
queryTypes
&
MOTHERBOARD_UUID
)
{
if
(
queryTypes
&
MOTHERBOARD_UUID
)
{
vec
.
push_back
(
MOTHERBOARD_UUID
);
vec
.
push_back
(
MOTHERBOARD_UUID
);
...
@@ -438,208 +325,70 @@ static bool query(size_t queryTypes, QueryResults& results)
...
@@ -438,208 +325,70 @@ static bool query(size_t queryTypes, QueryResults& results)
}
}
auto
ok
=
query
(
vec
,
results
);
auto
ok
=
query
(
vec
,
results
);
if
(
queryTypes
&
WINDOWS_MACHINE_GUID
)
{
results
[
WINDOWS_MACHINE_GUID
]
=
(
detail
::
getMachineGUID
());
}
return
ok
;
return
ok
;
}
}
// 基于Windows Management Instrumentation(Windows管理规范)
static
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
QueryResults
&
results
)
static
bool
query
(
const
std
::
vector
<
QueryType
>&
queryTypes
,
QueryResults
&
results
)
{
{
bool
ok
=
false
;
std
::
vector
<
std
::
wstring
>
values
,
errors
;
auto
output
=
[
&
values
](
const
std
::
wstring
&
key
,
const
std
::
wstring
&
value
)
{
// 初始化COM COINIT_APARTMENTTHREADED
values
.
push_back
(
value
);
HRESULT
hres
=
CoInitializeEx
(
NULL
,
COINIT_MULTITHREADED
);
};
if
(
FAILED
(
hres
))
{
#ifdef QT_VERSION
auto
error
=
[
&
errors
](
HRESULT
hr
,
const
std
::
wstring
&
msg
)
{
_com_error
ce
(
hres
);
errors
.
push_back
(
msg
);
qDebug
()
<<
"CoInitializeEx with COINIT_MULTITHREADED failed:
\n
"
<<
ce
.
Error
()
<<
QString
::
fromWCharArray
(
ce
.
ErrorMessage
());
//
};
#endif
wmi
::
WmiBase
wmi
(
L"ROOT
\\
CIMV2"
,
output
,
error
);
if
(
hres
==
0x80010106
)
{
wmi
.
prepare
();
#ifdef QT_VERSION
for
(
auto
queryType
:
queryTypes
)
{
qDebug
()
<<
"already initilized, pass"
;
//
/*if (queryType == WINDOWS_MACHINE_GUID) {
#endif
results[WINDOWS_MACHINE_GUID] = (detail::getMachineGUID());
}
else
{
continue;
#ifdef QT_VERSION
} else */
if
(
queryType
==
BOOTABLE_HARDDISK_SERIAL
)
{
qDebug
()
<<
"trying CoInitializeEx with COINIT_APARTMENTTHREADED"
;
//
auto
sz
=
values
.
size
();
#endif
if
(
wmi
.
execute
(
L"SELECT DiskIndex FROM Win32_DiskPartition WHERE Bootable = TRUE"
)
&&
values
.
size
()
==
sz
+
1
)
{
hres
=
CoInitializeEx
(
NULL
,
COINIT_APARTMENTTHREADED
);
auto
index
=
values
.
back
();
values
.
pop_back
();
if
(
wmi
.
execute
(
L"SELECT SerialNumber FROM Win32_DiskDrive WHERE Index = "
+
index
))
{
if
(
FAILED
(
hres
))
{
results
[
queryType
]
=
values
.
back
();
values
.
pop_back
();
#ifdef QT_VERSION
continue
;
qDebug
()
<<
"CoInitializeEx with COINIT_APARTMENTTHREADED failed, exit"
;
#endif
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
))
{
#ifdef QT_VERSION
qDebug
()
<<
"CoInitializeSecurity:"
<<
hres
<<
QString
::
fromWCharArray
(
_com_error
(
hres
).
ErrorMessage
());
#elif defined(__AFXWIN_H__)
CString
msg
;
msg
.
Format
(
L"0x%X : %s"
,
hres
,
_com_error
(
hres
).
ErrorMessage
());
MessageBoxW
(
NULL
,
msg
,
L"error"
,
MB_ICONERROR
);
#endif
if
(
hres
==
E_OUTOFMEMORY
)
{
#ifdef QT_VERSION
qDebug
()
<<
"E_OUTOFMEMORY"
;
#else
MessageBoxW
(
NULL
,
L"E_OUTOFMEMORY"
,
L"error"
,
MB_ICONERROR
);
#endif
}
else
{
}
else
{
CoUninitialize
();
auto
wql
=
detail
::
getWQLQuery
(
queryType
);
return
false
;
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
;
}
}
// 获得WMI连接COM接口
IWbemLocator
*
pLoc
=
NULL
;
hres
=
CoCreateInstance
(
CLSID_WbemLocator
,
NULL
,
CLSCTX_INPROC_SERVER
,
IID_IWbemLocator
,
reinterpret_cast
<
LPVOID
*>
(
&
pLoc
)
);
if
(
FAILED
(
hres
))
{
#ifdef QT_VERSION
qDebug
()
<<
"CoCreateInstance:"
<<
QString
::
fromWCharArray
(
_com_error
(
hres
).
ErrorMessage
());
#endif
CoUninitialize
();
return
false
;
}
}
}
else
{
// 通过连接接口连接WMI的内核对象名"ROOT//CIMV2"
results
[
queryType
]
=
values
.
back
();
values
.
pop_back
();
IWbemServices
*
pSvc
=
NULL
;
while
(
values
.
size
()
>
sz
)
{
hres
=
pLoc
->
ConnectServer
(
results
[
queryType
]
+=
L"|"
+
values
.
back
();
values
.
pop_back
();
_bstr_t
(
L"ROOT
\\
CIMV2"
),
NULL
,
NULL
,
NULL
,
0
,
NULL
,
NULL
,
&
pSvc
);
if
(
FAILED
(
hres
))
{
#ifdef QT_VERSION
qDebug
()
<<
"ConnectServer:"
<<
QString
::
fromWCharArray
(
_com_error
(
hres
).
ErrorMessage
());
#endif
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
))
{
#ifdef QT_VERSION
qDebug
()
<<
"CoSetProxyBlanket:"
<<
QString
::
fromWCharArray
(
_com_error
(
hres
).
ErrorMessage
());
#endif
pSvc
->
Release
();
pLoc
->
Release
();
CoUninitialize
();
return
false
;
}
}
for
(
auto
queryType
:
queryTypes
)
{
if
(
queryType
==
WINDOWS_MACHINE_GUID
)
{
results
[
WINDOWS_MACHINE_GUID
]
=
(
detail
::
getMachineGUID
());
continue
;
continue
;
}
}
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();
#ifdef QT_VERSION
qDebug
()
<<
"ExecQuery:
\n
"
<<
QString
::
fromWCharArray
(
query
.
szSelect
)
<<
'\n'
<<
QString
::
fromWCharArray
(
_com_error
(
hres
).
ErrorMessage
());
#endif
results
[
queryType
]
=
_com_error
(
hres
).
ErrorMessage
();
continue
;
}
}
// 循环枚举所有的结果对象
// error
while
(
pEnumerator
)
{
if
(
!
errors
.
empty
())
{
IWbemClassObject
*
pclsObj
=
NULL
;
results
[
queryType
]
=
errors
.
back
();
errors
.
pop_back
();
ULONG
uReturn
=
0
;
}
else
{
results
[
queryType
]
=
std
::
wstring
(
L"Get "
)
+
queryTypeString
(
queryType
)
+
L" failed"
;
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
[
queryType
]
=
(
deviceProperty
.
szProperty
);
ok
=
true
;
pclsObj
->
Release
();
break
;
}
}
}
}
pclsObj
->
Release
();
return
true
;
}
// End While
// 释放资源
pEnumerator
->
Release
();
}
pSvc
->
Release
();
pLoc
->
Release
();
CoUninitialize
();
return
ok
;
}
}
static
std
::
wstring
join_result
(
const
QueryResults
&
results
,
const
std
::
wstring
&
conjunction
)
static
std
::
wstring
join_result
(
const
QueryResults
&
results
,
const
std
::
wstring
&
conjunction
)
...
...
jlib/win32/wmi.h
View file @
b657c6e8
...
@@ -29,8 +29,6 @@ typedef std::function<void(const std::wstring&, const std::wstring&)> OutputFunc
...
@@ -29,8 +29,6 @@ typedef std::function<void(const std::wstring&, const std::wstring&)> OutputFunc
class
WmiBase
class
WmiBase
{
{
public
:
public
:
WmiBase
(
const
std
::
wstring
&
_namespace
,
OutputFunc
outputFunc
,
ErrorFunc
errorFunc
=
nullptr
)
WmiBase
(
const
std
::
wstring
&
_namespace
,
OutputFunc
outputFunc
,
ErrorFunc
errorFunc
=
nullptr
)
:
namespace_
(
_namespace
)
:
namespace_
(
_namespace
)
,
outputFunc_
(
outputFunc
)
,
outputFunc_
(
outputFunc
)
...
@@ -100,7 +98,65 @@ public:
...
@@ -100,7 +98,65 @@ public:
}
while
(
0
);
}
while
(
0
);
return
hr
;
return
!
FAILED
(
hr
);
}
protected
:
bool
initCom
(
HRESULT
&
hr
)
{
hr
=
CoInitializeEx
(
NULL
,
COINIT_MULTITHREADED
);
if
(
FAILED
(
hr
))
{
if
(
hr
==
0x80010106
)
{
// already initilized, pass
}
else
{
hr
=
CoInitializeEx
(
NULL
,
COINIT_APARTMENTTHREADED
);
if
(
FAILED
(
hr
))
{
return
false
;
}
}
}
return
true
;
}
HRESULT
setComSecurityLevel
()
{
return
CoInitializeSecurity
(
NULL
,
-
1
,
NULL
,
NULL
,
RPC_C_AUTHN_LEVEL_DEFAULT
,
RPC_C_IMP_LEVEL_IMPERSONATE
,
NULL
,
EOAC_NONE
,
NULL
);
}
HRESULT
obtainWbemLocator
(
CComPtr
<
IWbemLocator
>&
locator
)
{
return
CoCreateInstance
(
CLSID_WbemLocator
,
0
,
CLSCTX_INPROC_SERVER
,
IID_IWbemLocator
,
(
LPVOID
*
)
&
locator
);
}
HRESULT
connect
(
CComPtr
<
IWbemLocator
>
locator
,
CComPtr
<
IWbemServices
>&
services
)
{
return
locator
->
ConnectServer
(
CComBSTR
(
namespace_
.
data
()),
NULL
,
NULL
,
NULL
,
0
,
NULL
,
NULL
,
&
services
);
}
HRESULT
setProxySecurityLevel
(
CComPtr
<
IWbemServices
>
services
)
{
return
CoSetProxyBlanket
(
services
,
// Indicates the proxy to set
RPC_C_AUTHN_WINNT
,
// RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE
,
// RPC_C_AUTHZ_xxx
NULL
,
// Server principal name
RPC_C_AUTHN_LEVEL_CALL
,
// RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE
,
// RPC_C_IMP_LEVEL_xxx
NULL
,
// client identity
EOAC_NONE
// proxy capabilities
);
}
}
HRESULT
parseIWbemClassObject
(
CComPtr
<
IWbemClassObject
>
object
)
{
HRESULT
parseIWbemClassObject
(
CComPtr
<
IWbemClassObject
>
object
)
{
...
@@ -201,65 +257,6 @@ public:
...
@@ -201,65 +257,6 @@ public:
return
WBEM_S_NO_ERROR
;
return
WBEM_S_NO_ERROR
;
}
}
protected
:
bool
initCom
(
HRESULT
&
hr
)
{
hr
=
CoInitializeEx
(
NULL
,
COINIT_MULTITHREADED
);
if
(
FAILED
(
hr
))
{
if
(
hr
==
0x80010106
)
{
// already initilized, pass
}
else
{
hr
=
CoInitializeEx
(
NULL
,
COINIT_APARTMENTTHREADED
);
if
(
FAILED
(
hr
))
{
return
false
;
}
}
}
return
true
;
}
HRESULT
setComSecurityLevel
()
{
return
CoInitializeSecurity
(
NULL
,
-
1
,
NULL
,
NULL
,
RPC_C_AUTHN_LEVEL_DEFAULT
,
RPC_C_IMP_LEVEL_IMPERSONATE
,
NULL
,
EOAC_NONE
,
NULL
);
}
HRESULT
obtainWbemLocator
(
CComPtr
<
IWbemLocator
>&
locator
)
{
return
CoCreateInstance
(
CLSID_WbemLocator
,
0
,
CLSCTX_INPROC_SERVER
,
IID_IWbemLocator
,
(
LPVOID
*
)
&
locator
);
}
HRESULT
connect
(
CComPtr
<
IWbemLocator
>
locator
,
CComPtr
<
IWbemServices
>&
services
)
{
return
locator
->
ConnectServer
(
CComBSTR
(
namespace_
.
data
()),
NULL
,
NULL
,
NULL
,
0
,
NULL
,
NULL
,
&
services
);
}
HRESULT
setProxySecurityLevel
(
CComPtr
<
IWbemServices
>
services
)
{
return
CoSetProxyBlanket
(
services
,
// Indicates the proxy to set
RPC_C_AUTHN_WINNT
,
// RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE
,
// RPC_C_AUTHZ_xxx
NULL
,
// Server principal name
RPC_C_AUTHN_LEVEL_CALL
,
// RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE
,
// RPC_C_IMP_LEVEL_xxx
NULL
,
// client identity
EOAC_NONE
// proxy capabilities
);
}
protected
:
protected
:
std
::
wstring
namespace_
=
{};
std
::
wstring
namespace_
=
{};
CComPtr
<
IWbemServices
>
services_
=
{};
CComPtr
<
IWbemServices
>
services_
=
{};
...
...
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