I'm writting wmi scripting wrapper class: connecting, requesting, selecting and requesting/changing properties is done and works like in vbs.
Now is time for executing methods. I have used class method of CDECL type, so variable number of arguments can be passed.
Arguments from stack are copied into VARIANT structure, strings and int's are no problem.
I'm not sure about float and double:
what i think:
- usage (pushing) of float is same as for int, string (4 bytes)
- double - pointer to double is pushed onto stack
also this it the important bit of my method:
CSWbemObject :: ExecMethod(/*MethodName, arguments*/...),heap
{
ÂÃ, int argc = va_count()-1;
ÂÃ, void *arg = va_start(this);
...
ÂÃ, VARIANT vArg;
ÂÃ, wbemCimtypeEnum cim;
...
ÂÃ, vArg.vt = cim;ÂÃ, // ISWbemProperty property->get_CIMType(&cim);
ÂÃ, vArg.intVal = *(int)arg; // as default for byte/word/int (and float ?)
ÂÃ, if (cim = wbemCimtypeString)
ÂÃ, Ã‚Ã, vArg.bstrVal = SysAllocString(a2w(*(string)*(pointer)arg)); // ok
ÂÃ, if (cim = wbemCimtypeReal32) vArg.fltVal = *(float)arg;ÂÃ, // i hope this can be removed
ÂÃ, // double
ÂÃ, if (cim = wbemCimtypeReal64) vArg.dblVal = *(double)*(pointer)arg;
ÂÃ, property->put_Value(vArg);
ÂÃ, VariantClear(vArg);
...
}
Am i correct?
Question: is someone interested in Aurora like scripting wmi? ;D
vbs:Set objWMIService = GetObject("winmgmts:" & "!\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery ("Select * from CIM_DataFile where Name = 'c:\\wmirenametest.vbs'")
For Each objFile in colFiles
ÂÃ, Ã‚Ã, errResult = objFile.Rename("c:\scripts\toggle_service.old")
Next
aurora:CSWbemServices root;
CSWbemServices *objWMIService = root.GetObject("winmgmts:!\\\\.\\root\\cimv2");
if (objWMIService)
{
CSWbemObjectSet *colFiles = objWMIService->ExecQuery(
"Select * from CIM_DataFile where Name = 'c:\\\\wmirenametest.vbs'");
if (colFiles)
{
CSWbemObject *objFile = colFiles->ForEach();
while (objFile)
{
string sret = objFile->ExecMethod("Rename", "c:\\wmirenametest.old");
delete objFile;
objFile = colFiles->ForEach();
}
delete colFiles;
}
delete objWMIService;
}
For a CDECL function doubles are pushed onto the stack by value, 8 bytes.
http://www.programmersheaven.com/2/Calling-conventions
yup, this is correct! thanks
extern byte _getch();
class CTest {
declare int_float_double_int(...);
}
global sub main() {
CTest c;
int idata = 1;
float fdata = 1.1;
double ddata = 1.2;
c.int_float_double_int(idata, fdata, ddata, idata);
return _getch();
}
CTest :: int_float_double_int(...)
{
int vacount;
#emit mov esi,[ebp+4] ; return address
#emit mov eax,[esi+2] ; add esp,dword
#emit shr eax,2 ; dword/4
#emit dec eax ; dword=1
#emit mov [ebp-4],eax ; save in vacount
print("vacount = ", vacount);
void *args = va_start(this);
// note: after *(double)(args+8) - next argument is at args+8+4+4
print("double: ",
*(int)(args+0)," ",
*(float)(args+4)," ",
*(double)(args+8)," ",
*(int)(args+16));
return;
}