🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #14639

Re: Trying to use a variant type for API/WMI access

#14639
From: Vladimir Afanasyev
Date: Tue, 05 Aug 2003 14:32
195 lines
7006 bytes
Hi Maurice,

"Maurice Anderson" <mauriceanderson@hotmail.com> wrote:
>Here is my code that doesn't work:
>
> String IPAddress1[2], SubnetMask1[2];
> IPAddress1 [0] = "169.164.146.81";
> SubnetMask1[0] = "255.255.255.192";
> ret_code =  (Variant(NetAdapter)).Exec(Function("EnableStatic") <<
>*IPAddress1, *SubnetMask1);
>

Good things have begin, good things have end...
It just about Exec method. In this case we need to use 
a one-dimensional Variant array and OleFunction method.
Code was tested for BCB5:

Project .cpp file:

//---------------------------------------------------------------------------
#include <comobj.hpp>
#include <vcl.h>
#pragma hdrstop
USERES("NetAdapterConf.res");
USEFORM("Unit1.cpp", Form1);
USEFORM("Unit2.cpp", Form2);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
//It will work only for NT/2000/XP but you should set it because WMI as
//a rule need in CoInitializeEx(0, COINIT_MULTITHREADED)
CoInitFlags=COINIT_MULTITHREADED;
        try
        {
                 Application->Initialize();
                 Application->CreateForm(__classid(TForm1), &Form1);
                 Application->CreateForm(__classid(TForm2), &Form2);
                 Application->Run();
        }
        catch (Exception &exception)
        {
                 Application->ShowException(&exception);
        }
        return 0;
}


unit1.h:

must be added:

#include <objbase.h>
#include  <utilcls.h>

unit1.cpp:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    HRESULT hres;

hres = CoInitializeEx(0, COINIT_MULTITHREADED); //Initialize COM.
if (FAILED(hres))
   { ShowMessage("Failed to initialize COM library. Error code = "+IntToHex((int)hres,8));
     Application->Terminate();
   }

Button1->Enabled=false;

punkEnum=0;

//The IBindCtx interface provides access to a bind context, which is an object
//that stores information about a particular moniker binding operation.
IBindCtx *pbindctx;

//The IMoniker interface is used for naming COM objects. An object that
//implements IMoniker is called a "moniker," which is a name that uniquely
//identifies a COM object. I will use moniker for connecting to WMI using
//later binding.
IMoniker *pmoniker;

//Using later binding by moniker I will obtain pointer to dispatch interface to
//SWbemServices
IDispatch *dispServ;
ULONG ul;

//Creates a bind context.
//A bind context is an object that stores information about a particular
//moniker-binding operation:
HRESULT hresult=::CreateBindCtx(0,&pbindctx);
if(hresult != S_OK)
        {
         ShowMessage("CreateBindCtx error");
         pbindctx->Release();
         Application->Terminate();
        }

//Converts a string into a moniker that identifies the object named by the string.
//So I will try to create "WMI Moniker"

AnsiString ServMoniker="WinMgmts:{impersonationLevel=impersonate}!//./root/cimv2";

BSTR Monik=StringToOleStr(ServMoniker);
hresult = ::MkParseDisplayName(pbindctx, Monik,&ul,&pmoniker);

if(hresult != S_OK)
        {
         ShowMessage("Bad day, may be I'll create WMI moniker but not today.");
         pbindctx->Release();
         pmoniker->Release();
         Application->Terminate();
        }

//"Binds" the moniker; that is, returns a pointer to the object identified by the moniker.
//The binding process involves finding the object, getting it into the running
//state if it's not already, and acquiring an interface pointer to it.
//See carefully - I "get" Dispatch interface just for later binding
hresult=pmoniker->BindToObject(pbindctx,NULL,IID_IDispatch,(void**)&dispServ);
if(hresult != S_OK)
        {
         ShowMessage("They are still not here, bad day");
         pbindctx->Release();
         pmoniker->Release();
         dispServ->Release();
         Application->Terminate();
        }

//WQL query for obtaining collection of REAL LAN adapters
//Really this code only for one adapter but no problem to expand it.
Variant NetAdapters=((Variant)dispServ).Exec(Function("ExecQuery") << "Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE");


lcount=NetAdapters.Exec(PropertyGet("Count"));


    Variant vRet, v;
    penum = NULL;

    int nIndex;

    unsigned long cc;
    //Geting NetAdapter from  NetAdapters enumerator
    // Get _NewEnum property. Returns enumerator's IUnknown.

      punkEnum =NetAdapters.Exec(PropertyGet("_NewEnum"));


    //get IEnumVARIANT interface to enumerate instances
    punkEnum->QueryInterface(IID_IEnumVARIANT, (LPVOID FAR*)&penum);
    penum->AddRef();
    punkEnum->Release();

      Variant result;

    for(;;)
    {
    AnsiString AdapterInfo;
    VariantInit(&NetAdapter);
    //Get object:
    penum->Next(1,&NetAdapter,&cc);
    if(NetAdapter.vt == 0)break;
    AdapterInfo=(Variant(NetAdapter.pdispVal)).Exec(PropertyGet("Caption"));

    result=(Variant(NetAdapter.pdispVal)).Exec(PropertyGet("MACAddress"));
    if(!result.IsNull())
    AdapterInfo=AdapterInfo+", MacAddress="+(Variant(NetAdapter.pdispVal)).Exec(PropertyGet("MACAddress"));
    else AdapterInfo=AdapterInfo+", ";

//////Just main part
    BSTR IP=SysAllocString(L"192.168.1.10");
    //create a one-dimensional Variant array
    Variant IPAddress=Variant(&Variant(IP),0);

    BSTR MASK=SysAllocString(L"255.255.255.0");
    Variant NetMask=Variant(&Variant(MASK),0);

int Result=(Variant(NetAdapter.pdispVal)).OleFunction<Variant,Variant>("EnableStatic",IPAddress,NetMask);

    if(Result)ShowMessage("EnableStatic error = "+ IntToStr(Result));
     else  ShowMessage("EnableStatic executed successfully");
//////

    }
    penum->Release(); //free interface


dispServ->Release();
pbindctx->Release();
pmoniker->Release();

CoUninitialize();
}

I hope it will work for BCB6 if not give me know.
Vladimir.
Technical Details
Message-ID: <3f2fc011$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-03!sn-xit-01!sn-xit-08!supernews.com!pln-w!extra.newsguy.com!lotsanews.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mail
References: <3f2bfc2f$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10cc67,bc37caa35c7396c7
X-Google-Attributes: gid10cc67,public
X-Google-ArrivalTime: 2003-08-05 07:38:12 PST
From: "Vladimir Afanasyev" <avv@systema.kiev.ua>
Sender: "Vladimir Afanasyev" <avv@systema.kiev.ua>
Reply-To: "Vladimir Afanasyev" <avv@systema.kiev.ua>
Subject: Re: Trying to use a variant type for API/WMI access
Newsgroups: borland.public.cppbuilder.nativeapi
X-User-Info: 212.82.216.226 212.82.216.226    
X-Forwarded-For: 192.168.0.147
References:  <3f2bfc2f$1@newsgroups.borland.com>
NNTP-Posting-Host: 207.105.83.65
Message-ID: <3f2fc011$1@newsgroups.borland.com>
Date: 5 Aug 2003 07:32:49 -0700
X-Trace: newsgroups.borland.com 1060093969 207.105.83.65 (5 Aug 2003 07:32:49 -0700)
Lines: 195
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-03!sn-xit-01!sn-xit-08!supernews.com!pln-w!extra.newsguy.com!lotsanews.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mail