Article View: borland.public.cppbuilder.nativeapi
Article #5249COM not initializing in custom compenent dropped on form
From: Maurice Anderson
Date: Wed, 21 Sep 2005 05:51
Date: Wed, 21 Sep 2005 05:51
463 lines
17222 bytes
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-mailShow 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