Windows Management Instrumentation (WMI) is the Microsoft implementation of Web-Based Enterprise Management (WBEM), which is an industry initiative to develop a standard technology for accessing management information in an enterprise environment
WMI is preinstalled in Windows Server 2003, Windows XP, Windows Me, and Windows 2000;
WMI CORE 1.5 (Windows 95/98/NT 4.0) is available as an Internet download from http://www.microsoft.com/downloads. This download requires Microsoft Internet Explorer version 5 or later
// compile for console
#include "com.inc"
//#use "wbemuuid.lib" // CLSID_WbemLocator IID_IWbemLocator
#use "oleaut32.lib"
#autodefine "off"
#asm
CLSID_WbemLocator dd 0x4590F811, 0x11D01D3A, 0xAA001F89, 0x242E4B00
IID_IWbemLocator dd 0xDC12A687, 0x11CF737F, 0xAA004D88, 0x242E4B00
#endasm
declare CLSID_WbemLocator();
declare IID_IWbemLocator();
// supported property-types: uint32, uint8, string, boolean
class CWMI
{
// private
declare CWMI();
declare _CWMI();
declare SetProperty(string *szproperty);
// public
declare SetClass(string *szclass);
declare QueryProperty(string *szproperty),string; // use for first enumeration
declare QueryString(string *szproperty),string; // use for n-th enumeration
declare next(opt string *prop=null),string; // use next() or QueryString(property) for current enumeration
DWORD CurrentState;
int ExecQueryFlags;
HRESULT hr;
string *ErrorDescription;
BSTR *m_bstrSystemClass;
BSTR *m_bstrQueryLanguage; // WQL
LPOLESTR *m_property; // FreeHeap
IWbemLocator *m_pLoc;
IWbemServices *m_pSvc;
IEnumWbemClassObject *m_pEnumerator;
IWbemClassObject *m_pclsObj;
}
//////////////////////////////////////////////////////////// test
global sub main()
{
CWMI wmi;
writeln("error:");
printf(wmi.*ErrorDescription);
printf("\n");
printf("\n----------- Win32_OperatingSystem ----------------\n\n");
wmi.SetClass("Win32_OperatingSystem");
printf("Name : %s\n", wmi.QueryProperty("Name"));
printf("BootDevice : %s\n", wmi.QueryProperty("BootDevice"));
printf("BuildType : %s\n", wmi.QueryProperty("BuildType"));
printf("CountryCode : %s\n", wmi.QueryProperty("CountryCode"));
printf("Description : %s\n", wmi.QueryProperty("Description"));
printf("Locale : %s\n", wmi.QueryProperty("Locale"));
printf("Manufacturer: %s\n", wmi.QueryProperty("Manufacturer"));
printf("Organization: %s\n", wmi.QueryProperty("Organization"));
printf("RegisteredUser: %s\n", wmi.QueryProperty("RegisteredUser"));
printf("Version : %s\n", wmi.QueryProperty("Version"));
printf("SystemDevice: %s\n", wmi.QueryProperty("SystemDevice"));
printf("SerialNumber: %s\n", wmi.QueryProperty("SerialNumber"));
printf("\n----------- Win32_UserAccount ----------------\n\n");
wmi.SetClass("Win32_UserAccount");
string *s = wmi.QueryProperty("Caption"); // root enum
if (*s="") printf("not installed: %s\n", wmi.ErrorDescription);
while (*s<>"")
{
printf( "Name : %s " , s);
printf( "(disabled:%s; " , wmi.QueryString("Disabled") );
printf( "AccountType:%s; ", wmi.QueryString("AccountType"));
printf( "SIDType:%s)\n" , wmi.QueryString("SIDType") ); // current enum
FreeHeap(s);
s=wmi.next(); // next enum
}
FreeHeap(s);
printf("\n----------- Win32_NetworkAdapter ----------------\n\n");
wmi.SetClass("Win32_NetworkAdapter");
s = wmi.QueryProperty("Caption"); // root enum
if (*s="") printf("not installed: %s\n", wmi.ErrorDescription);
while (*s<>"")
{
printf( "Name : %s\n", s);
// printf( "[mac:%s]\n", wmi.QueryString("MACAddress"));// crash on "LPT"
FreeHeap(s);
s=wmi.next(); // next enum
}
FreeHeap(s);
printf("\n\nerror:%s\n\nend.", wmi.*ErrorDescription);
getch();
return;
}
#define CWMI_STATE_COINIT 1
////////////////////////////////////////////////////////////
CWMI :: CWMI
{
ErrorDescription = "Uninitialized";
m_bstrSystemClass = null;
m_bstrQueryLanguage = SysAllocString("W\x00Q\x00L\x00\x00");
m_property = null;
m_pclsObj = null;
CurrentState = 0;
m_pLoc = null;
m_pSvc = null;
m_pEnumerator = null;
ExecQueryFlags = WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY;
// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (hr)
{
ErrorDescription = "Failed to initialize COM library";
return;
}
CurrentState |= CWMI_STATE_COINIT;
// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------
// Note: If you are using Windows 2000, you need to specify -
// the default authentication credentials for a user by using
// a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
// parameter of CoInitializeSecurity ------------------------
hr = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (hr)
{
ErrorDescription = "Failed to initialize security";
return;
}
// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------
hr = CoCreateInstance(
&CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
&IID_IWbemLocator, &m_pLoc);
if (hr)
{
ErrorDescription = "Failed to create IWbemLocator object";
return;
}
// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
BSTR object = SysAllocString(OLESTR("ROOT\\CIMV2"));
hr = m_pLoc->ConnectServer(
object, // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&m_pSvc // pointer to IWbemServices proxy
);
SysFreeString(object);
if (hr)
{
ErrorDescription = "Could not connect to root\\cimv2";
return;
}
// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------
hr = CoSetProxyBlanket(
m_pSvc, // 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
);
if (hr)
{
ErrorDescription = "Could not set proxy blanket";
return;
}
ErrorDescription = "OK";
return;
}
////////////////////////////////////////////////////////////
CWMI :: _CWMI
{
if (m_bstrQueryLanguage <> null) SysFreeString(m_bstrQueryLanguage);
SetClass(null);
SetProperty(null);
if (m_pclsObj <> null) m_pclsObj->Release();
if (m_pEnumerator <> null) m_pEnumerator->Release();
if (m_pSvc <> null) m_pSvc->Release();
if (m_pLoc <> null) m_pLoc->Release();
if (CurrentState & CWMI_STATE_COINIT) CoUninitialize();
return;
}
////////////////////////////////////////////////////////////
CWMI :: SetClass(string *szclass)
{
if (m_bstrSystemClass<>null)
{
SysFreeString(m_bstrSystemClass);
m_bstrSystemClass = null;
}
if (szclass <> null)
{
m_bstrSystemClass = SysAllocString(OLESTR("SELECT * FROM " + *(string)szclass));
}
return;
}
////////////////////////////////////////////////////////////
CWMI :: SetProperty(string *szproperty)
{
if (m_property <> null) {
FreeHeap(m_property);
m_property = null;
}
if (szproperty <> null) {
m_property = _OLESTR(szproperty);
}
return;
}
////////////////////////////////////////////////////////////
CWMI :: QueryProperty(string *szproperty),string
{
if (m_bstrQueryLanguage = null) or (m_bstrSystemClass = null) return "";
SetProperty(szproperty);
if (m_pclsObj <> null)
{
m_pclsObj->Release();
m_pclsObj = null;
}
if (m_pEnumerator <> null)
{
m_pEnumerator->Release();
m_pEnumerator = null;
}
// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----
ErrorDescription = "OK";
hr = m_pSvc->ExecQuery(m_bstrQueryLanguage, m_bstrSystemClass,
ExecQueryFlags, NULL, &m_pEnumerator);
if (hr)
{
m_pEnumerator = null;
ErrorDescription = "Query for class failed";
return "";
}
// Step 7: -------------------------------------------------
// Get the data from the query in step 6 -------------------
return next();
}
////////////////////////////////////////////////////////////
CWMI :: QueryString(string *szproperty),string
{
return next(szproperty);
}
////////////////////////////////////////////////////////////
CWMI :: next(string *prop),string
{
if (m_pEnumerator = null) or (m_property = null) return "";
int uReturn = 0;
ErrorDescription = "OK";
if (prop=null)
{
if (m_pclsObj <> null)
{
m_pclsObj->Release();
m_pclsObj = null;
}
m_pEnumerator->Next(WBEM_INFINITE, 1, &m_pclsObj, &uReturn);
if (uReturn = 0) {
ErrorDescription = "No More";
return "";
}
}
VARIANT vtProp;
vtProp.vt = VT_EMPTY;
vtProp.bstrVal = null;
// Get the value of the Name property
if (m_pclsObj <> null)
{
if (prop=null)
{
hr = m_pclsObj->Get(m_property, 0, &vtProp, 0, 0);
}
else
{
hr = m_pclsObj->Get(OLESTR(prop), 0, &vtProp, 0, 0);
}
if (hr) return "";
}
dstring ansi[MAX_PATH]; // with *ansi - crash in all return cases
ansi = "*unsupported variant type*";
if (vtProp.vt = VT_BSTR) and (vtProp.bstrVal <> null) // string
{
ansi = ToAnsi(vtProp.bstrVal);
}
if (vtProp.vt = VT_INT) or (vtProp.vt = VT_I4) // int32
{
ansi = str$(vtProp.intVal,0);
}
if (vtProp.vt = VT_UI1) // uint8
{
ansi = str$(vtProp.bVal,0);
}
if (vtProp.vt = VT_UINT) or (vtProp.vt = VT_UI4) // uint32
{
ansi = str$(vtProp.intVal,0);
}
if (vtProp.vt = VT_R4) // float
{
ansi = str$(vtProp.fltVal,3);
}
if (vtProp.vt = VT_R8) // double
{
ansi = str$(vtProp.dblVal,3);
}
if (vtProp.vt = VT_NULL) // nothing
{
ansi = "NULL";
}
if (vtProp.vt = VT_BOOL) // double
{
if (vtProp.boolVal<>0) ansi = "TRUE" else ansi="FALSE";
}
//printf("[vt=%d]",vtProp.vt);
VariantClear(vtProp);
return ansi;
}
Great job ! :) Is there a translation to EB language ?