File: n_wmi_base.sru
Size: 7230
Date: Thu, 29 May 2025 21:40:48 +0200
$PBExportHeader$n_wmi_base.sru
forward
global type n_wmi_base from nonvisualobject
end type
end forward

global type n_wmi_base from nonvisualobject autoinstantiate
end type

forward prototypes
public function long of_split (string as_text, string as_sep, ref string as_array[])
public function long of_querywmi (string as_query, ref s_wmi_property astr_property[])
public function string of_getpropstring (string as_propname, s_wmi_property astr_property)
public function longlong of_getpropnumber (string as_propname, s_wmi_property astr_property)
end prototypes

public function long of_split (string as_text, string as_sep, ref string as_array[]);// -----------------------------------------------------------------------------
// SCRIPT:     of_Split
//
// PURPOSE:    This function splits a string into an array.
//
// ARGUMENTS:  as_text  - The text to be split
//             as_sep   - The separator characters
//             as_array - By ref output array
//
// RETURN:     The number of items in the array
//
// DATE        CHANGED BY  DESCRIPTION OF CHANGE / REASON
// ----------  ----------  -----------------------------------------------------
// 05/15/2025  RolandS     Initial creation
// -----------------------------------------------------------------------------

String ls_empty[], ls_work
Long ll_pos

as_array = ls_empty

If IsNull(as_text) Or as_text = "" Then Return 0

ll_pos = Pos(as_text, as_sep)
DO WHILE ll_pos > 0
   ls_work = Trim(Left(as_text, ll_pos - 1))
   as_text = Trim(Mid(as_text, ll_pos + Len(as_sep)))
   as_array[UpperBound(as_array) + 1] = ls_work
   ll_pos = Pos(as_text, as_sep)
LOOP
If Len(as_text) > 0 Then
   as_array[UpperBound(as_array) + 1] = as_text
End If

Return UpperBound(as_array)

end function

public function long of_querywmi (string as_query, ref s_wmi_property astr_property[]);// -----------------------------------------------------------------------------
// SCRIPT:     of_QueryWMI
//
// PURPOSE:    This function runs an WMI query and returns the results.
//             This is based on an example by John Fauss.
//
// ARGUMENTS:  as_query       - The query to be run
//             astr_property  - By ref output structure array
//
// RETURN:     The number of items in the array
//
// DATE        CHANGED BY  DESCRIPTION OF CHANGE / REASON
// ----------  ----------  -----------------------------------------------------
// 05/15/2025  RolandS     Initial creation
// -----------------------------------------------------------------------------

OLEObject lole_locator, lole_services, lole_instances
Integer li_rc
Long ll_index, ll_count, ll_idx, ll_max, ll_prop
String ls_msg, ls_ObjectText, ls_line[]
String ls_propname, ls_propvalue
UInt lui_cp

// connect to the WMI Scripting Locator
try
   lole_locator = CREATE OLEObject
   li_rc = lole_locator.ConnectToNewObject('WbemScripting.SWbemLocator')
   If li_rc < 0 Then
   End If
catch(OLERuntimeError ore1)
   ls_msg = 'An error occurred connecting to WMI Scripting Locator.~r~n~r~n' + &
            'Error number: ' + String(ore1.Number) + '~r~n' + &
            'Description: ' + ore1.Description + '~r~n' + &
            'Source: ' + ore1.Source + '~r~n' + &
            'Message: ' + ore1.Text
   Post Function MessageBox("QueryWMI Error", ls_msg, StopSign!, OK!)
   Return -1
end try

// connect to the WMI Namespace Server
try
   lole_services = lole_locator.ConnectServer('.','root\cimv2')
catch(OLERuntimeError ore2)
   ls_msg = 'An error occurred connecting to WMI Namespace Server.~r~n~r~n' + &
            'Error number: ' + String(ore2.Number) + '~r~n' + &
            'Description: ' + ore2.Description + '~r~n' + &
            'Source: ' + ore2.Source + '~r~n' + &
            'Message: ' + ore2.Text
   Post Function MessageBox("QueryWMI Error", ls_msg, StopSign!, OK!)
   Return -1
end try

// run the query
lole_instances = lole_services.ExecQuery(as_query)

// parse out the results
ll_count = lole_instances.Count
For ll_index = 1 To ll_count
   // get object values into a string array
   ls_ObjectText = lole_instances.ItemIndex(ll_index - 1).GetObjectText_()
   ls_ObjectText = Mid(ls_ObjectText, Pos(ls_ObjectText, "{") + 1)
   ls_ObjectText = Left(ls_ObjectText, LastPos(ls_ObjectText, "}") - 2)
   ll_max = of_Split(ls_ObjectText, ";", ls_line)

   ll_prop = 0
   For ll_idx = 1 To ll_max
      // parse out the property name and value
      ls_propname = Mid(ls_line[ll_idx], 3)
      ls_propvalue = Mid(ls_propname, Pos(ls_propname, "=") + 2)
      ls_propname = Left(ls_propname, Pos(ls_propname, "=") - 2)
      If Left(ls_propvalue, 1) = '"' Then
         ls_propvalue = Mid(ls_propvalue, 2)
      End If
      If Right(ls_propvalue, 1) = '"' Then
         ls_propvalue = Left(ls_propvalue, Len(ls_propvalue) - 1)
      End If
      
      // set property name & value in the structure
      ll_prop = ll_prop + 1
      astr_property[ll_index].propname[ll_prop]  = ls_propname
      astr_property[ll_index].propvalue[ll_prop] = ls_propvalue
   Next
Next

// Cleanup
li_rc = lole_instances.DisconnectObject()
li_rc = lole_services.DisconnectObject()
li_rc = lole_locator.DisconnectObject()

Destroy lole_locator

Return ll_count

end function

public function string of_getpropstring (string as_propname, s_wmi_property astr_property);// -----------------------------------------------------------------------------
// SCRIPT:     of_GetPropString
//
// PURPOSE:    This function returns a string property from the structure.
//
// ARGUMENTS:  as_propname    - The property name
//             astr_property  - Structure array
//
// RETURN:     The value of the passed property name
//
// DATE        CHANGED BY  DESCRIPTION OF CHANGE / REASON
// ----------  ----------  -----------------------------------------------------
// 05/15/2025  RolandS     Initial creation
// -----------------------------------------------------------------------------

Long ll_idx, ll_max

ll_max = UpperBound(astr_property.PropName)
For ll_idx = 1 To ll_max
   If Lower(as_propname) = Lower(astr_property.PropName[ll_idx]) Then
      Return astr_property.PropValue[ll_idx]
   End If
Next

Return ""

end function

public function longlong of_getpropnumber (string as_propname, s_wmi_property astr_property);// -----------------------------------------------------------------------------
// SCRIPT:     of_GetPropNumber
//
// PURPOSE:    This function returns a number property from the structure.
//
// ARGUMENTS:  as_propname    - The property name
//             astr_property  - Structure array
//
// RETURN:     The value of the passed property name
//
// DATE        CHANGED BY  DESCRIPTION OF CHANGE / REASON
// ----------  ----------  -----------------------------------------------------
// 05/15/2025  RolandS     Initial creation
// -----------------------------------------------------------------------------

Long ll_idx, ll_max

ll_max = UpperBound(astr_property.PropName)
For ll_idx = 1 To ll_max
   If Lower(as_propname) = Lower(astr_property.PropName[ll_idx]) Then
      Return LongLong(astr_property.PropValue[ll_idx])
   End If
Next

Return 0

end function

on n_wmi_base.create
call super::create
TriggerEvent( this, "constructor" )
end on

on n_wmi_base.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on