@oxmc/node-smbios 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/binding.gyp ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "smbios",
5
+ "cflags!": [ "-fno-exceptions" ],
6
+ "cflags_cc!": [ "-fno-exceptions" ],
7
+ "cflags_cc": [ "-std=c++17" ],
8
+ "sources": [
9
+ "src/binding.cpp",
10
+ "src/smbios_common.cpp"
11
+ ],
12
+ "include_dirs": [
13
+ "<!@(node -p \"require('node-addon-api').include\")"
14
+ ],
15
+ "dependencies": [
16
+ "<!(node -p \"require('node-addon-api').gyp\")"
17
+ ],
18
+ "defines": [
19
+ "NAPI_DISABLE_CPP_EXCEPTIONS"
20
+ ],
21
+ "conditions": [
22
+ ["OS=='win'", {
23
+ "sources": [ "src/windows/smbios_windows.cpp" ],
24
+ "libraries": [],
25
+ "msvs_settings": {
26
+ "VCCLCompilerTool": {
27
+ "ExceptionHandling": 1,
28
+ "AdditionalOptions": [ "/std:c++17" ]
29
+ }
30
+ }
31
+ }],
32
+ ["OS=='mac'", {
33
+ "sources": [ "src/mac/smbios_macos.cpp" ],
34
+ "xcode_settings": {
35
+ "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
36
+ "CLANG_CXX_LANGUAGE_STANDARD": "c++17",
37
+ "CLANG_CXX_LIBRARY": "libc++",
38
+ "MACOSX_DEPLOYMENT_TARGET": "10.13"
39
+ },
40
+ "link_settings": {
41
+ "libraries": [
42
+ "-framework IOKit",
43
+ "-framework CoreFoundation"
44
+ ]
45
+ }
46
+ }],
47
+ ["OS=='linux'", {
48
+ "sources": [ "src/linux/smbios_linux.cpp" ]
49
+ }]
50
+ ]
51
+ },
52
+ {
53
+ "target_name": "action_after_build",
54
+ "type": "none",
55
+ "dependencies": [ "smbios" ],
56
+ "copies": [
57
+ {
58
+ "files": [ "<(PRODUCT_DIR)/smbios.node" ],
59
+ "destination": "<(module_path)"
60
+ }
61
+ ]
62
+ }
63
+ ]
64
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxmc/node-smbios",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "A Node.js module designed to retrieve detailed system and hardware information from SMBIOS.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,7 +22,8 @@
22
22
  "files": [
23
23
  "index.js",
24
24
  "lib/**/*",
25
- "src/**/*"
25
+ "src/**/*",
26
+ "binding.gyp"
26
27
  ],
27
28
  "keywords": [
28
29
  "smbios",
@@ -7,22 +7,14 @@
7
7
  #include <comdef.h>
8
8
  #include <Wbemidl.h>
9
9
  #include <string>
10
+ #include <vector>
10
11
 
11
12
  #pragma comment(lib, "wbemuuid.lib")
12
13
 
13
14
  namespace smbios {
14
15
 
15
- static std::string WideToUtf8(const wchar_t* wstr) {
16
- if (!wstr) return "";
17
- int len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
18
- if (len <= 0) return "";
19
- std::string result(len - 1, '\0');
20
- WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &result[0], len, NULL, NULL);
21
- return result;
22
- }
23
-
24
16
  /**
25
- * Lightweight WMI query class - no COM init/uninit, connection reuse
17
+ * Helper class for WMI queries
26
18
  */
27
19
  class WMIQuery {
28
20
  private:
@@ -32,19 +24,38 @@ private:
32
24
 
33
25
  public:
34
26
  WMIQuery() : pLoc(nullptr), pSvc(nullptr), initialized(false) {
35
- // Don't call CoInitialize - Node.js already initialized COM
36
- // Don't call CoInitializeSecurity - it's already set or will fail with RPC_E_TOO_LATE
37
-
38
- HRESULT hres = CoCreateInstance(
27
+ // Initialize COM
28
+ HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
29
+ if (FAILED(hres) && hres != RPC_E_CHANGED_MODE) {
30
+ return;
31
+ }
32
+
33
+ // Set general COM security levels
34
+ hres = CoInitializeSecurity(
35
+ NULL, -1, NULL, NULL,
36
+ RPC_C_AUTHN_LEVEL_DEFAULT,
37
+ RPC_C_IMP_LEVEL_IMPERSONATE,
38
+ NULL, EOAC_NONE, NULL
39
+ );
40
+
41
+ if (FAILED(hres) && hres != RPC_E_TOO_LATE) {
42
+ CoUninitialize();
43
+ return;
44
+ }
45
+
46
+ // Obtain the initial locator to WMI
47
+ hres = CoCreateInstance(
39
48
  CLSID_WbemLocator, 0,
40
49
  CLSCTX_INPROC_SERVER,
41
50
  IID_IWbemLocator, (LPVOID*)&pLoc
42
51
  );
43
52
 
44
53
  if (FAILED(hres)) {
54
+ CoUninitialize();
45
55
  return;
46
56
  }
47
57
 
58
+ // Connect to WMI
48
59
  hres = pLoc->ConnectServer(
49
60
  _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0,
50
61
  NULL, 0, 0, &pSvc
@@ -52,10 +63,11 @@ public:
52
63
 
53
64
  if (FAILED(hres)) {
54
65
  pLoc->Release();
55
- pLoc = nullptr;
66
+ CoUninitialize();
56
67
  return;
57
68
  }
58
69
 
70
+ // Set security levels on the proxy
59
71
  hres = CoSetProxyBlanket(
60
72
  pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
61
73
  RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,
@@ -65,8 +77,7 @@ public:
65
77
  if (FAILED(hres)) {
66
78
  pSvc->Release();
67
79
  pLoc->Release();
68
- pSvc = nullptr;
69
- pLoc = nullptr;
80
+ CoUninitialize();
70
81
  return;
71
82
  }
72
83
 
@@ -74,15 +85,9 @@ public:
74
85
  }
75
86
 
76
87
  ~WMIQuery() {
77
- if (pSvc) {
78
- pSvc->Release();
79
- pSvc = nullptr;
80
- }
81
- if (pLoc) {
82
- pLoc->Release();
83
- pLoc = nullptr;
84
- }
85
- // Don't call CoUninitialize - we didn't initialize COM
88
+ if (pSvc) pSvc->Release();
89
+ if (pLoc) pLoc->Release();
90
+ CoUninitialize();
86
91
  }
87
92
 
88
93
  std::string QueryProperty(const wchar_t* wmiClass, const wchar_t* property) {
@@ -93,7 +98,7 @@ public:
93
98
  query += L" FROM ";
94
99
  query += wmiClass;
95
100
 
96
- IEnumWbemClassObject* pEnumerator = nullptr;
101
+ IEnumWbemClassObject* pEnumerator = NULL;
97
102
  HRESULT hres = pSvc->ExecQuery(
98
103
  bstr_t("WQL"),
99
104
  bstr_t(query.c_str()),
@@ -101,44 +106,40 @@ public:
101
106
  NULL, &pEnumerator
102
107
  );
103
108
 
104
- if (FAILED(hres) || !pEnumerator) {
109
+ if (FAILED(hres)) {
105
110
  return "";
106
111
  }
107
112
 
108
- IWbemClassObject* pclsObj = nullptr;
113
+ IWbemClassObject* pclsObj = NULL;
109
114
  ULONG uReturn = 0;
110
115
  std::string result;
111
116
 
112
- hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
113
-
114
- if (SUCCEEDED(hres) && uReturn == 1 && pclsObj) {
117
+ while (pEnumerator) {
118
+ HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
119
+ if (0 == uReturn) {
120
+ break;
121
+ }
122
+
115
123
  VARIANT vtProp;
116
124
  VariantInit(&vtProp);
125
+ hr = pclsObj->Get(property, 0, &vtProp, 0, 0);
117
126
 
118
- hres = pclsObj->Get(property, 0, &vtProp, 0, 0);
119
-
120
- if (SUCCEEDED(hres)) {
121
- if (vtProp.vt == VT_BSTR && vtProp.bstrVal) {
122
- result = WideToUtf8(vtProp.bstrVal);
123
- } else if (vtProp.vt == VT_I4) {
127
+ if (SUCCEEDED(hr)) {
128
+ if (vtProp.vt == VT_BSTR) {
129
+ _bstr_t bstr(vtProp.bstrVal);
130
+ result = (char*)bstr;
131
+ } else if (vtProp.vt == VT_I4 || vtProp.vt == VT_UI4) {
124
132
  result = std::to_string(vtProp.lVal);
125
- } else if (vtProp.vt == VT_UI4) {
126
- result = std::to_string(vtProp.ulVal);
127
- } else if (vtProp.vt == VT_I2) {
133
+ } else if (vtProp.vt == VT_I2 || vtProp.vt == VT_UI2) {
128
134
  result = std::to_string(vtProp.iVal);
129
- } else if (vtProp.vt == VT_UI2) {
130
- result = std::to_string(vtProp.uiVal);
131
135
  } else if (vtProp.vt == VT_UI1) {
132
136
  result = std::to_string(vtProp.bVal);
133
- } else if (vtProp.vt == VT_I8) {
134
- result = std::to_string(vtProp.llVal);
135
- } else if (vtProp.vt == VT_UI8) {
136
- result = std::to_string(vtProp.ullVal);
137
137
  }
138
138
  }
139
139
 
140
140
  VariantClear(&vtProp);
141
141
  pclsObj->Release();
142
+ break; // Get only first result
142
143
  }
143
144
 
144
145
  pEnumerator->Release();
@@ -167,6 +168,7 @@ SystemInfo GetSystemInfo() {
167
168
  info.uuid = wmi.QueryProperty(L"Win32_ComputerSystemProduct", L"UUID");
168
169
  info.wakeUpType = wmi.QueryProperty(L"Win32_ComputerSystem", L"WakeUpType");
169
170
 
171
+ // Try to get serial number from ComputerSystemProduct
170
172
  std::string serial = wmi.QueryProperty(L"Win32_ComputerSystemProduct", L"IdentifyingNumber");
171
173
  if (serial.empty() || serial == "To Be Filled By O.E.M.") {
172
174
  serial = wmi.QueryProperty(L"Win32_BIOS", L"SerialNumber");
@@ -220,6 +222,7 @@ MemoryInfo GetMemoryInfo() {
220
222
  info.maxCapacity = wmi.QueryProperty(L"Win32_PhysicalMemoryArray", L"MaxCapacity");
221
223
  info.memoryDevices = wmi.QueryProperty(L"Win32_PhysicalMemoryArray", L"MemoryDevices");
222
224
 
225
+ // Get available memory from OS
223
226
  MEMORYSTATUSEX memStatus;
224
227
  memStatus.dwLength = sizeof(memStatus);
225
228
  if (GlobalMemoryStatusEx(&memStatus)) {