PowerBASIC Forums
  Source Code
  Windows Management Instrumentation (WMI) example

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   Windows Management Instrumentation (WMI) example
JOSE ROCA
Member
posted August 24, 2003 02:13 PM     Click Here to See the Profile for JOSE ROCA     Edit/Delete Message   Reply w/Quote

' *********************************************************************************************
' What Is WMI?
' ============
' "Originally released in 1998 as an add-on component with Windows NT 4.0 Service Pack 4, WMI is
' the core management-enabling technology built into Windows 2000, Windows XP, and the Windows
' Server 2003 family of operating systems. Based on industry standards overseen by the Distributed
' Management Task Force (DMTF), WMI is the instrumentation and plumbing through which all--well,
' almost all--Windows resources can be accessed, configured, managed, and monitored."
' For further reading:
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/ html/scripting06112002.asp
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/ html/scripting08132002.asp
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/ html/scripting01142003.asp
' For the SDK documentation:
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_ start_page.asp
'
' I have begin to explore the Windows Management Instrumentation (WMI) component and have made an
' example to help you to get started. The two main problems when reading the documentation is that
' most of the examples are for VB or VBScript and they use some instructions not available in PB,
' mainly GetObject and For Each.
'
' An instruction like
'
' Set objWMIService = GetObject("winmgmts:" _
' & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
'
' translates to PB as
'
' DIM oLocator AS DISPATCH
' SET oLocator = NEW DISPATCH IN "WbemScripting.SWbemLocator"
' DIM vServer AS VARIANT, vNameSpace AS VARIANT, vImpersonation AS VARIANT
' vComputer = "." : vNameSpace = "root\cimv2"
' OBJECT CALL oLocator.ConnectServer(vComputer, vNameSpace) TO vRes
' SET objWMIService = vRes
' vImpersonation = 3 AS LONG ' Impersonate
' OBJECT LET objWMIService.Security_.ImpersonationLevel = vImpersonation
'
' Regarding For Each, used to enumerate collections, I have made some functions to access the
' IEnumVARIANT interface, that provides enumeration functionality.
'
' There are a lot of classes, and the easiest way is to use ExecQuery, that uses an WQL string
' (a subset of the SQL query language) as the parameter. You can control the number of properties
' returned, e.g.
'
' vWQL = "SELECT * FROM Win32_Process"
' OBJECT CALL oServices.ExecQuery(vWQL) TO vRes
'
' returns all the properties of the "Win32_Process" class, while
'
' vWQL = "SELECT ProcessID FROM Win32_Process"
'
' only returns the ProcessID property, and
'
' vWQL = "SELECT * FROM Win32_Process WHERE name='AcroRd32.exe'"
'
' returns all the properties of Acrobat Reader (if it is running).
'
' Knowing the ProcessID of a program, you can terminate it calling the method Terminate.
'
' The properties of the "Win32_Process" class are:
'
' class Win32_Process : CIM_Process
' {
' string Caption;
' string CommandLine;
' string CreationClassName;
' datetime CreationDate;
' string CSCreationClassName;
' string CSName;
' string Description;
' string ExecutablePath;
' uint16 ExecutionState;
' string Handle;
' uint32 HandleCount;
' datetime InstallDate;
' uint64 KernelModeTime;
' uint32 MaximumWorkingSetSize;
' uint32 MinimumWorkingSetSize;
' string Name;
' string OSCreationClassName;
' string OSName;
' uint64 OtherOperationCount;
' uint64 OtherTransferCount;
' uint32 PageFaults;
' uint32 PageFileUsage;
' uint32 ParentProcessId;
' uint32 PeakPageFileUsage;
' uint64 PeakVirtualSize;
' uint32 PeakWorkingSetSize;
' uint32 Priority;
' uint64 PrivatePageCount;
' uint32 ProcessId;
' uint32 QuotaNonPagedPoolUsage;
' uint32 QuotaPagedPoolUsage;
' uint32 QuotaPeakNonPagedPoolUsage;
' uint32 QuotaPeakPagedPoolUsage;
' uint64 ReadOperationCount;
' uint64 ReadTransferCount;
' uint32 SessionId;
' string Status;
' datetime TerminationDate;
' uint32 ThreadCount;
' uint64 UserModeTime;
' uint64 VirtualSize;
' string WindowsVersion;
' uint64 WorkingSetSize;
' uint64 WriteOperationCount;
' uint64 WriteTransferCount;
' };
'
' and the methods:
'
' AttachDebugger : Launches the currently registered debugger for a process.
' Create : Creates a new process.
' GetOwner : Retrieves the user name and domain name under which the process is running.
' GetOwnerSid : Retrieves the security identifier (SID) for the owner of a process.
' SetPriority : Changes the execution priority of a process.
' Terminate : Terminates a process and all of its threads.
' *********************************************************************************************

#COMPILE EXE
#DIM ALL
#DEBUG ERROR ON

#INCLUDE "win32api.inc"

' *********************************************************************************************
' Determines whether the object supports a particular COM interface. If it does, the system
' increases the object's reference count, and the application can use that interface
' Parameters:
' pThis [in] : Pointer to the interface to be queried.
' riid [in] : A Guid, passed by reference, that is the interface identifier (IID) of the
' requested interface.
' ppvObj [out] : Address of pointer variable that receives the interface pointer requested in
' riid. Upon successful return, *ppvObject contains the requested interface pointer to
' the object. If the object does not support the interface specified in iid, *ppvObject
' is set to NULL.
' Return Value:
' %S_OK if the interface is supported, %E_NOINTERFACE if not.
' *********************************************************************************************
DECLARE FUNCTION Template_IEnumVARIANT_QueryInterface (BYVAL pThis AS DWORD, BYREF riid AS GUID, BYVAL ppvObj AS DWORD) AS DWORD
' *********************************************************************************************
FUNCTION IEnumVARIANT_QueryInterface (BYVAL pThis AS DWORD, BYREF riid AS GUID, BYVAL ppvObj AS DWORD) AS DWORD
LOCAL HRESULT AS DWORD
LOCAL ppthis AS DWORD PTR
LOCAL pvtbl AS DWORD PTR
LOCAL ppmethod AS DWORD PTR
LOCAL pmethod AS DWORD
ppthis = pThis
pvtbl = @ppthis
ppmethod = pvtbl
pmethod = @ppmethod
CALL DWORD pmethod USING Template_IEnumVARIANT_QueryInterface(pThis, riid, ppvObj) TO HRESULT
FUNCTION = HRESULT
END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' Decrements the reference count on the specified interface. If the reference count on the
' object falls to 0, the object is freed from memory.
' Returns the resulting value of the reference count, which is used for diagnostic/testing
' purposes only.
' *********************************************************************************************
DECLARE FUNCTION Template_IEnumVARIANT_Release (BYVAL pThis AS DWORD) AS DWORD
' *********************************************************************************************
FUNCTION IEnumVARIANT_Release (BYVAL pThis AS DWORD) AS DWORD
LOCAL HRESULT AS DWORD
LOCAL ppthis AS DWORD PTR
LOCAL pvtbl AS DWORD PTR
LOCAL ppmethod AS DWORD PTR
LOCAL pmethod AS DWORD
ppthis = pThis
pvtbl = @ppthis
ppmethod = pvtbl + 8
pmethod = @ppmethod
CALL DWORD pmethod USING Template_IEnumVARIANT_Release(pThis) TO HRESULT
FUNCTION = HRESULT
END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' The Next method enumerates the next celt elements in the enumerator's list, returning them in
' rgelt along with the actual number of enumerated elements in pceltFetched.
' Parameters:
' celt : [in] Number of items in the array.
' rgelt : [out] Address of array containing items.
' pceltFetched: [out] Address of variable containing actual number of items.
' Return Value:
' Returns %S_OK if the method succeeds.
' *********************************************************************************************
DECLARE FUNCTION Template_IEnumVARIANT_Next (BYVAL pThis AS DWORD, BYVAL celt AS DWORD, BYREF rgelt AS VARIANT, BYREF pceltFetched AS DWORD) AS DWORD
' *********************************************************************************************
FUNCTION IEnumVARIANT_Next (BYVAL pThis AS DWORD, BYVAL celt AS DWORD, BYREF rgelt AS VARIANT, BYREF pceltFetched AS DWORD) AS DWORD
LOCAL HRESULT AS DWORD
LOCAL ppthis AS DWORD PTR
LOCAL pvtbl AS DWORD PTR
LOCAL ppmethod AS DWORD PTR
LOCAL pmethod AS DWORD
ppthis = pThis
pvtbl = @ppthis
ppmethod = pvtbl + 12
pmethod = @ppmethod
CALL DWORD pmethod USING Template_IEnumVARIANT_Next(pThis,celt,rgelt,pceltFetched) TO HRESULT
FUNCTION = HRESULT
END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' The Reset method instructs the enumerator to position itself at the beginning of the list
' of elements.
' Return Value:
' Returns %S_OK if the method succeeds.
' *********************************************************************************************
DECLARE FUNCTION Template_IEnumVARIANT_Reset (BYVAL pThis AS DWORD) AS DWORD
' *********************************************************************************************
FUNCTION IEnumVARIANT_Reset (BYVAL pThis AS DWORD) AS DWORD
LOCAL HRESULT AS DWORD
LOCAL ppthis AS DWORD PTR
LOCAL pvtbl AS DWORD PTR
LOCAL ppmethod AS DWORD PTR
LOCAL pmethod AS DWORD
ppthis = pThis
pvtbl = @ppthis
ppmethod = pvtbl + 20
pmethod = @ppmethod
CALL DWORD pmethod USING Template_IEnumVARIANT_Reset(pThis) TO HRESULT
FUNCTION = HRESULT
END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' Decrements the reference count on the specified interface. If the reference count on the
' object falls to 0, the object is freed from memory.
' Returns the resulting value of the reference count, which is used for diagnostic/testing
' purposes only.
' *********************************************************************************************
DECLARE FUNCTION Template_WbemCollection_Release (BYVAL pThis AS DWORD) AS DWORD
' *********************************************************************************************
FUNCTION WbemCollection_Release (BYVAL pThis AS DWORD) AS DWORD
LOCAL HRESULT AS DWORD
LOCAL ppthis AS DWORD PTR
LOCAL pvtbl AS DWORD PTR
LOCAL ppmethod AS DWORD PTR
LOCAL pmethod AS DWORD
ppthis = pThis
pvtbl = @ppthis
ppmethod = pvtbl + 8
pmethod = @ppmethod
CALL DWORD pmethod USING Template_WbemCollection_Release(pThis) TO HRESULT
FUNCTION = HRESULT
END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' Returns a pointer to the IEnumVARIANT interface.
' *********************************************************************************************
DECLARE FUNCTION Proto_WbemCollection_NewEnum (BYVAL pThis AS DWORD, BYREF pEnum AS DWORD) AS DWORD
' *********************************************************************************************
FUNCTION WbemCollection_NewEnum (BYVAL pThis AS DWORD) AS DWORD
LOCAL pEnum AS DWORD
LOCAL HRESULT AS DWORD
LOCAL ppthis AS DWORD PTR
LOCAL pvtbl AS DWORD PTR
LOCAL ppmethod AS DWORD PTR
LOCAL pmethod AS DWORD
ppthis = pThis
pvtbl = @ppthis
ppmethod = pvtbl + 28
pmethod = @ppmethod
CALL DWORD pmethod USING Proto_WbemCollection_NewEnum(pThis, pEnum) TO HRESULT
FUNCTION = pEnum
END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' Returns the number ob objects in the collection.
' *********************************************************************************************
DECLARE FUNCTION Proto_WbemCollection_Count (BYVAL pThis AS DWORD, BYREF nCount AS LONG) AS DWORD
' *********************************************************************************************
FUNCTION WbemCollection_Count (BYVAL pThis AS DWORD) AS LONG
LOCAL nCount AS DWORD
LOCAL HRESULT AS DWORD
LOCAL ppthis AS DWORD PTR
LOCAL pvtbl AS DWORD PTR
LOCAL ppmethod AS DWORD PTR
LOCAL pmethod AS DWORD
ppthis = pThis
pvtbl = @ppthis
ppmethod = pvtbl + 36
pmethod = @ppmethod
CALL DWORD pmethod USING Proto_WbemCollection_Count(pThis, nCount) TO HRESULT
FUNCTION = nCount
END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' Helper function to enumerate collectios.
' Parameters:
' pThis = Pointer to the collection.
' vArray = A dimensioned array of variants.
' *********************************************************************************************
FUNCTION WbemCollection_Enumerate (BYVAL pThis AS DWORD, BYREF vArray() AS VARIANT) EXPORT AS LONG

LOCAL IID_IEnumVariant AS GUID
IID_IEnumVARIANT = GUID$("{00020404-0000-0000-c000-000000000046}")

LOCAL HRESULT AS DWORD
LOCAL pIEnumVARIANT AS DWORD
LOCAL celtFetched AS DWORD
LOCAL vRes AS VARIANT
LOCAL idx AS LONG

IF pThis = 0 THEN EXIT FUNCTION ' Null pointer
IF UBOUND(vArray) = -1 THEN EXIT FUNCTION ' Array not dimensioned

' See if the interface is supported
HRESULT = IEnumVARIANT_QueryInterface (pThis, IID_IEnumVARIANT, VARPTR(pIEnumVARIANT))
IF HRESULT <> %S_OK THEN EXIT FUNCTION

' Position the enumerator at the beginning of the list of elements
HRESULT = IEnumVARIANT_Reset (pIEnumVARIANT)
IF HRESULT <> %S_OK THEN
IEnumVARIANT_Release pIEnumVARIANT
EXIT FUNCTION
END IF

' Fill the array
idx = LBOUND(vArray)

DO
HRESULT = IEnumVARIANT_Next (pIEnumVARIANT, 1, vRes, celtFetched)
IF HRESULT <> %S_OK OR celtFetched < 1 THEN EXIT DO
vArray (idx) = vRes
idx = idx + 1
IF idx > UBOUND(vArray) THEN EXIT DO
LOOP

' Release the interface
HRESULT = IEnumVARIANT_Release(pIEnumVARIANT)
FUNCTION = -1

END FUNCTION
' *********************************************************************************************

' *********************************************************************************************
' Main
' *********************************************************************************************
FUNCTION PBMAIN

LOCAL oLocator AS DISPATCH
LOCAL oServices AS DISPATCH
LOCAL oProcess AS DISPATCH
LOCAL vServer AS VARIANT
LOCAL vVar AS VARIANT
LOCAL vRes AS VARIANT
LOCAL i AS LONG
LOCAL hr AS DWORD
LOCAL pCollection AS DWORD
LOCAL pEnum AS DWORD
LOCAL nCount AS LONG
LOCAL ProcID AS DWORD

SET oLocator = NEW DISPATCH IN "WbemScripting.SWbemLocator"
IF ISFALSE ISOBJECT(oLocator) THEN EXIT FUNCTION

' Create a new connection to a computer (the local computer in this case) and
' retrieve an SWbemServices object, so you can work with WMI.
' vServer = "." equals to local server.
vServer = "." : OBJECT CALL oLocator.ConnectServer(vServer) TO vRes
SET oServices = vRes
vVar = "SELECT * FROM Win32_Process"
OBJECT CALL oServices.ExecQuery(vVar) TO vRes
pCollection = VARIANT#(vRes)

' Get the number of the objects in the collection
nCount = WbemCollection_Count(pCollection)
IF nCount = 0 THEN GOTO Terminate
' Get a pointer to the iEnumVARIANT interface
pEnum = WbemCollection_NewEnum(pCollection)
IF pEnum = 0 THEN GOTO Terminate
' DIM an array of variants
DIM vArray(1 TO nCount) AS VARIANT

' Iterate throught the collection of objects.
IF ISFALSE WbemCollection_Enumerate(pEnum, vArray()) THEN GOTO Terminate
' Release the collection
hr = WbemCollection_Release(pCollection)

FOR i = 1 TO nCount
IF VARIANT#(vArray(i)) <> 0 THEN
SET oProcess = vArray(i)
IF OBJRESULT THEN EXIT FOR
vRes = EMPTY : OBJECT GET oProcess.ProcessID TO vRes
PRINT "ProcID: " VARIANT#(vRes) " ";
vRes = EMPTY : OBJECT GET oProcess.ExecutablePath TO vRes
PRINT "Executable path: " VARIANT$(vRes)
SET oProcess = NOTHING
END IF
NEXT

Terminate:

SET oServices = NOTHING
SET oLocator = NOTHING

WAITKEY$

END FUNCTION
' *********************************************************************************************


------------------


[This message has been edited by JOSE ROCA (edited August 25, 2003).]

IP: Logged

José Roca
Member
posted February 22, 2006 10:17 PM     Click Here to See the Profile for José Roca     Edit/Delete Message   Reply w/Quote

As remarked above, the two main problems to use WMI with the PB compilers
are that most of the examples use GetObject and For Each. The code posted
provides a solution, but many users find difficulties to translate the VB
scripts.

The include file below provides the function WmiGetObject that lets you
to connect to WMI using a moniker, like VB and VBScript. The example that
follows shows you how to connect to WMI, execute a query and iterate
through the returned collection of objects. It's not exactly as the
GetObject/For Each combination, but almost.


------------------
Website: http://com.it-berater.org
SED Editor, TypeLib Browser, Wrappers for ADO, DAO, ODBC, OLE DB, SQL-DMO, WebBrowser Control, MSHTML, HTML Editing, CDOEX, MSXML, WMI, MSAGENT, Flash Player, Task Scheduler, Accesibility, Structured Storage, WinHTTP, Microsoft ActiveX Controls (Data Binding, ADODC, Flex Grid, Hierarchical Flex Grid, Masked Edit Control, DataList, DataCombo, MAPI, INET, MCI, Winsock, Common Dialog, MSChart, Outlook View Control), and Microsoft Scripting Components.

[This message has been edited by José Roca (edited February 23, 2006).]

IP: Logged

José Roca
Member
posted February 22, 2006 10:18 PM     Click Here to See the Profile for José Roca     Edit/Delete Message   Reply w/Quote
Save as TB_WMILIB.INC


' ========================================================================================
' WMI helper functions to provide VB-like GetObject capability and collection's
' enumeration. For PowerBASIC compilers.
' (c) 2006 by José Roca. Freeware. Use at your own risk.
' ========================================================================================

#IF NOT %DEF(%TB_WMILIB_INC)
%TB_WMILIB_INC = 1

' Pull in Windows includes if necessary
#IF NOT %DEF(%WINAPI)
#INCLUDE "win32api.inc"
#ENDIF

' ========================================================================================
' CreateBindCtx
' Supplies a pointer to an implementation of IBindCtx (a bind context object). This object
' stores information about a particular moniker-binding operation. The pointer this
' function supplies is required as a parameter in many methods of the IMoniker interface
' and in certain functions related to monikers.
' ========================================================================================
DECLARE FUNCTION CreateBindCtx LIB "OLE32.DLL" ALIAS "CreateBindCtx" ( _
BYVAL reserved AS DWORD, BYREF ppbc AS DWORD) AS LONG

' ========================================================================================
' MkParseDisplayNameEx
' Creates a moniker to the object that is specified by the given string.
' ========================================================================================
DECLARE FUNCTION MkParseDisplayNameEx LIB "URLMON.DLL" ALIAS "MkParseDisplayNameEx" ( _
BYVAL pbc AS DWORD, BYVAL szUserName AS STRING, _
BYREF pcchEaten AS DWORD, BYREF ppmk AS DWORD) AS LONG

' ========================================================================================
' Wmi_QueryInterface method
' Returns a pointer to a specified interface on an object to which a client currently
' holds an interface pointer. You must release the returned interface, when no longer
' needed, with a call to the Release method.
' ========================================================================================
FUNCTION WmiQueryInterface (BYVAL pthis AS DWORD PTR, BYREF riid AS GUID, BYREF ppvObj AS DWORD) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[0] USING WmiQueryInterface (pthis, riid, ppvObj) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ========================================================================================
' Wmi_AddRef method
' Increments the reference count for an interface on an object. It should be called for
' every new copy of a pointer to an interface on a given object.
' ========================================================================================
FUNCTION WmiAddRef (BYVAL pthis AS DWORD PTR) AS DWORD
LOCAL DWRESULT AS LONG
IF ISFALSE pthis THEN EXIT FUNCTION
CALL DWORD @@pthis[1] USING WmiAddRef (pthis) TO DWRESULT
FUNCTION = DWRESULT
END FUNCTION

' ========================================================================================
' Wmi_Release method
' Decrements the reference count for the calling interface on a object. If the reference
' count on the object falls to 0, the object is freed from memory.
' ========================================================================================
FUNCTION WmiRelease (BYVAL pthis AS DWORD PTR) AS DWORD
LOCAL DWRESULT AS DWORD
IF ISFALSE pthis THEN EXIT FUNCTION
CALL DWORD @@pthis[2] USING WmiRelease (pthis) TO DWRESULT
FUNCTION = DWRESULT
END FUNCTION

' ========================================================================================
' Next method
' Gets the next items in the enumeration sequence.
' ========================================================================================
FUNCTION WmiEnum_Next (BYVAL pthis AS DWORD PTR, BYVAL celt AS DWORD, BYVAL rgelt AS DWORD, BYREF pceltFetched AS DWORD) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[3] USING WmiEnum_Next (pthis, celt, rgelt, pceltFetched) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ========================================================================================
' NextItem method
' Gets the next item in the enumeration sequence.
' ========================================================================================
FUNCTION WmiEnum_NextItem (BYVAL pthis AS DWORD PTR, BYREF elt AS VARIANT) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[3] USING WmiEnum_Next (pthis, 1, VARPTR(elt), BYVAL %NULL) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ========================================================================================
' Skip method
' Attempts to skip over the next celt elements in the enumeration sequence.
' ========================================================================================
FUNCTION WmiEnum_Skip (BYVAL pthis AS DWORD PTR, BYVAL celt AS DWORD) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[4] USING WmiEnum_Skip (pthis, celt) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ========================================================================================
' Reset method
' Resets the enumeration sequence to the beginning.
' ========================================================================================
FUNCTION WmiEnum_Reset (BYVAL pthis AS DWORD PTR) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[5] USING WmiEnum_Reset (pthis) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ========================================================================================
' Clone method
' Creates a copy of the current state of enumeration.
' ========================================================================================
FUNCTION WmiEnum_Clone (BYVAL pthis AS DWORD PTR, BYREF ppenum AS DWORD) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[6] USING WmiEnum_Clone (pthis, ppenum) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ========================================================================================
' Wmi_NewEnum
' Returns a reference to an WMI collection
' ========================================================================================
FUNCTION Wmi_NewEnum (BYVAL pthis AS DWORD PTR, BYREF ppenum AS DWORD) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[7] USING Wmi_NewEnum(pthis, ppenum) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ========================================================================================
' Uses the moniker to bind to the object it identifies. The binding process involves
' finding the object, putting it into the running state if necessary, and supplying the
' caller with a pointer to a specified interface on the identified object.
' ========================================================================================
FUNCTION WmiMoniker_BindToObject (BYVAL pthis AS DWORD PTR, BYVAL pbc AS DWORD, _
BYVAL pmkToLeft AS DWORD, BYREF riidResult AS GUID, BYREF ppvResult AS DWORD) AS LONG
LOCAL HRESULT AS LONG
IF ISFALSE pthis THEN FUNCTION = %E_POINTER : EXIT FUNCTION
CALL DWORD @@pthis[8] USING WmiMoniker_BindToObject (pthis, pbc, pmkToLeft, riidResult, ppvResult) TO HRESULT
FUNCTION = HRESULT
END FUNCTION

' ****************************************************************************************
' Returns a reference to an object provided by a COM component.
' Emulates the Visual Basic GetObject function
' ****************************************************************************************
FUNCTION WmiGetObject (BYVAL strDisplayName AS STRING, BYREF vObj AS VARIANT) AS LONG

LOCAL hr AS LONG ' // HRESULT
LOCAL pbc AS DWORD ' // Pointer to the new bind context
LOCAL pmk AS DWORD ' // IMoniker interface pointer
LOCAL pObj AS DWORD ' // Interface pointer
LOCAL pcchEaten AS DWORD ' // Number of characters successfully parsed
LOCAL IID_IDispatch AS GUID ' // IDispatch interface identifier
LOCAL pvObj AS VARIANTAPI PTR ' // Pointer to a VARIANTAPI structure

IID_IDispatch = GUID$("{00020400-0000-0000-c000-000000000046}")

' // Creates a new bind context.
hr = CreateBindCtx(0, pbc)
IF hr = %S_OK AND ISTRUE pbc THEN
' // Converts a string into a moniker that identifies the object named by the string.
strDisplayName = UCODE$(strDisplayName & $NUL)
hr = MkParseDisplayNameEx(pbc, strDisplayName, pcchEaten, pmk)
IF hr = %S_OK AND ISTRUE pmk THEN
' // Uses the moniker to bind to the object it identifies.
' // The binding process involves finding the object, putting it into the running
' // state if necessary, and supplying the caller with a pointer to a specified
' // interface on the identified object.
hr = WmiMoniker_BindToObject(pmk, pbc, %NULL, IID_IDispatch, pObj)
IF hr = %S_OK THEN
' // Makes a dispatch variant containing the reference to the object.
' // Note: No need to call AddRef because IMoniker_BindToObject has
' // already called it. Just don't release pObj here.
vObj = EMPTY ' // Make sure is empty to avoid memory leaks
pvObj = VARPTR(vObj) ' // Get the VARIANT address
@pvObj.vt = %VT_DISPATCH ' // Mark it as containing a dispatch variable
@pvObj.vd.pdispVal = pObj ' // Set the dispatch pointer address
END IF
END IF
END IF

IF ISTRUE pmk THEN WmiRelease pmk
IF ISTRUE pbc THEN WmiRelease pbc

FUNCTION = hr

END FUNCTION
' ****************************************************************************************

#ENDIF


[This message has been edited by José Roca (edited February 24, 2006).]

IP: Logged

José Roca
Member
posted February 22, 2006 10:20 PM     Click Here to See the Profile for José Roca     Edit/Delete Message   Reply w/Quote
Example to demonstrate the use of the wrapper functions


' ========================================================================================
' WMI example - Enumerates the list of running processes
' SED_PBCC - Use the PBCC compiler
' ========================================================================================

#COMPILE EXE
#DIM ALL
#INCLUDE "TB_WMILIB.INC" ' // WMI helper functions

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

LOCAL hr AS LONG ' // HRESULT
LOCAL oServices AS DISPATCH ' // Services object
LOCAL vServices AS VARIANT ' // Services object reference
LOCAL oItems AS DISPATCH ' // Generic collection object
LOCAL vItems AS VARIANT ' // Generic collection object reference
LOCAL oItem AS DISPATCH ' // Generic item object
LOCAL vItem AS VARIANT ' // Generic item object reference
LOCAL penum AS DWORD ' // Collection's enumerator reference
LOCAL vCount AS VARIANT ' // Number of items in the collection
LOCAL vVar AS VARIANT ' // General purpose variant
LOCAL vRes AS VARIANT ' // General purpose variant
LOCAL i AS LONG ' // Loop counter

' // Connect to WMI using a moniker
hr = WmiGetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2", vServices)
IF hr <> %S_OK THEN GOTO Terminate
SET oServices = vServices
vServices = EMPTY
IF ISFALSE ISOBJECT(oServices) THEN GOTO Terminate

' // Execute a query to get a reference to the collection of running processes
vVar = "SELECT * FROM Win32_Process"
OBJECT CALL oServices.ExecQuery(vVar) TO vItems
IF OBJRESULT THEN GOTO Terminate
SET oItems = vItems
vItems = EMPTY
IF ISFALSE ISOBJECT(oItems) THEN GOTO Terminate

' // Retrieve the number of items in the collection
OBJECT GET oItems.Count TO vCount
STDOUT "nCount = " & STR$(VARIANT#(vCount))

' // Retrieve a reference to the collection's enumerator
hr = Wmi_NewEnum(OBJPTR(oItems), penum)
IF hr <> %S_OK OR penum = %NULL THEN GOTO Terminate

' // Iterate throught the collection of objects.
FOR i = 1 TO VARIANT#(vCount)
' // Retrieve a reference to the next object in the collection
hr = WmiEnum_NextItem(penum, vItem)
IF hr <> %S_OK THEN EXIT FOR
SET oItem = vItem
IF ISFALSE ISOBJECT(oItem) THEN EXIT FOR
' // Retrieve some information about the process
OBJECT GET oItem.ProcessID TO vRes
STDOUT "ProcID: " & STR$(VARIANT#(vRes))
OBJECT GET oItem.Name TO vRes
STDOUT "Name: " & VARIANT$(vRes)
OBJECT GET oItem.ExecutablePath TO vRes
STDOUT "Executable path: " & VARIANT$(vRes)
' // Release the object
SET oItem = NOTHING
NEXT

' // Release the collection enumerator
WmiRelease penum
' // Release the collection object
IF ISOBJECT(oItems) THEN SET oItems = NOTHING

Terminate:

IF ISOBJECT(oServices) THEN SET oServices = NOTHING
WAITKEY$

END FUNCTION
' ========================================================================================


------------------
Website: http://com.it-berater.org
SED Editor, TypeLib Browser, Wrappers for ADO, DAO, ODBC, OLE DB, SQL-DMO, WebBrowser Control, MSHTML, HTML Editing, CDOEX, MSXML, WMI, MSAGENT, Flash Player, Task Scheduler, Accesibility, Structured Storage, WinHTTP, Microsoft ActiveX Controls (Data Binding, ADODC, Flex Grid, Hierarchical Flex Grid, Masked Edit Control, DataList, DataCombo, MAPI, INET, MCI, Winsock, Common Dialog, MSChart, Outlook View Control), and Microsoft Scripting Components.

[This message has been edited by José Roca (edited February 22, 2006).]

IP: Logged

José Roca
Member
posted February 22, 2006 11:57 PM     Click Here to See the Profile for José Roca     Edit/Delete Message   Reply w/Quote

' ========================================================================================
' WMI example - Retrieving BIOS information
' SED_PBCC - Use the PBCC compiler
' ========================================================================================

#COMPILE EXE
#DIM ALL
#INCLUDE "TB_WMILIB.INC" ' // WMI helper functions

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

LOCAL hr AS LONG ' // HRESULT
LOCAL oServices AS DISPATCH ' // Services object
LOCAL vServices AS VARIANT ' // Services object reference
LOCAL oItems AS DISPATCH ' // Generic collection object
LOCAL vItems AS VARIANT ' // Generic collection object reference
LOCAL oItem AS DISPATCH ' // Generic item object
LOCAL vItem AS VARIANT ' // Generic item object reference
LOCAL penum AS DWORD ' // Collection's enumerator reference
LOCAL vCount AS VARIANT ' // Number of items in the collection
LOCAL vVar AS VARIANT ' // General purpose variant
LOCAL vRes AS VARIANT ' // General purpose variant
LOCAL i AS LONG ' // Loop counter
LOCAL x AS LONG ' // Loop counter
DIM vArray(0) AS VARIANT ' // General purpose array of variants

' // Connect to WMI using a moniker
hr = WmiGetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2", vServices)
IF hr <> %S_OK THEN GOTO Terminate
SET oServices = vServices
vServices = EMPTY
IF ISFALSE ISOBJECT(oServices) THEN GOTO Terminate

' // Execute a query to get a reference to the collection of running processes
vVar = "SELECT * FROM Win32_BIOS"
OBJECT CALL oServices.ExecQuery(vVar) TO vItems
IF OBJRESULT THEN GOTO Terminate
SET oItems = vItems
vItems = EMPTY
IF ISFALSE ISOBJECT(oItems) THEN GOTO Terminate

' // Retrieve the number of items in the collection
OBJECT GET oItems.Count TO vCount

' // Retrieve a reference to the collection's enumerator
hr = Wmi_NewEnum(OBJPTR(oItems), penum)
IF hr <> %S_OK OR penum = %NULL THEN GOTO Terminate

' // Iterate throught the collection of objects.
FOR i = 1 TO VARIANT#(vCount)
' // Retrieve a reference to the next object in the collection
hr = WmiEnum_NextItem(penum, vItem)
IF hr <> %S_OK THEN EXIT FOR
SET oItem = vItem
IF ISFALSE ISOBJECT(oItem) THEN EXIT FOR
' // Retrieve information about the BIOS
' // BIOS version (array of the complete system BIOS information)
OBJECT GET oItem.BIOSVersion TO vRes
vArray() = vRes
PRINT "BIOS version:"
FOR x = LBOUND(vArray) TO UBOUND(vArray)
STDOUT VARIANT$(vArray(x))
NEXT
' // BIOS characteristics (array of words)
OBJECT GET oItem.BIOSCharacteristics TO vRes
vArray() = vRes
PRINT "BIOS characteristics:";
FOR x = LBOUND(vArray) TO UBOUND(vArray)
PRINT STR$(VARIANT#(vArray(x)));
NEXT
PRINT
' // Build number
OBJECT GET oItem.BuildNumber TO vRes
PRINT "Build number: " & VARIANT$(vRes)
' // Caption
OBJECT GET oItem.Caption TO vRes
PRINT "Caption: " & VARIANT$(vRes)
' // Code set
OBJECT GET oItem.CodeSet TO vRes
PRINT "Code set: " & VARIANT$(vRes)
' // Current language
OBJECT GET oItem.CurrentLanguage TO vRes
PRINT "Current language: " & VARIANT$(vRes)
' // Description
OBJECT GET oItem.Description TO vRes
PRINT "Description: " & VARIANT$(vRes)
' // Identification code
OBJECT GET oItem.IdentificationCode TO vRes
PRINT "Identification code: " & VARIANT$(vRes)
' // Installable languages
OBJECT GET oItem.InstallableLanguages TO vRes
PRINT "Installable languages: " VARIANT#(vRes)
' // Install date
OBJECT GET oItem.InstallDate TO vRes
PRINT "Install date: " & VARIANT$(vRes)
' // Language edition
OBJECT GET oItem.LanguageEdition TO vRes
PRINT "Language edition: " & VARIANT$(vRes)
' // List of languages
OBJECT GET oItem.ListOfLanguages TO vRes
vArray() = vRes
PRINT "List of languages:"
FOR x = LBOUND(vArray) TO UBOUND(vArray)
STDOUT VARIANT$(vArray(x))
NEXT
' // Manufacturer
OBJECT GET oItem.Manufacturer TO vRes
PRINT "Manufacturer: " & VARIANT$(vRes)
' // Name
OBJECT GET oItem.Name TO vRes
PRINT "Name: " & VARIANT$(vRes)
' // Other target OS
OBJECT GET oItem.OtherTargetOS TO vRes
PRINT "Other target OS: " & VARIANT$(vRes)
' // Primary BIOS
OBJECT GET oItem.PrimaryBIOS TO vRes
PRINT "Primary BIOS: " CINT(VARIANT#(vRes))
' // Release date
OBJECT GET oItem.ReleaseDate TO vRes
PRINT "Release date: " & VARIANT$(vRes)
' // Serial number
OBJECT GET oItem.SerialNumber TO vRes
PRINT "Serial number: " & VARIANT$(vRes)
' // BIOS version as reported by SMBIOS
OBJECT GET oItem.SMBIOSBIOSVersion TO vRes
PRINT "SMBIOS BIOS version: " & VARIANT$(vRes)
' // Major SMBIOS version number
OBJECT GET oItem.SMBIOSMajorVersion TO vRes
PRINT "SMBIOS major version: " VARIANT#(vRes)
' // Minor SMBIOS version number
OBJECT GET oItem.SMBIOSMinorVersion TO vRes
PRINT "SMBIOS minor version: " VARIANT#(vRes)
' // SMBIOS present
OBJECT GET oItem.SMBIOSPresent TO vRes
PRINT "SMBIOS present: " CINT(VARIANT#(vRes))
' // Software element ID
OBJECT GET oItem.SoftwareElementID TO vRes
PRINT "Software element ID: " & VARIANT$(vRes)
' // Software element state
OBJECT GET oItem.SoftwareElementState TO vRes
PRINT "Software element state: " VARIANT#(vRes)
' // Status
OBJECT GET oItem.Status TO vRes
PRINT "Status : " & VARIANT$(vRes)
' // Target operating system
OBJECT GET oItem.TargetOperatingSystem TO vRes
PRINT "Target operating system: " VARIANT#(vRes)
' // Version
OBJECT GET oItem.Version TO vRes
PRINT "Version: " & VARIANT$(vRes)
' // Release the object
SET oItem = NOTHING
NEXT

' // Release the collection enumerator
WmiRelease penum
' // Release the collection object
IF ISOBJECT(oItems) THEN SET oItems = NOTHING

Terminate:

IF ISOBJECT(oServices) THEN SET oServices = NOTHING
WAITKEY$

END FUNCTION
' ========================================================================================


------------------
Website: http://com.it-berater.org
SED Editor, TypeLib Browser, Wrappers for ADO, DAO, ODBC, OLE DB, SQL-DMO, WebBrowser Control, MSHTML, HTML Editing, CDOEX, MSXML, WMI, MSAGENT, Flash Player, Task Scheduler, Accesibility, Structured Storage, WinHTTP, Microsoft ActiveX Controls (Data Binding, ADODC, Flex Grid, Hierarchical Flex Grid, Masked Edit Control, DataList, DataCombo, MAPI, INET, MCI, Winsock, Common Dialog, MSChart, Outlook View Control), and Microsoft Scripting Components.

[This message has been edited by José Roca (edited February 23, 2006).]

IP: Logged

All times are EasternTime (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | PowerBASIC BASIC Compilers

Copyright © 1999-2005 PowerBASIC, Inc. All Rights Reserved.


Ultimate Bulletin Board 5.45c