🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

COM not initializing in custom compenent dropped on form

#5249
From: Maurice Anderson
Date: Wed, 21 Sep 2005 05:51
463 lines
17222 bytes
I have a component name TWmi.  It basically makes a connection to WMI using 
COM.  In the component's constructor, I have six functions ranging
from initializing COM to Executing a WMI Query.

A little background:
--------------------
In the first function "InitializeCOM()", I divert to a separate TThread 
object to initialize COM.  I do this so I can set 
CoInitFlags=COINIT_MULTITHREADED.  That way a developer doesn't have to 
worry about setting the flag in his/her project application.

To test the component, I created a basic application with a single form 
(Form1).  I then explicitly create the TWmi object using the new keyword as 
in Wmi2 = new TWmi(this);  It is created in the OnShow event of Form1.  And 
presto!, it works great; COM gets initialized and I am able to execute a WMI 
Query.

However, if I decide to drop the component on Form1, COM does not 
initialize.  It flat out doesn't work and I am able to test this by my 
putting a ShowMessage if it fails.  So my custom message pops up saying it 
fails.

Does anyone know what could be the problem?  I am including all my CPP and H 
files as reference.

Thanks,

-M-


*******************************************Unit1.cpp****************************************************************
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button2Click(TObject *Sender)
{
// Wmi1->SQL = "SELECT * FROM  Win32_NetworkAdapter";
// Wmi1->SQL = "SELECT * FROM  Win32_IRQResource";
// Wmi1->SQL = "SELECT * FROM  Win32_DiskDrive";

}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormShow(TObject *Sender)
{
 Wmi2 = new TWmi(this);
}
//---------------------------------------------------------------------------

***********************************************Unit1.h************************************************************
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "E:\Moe\Programming\FromWork\ForNewsGroup\TWmi.h"
#include <Db.hpp>

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
        TMemo *Memo1;
        TButton *Button2;
        TEdit *Edit1;
        TButton *Button1;
        void __fastcall Button2Click(TObject *Sender);
        void __fastcall FormShow(TObject *Sender);
private:
    // User declarations
        TWmi *Wmi2;
public:  // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
***********************************************TWmi.cpp************************************************************
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "TWmi.h"
#include "Unit1.h"
//#include "Unit1.cpp"
#include <safearry.h>
# pragma comment(lib, "wbemuuid.lib")

#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TWmi *)
{
        new TWmi(NULL);
}
//---------------------------------------------------------------------------
__fastcall TWmi::TWmi(TComponent* Owner)
        : TDataSource(Owner)
{
 InitializeCOM();
 InitializeCOMSecurity();
 InitializeCOMLocator();
 ConnectToWmiRoot("ROOT\\CIMV2");
 SetCOMSecurity();
 ExecuteCOMQuery("SELECT * FROM  Win32_NetworkAdapter");

}
//---------------------------------------------------------------------------
namespace Twmi
{
        void __fastcall PACKAGE Register()
        {
                 TComponentClass classes[1] = {__classid(TWmi)};
                 RegisterComponents("Maurice", classes, 0);
        }
}
//---------------------------------------------------------------------------

void __fastcall TWmi::InitializeCOM(void)
{
    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------


  TComInitialize *SecondProcess = new TComInitialize(true, pSvc, pLoc); // 
create but don't run
  SecondProcess->Priority = tpLower; // set the priority lower than normal
  SecondProcess->Resume();
  SecondProcess->WaitFor();
}
//---------------------------------------------------------------------------
void __fastcall TWmi::InitializeCOMSecurity(void)
{
    // 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 ------------------------
//   Form1->Memo1->Lines->Add("Initializing Security.....");


    hres =  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 (FAILED(hres))
    {
    ShowMessage("Failed on InitializeCOMSecurity");
        //Form1->Memo1->Lines->Add("Failed to initialize security. Error 
code = 0x");
        //CoUninitialize();
        return;                    // Program has failed.
    }

        //Form1->Memo1->Lines->Add("Initialized Security.....");
}
//---------------------------------------------------------------------------
void __fastcall TWmi::InitializeCOMLocator(void)
{
    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------
//    Form1->Memo1->Lines->Add("Obtaining IWbemLocator object.....");

     hres = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator,
        (LPVOID *) &pLoc
        );


    if (FAILED(hres))
    {
        ShowMessage("Failed on InitializeCOMLocator");
        //Form1->Memo1->Lines->Add("Failed to create IWbemLocator object.");
        //CoUninitialize();
        return;                 // Program has failed.
    }
        //Form1->Memo1->Lines->Add("Obtained IWbemLocator object.....");
}
//---------------------------------------------------------------------------
void __fastcall TWmi::ConnectToWmiRoot(AnsiString Path)
{
//    Form1->Memo1->Lines->Add("Connecting to " + Path + " WMI namespace");
    // 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.

    hres = pLoc->ConnectServer(
         WideString(L"ROOT\\CIMV2"), // 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
         &pSvc                    // pointer to IWbemServices proxy
         );

    if (FAILED(hres))
    {
        ShowMessage("Failed on ConnectToWmiRoot");
        pLoc->Release();
        //Form1->Memo1->Lines->Add("Could not connect. Error code = 0x");
        //CoUninitialize();
        return;                // Program has failed.
    }
        //Form1->Memo1->Lines->Add("Connected to ROOT\\CIMV2 WMI 
namespace");
}
//---------------------------------------------------------------------------
void __fastcall TWmi::SetCOMSecurity(void)
{
    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------
//    Form1->Memo1->Lines->Add("Setting Security Levels.....");


    hres = CoSetProxyBlanket(
       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 (FAILED(hres))
    {
        ShowMessage("Failed on SetCOMSecurity");
        //Form1->Memo1->Lines->Add("Could not set proxy blanket. Error code 
= 0x");
        pSvc->Release();
        pLoc->Release();
//        CoUninitialize();
        return;               // Program has failed.
    }
        //Form1->Memo1->Lines->Add("Setted Security Levels.....");
}
//---------------------------------------------------------------------------

void __fastcall TWmi::ExecuteCOMQuery(AnsiString Query)
{
    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----
    // For example, get the name of the operating system

//    Form1->Memo1->Lines->Add("Testing.......");
    pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        WideString("WQL"),
        WideString(Query),
        WBEM_FLAG_BIDIRECTIONAL | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

    if (FAILED(hres))
    {
        ShowMessage("Failed on ExecuteCOMQuery");
        //Form1->Memo1->Lines->Add("Query for operating system name 
failed.");
        pSvc->Release();
        pLoc->Release();
//        CoUninitialize();
        return ;               // Program has failed.
    }
        //Form1->Memo1->Lines->Add("Query Successful");
}
//---------------------------------------------------------------------------
__fastcall TWmi::~TWmi(void)
{
    // Cleanup
    // ========

    if(pSvc){pSvc->Release();};
    if(pLoc){pLoc->Release();};
    if(pEnumerator){pEnumerator->Release();};
    if(pclsObj){pclsObj->Release();};
    if(pclsObj1){pclsObj1->Release();};

    CoUninitialize();
}
*********************************************TWmi.h**************************************************************
//---------------------------------------------------------------------------

#ifndef TWmiH
#define TWmiH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include "Include\Wbemidl.h"
#include "Unit2.h"
#include <safearry.h>

//---------------------------------------------------------------------------
class PACKAGE TWmi : public TDataSource
{
private:
        IWbemServices *pSvc;// = NULL;
        IWbemLocator  *pLoc;// = NULL;
        IEnumWbemClassObject* pEnumerator;
        IWbemClassObject *pclsObj, *pclsObj1;
        HRESULT hres ;


        //---------------------------------------------------------------------------
        void __fastcall InitializeCOM(void);
        void __fastcall InitializeCOMSecurity(void);
        void __fastcall InitializeCOMLocator(void);
        void __fastcall ConnectToWmiRoot(AnsiString Path);
        void __fastcall SetCOMSecurity(void);
        void __fastcall ExecuteCOMQuery(AnsiString Query);

protected:

public:
        __fastcall  TWmi(TComponent* Owner);
        __fastcall ~TWmi(void);
__published:

};
//---------------------------------------------------------------------------
#endif
***********************************************Unit2.cpp************************************************************
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <comobj.hpp>

#include "Unit2.h"
#include "..\Wmi\Unit1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------

//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall Unit2::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------

__fastcall TComInitialize::TComInitialize(bool CreateSuspended,
                                      IWbemServices *pSvc1, IWbemLocator 
*pLoc1)
        : TThread(CreateSuspended)
{
 CoInitFlags=COINIT_MULTITHREADED;
 pSvc = pSvc1;
 pLoc = pLoc1;
 this->OnTerminate = ThreadTerminate;
}
//---------------------------------------------------------------------------
void __fastcall TComInitialize::Execute()
{
 InitializeCOM();
}
//---------------------------------------------------------------------------

void __fastcall TComInitialize::InitializeCOM(void)
{
    // Step 1: -------------------------------------------------- 
    // Initialize COM. ------------------------------------------
//    Form1->Memo1->Lines->Add("Initializing COM Library.....");
    HRESULT hres;

    hres =  CoInitializeEx(0, COINIT_MULTITHREADED);

   if (FAILED(hres))
    {
    ShowMessage("Failed on InitializeCOM");

        return;                  // Program has failed.
    }

}
//---------------------------------------------------------------------------
void __fastcall TComInitialize::ThreadTerminate(TObject *Sender)
{
//  ShowMessage("ThreadTerminate");
}
//---------------------------------------------------------------------------

**********************************************Unit2.h*************************************************************
//---------------------------------------------------------------------------

#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include "Include\Wbemidl.h"
//---------------------------------------------------------------------------
class TComInitialize : public TThread
{
private:
        HRESULT hres;
        IWbemServices *pSvc;
        IWbemLocator  *pLoc;
        IEnumWbemClassObject* pEnumerator;
        IWbemClassObject *pclsObj;
        void __fastcall ThreadTerminate(TObject *Sender);
protected:
        void __fastcall Execute();
        void  __fastcall InitializeCOM(void);
public:
         __fastcall TComInitialize(bool CreateSuspended, IWbemServices 
*pSvc1,
                                                          IWbemLocator 
*pLoc1);
};
//---------------------------------------------------------------------------
#endif
Technical Details
Message-ID: <4330f48c@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!feed6.newsreader.com!newsreader.com!news-out2.kabelfoon.nl!newsfeed.kabelfoon.nl!xindi.nntp.kabelfoon.nl!194.25.134.62.MISMATCH!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,83e8798583d6ac12,start
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Maurice Anderson" <mauriceanderson@hotmail.com>
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: COM not initializing in custom compenent dropped on form
Date: Tue, 20 Sep 2005 22:51:38 -0700
Lines: 465
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2180
X-RFC2646: Format=Flowed; Original
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
NNTP-Posting-Host: 64.30.203.223
Message-ID: <4330f48c@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1127281804 64.30.203.223 (20 Sep 2005 22:50:04 -0700)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!feed6.newsreader.com!newsreader.com!news-out2.kabelfoon.nl!newsfeed.kabelfoon.nl!xindi.nntp.kabelfoon.nl!194.25.134.62.MISMATCH!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail