////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001-2023 Alexey Kuryakin daqgroup@mail.ru under MIT license //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// This file is part of the CRW-DAQ project by DaqGroup - component CRWLIB.   //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Purpose:                                                                   //
// Header for SMI++ User Interface Runtime Library SMIUIRTL.DLL               //
// See http://smi.web.cern.ch                                                 //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// History:                                                                   //
// 20201123 - 1st release                                                     //
// 20210122 - Update to v56r1                                                 //
// 20230907 - Modified for FPC (A.K.) & update to v58r1                       //
////////////////////////////////////////////////////////////////////////////////

unit _crw_smiuirtl; // SMI++ UI runtime library header, see http://smi.web.cern.ch

{$I _crw_sysdef}

{$IFDEF FPC}{$mode Delphi}{$ENDIF}{$H+}

 // Define the SMI_STATIC parameter to use static DLL linking.
 // When using static  linking, EXE file will depend from DLL.
 // When using dynamic linking - call LoadSmiLibrary on start,
 // and use ValidSmiLibrary to check library is really loaded.
 // If ValidSmiLibrary return false, any call of SMI functions
 // will raise general violation exception (nil address call).

{-$DEFINE SMI_STATIC}

interface

uses
 _crw_sharemem, // NB: THIS UNIT MUST BE FIRST !!!
 {$IFDEF UNIX} cthreads, dl, {$ENDIF}
 {$IFDEF WINDOWS} windows, {$ENDIF}
 sysutils, classes,
 _crw_alloc, _crw_dim;

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //
 // smiuirtl.h
 //
 // SMIUIRTL implements the routines used by a user interface or any other process wanting to get information
 //          on the states of objects running in a certain SM and/or to send commands to them.
 //
 // smiui_current_state(obj_name, state, busy_action)
 // Parametes:
 //     char *obj_name      The name of the object in the form <domain_name>::<object_name>
 //     char *state         The buffer where the state will be stored on return.
 //     char *busy_action   If the object is busy the name of the action it is currently executing, otherwise a null string.
 // Description:
 //     Used to know the current state of an object in a given domain. It also returns information
 //     on whether the object is busy executing an action or idle.
 //     Return status 0/1 = object not/connected.
 //
 //
 // smiui_send_command(obj_name, cmnd)
 // smiui_ep_send_command(obj_name, cmnd)
 // Parameters:
 //     char *obj_name      The name of the object in the form <domain_name>::<object_name>
 //     char *cmnd          The cmnd in the form action/par="val"…
 // Description:
 //     Used to send a command to any object in any domain.
 //     *_ep_* send command to proxy directly.
 //     Return 1 always (nonblocking call).
 //
 //
 // smiui_send_command_wait(obj_name, cmnd)
 // smiui_ep_send_command_wait(obj_name, cmnd)
 // Parameters:
 //     char *obj_name      The name of the object in the form <domain_name>::<object_name>
 //     char *cmnd          The cmnd in the form action/par="val"…
 // Description:
 //     Used to send a command to any object in any domain.
 //     Return 0/1 if command was not/sent (blocking call).
 //     *_ep_* send command to proxy directly.
 //
 //
 // smiui_change_option(domain, option, value)
 // smiui_change_option_wait(domain, option, value)
 // Parameters:
 //     char *domain        The name of the domain
 //     char *option        Option name
 //     char *value         Option value
 // Description:
 //     Used to change option value of domain server.  *_wait uses blocking call.
 //     Return 0/1 (nonblocking always 1).
 //
 //
 // smiui_get_options(domain, options)
 // Parameters:
 //     char *domain        The name of the domain
 //     char *options       Options buffer >= 512 bytes
 // Description:
 //     Get all options values of domain server.
 //     Options=d/INT/3/Diagnostic Level|u/BOOL/0/Unlocked IFs|t/BOOL/1/New time format|dns/STRING/localhost/Dns node ...
 //     Return 0/1 status.
 //
 //
 // int smiui_connect_domain(domain)
 // Parameters:
 //     char *domain        The name of the domain to connect to.
 // Description:
 //     Used to connect to a specific domain, it's a blocking call, it waits until the domain responds.
 //     It returns the number of objects in the domain or 0 if it fails. The calls smiui_get_next_object,
 //     smiui_get_next_objectset call smiui_connect_domain implicitly if not done before.
 //
 //
 // int smiui_book_connect_domain(domain, domainchange_handler, param)
 // Parameters:
 //     char *domain        The name of the domain.
 //     void (*domainchange_handler)(dim_long *par, int *nobjs)  The routine to handle domain changes
 //     dim_long param      A parameter to pass to the above routine
 // Description:
 //     Set up a callback routine to be called whenever the domain starts or stops.
 //     The domainchange_handler routine will be called with two parameters: param and the number of objects
 //     in the domain - both parameters are passed by reference.
 //
 //
 // smiui_cancel_connect_domain(domain)
 // Parameters:
 //     char *domain        The name of the domain.
 // Description:
 //     Cancel attention on the domain, further changes will not be signaled.
 //
 //
 // int smiui_number_of_objects(domain)
 // Parameters:
 //     char *domain        The name of the domain.
 // Description:
 //     Returns the number of objects in the domain or 0 if it fails.
 //
 //
 // int smiui_get_next_object(domain, obj_name)
 // Parameters:
 //     char *domain        The name of the domain.
 //     char *obj_name      The name of the object in the form <domain_name>::<object_name>.
 // Description:
 //     Get the name of the next object in a domain (several domains can be accessed at the "same time").
 //     This routine returns 0 when all the objects of a particular domain have been retrieved
 //
 //
 // int smiui_book_statechange(obj_name, statechange_handler, param)
 // Parameters:
 //     char *obj_name                  The name of the object.
 //     void (*statechange_handler)(int *id, dim_long *par)   The routine to handle state changes
 //     long param                      A parameter to pass to the above routine
 // Description:
 //     Set up a callback routine to be called whenever the specified object changes state.
 //     smiui_book_statechange returns an identifier that should be used on the following calls.
 //     The statechange_handler routine will be called with two parameters: the address of the identifier mentioned
 //     above and the address of param (i.e. both parameters are passed by reference).
 //     See the Example for clarification
 //
 // /**********************************************************************
 //  This small selfcontained program will print a line of text everytime
 //    either object DOMAIN::A   or  DOMAIN::B changes state 
 // ***********************************************************************/
 // #include <stdio.h>
 // #include <smiuirtl.h>    /* the header file provided as part of SMIXX package*/
 // /*  Look at the main program first */
 // /*------------------------------------------------------------*/
 // void handler(int* pId, long* pParam)
 // {
 //     int Id; long Param;
 //     int busy_flag,nac;
 //     char objName[32];
 //     char curr_state[32];
 //     Id =  *pId;
 //     Param = *pParam;
 //     smiui_get_name(Id,objName);  /* Id of the booking call passed to handler is used to retrieve the object name of the object that changed state */
 //     smiui_get_state(Id,&busy_flag,curr_state,&nac);  /* Id of the booking call passed to handler is used to retrieve the name of the object's current state */
 //     printf("\n Object : %s   Current state : %s \n",objName,curr_state); fflush(stdout);
 //     return;
 // }
 // /*-----------------------------------------------------------------*/
 // int main(int argc, char* argv[])
 // {
 //     int Id1; char objectName1[] = "DOMAIN::A"; long param1 = 0;
 //     int Id2; char objectName2[] = "DOMAIN::B"; long param2 = 0;
 // /* The two following calls register callback function 'handler' that
 //    will be called by SMI system everytime either of the two objects changes its state.
 //    We could have register two different callbacks, but in this example we
 //    opted for the same one for both objects.
 //    Id1 and Id2 are identification codes assigned and returned by SMI
 //    system and are passed to the callback function.
 //    parm1 and parm2 are arbitrary user parameters that are also passed
 //    to the callback function. In this example we make no use of them
 //    and so they are set to zero
 // */
 //     Id1 = smiui_book_statechange( objectName1, handler ,param1);
 //     Id2 = smiui_book_statechange( objectName2, handler ,param2);
 //     while (1)
 //     {
 //         sleep(1);
 //     }
 //     return 0;
 // }
 //
 //
 // smiui_cancel_statechange(id)
 // Parameters:
 //     int id              The identifier returned by the previous call.
 // Description:
 //     Cancel attention on the object, further state changes will not be signaled.
 //
 //
 // smiui_get_name(id, obj_name)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange
 //     char *obj_name      Returns the name of the current object
 // Description:
 //     This routine is normally called from the statechange_handler routine in order to get the name of the current object.
 //     See the Example for clarification
 //
 //
 // smiui_get_state(id, busi_flag, state, n_actions)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     int *busy_flag      Returns a flag indicating if the current object is busy
 //     char *state         Returns the current state of the object
 //     int *n_actions      Returns the number of possible actions in the object’s current state
 // Description:
 //     This routine is normally called from the statechange_handler routine in order to get the object state and some additional parameters.
 //     See the Example for clarification
 //
 //
 // smiui_get_action_in_progress(id, action)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     char *action        The action currently being executed.
 // Description:
 //     Called in order to get the action currently being executed by an object whenever the busy_flag in the previous routine is 1.
 //
 //
 // int smiui_get_next_action(id, action, n_pars)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     char *action        The action name.
 //     int n_pars          The number of parameters this action takes.
 // Description:
 //     This routine retrieves the next action available to an object in the current state.
 //
 //
 // smiui_get_first_action(id, action, n_pars)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     char *action        The action name.
 //     int n_pars          The number of parameters this action takes
 // Description:
 //     Positions the next_action pointer back to the first action and retrieves it.
 //     smiui_get_next_action can be called again from then on.
 //
 //
 // int smiui_get_next_param(id, param, type, default_value_size)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     char *param         The action’s parameter name.
 //     int *type           The parameter type (SMI_STRING, SMI_ INTEGER, SMI_ FLOAT)
 //     int *default_value_size     The size of the parameter's default value if a default has been specified, otherwise 0.
 // Description:
 //     This routine retrieves the next parameter specified for the current action available to an object in the current state.
 //     It returns 0 when all parameters have been returned.
 //
 //
 // int smiui_get_param_default_value(id, default_value)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     void *default_value The parameter’s default value.
 // Description:
 //     This routine retrieves the parameter default value, for the parameter received from smiui_get_next_param.
 //     This routine should only be called if default_value_size was not zero.
 //     It returns 0 if the parameter did not have a default value.
 //     The contents of default_value can be of type integer, float or character string according to the previous routine.
 //
 //
 // int smiui_get_next_obj_param(id, param, type, value_size)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     char *param         The object’s parameter name.
 //     int *type           The parameter type (SMI_STRING, SMI_ INTEGER, SMI_ FLOAT)
 //     int *value_size     The size of the parameter's value.
 // Description:
 //     This routine retrieves the next parameter specified for the current object.
 //     It returns 0 when all parameters have been returned.
 //
 //
 // int smiui_get_obj_param_value(id, value)
 // Parameters:
 //     int id              The identifier returned by smiui_book_statechange.
 //     void *value         The parameter’s value.
 // Description:
 //     This routine retrieves the parameter value, for the parameter received from smiui_get_next_obj_param.
 //     The contents of value can be of type integer, float or character string according to the previous routine.
 //
 //
 // int smiui_number_of_objectsets(domain)
 // Parameters:
 //     char *domain        The name of the domain.
 // Description:
 //     Returns the number of objects sets in the domain.
 //
 //
 // int smiui_get_next_objectset(domain, objset_name)
 // Parameters:
 //     char *domain        The name of the domain.
 //     char *objset_name   The name of the object set in the form <domain_name>::<objectset_name>.
 // Description:
 //     Get the name of the next object set in a domain (several domains can be accessed at the "same time").
 //     This routine returns 0 when all the object sets of a particular domain have been retrieved
 //
 //
 // int smiui_book_objectsetchange(objset_name, objectsetchange_handler, param)
 // Parameters:
 //     char *objset_name                   The name of the object set.
 //     void (*objectsetchange_handler)(int *id, dim_long *par)   The routine to handle changes in the contents of the set.
 //     long param                          A parameter to pass to the above routine
 // Description:
 //     Set up a callback routine to be called whenever the specified object set changes (i.e. objects are added or removed from the set).
 //     smiui_book_objectsetchange returns an identifier that should be used on the following calls.
 //     The objectsetchange_handler routine will be called with two parameters: the address of the identifier mentioned
 //     above and the address of param (i.e. both parameters are passed by reference).
 //
 //
 // smiui_cancel_objectsetchange(id)
 // Parameters:
 //     int id              The identifier returned by the previous call.
 // Description:
 //     Cancel attention on the object set, further set changes will not be signaled.
 //
 //
 // smiui_get_setname(id, objset_name)
 // Parameters:
 //     int id              The identifier returned by smiui_book_objectsetchange
 //     char *objset_name   Returns the name of the current object set
 // Description:
 //     This routine is normally called from the objectsetchange_handler routine in order to get the name of the current object set.
 //
 //
 // int smiui_get_next_object_in_set(id, object)
 // Parameters:
 //     int id              The identifier returned by smiui_book_objectsetchange.
 //     char *object        The object name.
 // Description:
 //     This routine retrieves the next object contained in the current object set, to be called from within objectsetchange_handler.
 //
 //
 // smiui_get_first_object_in_set(id, object)
 // Parameters:
 //     int id              The identifier returned by smiui_book_objectsetchange.
 //     char *object        The object name.
 // Description:
 //     Positions the next_object pointer back to the first object is the set and retrieves it.
 //     smiui_get_next_object_in_set can be called again from then on.
 //
 //
 // int smiui_book_alloc_statechange(domain, alloc_statechange_handler, param)
 // Parameters:
 //     char *domain                            The SMI domain name.
 //     void (*alloc_statechange_handler)(int *id, dim_long *par)     The routine to handle state changes
 //     long param                              A parameter to pass to the above routine
 // Description:
 //     Set up a callback routine to be called whenever the allocation state of the specified domain changes state.
 //     smiui_book_alloc_statechange returns an identifier that should be used on the following calls.
 //     The alloc_statechange_handler routine will be called with two parameters: the address of the identifier
 //     mentioned above and the address of param (i.e. both parameters are passed by reference).
 //
 //
 // smiui_cancel_alloc_statechange(id)
 // Parameters:
 //     int id              The identifier returned by the previous call.
 // Description:
 //     Cancel attention on the allocation state of the domain, further state changes will not be signalled.
 //
 //
 // smiui_get_alloc_state(id, busy_flag, state)
 // Parameters:
 //     int id              The identifier returned by smiui_book_alloc_statechange.
 //     int *busy_flag      Returns a flag indicating if the domain allocation object is currently busy
 //     char *state         Returns the current state of the allocation object
 // Description:
 //     This routine is normally called from the alloc_statechange_handler routine in order to get the allocation state of the domain.
 //
 //
 // int smiui_allocate(domain)
 // Parameters:
 //     char *domain        The domain name.
 // Description:
 //     This routine can be used by a user interface or another process in order to allocate an SMI domain to itself.
 //     An smiui_connect_domain should have been done before hand. Smiui_allocate domain returns 1 if the domain was
 //     successfully allocated and 0 if it was not connected or already allocated to someone else.
 //
 //
 // int smiui_allocate_to(domainA, domainB)
 // Parameters:
 //     char *domainA       The domain to be allocated.
 //     char *domainB       The domain to allocate to.
 // Description:
 //     This routine can be used by a user interface or another process in order to allocate an SMI domain to another SMI domain.
 //     An smiui_connect_domain should have been done before hand to the allocator domain (domainB).
 //     Smiui_allocate domain returns 1 if domainA was successfully allocated to domainB and 0
 //     if it domainB was not connected or domainA already allocated to someone else.
 //
 //
 // int smiui_release(domain)
 // Parameters:
 //     char *domain        The domain name.
 // Description:
 //     This routine can be used by a user interface or another process in order to release a previously allocated SMI domain.
 //     An smiui_connect_domain should have been done before hand. Smiui_release domain returns 1
 //     if the domain was successfully released and 0 if the domain was not allocated to this process.
 //
 //
 // int smiui_release_from(domainA, domainB)
 // Parameters:
 //     char *domainA       The domain allocated.
 //     char *domainB       The domain that allocated domainA.
 // Description:
 //     This routine can be used by a user interface or another process in order to release a domain from another one.
 //     An smiui_connect_domain should have been done before hand to domainB. Smiui_release domain returns 1
 //     if domainA was successfully released from domainB and 0 if domainA was not allocated to domainB.
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const SMIXX_VERSION                 = 5801;                             // Version of SMI++
const MAX_NAME                      = 132;                              // Max. size of name
const SMI_STRING                    = 0;                                // String  parameter
const SMI_INTEGER                   = 1;                                // Integer parameter
const SMI_FLOAT                     = 2;                                // Float   parameter
type  dim_long_t                    = PtrInt;                           // Should be pointer-size integer
type  smiui_domainchange_handler_t  = procedure(var par:dim_long_t; var nobjs:Integer); cdecl; // Domain change handler
type  smiui_statechange_handler_t   = procedure(var id:Integer; var par:dim_long_t); cdecl; // State change handler
type  smiui_setchange_handler_t     = procedure(var id:Integer; var par:dim_long_t); cdecl; // Object set change handler
type  smiui_message_handler_t       = procedure(var id:Integer; var par:dim_long_t); cdecl; // Message handler

{$IFDEF SMI_STATIC}

function smiui_set_dns(node:PChar; port:Integer):dim_long_t; cdecl;
function smiui_current_state(obj:PChar; state:PChar; action:PChar):Integer; cdecl;
function smiui_current_state_dns( dnsid:dim_long_t; obj:PChar; state:PChar; action:PChar):Integer; cdecl;
function smiui_send_command(obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_send_command_dns(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_ep_send_command(obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_ep_send_command_dns(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_send_command_wait(obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_send_command_wait_dns(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_ep_send_command_wait(obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_ep_send_command_wait_dns(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
function smiui_change_option(domain:PChar; option:PChar; value:PChar):Integer; cdecl;
function smiui_change_option_wait(domain:PChar; option:PChar; value:PChar):Integer; cdecl;
function smiui_get_options(domain:PChar; optString:PChar):Integer; cdecl;
function smiui_get_options_dns(dnsid:dim_long_t; domain:PChar; optString:PChar):Integer; cdecl;
function smiui_number_of_objects(domain:PChar):Integer; cdecl;
function smiui_number_of_objects_dns(dnsid:dim_long_t; domain:PChar):Integer; cdecl;
function smiui_connect_domain(domain:PChar):Integer; cdecl;
function smiui_connect_domain_dns(dnsid:dim_long_t; domain:PChar):Integer; cdecl;
function smiui_book_connect_domain(domain:PChar; command_handler:smiui_domainchange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_book_connect_domain_dns(dnsid:dim_long_t; domain:PChar; command_handler:smiui_domainchange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_cancel_connect_domain(domain:PChar):Integer; cdecl;
function smiui_shutdown_domain(domain:PChar):Integer; cdecl;
function smiui_check_proxy(proxy:PChar):Integer; cdecl;
function smiui_check_proxy_dns(dnsid:dim_long_t; proxy:PChar):Integer; cdecl;
function smiui_kill(server:PChar):Integer; cdecl;
function smiui_get_next_object(domain:PChar; obj:PChar):Integer; cdecl;
function smiui_get_next_attribute(obj:PChar; attribute:PChar):Integer; cdecl;
function smiui_book_statechange(obj:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_book_statechange_dns(dnsid:dim_long_t; obj:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_cancel_statechange(id:Integer):Integer; cdecl;
function smiui_get_name(id:Integer; name:PChar):Integer; cdecl;
function smiui_get_state(id:Integer; var busy_flg:Integer; state:PChar; var n_actions:Integer):Integer; cdecl;
function smiui_get_smi_message(id:Integer; dom:PChar; mess:PChar):Integer; cdecl;
function smiui_get_user_message(id:Integer; dom:PChar; mess:PChar):Integer; cdecl;   
function smiui_get_action_in_progress(id:Integer; action:PChar):Integer; cdecl;
function smiui_get_first_action(id:Integer; action:PChar; var n_pars:Integer):Integer; cdecl;
function smiui_get_next_action(id:Integer; action:PChar; var n_pars:Integer):Integer; cdecl;
function smiui_get_next_param(id:Integer; par:PChar; var typ:Integer; var size:Integer):Integer; cdecl;
function smiui_get_param_default_value(id:Integer; value:Pointer):Integer; cdecl;
function smiui_get_next_obj_param(id:Integer; par:PChar; var typ:Integer; var size:Integer):Integer; cdecl;
function smiui_get_obj_param_value(id:Integer; value:Pointer):Integer; cdecl;
function smiui_book_alloc_statechange(domain:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_book_alloc_statechange_dns(dnsid:dim_long_t; domain:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_cancel_alloc_statechange(id:Integer):Integer; cdecl;
function smiui_get_alloc_state(id:Integer; var busy_flg:Integer; state:PChar):Integer; cdecl;
function smiui_allocate(domain:PChar):Integer; cdecl;
function smiui_release(domain:PChar):Integer; cdecl;
function smiui_allocate_to(domainA:PChar; domainB:PChar):Integer; cdecl;
function smiui_release_from(domainA:PChar; domainB:PChar):Integer; cdecl;
function smiui_get_next_objectset(domain:PChar; objectset:PChar):Integer; cdecl;
function smiui_book_objectsetchange(obj:PChar; command_handler:smiui_setchange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_book_objectsetchange_dns(dnsid:dim_long_t; obj:PChar; command_handler:smiui_setchange_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_cancel_objectsetchange(id:Integer):Integer; cdecl;
function smiui_book_smi_message(dom:PChar; command_handler:smiui_message_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_cancel_smi_message(id:Integer):Integer; cdecl;
function smiui_book_user_message(dom:PChar; command_handler:smiui_message_handler_t; par:dim_long_t):Integer; cdecl;
function smiui_cancel_user_message(id:Integer):Integer; cdecl;   
function smiui_get_first_object_in_set(id:Integer; obj:PChar):Integer; cdecl;
function smiui_get_next_object_in_set(id:Integer; obj:PChar):Integer; cdecl;
function smiui_get_setname(id:Integer; objset:PChar):Integer; cdecl;
function smiui_number_of_objectsets(domain:PChar):Integer; cdecl;
function smiui_number_of_objectsets_dns(dnsid:dim_long_t; domain:PChar):Integer; cdecl;
function smiui_create_command(action:PChar):Pointer; cdecl;
function smiui_add_param_to_command(id:Pointer; name:PChar; value:Pointer; typ:Integer):Integer; cdecl;
function smiui_delete_command(cmnd:Pointer):Integer; cdecl;
function smiui_get_command_string(id:Pointer):PChar; cdecl;
function smiui_get_action_in_progress_size(id:Integer; var size:Integer):Integer; cdecl;

{$ELSE  SMI_STATIC}

var smiui_set_dns: function(node:PChar; port:Integer):dim_long_t; cdecl;
var smiui_current_state: function(obj:PChar; state:PChar; action:PChar):Integer; cdecl;
var smiui_current_state_dns: function( dnsid:dim_long_t; obj:PChar; state:PChar; action:PChar):Integer; cdecl;
var smiui_send_command: function(obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_send_command_dns: function(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_ep_send_command: function(obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_ep_send_command_dns: function(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_send_command_wait: function(obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_send_command_wait_dns: function(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_ep_send_command_wait: function(obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_ep_send_command_wait_dns: function(dnsid:dim_long_t; obj:PChar; cmnd:PChar):Integer; cdecl;
var smiui_change_option: function(domain:PChar; option:PChar; value:PChar):Integer; cdecl;
var smiui_change_option_wait: function(domain:PChar; option:PChar; value:PChar):Integer; cdecl;
var smiui_get_options: function(domain:PChar; optString:PChar):Integer; cdecl;
var smiui_get_options_dns: function(dnsid:dim_long_t; domain:PChar; optString:PChar):Integer; cdecl;
var smiui_number_of_objects: function(domain:PChar):Integer; cdecl;
var smiui_number_of_objects_dns: function(dnsid:dim_long_t; domain:PChar):Integer; cdecl;
var smiui_connect_domain: function(domain:PChar):Integer; cdecl;
var smiui_connect_domain_dns: function(dnsid:dim_long_t; domain:PChar):Integer; cdecl;
var smiui_book_connect_domain: function(domain:PChar; command_handler:smiui_domainchange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_book_connect_domain_dns: function(dnsid:dim_long_t; domain:PChar; command_handler:smiui_domainchange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_cancel_connect_domain: function(domain:PChar):Integer; cdecl;
var smiui_shutdown_domain: function(domain:PChar):Integer; cdecl;
var smiui_check_proxy: function(proxy:PChar):Integer; cdecl;
var smiui_check_proxy_dns: function(dnsid:dim_long_t; proxy:PChar):Integer; cdecl;
var smiui_kill: function(server:PChar):Integer; cdecl;
var smiui_get_next_object: function(domain:PChar; obj:PChar):Integer; cdecl;
var smiui_get_next_attribute: function(obj:PChar; attribute:PChar):Integer; cdecl;
var smiui_book_statechange: function(obj:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_book_statechange_dns: function(dnsid:dim_long_t; obj:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_cancel_statechange: function(id:Integer):Integer; cdecl;
var smiui_get_name: function(id:Integer; name:PChar):Integer; cdecl;
var smiui_get_state: function(id:Integer; var busy_flg:Integer; state:PChar; var n_actions:Integer):Integer; cdecl;
var smiui_get_smi_message: function(id:Integer; dom:PChar; mess:PChar):Integer; cdecl;
var smiui_get_user_message: function(id:Integer; dom:PChar; mess:PChar):Integer; cdecl;
var smiui_get_action_in_progress: function(id:Integer; action:PChar):Integer; cdecl;
var smiui_get_first_action: function(id:Integer; action:PChar; var n_pars:Integer):Integer; cdecl;
var smiui_get_next_action: function(id:Integer; action:PChar; var n_pars:Integer):Integer; cdecl;
var smiui_get_next_param: function(id:Integer; par:PChar; var typ:Integer; var size:Integer):Integer; cdecl;
var smiui_get_param_default_value: function(id:Integer; value:Pointer):Integer; cdecl;
var smiui_get_next_obj_param: function(id:Integer; par:PChar; var typ:Integer; var size:Integer):Integer; cdecl;
var smiui_get_obj_param_value: function(id:Integer; value:Pointer):Integer; cdecl;
var smiui_book_alloc_statechange: function(domain:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_book_alloc_statechange_dns: function(dnsid:dim_long_t; domain:PChar; command_handler:smiui_statechange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_cancel_alloc_statechange: function(id:Integer):Integer; cdecl;
var smiui_get_alloc_state: function(id:Integer; var busy_flg:Integer; state:PChar):Integer; cdecl;
var smiui_allocate: function(domain:PChar):Integer; cdecl;
var smiui_release: function(domain:PChar):Integer; cdecl;
var smiui_allocate_to: function(domainA:PChar; domainB:PChar):Integer; cdecl;
var smiui_release_from: function(domainA:PChar; domainB:PChar):Integer; cdecl;
var smiui_get_next_objectset: function(domain:PChar; objectset:PChar):Integer; cdecl;
var smiui_book_objectsetchange: function(obj:PChar; command_handler:smiui_setchange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_book_objectsetchange_dns: function(dnsid:dim_long_t; obj:PChar; command_handler:smiui_setchange_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_cancel_objectsetchange: function(id:Integer):Integer; cdecl;
var smiui_book_smi_message: function(dom:PChar; command_handler:smiui_message_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_cancel_smi_message: function(id:Integer):Integer; cdecl;
var smiui_book_user_message: function(dom:PChar; command_handler:smiui_message_handler_t; par:dim_long_t):Integer; cdecl;
var smiui_cancel_user_message: function(id:Integer):Integer; cdecl;
var smiui_get_first_object_in_set: function(id:Integer; obj:PChar):Integer; cdecl;
var smiui_get_next_object_in_set: function(id:Integer; obj:PChar):Integer; cdecl;
var smiui_get_setname: function(id:Integer; objset:PChar):Integer; cdecl;
var smiui_number_of_objectsets: function(domain:PChar):Integer; cdecl;
var smiui_number_of_objectsets_dns: function(dnsid:dim_long_t; domain:PChar):Integer; cdecl;
var smiui_create_command: function(action:PChar):Pointer; cdecl;
var smiui_add_param_to_command: function(id:Pointer; name:PChar; value:Pointer; typ:Integer):Integer; cdecl;
var smiui_delete_command: function(cmnd:Pointer):Integer; cdecl;
var smiui_get_command_string: function(id:Pointer):PChar; cdecl;
var smiui_get_action_in_progress_size: function(id:Integer; var size:Integer):Integer; cdecl;

{$ENDIF SMI_STATIC}

 //////////////////////////////
 // Service to load SMI library
 //////////////////////////////
function  ValidSmiuiRtlLibrary:Boolean; inline; // Check status
function  LoadSmiuiRtlLibrary(const FileName:String=''):Boolean;
procedure FreeSmiuiRtlLibrary; // Do not use this call directly
function  SmiuiRtlLibraryName:String; // smiui, smiuirtl.dll, libsmiui.so

type // For exceptions on SmiuiRtl load.
 ESmiuiRtlLibrary = class(Exception);

var // Internal SMI data, please don't change
 SmiuiRtlLibrary : record  // SMI library data
  Valid     : Boolean;     // Library status
  libHandle : TLibHandle;  // Library handle
  numLoaded : Integer;     // Num functions loaded
  numFailed : Integer;     // Num functions failed
  Report    : ShortString; // Report result on Load
 end = ( Valid:false; libHandle:0; numLoaded:0; numFailed:0; Report:'' );

implementation

const // Expected number of functions loaded
 ExpectedNumLoaded = 68;

{$IFDEF SMI_STATIC}

const // The Name of SMI library
 SmiuiRtlDll = {$IFDEF WINDOWS} 'smiuirtl.dll' {$ELSE} 'smiui' {$ENDIF};

function  smiui_set_dns;                        external SmiuiRtlDll name 'smiui_set_dns';
function  smiui_current_state;                  external SmiuiRtlDll name 'smiui_current_state';
function  smiui_current_state_dns;              external SmiuiRtlDll name 'smiui_current_state_dns';
function  smiui_send_command;                   external SmiuiRtlDll name 'smiui_send_command';
function  smiui_send_command_dns;               external SmiuiRtlDll name 'smiui_send_command_dns';
function  smiui_ep_send_command;                external SmiuiRtlDll name 'smiui_ep_send_command';
function  smiui_ep_send_command_dns;            external SmiuiRtlDll name 'smiui_ep_send_command_dns';
function  smiui_send_command_wait;              external SmiuiRtlDll name 'smiui_send_command_wait';
function  smiui_send_command_wait_dns;          external SmiuiRtlDll name 'smiui_send_command_wait_dns';
function  smiui_ep_send_command_wait;           external SmiuiRtlDll name 'smiui_ep_send_command_wait';
function  smiui_ep_send_command_wait_dns;       external SmiuiRtlDll name 'smiui_ep_send_command_wait_dns';
function  smiui_change_option;                  external SmiuiRtlDll name 'smiui_change_option';
function  smiui_change_option_wait;             external SmiuiRtlDll name 'smiui_change_option_wait';
function  smiui_get_options;                    external SmiuiRtlDll name 'smiui_get_options';
function  smiui_get_options_dns;                external SmiuiRtlDll name 'smiui_get_options_dns';
function  smiui_number_of_objects;              external SmiuiRtlDll name 'smiui_number_of_objects';
function  smiui_number_of_objects_dns;          external SmiuiRtlDll name 'smiui_number_of_objects_dns';
function  smiui_connect_domain;                 external SmiuiRtlDll name 'smiui_connect_domain';
function  smiui_connect_domain_dns;             external SmiuiRtlDll name 'smiui_connect_domain_dns';
function  smiui_book_connect_domain;            external SmiuiRtlDll name 'smiui_book_connect_domain';
function  smiui_book_connect_domain_dns;        external SmiuiRtlDll name 'smiui_book_connect_domain_dns';
function  smiui_cancel_connect_domain;          external SmiuiRtlDll name 'smiui_cancel_connect_domain';
function  smiui_shutdown_domain;                external SmiuiRtlDll name 'smiui_shutdown_domain';
function  smiui_check_proxy;                    external SmiuiRtlDll name 'smiui_check_proxy';
function  smiui_check_proxy_dns;                external SmiuiRtlDll name 'smiui_check_proxy_dns';
function  smiui_kill;                           external SmiuiRtlDll name 'smiui_kill';
function  smiui_get_next_object;                external SmiuiRtlDll name 'smiui_get_next_object';
function  smiui_get_next_attribute;             external SmiuiRtlDll name 'smiui_get_next_attribute';
function  smiui_book_statechange;               external SmiuiRtlDll name 'smiui_book_statechange';
function  smiui_book_statechange_dns;           external SmiuiRtlDll name 'smiui_book_statechange_dns';
function  smiui_cancel_statechange;             external SmiuiRtlDll name 'smiui_cancel_statechange';
function  smiui_get_name;                       external SmiuiRtlDll name 'smiui_get_name';
function  smiui_get_state;                      external SmiuiRtlDll name 'smiui_get_state';
function  smiui_get_smi_message;                external SmiuiRtlDll name 'smiui_get_smi_message';
function  smiui_get_user_message;               external SmiuiRtlDll name 'smiui_get_user_message';
function  smiui_get_action_in_progress;         external SmiuiRtlDll name 'smiui_get_action_in_progress';
function  smiui_get_first_action;               external SmiuiRtlDll name 'smiui_get_first_action';
function  smiui_get_next_action;                external SmiuiRtlDll name 'smiui_get_next_action';
function  smiui_get_next_param;                 external SmiuiRtlDll name 'smiui_get_next_param';
function  smiui_get_param_default_value;        external SmiuiRtlDll name 'smiui_get_param_default_value';
function  smiui_get_next_obj_param;             external SmiuiRtlDll name 'smiui_get_next_obj_param';
function  smiui_get_obj_param_value;            external SmiuiRtlDll name 'smiui_get_obj_param_value';
function  smiui_book_alloc_statechange;         external SmiuiRtlDll name 'smiui_book_alloc_statechange';
function  smiui_book_alloc_statechange_dns;     external SmiuiRtlDll name 'smiui_book_alloc_statechange_dns';
function  smiui_cancel_alloc_statechange;       external SmiuiRtlDll name 'smiui_cancel_alloc_statechange';
function  smiui_get_alloc_state;                external SmiuiRtlDll name 'smiui_get_alloc_state';
function  smiui_allocate;                       external SmiuiRtlDll name 'smiui_allocate';
function  smiui_release;                        external SmiuiRtlDll name 'smiui_release';
function  smiui_allocate_to;                    external SmiuiRtlDll name 'smiui_allocate_to';
function  smiui_release_from;                   external SmiuiRtlDll name 'smiui_release_from';
function  smiui_get_next_objectset;             external SmiuiRtlDll name 'smiui_get_next_objectset';
function  smiui_book_objectsetchange;           external SmiuiRtlDll name 'smiui_book_objectsetchange';
function  smiui_book_objectsetchange_dns;       external SmiuiRtlDll name 'smiui_book_objectsetchange_dns';
function  smiui_cancel_objectsetchange;         external SmiuiRtlDll name 'smiui_cancel_objectsetchange';
function  smiui_book_smi_message;               external SmiuiRtlDll name 'smiui_book_smi_message';
function  smiui_cancel_smi_message;             external SmiuiRtlDll name 'smiui_cancel_smi_message';
function  smiui_book_user_message;              external SmiuiRtlDll name 'smiui_book_user_message';
function  smiui_cancel_user_message;            external SmiuiRtlDll name 'smiui_cancel_user_message';
function  smiui_get_first_object_in_set;        external SmiuiRtlDll name 'smiui_get_first_object_in_set';
function  smiui_get_next_object_in_set;         external SmiuiRtlDll name 'smiui_get_next_object_in_set';
function  smiui_get_setname;                    external SmiuiRtlDll name 'smiui_get_setname';
function  smiui_number_of_objectsets;           external SmiuiRtlDll name 'smiui_number_of_objectsets';
function  smiui_number_of_objectsets_dns;       external SmiuiRtlDll name 'smiui_number_of_objectsets_dns';
function  smiui_create_command;                 external SmiuiRtlDll name 'smiui_create_command';
function  smiui_add_param_to_command;           external SmiuiRtlDll name 'smiui_add_param_to_command';
function  smiui_delete_command;                 external SmiuiRtlDll name 'smiui_delete_command';
function  smiui_get_command_string;             external SmiuiRtlDll name 'smiui_get_command_string';
function  smiui_get_action_in_progress_size;    external SmiuiRtlDll name 'smiui_get_action_in_progress_size';

function LoadSmiuiRtlLibrary(const FileName:String=''):Boolean;
var libName:String;
begin
 SmiuiRtlLibrary.Valid:=true;
 SmiuiRtlLibrary.libHandle:=0;
 SmiuiRtlLibrary.numLoaded:=ExpectedNumLoaded;
 SmiuiRtlLibrary.numFailed:=0;
 libName:=Trim(FileName);
 if (libName='') then libName:=SmiuiRtlDll;
 SmiuiRtlLibrary.Report:=libName+': Success';
 Result:=SmiuiRtlLibrary.Valid;
end;

{$ELSE  SMI_STATIC}

const // The Name of SMI library
 SmiuiRtlDll = {$IFDEF WINDOWS} 'smiuirtl.dll' {$ELSE} 'libsmiui.so' {$ENDIF};

function LoadSmiuiRtlLibrary(const FileName:String=''):Boolean;
var lib:TLibHandle; numOk,numEr:Integer; libName:String;
 function DoGetProcAddress(ProcName:String):Pointer;
 begin
  if (lib=0)
  then Result:=nil
  else Result:=System.GetProcAddress(lib,ProcName);
  if (Result<>nil) then inc(numOk) else inc(numEr);
 end;
begin
 if not LoadDimLibrary then begin
  Result:=false; // SMI depends on DIM
  Exit;
 end;
 if SmiuiRtlLibrary.Valid then begin
  Result:=true; // Already done
  Exit;
 end;
 numOk:=0; numEr:=0;
 libName:=Trim(FileName);
 if (libName='') then libName:=SmiuiRtlDll;
 lib:=SafeLoadLibrary(libName);
 smiui_set_dns                     := DoGetProcAddress( 'smiui_set_dns' );
 smiui_current_state               := DoGetProcAddress( 'smiui_current_state' );
 smiui_current_state_dns           := DoGetProcAddress( 'smiui_current_state_dns' );
 smiui_send_command                := DoGetProcAddress( 'smiui_send_command' );
 smiui_send_command_dns            := DoGetProcAddress( 'smiui_send_command_dns' );
 smiui_ep_send_command             := DoGetProcAddress( 'smiui_ep_send_command' );
 smiui_ep_send_command_dns         := DoGetProcAddress( 'smiui_ep_send_command_dns' );
 smiui_send_command_wait           := DoGetProcAddress( 'smiui_send_command_wait' );
 smiui_send_command_wait_dns       := DoGetProcAddress( 'smiui_send_command_wait_dns' );
 smiui_ep_send_command_wait        := DoGetProcAddress( 'smiui_ep_send_command_wait' );
 smiui_ep_send_command_wait_dns    := DoGetProcAddress( 'smiui_ep_send_command_wait_dns' );
 smiui_change_option               := DoGetProcAddress( 'smiui_change_option' );
 smiui_change_option_wait          := DoGetProcAddress( 'smiui_change_option_wait' );
 smiui_get_options                 := DoGetProcAddress( 'smiui_get_options' );
 smiui_get_options_dns             := DoGetProcAddress( 'smiui_get_options_dns' );
 smiui_number_of_objects           := DoGetProcAddress( 'smiui_number_of_objects' );
 smiui_number_of_objects_dns       := DoGetProcAddress( 'smiui_number_of_objects_dns' );
 smiui_connect_domain              := DoGetProcAddress( 'smiui_connect_domain' );
 smiui_connect_domain_dns          := DoGetProcAddress( 'smiui_connect_domain_dns' );
 smiui_book_connect_domain         := DoGetProcAddress( 'smiui_book_connect_domain' );
 smiui_book_connect_domain_dns     := DoGetProcAddress( 'smiui_book_connect_domain_dns' );
 smiui_cancel_connect_domain       := DoGetProcAddress( 'smiui_cancel_connect_domain' );
 smiui_shutdown_domain             := DoGetProcAddress( 'smiui_shutdown_domain' );
 smiui_check_proxy                 := DoGetProcAddress( 'smiui_check_proxy' );
 smiui_check_proxy_dns             := DoGetProcAddress( 'smiui_check_proxy_dns' );
 smiui_kill                        := DoGetProcAddress( 'smiui_kill' );
 smiui_get_next_object             := DoGetProcAddress( 'smiui_get_next_object' );
 smiui_get_next_attribute          := DoGetProcAddress( 'smiui_get_next_attribute' );
 smiui_book_statechange            := DoGetProcAddress( 'smiui_book_statechange' );
 smiui_book_statechange_dns        := DoGetProcAddress( 'smiui_book_statechange_dns' );
 smiui_cancel_statechange          := DoGetProcAddress( 'smiui_cancel_statechange' );
 smiui_get_name                    := DoGetProcAddress( 'smiui_get_name' );
 smiui_get_state                   := DoGetProcAddress( 'smiui_get_state' );
 smiui_get_smi_message             := DoGetProcAddress( 'smiui_get_smi_message' );
 smiui_get_user_message            := DoGetProcAddress( 'smiui_get_user_message' );
 smiui_get_action_in_progress      := DoGetProcAddress( 'smiui_get_action_in_progress' );
 smiui_get_first_action            := DoGetProcAddress( 'smiui_get_first_action' );
 smiui_get_next_action             := DoGetProcAddress( 'smiui_get_next_action' );
 smiui_get_next_param              := DoGetProcAddress( 'smiui_get_next_param' );
 smiui_get_param_default_value     := DoGetProcAddress( 'smiui_get_param_default_value' );
 smiui_get_next_obj_param          := DoGetProcAddress( 'smiui_get_next_obj_param' );
 smiui_get_obj_param_value         := DoGetProcAddress( 'smiui_get_obj_param_value' );
 smiui_book_alloc_statechange      := DoGetProcAddress( 'smiui_book_alloc_statechange' );
 smiui_book_alloc_statechange_dns  := DoGetProcAddress( 'smiui_book_alloc_statechange_dns' );
 smiui_cancel_alloc_statechange    := DoGetProcAddress( 'smiui_cancel_alloc_statechange' );
 smiui_get_alloc_state             := DoGetProcAddress( 'smiui_get_alloc_state' );
 smiui_allocate                    := DoGetProcAddress( 'smiui_allocate' );
 smiui_release                     := DoGetProcAddress( 'smiui_release' );
 smiui_allocate_to                 := DoGetProcAddress( 'smiui_allocate_to' );
 smiui_release_from                := DoGetProcAddress( 'smiui_release_from' );
 smiui_get_next_objectset          := DoGetProcAddress( 'smiui_get_next_objectset' );
 smiui_book_objectsetchange        := DoGetProcAddress( 'smiui_book_objectsetchange' );
 smiui_book_objectsetchange_dns    := DoGetProcAddress( 'smiui_book_objectsetchange_dns' );
 smiui_cancel_objectsetchange      := DoGetProcAddress( 'smiui_cancel_objectsetchange' );
 smiui_book_smi_message            := DoGetProcAddress( 'smiui_book_smi_message' );
 smiui_cancel_smi_message          := DoGetProcAddress( 'smiui_cancel_smi_message' );
 smiui_book_user_message           := DoGetProcAddress( 'smiui_book_user_message' );
 smiui_cancel_user_message         := DoGetProcAddress( 'smiui_cancel_user_message' );
 smiui_get_first_object_in_set     := DoGetProcAddress( 'smiui_get_first_object_in_set' );
 smiui_get_next_object_in_set      := DoGetProcAddress( 'smiui_get_next_object_in_set' );
 smiui_get_setname                 := DoGetProcAddress( 'smiui_get_setname' );
 smiui_number_of_objectsets        := DoGetProcAddress( 'smiui_number_of_objectsets' );
 smiui_number_of_objectsets_dns    := DoGetProcAddress( 'smiui_number_of_objectsets_dns' );
 smiui_create_command              := DoGetProcAddress( 'smiui_create_command' );
 smiui_add_param_to_command        := DoGetProcAddress( 'smiui_add_param_to_command' );
 smiui_delete_command              := DoGetProcAddress( 'smiui_delete_command' );
 smiui_get_command_string          := DoGetProcAddress( 'smiui_get_command_string' );
 smiui_get_action_in_progress_size := DoGetProcAddress( 'smiui_get_action_in_progress_size' );
 SmiuiRtlLibrary.Valid:=(numOk=ExpectedNumLoaded) and (numEr=0);
 SmiuiRtlLibrary.libHandle:=lib;
 SmiuiRtlLibrary.numLoaded:=numOk;
 SmiuiRtlLibrary.numFailed:=numEr;
 if SmiuiRtlLibrary.Valid
 then SmiuiRtlLibrary.Report:=libName+': Success'
 else SmiuiRtlLibrary.Report:=libName+': Failure';
 {$IFDEF UNIX}
 if lib=0 then SmiuiRtlLibrary.Report:=StrPas(dlerror);
 {$ENDIF UNIX}
 Result:=SmiuiRtlLibrary.Valid;
end;

{$ENDIF SMI_STATIC}

procedure FreeSmiuiRtlLibrary;
begin
 if (SmiuiRtlLibrary.libHandle<>0) then begin
  if SmiuiRtlLibrary.Valid then begin
  end;
  FreeLibrary(SmiuiRtlLibrary.libHandle);
 end;
 SmiuiRtlLibrary.Valid:=false;
 SmiuiRtlLibrary.libHandle:=0;
 SmiuiRtlLibrary.numLoaded:=0;
 SmiuiRtlLibrary.numFailed:=0;
 SmiuiRtlLibrary.Report:='';
end;

function  ValidSmiuiRtlLibrary:Boolean;
begin
 Result:=SmiuiRtlLibrary.Valid;
end;

function SmiuiRtlLibraryName:String;
begin
 Result:=SmiuiRtlDll;
end;

///////////////////////////////////////
// Unit initialization and finalization
///////////////////////////////////////

procedure Init_crw_smiuirtl;
begin
 LoadSmiuiRtlLibrary;
end;

procedure Free_crw_smiuirtl;
begin
 // FreeSmiuiRtlLibrary;
end;

initialization

 Init_crw_smiuirtl;

finalization

 Free_crw_smiuirtl;

end.

//////////////
// END OF FILE
//////////////

