News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

WMI Win32_ComputerSystem Rename method

Started by Drmres, November 08, 2011, 02:18:26 AM

Previous topic - Next topic

Drmres

Hi,

Can anyone point me in the right direction for implementing the Rename method of the Win32_ComputerSystem class?

http://msdn.microsoft.com/en-us/library/windows/desktop/aa393056(v=VS.85).aspx

I'm going around in circles trying to find where to go from the folowing...


INVOKE CoInitializeEx, NULL, COINIT_MULTITHREADED
INVOKE CoInitializeSecurity, NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL
INVOKE CoCreateInstance, ADDR CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, ADDR IID_IWbemLocator, ADDR Locator

;GetObject
    mov esi,Locator
    lodsd
    push    OFFSET Service
    push    NULL
    push    NULL
    push    WBEM_FLAG_CONNECT_USE_MAX_WAIT
    push    NULL
    push    NULL
    push    NULL
    push    OFFSET wszNameSpace
    push    DWORD PTR [Locator]
    call    DWORD PTR [eax][IWbemLocatorVtbl.ConnectServer]

;ExecQuery
    mov esi, Service
    lodsd
    push    OFFSET Enumerator
    push    NULL
    push    WBEM_FLAG_FORWARD_ONLY
    push    OFFSET wszQuery ;Unicode: SELECT * FROM Win32_ComputerSystem
    push    OFFSET wszQueryLanguage ;Unicode: WQL
    push    DWORD PTR [Service]
    call    DWORD PTR [eax][IWbemServicesVtbl.ExecQuery]

;Start enumeration
    mov esi, Enumerator
    lodsd
    push    OFFSET retCount
    push    OFFSET Processor
    push    TRUE
    push    WBEM_INFINITE
    push    DWORD PTR [Enumerator]
    call    DWORD PTR [eax][IEnumWbemClassObjectVtbl.Next]


Thank you

ToutEnMasm

You need first to connect the Winmgmts:root\cimv2.
A sample doing this is in "ready to use sdk" in windows.inc subforum.
\sdkrc7\samples\WMI
Quote
;################################################################
initWMI PROC
         Local  retour:DWORD
   mov retour,0
   invoke CoInitializeEx,NULL,COINIT_MULTITHREADED   
   invoke CoInitializeSecurity,NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
         RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL
   .if eax != S_OK
      jmp FindeinitWMI
   .endif
   
   ;-------- accès au serveur -----------------------------
   invoke CoCreateInstance,addr CLSID_WbemLocator,NULL ,
            CLSCTX_INPROC_SERVER ,addr IID_IWbemLocator ,addr ppvIWbemLocator
   .if eax != S_OK
      jmp FindeinitWMI
   .endif
      ;connect to WMI
   mov ecx,FUNC(CreateBstr,SADR("root\cimv2"))
   ;WBEM_FLAG_CONNECT_USE_MAX_WAIT
   IWbemLocator ConnectServer,ecx,NULL,NULL,NULL,NULL,\
                  NULL,NULL,addr ppvIWbemServices
   .if eax != WBEM_S_NO_ERROR
      mov edx,eax
      invoke ErrorConnect,edx
      jmp FindeinitWMI
   .endif
      ; Step 5: --------------------------------------------------
       ; Set security levels for the proxy ------------------------
   invoke CoSetProxyBlanket,ppvIWbemServices,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,\
      RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE    
   .if eax != S_OK
      jmp FindeinitWMI   ;let's do the freeing routines
   .endif
   ; Step 6: --------------------------------------------------
   ; Use the IWbemServices pointer to make requests of WMI ----   
   
   mov ClassName,FUNC(CreateBstr,SADR("Win32_Process"))
   mov MethodName,FUNC(CreateBstr,SADR("Create"))
   ;GetObject is also a library function
   ;so the interface function GetObject as been renamed GetObject1
   ;to avoid errors at link time   
       IWbemServices GetObject1,ClassName, 0, NULL,addr ppvIWbemClassObject, NULL
   IWbemClassObject GetMethod,MethodName, 0,addr ppvInParamsDefinition, NULL
   ;The GetMethod return a new pointer on a IWbemClassObject
   InParamsDefinition SpawnInstance,0,addr ppvClassInstance
   ;SpawnInstance create a new instance of IWbemClassObject
   mov varCommand.n1.n2.vt,VT_BSTR
   mov varCommand.n1.n2.n3.bstrVal,FUNC(CreateBstr,SADR("notepad.exe"))
   mov command,FUNC(CreateBstr,SADR("CommandLine"))
   ClassInstance Put,command, 0,addr varCommand,0
   ;------------ launch notepad.exe -----------------------
   IWbemServices ExecMethod,ClassName,MethodName, 0,NULL,ppvClassInstance,addr ppvOutParams, NULL
FindeinitWMI:
   mov eax,retour
   ret
initWMI endp


ToutEnMasm


WMI made  complex use of com.
Some com pointers are duplicate (Same interface but with a new pointer)
tO avoid to create  new macro use this one.
Quote
;add: DECLARE_pointeur TEXTEQU <STInterFace>
;where pointeur is
; pointeur dd     ;all name who get the com pointer
; USAGE:
; COM pointeur,Release  ;usefull with duplicate pointer
COM MACRO ppv:REQ,fonction:REQ,args:VARARG
   local InvokeInterface
   computeoffset CATSTR <DECLARE_>,<ppv>
   ;---------- controle les arguments
    FOR arg, <args>     ;verifier que edx n'est pas dans la liste d'arguments args
        IFIDNI <&arg>, <edx>   ;
            .ERR <edx is not allowed as a coinvoke parameter>
        ENDIF
    ENDM
    IFIDNI <&pInterface>, <edx>
        .ERR <edx is not allowed as a coinvoke parameter>
    ENDIF
   ;------------ fin de controle --------------------------------
   ;InvokeInterface = concatene ...CATSTR(concatene) MACRO instruction MASM32   
   ;---------- on doit mettre ppv en premier argument -----------------------------------
    InvokeInterface CATSTR <invoke (computeoffset ptr  [edx]).>,<&fonction,ppv>
    IFNB <args>     ; add the list of parameter arguments if any
        InvokeInterface CATSTR InvokeInterface, <, >, <&args>
    ENDIF
   ; -- charge le pointeur ---------------------
    mov edx, ppv
    mov edx, [edx]
    InvokeInterface      
ENDM

Usind it,you have the arguments in the same order as c++.
Where c++ write  Mycompointer->function ...
You write            COM Mycompointer,function,.....

ToutEnMasm


two functions can be used:
SetComputerName and GetComputerName

Drmres

I have already successfully connected to the COM interface and have enumerated WIN32_ComputerSystem.

This is where I am stuck as I can't work out how to find the Rename method with IWbemClassObjectVtbl.GetMethod and then implement it.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa391443(v=VS.85).aspx

Your code seems to be a direct port from the C++ example -

http://msdn.microsoft.com/en-us/library/windows/desktop/aa390421(v=VS.85).aspx

- which I had already found, but it does not explain what I need help with.

Also SetComputerName and GetComputerName only relate to NetBIOS.

Can anyone help with what I should do next after the original code?


ToutEnMasm

the:
Quote
IWbemServices GetObject1,ClassName, WBEM_FLAG_DIRECT_READ, NULL,addr ppvISWbemServices,
don't work also.
Quote
push    OFFSET wszQuery ;Unicode: SELECT * FROM Win32_ComputerSystem
is wrong,must be
Quote
push    OFFSET wszQuery ;wszQuery db "Win32_ComputerSystem",0 in unicode

ToutEnMasm


Drmres

ToutEnMASM, thank you very much for trying to help, but I think there is a language gap and you aren't seeing what I am trying to achieve.

The code I posted, athough it is partial, works without problems and I implement it elsewhere.

I can connect to WMI, can evaluate its classes, and can retrieve values. All with the code I posted. The text after the semicolons (;) are comments to show I am passing Unicode (Your first quote comes from your own code!). One section of my code accesses WMI to retrieve the current computer name (without problems).

I am trying to access the 'Rename' method of 'WIN32_ComputerSystem', and am failing because MSDN doesn't adecuatley explain the process logically, as far as I can see.

I am trying to rename the local computer via the WIN32_ComputerSystem.Rename method. I'm not interested at the moment of doing so across a domain, so its user/pass options are not relevant, but I have searched everywhere for how to evaluate and process this method without luck.

I really don't want it to be a port from C++ or equivalent, as I would have attempted it in that language or higher if I needed to - with its overheads. I need pure assembler without shortcuts and macros.

I am still going in circles! Can you help?

Thank you very much.

ToutEnMasm


At the instant ,i see that you use only unicode string , the api need BSTR.
A bstr is an unicode string in memory allocated by SysAllocString.
Take care of this.
This made two changes     :The memory haven't the same access property
                                      :The SysAllocString add a 0,0 at the start of the chain.
To read a bstr you have to do this:
Quote
         mov edx,pBstrDescription          ;bstr value
         add edx,2                               ;add two to the pointer
         invoke UtoA,edx                      ;translate to ANSI

ToutEnMasm


I think i have found the way
Quote
   mov methodfor,BSTR("Win32_ComputerSystem")
   IWbemServices GetObject1,methodfor,0,0,0,addr ppvIWbemCallResult
   .if ppvIWbemCallResult != 0
      IWbemCallResult Release
   .else
      invoke MessageBox,NULL,NULL,SADR("IWbemCallResult"),MB_OK
   .endif

then follow the c++ smple
void GetObjSemiSync(IWbemServices *pSvc)
{

    IWbemCallResult *pCallRes = 0;<<<<<<<<< you have this one
    IWbemClassObject *pObj = 0;
   
    HRESULT hRes = pSvc->GetObject(_bstr_t(L"MyClass=\"AAA\""), 0,
        0, 0, &pCallRes
        );       It's done upper
       
    if (hRes || pCallRes == 0)
        return;
       
    while (1)
    {
        LONG lStatus = 0;
        HRESULT hRes = pCallRes->GetCallStatus(5000, &lStatus);
        if (!(hRes == WBEM_S_NO_ERROR) || (hRes == WBEM_S_TIMEDOUT)))
            break;

        // Do another task
    }

    hRes = pCallRes->GetResultObject(5000, &pObj);
    if (hRes)
    {
        pCallRes->Release();
        return;
    }

    pCallRes->Release();

    // Use the object.

    // ...

    // Release it.
    // ===========
       
    pObj->Release();    // Release objects not owned.           
 
}



ToutEnMasm

Final soluce:
There is a trick with
Quote
********** IWbemServices ExecMethod strObjectPath ********
\\HERISSON\root\cimv2:Win32_ComputerSystem.Name="HERISSON"

and NOT   
QuoteWin32_ComputerSystem
   only

This can be get as follow:
Quote
   IWbemLocator ConnectServer,ecx,NULL,NULL,NULL,NULL,\
                  NULL,NULL,addr ppvIWbemServices

.............................

;
   mov langage,BSTR("WQL")
   mov query,BSTR("SELECT * FROM Win32_ComputerSystem")
   IWbemServices   ExecQuery,langage,query,\
      WBEM_FLAG_FORWARD_ONLY OR WBEM_FLAG_RETURN_IMMEDIATELY,\
      NULL,addr pEnumerator ;IEnumWbemClassObject
   .if ppvIWbemClassObject != 0
      mov edx,0
   .endif
   @@:
   COM pEnumerator,Next,WBEM_INFINITE, 1,addr ppvIWbemClassObject,addr retour ;IWbemClassObject
   .if retour != 0
      jmp @B
   .endif
   COM pEnumerator,Release

   invoke VariantInit,addr varpath
   invoke AtoU,SADR("__PATH")
   mov ecx,eax
   IWbemClassObject Get,ecx,NULL ,addr varpath,NULL,NULL   
   IWbemClassObject Release
   ;----------------------------------------------------------------------
IWbemServices ExecMethod,varpath.n1.n2.n3.bstrVal,MethodName,0,NULL,MethodNewInstance,NULL, NULL


I will post a complete sample in another post