20 #define LIBSMBIOS_SOURCE
27 #ifdef LIBSMBIOS_WIN_USE_WMI
34 # pragma comment(lib, "wbemuuid")
47 using namespace smbiosLowlevel;
59 hKerneldll = GetModuleHandle( L
"kernel32.dll" );
74 u8 *newSmbiosBuffer = 0;
76 DWORD iSignature =
'R';
77 iSignature = iSignature << 8 |
'S';
78 iSignature = iSignature << 8 |
'M';
79 iSignature = iSignature << 8 |
'B';
83 throw ParseExceptionImpl(
_(
"Could not load dll functions.") );
86 throw ParseExceptionImpl(
_(
"Could not access GetSystemFirmwareTable() API.") );
89 if( iBufferSizeNeeded <= 0 )
90 throw ParseExceptionImpl(
_(
"GetSystemFirmwareTable returned 0 for table length.") );
92 newSmbiosBuffer =
new u8[iBufferSizeNeeded];
93 if( ! newSmbiosBuffer )
94 throw ParseExceptionImpl(
_(
"Failed to allocate memory for Firmware table.") );
95 memset( newSmbiosBuffer, 0,
sizeof(
u8) * iBufferSizeNeeded );
108 table_header->
major_ver = newSmbiosBuffer[1];
109 table_header->
minor_ver = newSmbiosBuffer[2];
113 # define MS_RSMB_HEADER_SIZE 8
121 memset (const_cast<u8 *>(*smbiosBuffer), 0,
sizeof (**smbiosBuffer));
122 delete []
const_cast<u8 *
>(*smbiosBuffer);
126 *smbiosBuffer = (
const u8 *) newSmbiosBuffer;
132 #ifdef LIBSMBIOS_WIN_USE_WMI
134 static void GetWMISMBIOSEntry( IWbemClassObject **pSmbios )
136 BSTR path = SysAllocString(L
"root\\wmi");
137 BSTR className = SysAllocString(L
"MSSmBios_RawSMBiosTables");
139 HRESULT hr = S_FALSE;
140 IWbemLocator *pLocator = NULL;
141 IWbemServices *pNamespace = NULL;
142 IEnumWbemClassObject *pEnumSMBIOS = NULL;
146 hr = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE,
147 NULL, EOAC_SECURE_REFS, NULL );
153 hr = CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLocator );
155 if (! SUCCEEDED( hr ) )
156 throw InternalErrorImpl(
_(
"CoCreateInstance() failed for locator. "
157 "Check that the security levels have been "
158 "properly initialized."
161 hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace );
164 if( WBEM_S_NO_ERROR != hr )
165 throw InternalErrorImpl(
_(
"ConnectServer() failed for namespace"));
167 hr = pNamespace->CreateInstanceEnum( className, 0, NULL, &pEnumSMBIOS );
168 pNamespace->Release();
170 if (! SUCCEEDED( hr ) )
171 throw InternalErrorImpl(
_(
"CreateInstanceEnum() failed for MSSmBios_RawSMBiosTables"));
173 hr = pEnumSMBIOS->Next( 4000, 1, pSmbios, &uReturned );
174 pEnumSMBIOS->Release();
176 if ( 1 != uReturned )
177 throw InternalErrorImpl(
_(
"Next() failed for pEnumSMBIOS"));
179 catch(
const exception &)
181 SysFreeString(className);
188 static void GetWMISMBIOSTable( IWbemClassObject *pSmbios, WMISMBIOSINFO &smbiosData )
193 SAFEARRAY *parray = NULL;
195 if ( NULL == pSmbios )
196 throw ParseExceptionImpl(
_(
"GetWMISMBIOSTable: NULL pointer to SMBIOS Entry specified.") );
200 propName = SysAllocString(L
"SMBiosData");
201 pSmbios->Get( propName, 0L, &pVal, &type, NULL);
202 SysFreeString(propName);
204 if ( ( VT_UI1 | VT_ARRAY ) != pVal.vt )
205 throw ParseExceptionImpl(
_(
"GetWMISMBIOSTable: SMBiosData returned unknown entry type.") );
207 parray = V_ARRAY(&pVal);
209 smbiosData.bufferSize = parray->rgsabound[0].cElements;
211 if ( smbiosData.bufferSize == 0 )
212 throw ParseExceptionImpl(
_(
"GetWMISMBIOSTable: Buffer size was zero.") );
214 smbiosData.buffer =
new u8[smbiosData.bufferSize];
215 if ( ! smbiosData.buffer )
216 throw ParseExceptionImpl(
_(
"GetWMISMBIOSTable: Failed to allocate memory for SMBIOS table.") );
218 memcpy(smbiosData.buffer, (
u8 *)parray->pvData, smbiosData.bufferSize);
221 static void GetWMISMBIOSVersion( IWbemClassObject *pSmbios,
u8 *majorVersion,
u8 *minorVersion )
228 if ( NULL == pSmbios )
229 throw ParseExceptionImpl(
_(
"GetWMISMBIOSVersion: null pointer passed as pSmbios.") );
231 VariantInit( &pVal );
232 propName = SysAllocString( L
"SmbiosMajorVersion" );
233 hr = pSmbios->Get( propName, 0L, &pVal, &type, NULL );
234 SysFreeString( propName );
236 if ( ! SUCCEEDED( hr ) || VT_UI1 != pVal.vt )
237 throw ParseExceptionImpl(
_(
"GetWMISMBIOSVersion: problem accessing WMI SmbiosMajorVersion.") );
240 *majorVersion = V_UI1(&pVal);
242 VariantClear( &pVal );
243 propName = SysAllocString( L
"SmbiosMinorVersion" );
244 hr = pSmbios->Get( propName, 0L, &pVal, &type, NULL );
245 SysFreeString( propName );
247 if ( !SUCCEEDED( hr ) || pVal.vt != VT_UI1 )
248 throw ParseExceptionImpl(
_(
"GetWMISMBIOSVersion: problem accessing WMI SmbiosMinorVersion.") );
251 *minorVersion = V_UI1(&pVal);
254 static void GetWMISMBIOSData( WMISMBIOSINFO &smbiosData )
256 IWbemClassObject *pSmbios = NULL;
260 if (! SUCCEEDED( CoInitialize(0) ) )
261 throw InternalErrorImpl(
_(
"Could not initialize COM.") );
263 GetWMISMBIOSEntry( &pSmbios );
264 GetWMISMBIOSTable( pSmbios, smbiosData );
265 GetWMISMBIOSVersion( pSmbios, &smbiosData.majorVersion, &smbiosData.minorVersion );
267 catch(
const exception &)
269 delete [] smbiosData.buffer;
270 smbiosData.buffer = 0;
280 WMISMBIOSINFO wmi_smbiosData;
281 memset(&wmi_smbiosData, 0,
sizeof(wmi_smbiosData));
283 GetWMISMBIOSData( wmi_smbiosData );
285 if( wmi_smbiosData.bufferSize <= 0 || ! wmi_smbiosData.buffer )
286 throw ParseExceptionImpl(
_(
"getSmbiosTable(): GetWMISMBIOSData returned 0 for buffer size.") );
290 table_header->
major_ver = wmi_smbiosData.majorVersion;
291 table_header->
minor_ver = wmi_smbiosData.minorVersion;
297 memset (const_cast<u8 *>(*smbiosBuffer), 0,
sizeof (**smbiosBuffer));
298 delete []
const_cast<u8 *
>(*smbiosBuffer);
302 *smbiosBuffer = (
const u8 *) wmi_smbiosData.buffer;