if (trace(1))
htrc("WMIColumns class %s space %s\n", SVP(classname), SVP(nsp));
/*********************************************************************/ /* Set default values for the namespace and class name. */ /*********************************************************************/ if (!nsp)
nsp = "root\\cimv2";
if (!classname) { if (!stricmp(nsp, "root\\cimv2"))
classname = "ComputerSystemProduct"; elseif (!stricmp(nsp, "root\\cli"))
classname = "Msft_CliAlias"; else {
safe_strcpy(g->Message, sizeof(g->Message), "Missing class name"); return NULL;
} // endif classname
if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "Failed to initialize COM library. " "Error code = %x", res); return NULL;
} // endif res
#if0// irrelevant for a DLL
res = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);
if (res != RPC_E_TOO_LATE && FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "Failed to initialize security. " "Error code = %p", res);
CoUninitialize(); return NULL;
} // endif Res #endif// 0
res = CoCreateInstance(CLSID_WbemLocator, NULL,
CLSCTX_INPROC_SERVER, IID_IWbemLocator,
(void**) &loc); if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "Failed to create Locator. " "Error code = %x", res);
CoUninitialize(); return NULL;
} // endif res
res = loc->ConnectServer(_bstr_t(nsp),
NULL, NULL, NULL, 0, NULL, NULL, &wp->Svc);
if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "Could not connect. Error code = %x", res);
loc->Release();
CoUninitialize(); return NULL;
} // endif res
loc->Release();
if (trace(1))
htrc("Successfully connected to namespace.\n");
/*********************************************************************/ /* Perform a full class object retrieval. */ /*********************************************************************/
p = (char*)PlugSubAlloc(g, NULL, strlen(classname) + 7);
if (strchr(classname, '_'))
strcpy(p, classname); else
strcat(strcpy(p, "Win32_"), classname);
res = wp->Svc->GetObject(bstr_t(p), 0, 0, &wp->Cobj, 0);
if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "failed GetObject %s in %s", classname, nsp);
wp->Svc->Release();
wp->Svc = NULL; // MUST be set to NULL (why?) return NULL;
} // endif res
return wp;
} // end of InitWMI
/***********************************************************************/ /* WMIColumns: constructs the result blocks containing the description */ /* of all the columns of a WMI table of a specified class. */ /***********************************************************************/
PQRYRES WMIColumns(PGLOBAL g, PCSZ nsp, PCSZ cls, bool info)
{ staticint buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME,
FLD_PREC, FLD_LENGTH, FLD_SCALE}; staticunsignedint len, length[] = {0, 6, 8, 10, 10, 6}; int i = 0, n = 0, ncol = sizeof(buftyp) / sizeof(int); int lng, typ, prec; LONG low, upp;
BSTR propname;
VARIANT val;
CIMTYPE type;
HRESULT res;
PWMIUT wp;
SAFEARRAY *prnlist = NULL;
PQRYRES qrp = NULL;
PCOLRES crp;
if (!info) { /*******************************************************************/ /* Initialize WMI if not done yet. */ /*******************************************************************/ if (!(wp = InitWMI(g, nsp, cls))) return NULL;
/*******************************************************************/ /* Get the number of properties to return. */ /*******************************************************************/
res = wp->Cobj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL);
if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "failed Get(__Property_Count) res=%d", res); goto err;
} // endif res
if (!(n = val.lVal)) {
snprintf(g->Message, sizeof(g->Message), "Class %s in %s has no properties",
cls, nsp); goto err;
} // endif res
/*******************************************************************/ /* Get max property name length. */ /*******************************************************************/
res = wp->Cobj->GetNames(NULL,
WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY,
NULL, &prnlist);
if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "failed GetNames res=%d", res); goto err;
} // endif res
res = SafeArrayGetLBound(prnlist, 1, &low);
res = SafeArrayGetUBound(prnlist, 1, &upp);
for (long i = low; i <= upp; i++) { // Get this property name.
res = SafeArrayGetElement(prnlist, &i, &propname);
if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "failed GetArrayElement res=%d", res); goto err;
} // endif res
len = (unsigned)SysStringLen(propname);
length[0] = MY_MAX(length[0], len);
} // enfor i
res = SafeArrayDestroy(prnlist);
} else
length[0] = 128;
/*********************************************************************/ /* Allocate the structures used to refer to the result set. */ /*********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, false, true);
if (info || !qrp) return qrp;
/*********************************************************************/ /* Now get the results into blocks. */ /*********************************************************************/
res = wp->Cobj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
while (TRUE) {
res = wp->Cobj->Next(0, &propname, &val, &type, NULL);
if (FAILED(res)) {
snprintf(g->Message, sizeof(g->Message), "failed getting Next hr=%d", res);
qrp = NULL; goto err;
} elseif (res == WBEM_S_NO_MORE_DATA) {
VariantClear(&val); break;
} // endif res
if (i >= n) break; // Should never happen else
prec = 0;
switch (type) { case CIM_STRING:
typ = TYPE_STRING;
lng = 255;
prec = 1; // Case insensitive break; case CIM_SINT32: case CIM_UINT32: case CIM_BOOLEAN:
typ = TYPE_INT;
lng = 11; break; case CIM_SINT8: case CIM_UINT8:
typ = TYPE_TINY;
lng = 4; break; case CIM_SINT16: case CIM_UINT16:
typ = TYPE_SHORT;
lng = 6; break; case CIM_REAL64: case CIM_REAL32:
prec = 2;
typ = TYPE_DOUBLE;
lng = 15; break; case CIM_SINT64: case CIM_UINT64:
typ = TYPE_BIGINT;
lng = 20; break; case CIM_DATETIME:
typ = TYPE_DATE;
lng = 19; break; case CIM_CHAR16:
typ = TYPE_STRING;
lng = 16; break; case CIM_EMPTY:
typ = TYPE_STRING;
lng = 24; // ??? break; default:
qrp->BadLines++; goto suite;
} // endswitch type
crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(_com_util::ConvertBSTRToString(propname), i);
crp = crp->Next; // Data Type
crp->Kdata->SetValue(typ, i);
crp = crp->Next; // Type Name
crp->Kdata->SetValue(GetTypeName(typ), i);
crp = crp->Next; // Precision
crp->Kdata->SetValue(lng, i);
crp = crp->Next; // Length
crp->Kdata->SetValue(lng, i);
crp = crp->Next; // Scale (precision)
crp->Kdata->SetValue(prec, i);
i++;
suite:
SysFreeString(propname);
VariantClear(&val);
} // endfor i
qrp->Nblin = i;
err: // Cleanup
wp->Cobj->Release();
wp->Svc->Release();
wp->Svc = NULL; // MUST be set to NULL (why?)
CoUninitialize();
/*********************************************************************/ /* Return the result pointer for use by GetData routines. */ /*********************************************************************/ return qrp;
} // end of WMIColumns
/* -------------- Implementation of the WMI classes ------------------ */
/***********************************************************************/ /* DefineAM: define specific AM values for WMI table. */ /***********************************************************************/ bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Nspace = GetStringCatInfo(g, "Namespace", "Root\\CimV2");
Wclass = GetStringCatInfo(g, "Class",
(!stricmp(Nspace, "root\\cimv2") ? "ComputerSystemProduct" :
!stricmp(Nspace, "root\\cli") ? "Msft_CliAlias" : ""));
if (!*Wclass) {
snprintf(g->Message, sizeof(g->Message), "Missing class name for %s", Nspace); returntrue;
} elseif (!strchr(Wclass, '_')) { char *p = (char*)PlugSubAlloc(g, NULL, strlen(Wclass) + 7);
Wclass = strcat(strcpy(p, "Win32_"), Wclass);
} // endif Wclass
if (Catfunc == FNC_NO)
Ems = GetIntCatInfo("Estimate", 100);
returnfalse;
} // end of DefineAM
/***********************************************************************/ /* GetTable: makes a new TDB of the proper type. */ /***********************************************************************/
PTDB WMIDEF::GetTable(PGLOBAL g, MODE m)
{ if (Catfunc == FNC_NO) returnnew(g) TDBWMI(this); elseif (Catfunc == FNC_COL) returnnew(g) TDBWCL(this);
snprintf(g->Message, sizeof(g->Message), "Bad catfunc %ud for WMI", Catfunc); return NULL;
} // end of GetTable
// Initialize COM.
Res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(Res)) {
snprintf(g->Message, sizeof(g->Message), "Failed to initialize COM library. " "Error code = %x", Res); returntrue; // Program has failed.
} // endif Res
// Obtain the initial locator to Windows Management // on a particular host computer.
IWbemLocator *loc; // Initial Windows Management locator
Res = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*) &loc);
if (FAILED(Res)) {
snprintf(g->Message, sizeof(g->Message), "Failed to create Locator. " "Error code = %x", Res);
CoUninitialize(); returntrue; // Program has failed.
} // endif Res
// Connect to the specified namespace with the // current user and obtain pointer to Svc // to make IWbemServices calls.
Res = loc->ConnectServer(_bstr_t(Nspace),
NULL, NULL,0, NULL, 0, 0, &Svc);
if (FAILED(Res)) {
snprintf(g->Message, sizeof(g->Message), "Could not connect. Error code = %x", Res);
loc->Release();
CoUninitialize(); returntrue; // Program has failed.
} // endif hres
loc->Release(); // Not used anymore
// Set the IWbemServices proxy so that impersonation // of the user (client) occurs.
Res = CoSetProxyBlanket(Svc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (FAILED(Res)) {
snprintf(g->Message, sizeof(g->Message), "Could not set proxy. Error code = %x", Res);
Svc->Release();
CoUninitialize(); returntrue; // Program has failed.
} // endif Res
Init = true; returnfalse;
} // end of Initialize
/***********************************************************************/ /* Changes '\' into '\\' in the filter. */ /***********************************************************************/ void TDBWMI::DoubleSlash(PGLOBAL g)
{ if (To_CondFil && strchr(To_CondFil->Body, '\\')) { char *body = To_CondFil->Body; char *buf = (char*)PlugSubAlloc(g, NULL, strlen(body) * 2); int i = 0, k = 0;
do { if (body[i] == '\\')
buf[k++] = '\\';
buf[k++] = body[i];
} while (body[i++]);
To_CondFil->Body = buf;
} // endif To_CondFil
} // end of DoubleSlash
/***********************************************************************/ /* MakeWQL: make the WQL statement use with WMI ExecQuery. */ /***********************************************************************/ char *TDBWMI::MakeWQL(PGLOBAL g)
{ char *colist, *wql/*, *pw = NULL*/; int len, ncol = 0; bool first = true, noloc = false;
PCOL colp;
// Normal WQL statement to retrieve results for (colp = Columns; colp; colp = colp->GetNext()) if (!colp->IsSpecial() && (colp->GetColUse(U_P | U_J_EXT) || noloc))
ncol++;
} else { // ncol == 0 can occur for queries such that sql count(*) from... // for which we will count the rows from sql * from...
colist = (char*)PlugSubAlloc(g, NULL, 2);
snprintf(colist, 2, "*");
} // endif ncol
// Below 14 is length of 'select ' + length of ' from ' + 1
len = (strlen(colist) + strlen(Wclass) + 14);
len += (To_CondFil ? strlen(To_CondFil->Body) + 7 : 0);
wql = (char*)PlugSubAlloc(g, NULL, len);
snprintf(wql, len, "SELECT %s FROM %s", colist, Wclass);
if (To_CondFil) {
safe_strcat(wql, len, " WHERE ");
safe_strcat(wql, len, To_CondFil->Body);
}
return wql;
} // end of MakeWQL
/***********************************************************************/ /* GetWMIInfo: Get info for the WMI class. */ /***********************************************************************/ bool TDBWMI::GetWMIInfo(PGLOBAL g)
{ if (Done) returnfalse;
char *cmd = MakeWQL(g);
if (cmd == NULL) {
snprintf(g->Message, sizeof(g->Message), "Error making WQL statement");
Svc->Release();
CoUninitialize(); returntrue; // Program has failed.
} // endif cmd
// Query for Wclass in Nspace
Rc = Svc->ExecQuery(bstr_t("WQL"), bstr_t(cmd), // WBEM_FLAG_BIDIRECTIONAL | WBEM_FLAG_RETURN_IMMEDIATELY,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &Enumerator);
if (FAILED(Rc)) {
snprintf(g->Message, sizeof(g->Message), "Query %s failed. Error code = %x", cmd, Rc);
Svc->Release();
CoUninitialize(); returntrue; // Program has failed.
} // endif Rc
Done = true; returnfalse;
} // end of GetWMIInfo
/***********************************************************************/ /* WMI: Get the number returned instances. */ /***********************************************************************/ int TDBWMI::GetMaxSize(PGLOBAL g)
{ if (MaxSize < 0) { /*******************************************************************/ /* Loop enumerating to get the count. This is prone to last a */ /* very long time for some classes such as DataFile, this is why */ /* we just return an estimated value that will be adjusted later. */ /*******************************************************************/
MaxSize = Ems; #if0 if (Initialize(g)) return -1; elseif (GetWMIInfo(g)) return -1; else
MaxSize = 0;
PDBUSER dup = PlgGetUser(g);
while (Enumerator) {
Res = Enumerator->Next(WBEM_INFINITE, 1, &ClsObj, &Rc);
if (Rc == 0) break;
MaxSize++;
} // endwhile Enumerator
Res = Enumerator->Reset(); #endif// 0
} // endif MaxSize
return MaxSize;
} // end of GetMaxSize
/***********************************************************************/ /* When making a Kindex, must provide the Key column info. */ /***********************************************************************/ int TDBWMI::GetRecpos(void)
{ if (!Kcol || !Vbp) return N;
Kcol->Reset();
Kcol->Eval(NULL);
Vbp->SetValue(Kcol->GetValue(), N); return N;
} // end of GetRecpos
/***********************************************************************/ /* WMI Access Method opening routine. */ /***********************************************************************/ bool TDBWMI::OpenDB(PGLOBAL g)
{ if (Use == USE_OPEN) { /*******************************************************************/ /* Table already open. */ /*******************************************************************/
Res = Enumerator->Reset();
N = 0; returnfalse;
} // endif use
if (Mode != MODE_READ) { /*******************************************************************/ /* WMI tables cannot be modified. */ /*******************************************************************/
safe_strcpy(g->Message, sizeof(g->Message), "WMI tables are read only"); returntrue;
} // endif Mode
if (!To_CondFil && !stricmp(Wclass, "CIM_Datafile")
&& !stricmp(Nspace, "root\\cimv2")) {
safe_strcpy(g->Message, sizeof(g->Message), "Would last forever when not filtered, use DIR table instead"); returntrue;
} else
DoubleSlash(g);
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/ /* Initialize the WMI processing. */ /*********************************************************************/ if (Initialize(g)) returntrue; else return GetWMIInfo(g);
} // end of OpenDB
/***********************************************************************/ /* Data Base read routine for WMI access method. */ /***********************************************************************/ int TDBWMI::ReadDB(PGLOBAL g)
{
Res = Enumerator->Next(WBEM_INFINITE, 1, &ClsObj, &Rc);
if (Rc == 0) return RC_EF;
N++; return RC_OK;
} // end of ReadDB
/***********************************************************************/ /* WriteDB: Data Base write routine for WMI access methods. */ /***********************************************************************/ int TDBWMI::WriteDB(PGLOBAL g)
{
safe_strcpy(g->Message, sizeof(g->Message), "WMI tables are read only"); return RC_FX;
} // end of WriteDB
/***********************************************************************/ /* Data Base delete line routine for WMI access methods. */ /***********************************************************************/ int TDBWMI::DeleteDB(PGLOBAL g, int irc)
{
safe_strcpy(g->Message, sizeof(g->Message), "Delete not enabled for WMI tables"); return RC_FX;
} // end of DeleteDB
/***********************************************************************/ /* Data Base close routine for WMI access method. */ /***********************************************************************/ void TDBWMI::CloseDB(PGLOBAL g)
{ // Cleanup if (ClsObj)
ClsObj->Release();
/***********************************************************************/ /* WMICOL public constructor. */ /***********************************************************************/
WMICOL::WMICOL(PCOLDEF cdp, PTDB tdbp, int n)
: COLBLK(cdp, tdbp, n)
{
Tdbp = (PTDBWMI)tdbp;
VariantInit(&Prop);
Ctype = CIM_ILLEGAL;
Res = 0;
} // end of WMICOL constructor
#if0 /***********************************************************************/ /* WMICOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/
WMICOL::WMICOL(WMICOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
{
} // end of WMICOL copy constructor #endif// 0
/***********************************************************************/ /* Read the next WMI address elements. */ /***********************************************************************/ void WMICOL::ReadColumn(PGLOBAL g)
{ // Get the value of the Name property
Res = Tdbp->ClsObj->Get(_bstr_t(Name), 0, &Prop, &Ctype, 0);
switch (Prop.vt) { case VT_EMPTY: case VT_NULL: case VT_VOID:
Value->Reset(); break; case VT_BSTR:
Value->SetValue_psz(_com_util::ConvertBSTRToString(Prop.bstrVal)); break; case VT_I4: case VT_UI4:
Value->SetValue((longlong)Prop.lVal); break; case VT_I2: case VT_UI2:
Value->SetValue(Prop.iVal); break; case VT_INT: case VT_UINT:
Value->SetValue((int)Prop.intVal); break; case VT_BOOL:
Value->SetValue(((int)Prop.boolVal) ? 1 : 0); break; case VT_R8:
Value->SetValue(Prop.dblVal); break; case VT_R4:
Value->SetValue((double)Prop.fltVal); break; case VT_DATE: switch (Value->GetType()) { case TYPE_DATE:
{SYSTEMTIME stm; struct tm ptm; int rc = VariantTimeToSystemTime(Prop.date, &stm);
break; default: // This will reset numeric column value
Value->SetValue_psz("Type not supported"); break;
} // endswitch vt
VariantClear(&Prop);
} // end of ReadColumn
/* ---------------------------TDBWCL class --------------------------- */
/***********************************************************************/ /* TDBWCL class constructor. */ /***********************************************************************/
TDBWCL::TDBWCL(PWMIDEF tdp) : TDBCAT(tdp)
{
Nsp = tdp->Nspace;
Cls = tdp->Wclass;
} // end of TDBWCL constructor
/***********************************************************************/ /* GetResult: Get the list of the WMI class properties. */ /***********************************************************************/
PQRYRES TDBWCL::GetResult(PGLOBAL g)
{ return WMIColumns(g, Nsp, Cls, false);
} // end of GetResult
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.3 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.