NT Services Status API calls

Chris Kelleher

Administrator
Staff member
NT Services Status

by Todd G. Nist, tnist@netcarrier.com

Program source is available for download: w-findservice.w (50 kbyte)

This is a program for an NT environment which will
determine all of the computers on a given network and which services they
are running. You can then inquire of a given server what the status is of
a services and it will return weather it is running, in error, etc...

It has only been tested under NT 4.0 with service pack 3. You will have to
be logged into and authenticated on the network in order to inquire of the
status of services running on other machines in the network.


--------------------------------------------------------------------------------
API-procedures used in this example are listed here to be included in the search index:
PROCEDURE CloseServiceHandle EXTERNAL "advapi32.dll"
PROCEDURE EnumServicesStatusA EXTERNAL "advapi32.dll"
PROCEDURE OpenSCManagerA EXTERNAL "advapi32.dll"
PROCEDURE OpenServiceA EXTERNAL "advapi32.dll"
PROCEDURE QueryServiceConfigA EXTERNAL "advapi32.dll"
PROCEDURE QueryServiceStatus EXTERNAL "advapi32.dll"
PROCEDURE NetServerEnum EXTERNAL "Netapi32.dll"
PROCEDURE NetApiBufferFree EXTERNAL "Netapi32.dll"
PROCEDURE lstrcpyW EXTERNAL "kernel32.dll"
PROCEDURE lstrlen EXTERNAL "kernel32.dll"
PROCEDURE RtlMoveMemory EXTERNAL "kernel32.dll"
PROCEDURE WideCharToMultiByte EXTERNAL "kernel32.dll"
PROCEDURE GetComputerNameA EXTERNAL "kernel32.dll"
 

Chris Kelleher

Administrator
Staff member
<BLOCKQUOTE><font size="1" face="Arial, Verdana">code:</font><HR><pre>&ANALYZE-SUSPEND _VERSION-NUMBER UIB_v8r12 GUI
&ANALYZE-RESUME
&Scoped-define WINDOW-NAME C-Win
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _DEFINITIONS C-Win
/*------------------------------------------------------------------------

File:

Description: Obtain information accross the network off services which are
running

Input Parameters:


Output Parameters:


Author: Todd G. Nist

Created: 3/1/99

------------------------------------------------------------------------*/
/* This .W file was created with the Progress UIB. */
/*----------------------------------------------------------------------*/

/* Create an unnamed pool to store all the widgets created
by this procedure. This is a good default which assures
that this procedure's triggers and internal procedures
will execute in this procedure's storage, and that proper
cleanup will occur on deletion of the procedure. */

CREATE WIDGET-POOL.

/* *************************** Definitions ************************** */

/* Parameters Definitions --- */

/* Local Variable Definitions --- */

define var hSCM as integer no-undo. /* handle to Service Control Manager */
define var iRetCode as integer no-undo.

/*------------------------------------------------------------------------------
Temp table to hold service information
------------------------------------------------------------------------------*/
define temp-table ttService no-undo
field cServerName as char format 'x(20)':U
field cServiceName as char format 'x(24)':U
field cDisplayName as char format 'x(32)':U
field cStatus as char format 'x(20)':U
field cDriverType as char format 'x(20)':U
index Server-ServiceName as PRIMARY
cServiceName
cServerName
index ServerStatus
cStatus.

/*------------------------------------------------------------------------------
Constants and declarations for making an NT Service
------------------------------------------------------------------------------*/

/********************* support structures

Public Type SERVICE_STATUS
dwServiceType As Long
dwCurrentState As Long
dwControlsAccepted As Long
dwWin32ExitCode As Long
dwServiceSpecificExitCode As Long
dwCheckPoint As Long
dwWaitHint As Long
End Type

Public Type ENUM_SERVICE_STATUS_PTR
psServiceName As Long
psDisplayName As Long
ServiceStatus As SERVICE_STATUS
End Type

Public Type QUERY_SERVICE_CONFIG_PTR
dwServiceType As Long
dwStartType As Long
dwErrorControl As Long
psBinaryPathName As Long
psLoadOrderGroup As Long
dwTagId As Long
psDependencies As Long
psServiceStartName As Long
psDisplayName As Long
End Type

*******************************/

&GLOB ERROR_MORE_DATA 234
&GLOB MAX_PREFERRED_LENGTH -1

&GLOB DELETE 65536
&GLOB STANDARD_RIGHTS_READ 131072
&GLOB STANDARD_RIGHTS_WRITE 131072
&GLOB STANDARD_RIGHTS_EXECUTE 131072
&GLOB STANDARD_RIGHTS_REQUIRED 983040
&GLOB STANDARD_RIGHTS_ALL 2031616

/*-----------------------------------------------------------------------------
Value to indicate no change to an optional parameter
-----------------------------------------------------------------------------*/
&GLOB SERVICE_NO_CHANGE 65535

/* ----------------------------------------------------------------------------
Service State -- for Enum Requests (Bit Mask)
-----------------------------------------------------------------------------*/
&GLOB SERVICE_ACTIVE 1
&GLOB SERVICE_INACTIVE 2
&GLOB SERVICE_STATE_ALL ({&SERVICE_ACTIVE} + {&SERVICE_INACTIVE})

/*----------------------------------------------------------------------------
Service Control Manager object specific access types
-----------------------------------------------------------------------------*/
&GLOB SERVICES_ACTIVE_DATABASE "ServicesActive":U

&GLOB SC_MANAGER_CONNECT 1
&GLOB SC_MANAGER_CREATE_SERVICE 2
&GLOB SC_MANAGER_ENUMERATE_SERVICE 4
&GLOB SC_MANAGER_LOCK 8
&GLOB SC_MANAGER_QUERY_LOCK_STATUS 16
&GLOB SC_MANAGER_MODIFY_BOOT_CONFIG 32

&GLOB SC_MANAGER_ALL_ACCESS {&STANDARD_RIGHTS_REQUIRED} + ~
{&SC_MANAGER_CONNECT} + ~
{&SC_MANAGER_CREATE_SERVICE} + ~
{&SC_MANAGER_ENUMERATE_SERVICE} + ~
{&SC_MANAGER_LOCK} + ~
{&SC_MANAGER_QUERY_LOCK_STATUS} + ~
{&SC_MANAGER_MODIFY_BOOT_CONFIG}

/* ----------------------------------------------------------------------------
Service object specific access type
-----------------------------------------------------------------------------*/
&GLOB SERVICE_QUERY_CONFIG 1
&GLOB SERVICE_CHANGE_CONFIG 2
&GLOB SERVICE_QUERY_STATUS 4
&GLOB SERVICE_ENUMERATE_DEPENDENTS 8
&GLOB SERVICE_START 16
&GLOB SERVICE_STOP 32
&GLOB SERVICE_PAUSE_CONTINUE 64
&GLOB SERVICE_INTERROGATE 128
&GLOB SERVICE_USER_DEFINED_CONTROL 256

&GLOB SERVICE_ALL_ACCESS {&STANDARD_RIGHTS_REQUIRED} + ~
{&SERVICE_QUERY_CONFIG} + ~
{&SERVICE_CHANGE_CONFIG} + ~
{&SERVICE_QUERY_STATUS} + ~
{&SERVICE_ENUMERATE_DEPENDENTS} + ~
{&SERVICE_START} + ~
{&SERVICE_STOP} + ~
{&SERVICE_PAUSE_CONTINUE} + ~
{&SERVICE_INTERROGATE} + ~
{&SERVICE_USER_DEFINED_CONTROL}

&GLOB SERVICE_WIN32_OWN_PROCESS 16
&GLOB SERVICE_WIN32_SHARE_PROCESS 32
&GLOB SERVICE_INTERACTIVE_PROCESS 256

&GLOB SERVICE_KERNEL_DRIVER 1
&GLOB SERVICE_FILE_SYSTEM_DRIVER 2
&GLOB SERVICE_ADAPTER 4
&GLOB SERVICE_RECOGNIZER_DRIVER 8


&GLOB SERVICE_DRIVER {&SERVICE_KERNEL_DRIVER} + ~
{&SERVICE_FILE_SYSTEM_DRIVER} + ~
{&SERVICE_RECOGNIZER_DRIVER}

&GLOB SERVICE_WIN32 {&SERVICE_WIN32_OWN_PROCESS} + ~
{&SERVICE_WIN32_SHARE_PROCESS}


&GLOB SERVICE_ERROR_IGNORE 0
&GLOB SERVICE_ERROR_NORMAL 1
&GLOB SERVICE_ERROR_SEVERE 2
&GLOB SERVICE_ERROR_CRITICAL 3

/*-----------------------------------------------------------------------------
Constants for type of computer
------------------------------------------------------------------------------*/
&GLOB SV_TYPE_WORKSTATION 1
&GLOB SV_TYPE_SERVER 2
&GLOB SV_TYPE_SQLSERVER 4
&GLOB SV_TYPE_DOMAIN_CTRL 8
&GLOB SV_TYPE_DOMAIN_BAKCTRL 16
&GLOB SV_TYPE_TIME_SOURCE 32
&GLOB SV_TYPE_AFP 64
&GLOB SV_TYPE_NOVELL 128
&GLOB SV_TYPE_DOMAIN_MEMBER 256
&GLOB SV_TYPE_PRINTQ_SERVER 512
&GLOB SV_TYPE_DIALIN_SERVER 1024
&GLOB SV_TYPE_XENIX_SERVER 2048
&GLOB SV_TYPE_SERVER_UNIX 2048
&GLOB SV_TYPE_NT 4096
&GLOB SV_TYPE_WFW 8192
&GLOB SV_TYPE_SERVER_MFPN 16384
&GLOB SV_TYPE_SERVER_NT 32768
&GLOB SV_TYPE_POTENTIAL_BROWSER 65536
&GLOB SV_TYPE_BACKUP_BROWSER 131072
&GLOB SV_TYPE_MASTER_BROWSER 262144
&GLOB SV_TYPE_DOMAIN_MASTER 524288
&GLOB SV_TYPE_SERVER_OSF 1048576
&GLOB SV_TYPE_SERVER_VMS 2097152
&GLOB SV_TYPE_WINDOWS 4194304
&GLOB SV_TYPE_ALTERNATE_XPORT 536870912
&GLOB SV_TYPE_LOCAL_LIST_ONLY 1073741824
&GLOB SV_TYPE_DOMAIN_ENUM 2147483648
&GLOB SV_TYPE_ALL 65535

/* ------------------------------------------------
Structured used by NetServerEnum
--------------------------------------------------*/
/**********************************
Private Type SERVER_INFO_101
wki101_platform_id As Long
wki101_servername As Long
wki101_langroup As Long
wki101_ver_major As Long
wki101_ver_minor As Long
wki101_lanroot As Long
End Type
*******************************/

/*-------------------------------------------------
Service State enumeration -- for CurrentState
--------------------------------------------------*/
&GLOB SERVICE_STOPPED 1
&GLOB SERVICE_START_PENDING 2
&GLOB SERVICE_STOP_PENDING 3
&GLOB SERVICE_RUNNING 4
&GLOB SERVICE_CONTINUE_PENDING 5
&GLOB SERVICE_PAUSE_PENDING 6
&GLOB SERVICE_PAUSED 7

/*-----------------------------------------------------------------------------
API declarations, NT Service specific
-----------------------------------------------------------------------------*/
PROCEDURE CloseServiceHandle EXTERNAL "advapi32.dll":
define input parameter hSCObject as long. /* handle to the service control manager object or the service object to close */
define return parameter iRetCode as long. /* non 0 on success */
END.

PROCEDURE EnumServicesStatusA EXTERNAL "advapi32.dll":
define input parameter hSCManager as long. /* handle to service control manager database */
define input parameter dwServiceType as long. /* type of services to enumerate */
define input parameter dwServiceState as long. /* state of services to enumerate */
define input parameter lpServices as long. /* pointer to service status buffer */
define input parameter cbBufSize as long. /* size of service status buffer */
define input parameter pbBytesNeeded as long. /* pointer to variable for bytes needed */
define input parameter pbServicesReturned as long. /* pointer to variable for number returned */
define input parameter lpResumeHandle as long. /* pointer to variable for next entry */
define return parameter iRetCode as long. /* non 0 on success */
END.

PROCEDURE OpenSCManagerA EXTERNAL "advapi32.dll":
define input parameter lpMachineName as long. /* pointer to machine name string */
define input parameter lpDatabaseName as long. /* pointer to database name string */
define input parameter dwDesiredAccess as long. /* type of access */
define return parameter iRetCode as long.
END.

PROCEDURE OpenServiceA EXTERNAL "advapi32.dll":
define input parameter hSCManager as long. /* handle to service control manager database */
define input parameter lpServiceName as long. /* pointer to name of service to start */
define input parameter dwDesiredAccess as long. /* type of access to service */
define return parameter iRetCode as long.
END.

PROCEDURE QueryServiceConfigA EXTERNAL "advapi32.dll":
define input parameter hService as long. /* handle to service */
define input parameter lpServiceConfig as long. /* service configuration structure */
define input parameter cbBufSize as long. /* size of structure */
define output parameter pcbBytesNeeded as long. /* pointer to a variable that receives the number of bytes needed to return all the config information if the function fails with and error "Error_insufficient_buffer" */
define return parameter iRetCode as long. /* non 0 if successful */
END.

PROCEDURE QueryServiceStatus EXTERNAL "advapi32.dll":
define input parameter hService as long. /* handle to service */
define input parameter lpServiceStatus as long. /* service status structure */
define return parameter iRetCode as long. /* non 0 if successful */
END.

/*------------------------------------------------
Network API declarations
------------------------------------------------*/
PROCEDURE NetServerEnum EXTERNAL "Netapi32.dll":
define input parameter lpServerName as long. /* pointer to string containing the name of the remote server on which the function is to execute */
define input parameter dwLevel as long. /* Specifis the information level of the data. */
define output parameter lpServerInfo as long. /* pointer to a buffer which contains the SERVER_INFO based on level (100 or 101) */
define input parameter dwPrefMaxLen as long. /* Perfered max len of returned data. If this is max_perfered_length, the function will allocate the amount of memory needed for the data */
define output parameter dwEntriesRead as long. /* pointer to dword value that receives the actual number of entries read */
define output parameter dwTotalEntries as long. /* pointer to a dword value that receives the total number of visible servers and workstations on the network */
define input parameter dwServerType as long. /* server type */
define input parameter lpDomain as long. /* pointer to string containing domain */
define input parameter ResumeHandle as long. /* reserved, must be 0. */
define return parameter iRetCode as long. /* non 0 on success */
END.

PROCEDURE NetApiBufferFree EXTERNAL "Netapi32.dll":
define input parameter lpServerInfo as long. /* pointer to a buffer that was previously returned by another network mamagement function. */
define return parameter iRetCode as long.
END.

PROCEDURE lstrcpyW EXTERNAL "kernel32.dll":
define input parameter lpDest as long.
define input parameter lpSrc as long.
define return parameter iRetCode as long.
END.

PROCEDURE lstrlen EXTERNAL "kernel32.dll":
define input parameter lpStr as long.
define return parameter cbStr as long.
END.

PROCEDURE RtlMoveMemory EXTERNAL "kernel32.dll":
define input parameter lpDest as long.
define input parameter lpSrc as long.
define input parameter cbToCopy as long.
define return parameter iRetCode as long.
END.

PROCEDURE WideCharToMultiByte EXTERNAL "KERNEL32.dll":
define input parameter uCodePage as long. /* code page */
define input parameter dwFlags as long. /* performance and mapping flags */
define input parameter lpWideCharStr as long. /* address of wide-character string */
define input parameter cbWideChar as long. /* number of characters in string, if -1 is calculated on the fly */
define input parameter lpMultiByteStr as long. /* address of buffer for new string */
define input parameter cbMultiByte as long. /* size of buffer */
define input parameter lpDefaultChar as long. /* address of default for unmappable characters */
define input parameter lpUsedDefaultChar as long. /* address of flag set when default char is used */
define return parameter iRetCode as long. /* if successful, number of bytes written to the lpMultiByteStr buffer, else 0 */
END.

/*------------------------------------------------
Miscellaneous API declarations
------------------------------------------------*/
PROCEDURE GetComputerNameA EXTERNAL "kernel32.dll":
define output parameter lpBuffer AS MEMPTR.
define input-output parameter nSize AS LONG.
define return parameter intResult AS SHORT.
END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-PREPROCESSOR-BLOCK

/* ******************** Preprocessor Definitions ******************** */

&Scoped-define PROCEDURE-TYPE Window

/* Name of first Frame and/or Browse and/or first Query */
&Scoped-define FRAME-NAME DEFAULT-FRAME
&Scoped-define BROWSE-NAME BROWSE-1

/* Internal Tables (found by Frame, Query & Browse Queries) */
&Scoped-define INTERNAL-TABLES ttService

/* Definitions for BROWSE BROWSE-1 */
&Scoped-define FIELDS-IN-QUERY-BROWSE-1 ttService.cServiceName ttService.cDisplayName ttService.cStatus ttService.cDriverType
&Scoped-define ENABLED-FIELDS-IN-QUERY-BROWSE-1
&Scoped-define FIELD-PAIRS-IN-QUERY-BROWSE-1
&Scoped-define SELF-NAME BROWSE-1
&Scoped-define OPEN-QUERY-BROWSE-1 OPEN QUERY {&SELF-NAME} FOR EACH ttService.
&Scoped-define TABLES-IN-QUERY-BROWSE-1 ttService
&Scoped-define FIRST-TABLE-IN-QUERY-BROWSE-1 ttService


/* Definitions for FRAME DEFAULT-FRAME */
&Scoped-define OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME ~
~{&OPEN-QUERY-BROWSE-1}

/* Standard List Definitions */
&Scoped-Define ENABLED-OBJECTS RECT-1 slServers BROWSE-1 TOGGLE-1 TOGGLE-2 ~
TOGGLE-3 TOGGLE-4 cSearchService btnSearch btnExit
&Scoped-Define DISPLAYED-OBJECTS slServers TOGGLE-1 TOGGLE-2 TOGGLE-3 ~
TOGGLE-4 cSearchService

/* Custom List Definitions */
/* List-1,List-2,List-3,List-4,List-5,List-6 */

/* _UIB-PREPROCESSOR-BLOCK-END */
&ANALYZE-RESUME


/* ************************ Function Prototypes ********************** */

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD CleanupServices C-Win
FUNCTION CleanupServices RETURNS LOGICAL
( /* parameter-definitions */ ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD CloseSCManager C-Win
FUNCTION CloseSCManager RETURNS CHARACTER
( input phSCManager as integer ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD EnumCurrentState C-Win
FUNCTION EnumCurrentState RETURNS CHARACTER
( input piCurrentState as integer ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD EnumDriverType C-Win
FUNCTION EnumDriverType RETURNS CHARACTER
( input piDriver as integer ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD GetComputerName C-Win
FUNCTION GetComputerName RETURNS CHARACTER
( /* parameter-definitions */ ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD GetServers C-Win
FUNCTION GetServers RETURNS CHARACTER
( input phSelectionList as handle ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD GetServices C-Win
FUNCTION GetServices RETURNS LOGICAL
( input phSCM as integer,
input pcSearchService as char,
input pcServerName as char) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD Initialize C-Win
FUNCTION Initialize RETURNS LOGICAL
( /* parameter-definitions */ ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD OpenSCManager C-Win
FUNCTION OpenSCManager RETURNS INTEGER
( input pcComputerName as char ) FORWARD.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


/* *********************** Control Definitions ********************** */

/* Define the widget handle for the window */
DEFINE VAR C-Win AS WIDGET-HANDLE NO-UNDO.

/* Definitions of the field level widgets */
DEFINE BUTTON btnEnumServices
LABEL "Enumerate Services"
SIZE 22.8 BY 1.14.

DEFINE BUTTON btnExit
LABEL "Exit"
SIZE 22.8 BY 1.14.

DEFINE BUTTON btnSearch
LABEL "Search"
SIZE 22.8 BY 1.14.

DEFINE VARIABLE cSearchService AS CHARACTER FORMAT "X(256)":U
VIEW-AS FILL-IN
SIZE 33.6 BY 1 NO-UNDO.

DEFINE RECTANGLE RECT-1
EDGE-PIXELS 2 GRAPHIC-EDGE NO-FILL
SIZE 116.6 BY 12.19.

DEFINE VARIABLE slServers AS CHARACTER
VIEW-AS SELECTION-LIST MULTIPLE
SIZE 33 BY 11.43 NO-UNDO.

DEFINE VARIABLE TOGGLE-1 AS LOGICAL INITIAL no
LABEL "Services"
VIEW-AS TOGGLE-BOX
SIZE 13.4 BY .81 NO-UNDO.

DEFINE VARIABLE TOGGLE-2 AS LOGICAL INITIAL no
LABEL "Drivers"
VIEW-AS TOGGLE-BOX
SIZE 13.4 BY .81 NO-UNDO.

DEFINE VARIABLE TOGGLE-3 AS LOGICAL INITIAL no
LABEL "NT Servers"
VIEW-AS TOGGLE-BOX
SIZE 15.6 BY .81 NO-UNDO.

DEFINE VARIABLE TOGGLE-4 AS LOGICAL INITIAL no
LABEL "All Systems"
VIEW-AS TOGGLE-BOX
SIZE 16.2 BY .81 NO-UNDO.

/* Query definitions */
&ANALYZE-SUSPEND
DEFINE QUERY BROWSE-1 FOR
ttService SCROLLING.
&ANALYZE-RESUME

/* Browse definitions */
DEFINE BROWSE BROWSE-1
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _DISPLAY-FIELDS BROWSE-1 C-Win _FREEFORM
QUERY BROWSE-1 DISPLAY
ttService.cServiceName
ttService.cDisplayName
ttService.cStatus
ttService.cDriverType
/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME
WITH NO-ROW-MARKERS SIZE 78.6 BY 11.43.


/* ************************ Frame Definitions *********************** */

DEFINE FRAME DEFAULT-FRAME
slServers AT ROW 1.76 COL 2.8 NO-LABEL
BROWSE-1 AT ROW 1.76 COL 37
TOGGLE-1 AT ROW 13.95 COL 2.8
TOGGLE-2 AT ROW 13.95 COL 19
TOGGLE-3 AT ROW 13.95 COL 36.4
TOGGLE-4 AT ROW 13.95 COL 55
cSearchService AT ROW 15.95 COL 2.8 NO-LABEL
btnEnumServices AT ROW 15.95 COL 44.8
btnSearch AT ROW 15.95 COL 68.2
btnExit AT ROW 15.95 COL 92.8
"Servers" VIEW-AS TEXT
SIZE 8 BY .62 AT ROW 1.1 COL 2.8
RECT-1 AT ROW 1.38 COL 1
"Service to Search For:" VIEW-AS TEXT
SIZE 22.2 BY .62 AT ROW 15.29 COL 2.8
WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY
SIDE-LABELS NO-UNDERLINE THREE-D
AT COL 1 ROW 1
SIZE 116.6 BY 16.38.


/* *********************** Procedure Settings ************************ */

&ANALYZE-SUSPEND _PROCEDURE-SETTINGS
/* Settings for THIS-PROCEDURE
Type: Window
Allow: Basic,Browse,DB-Fields,Window,Query
Other Settings: COMPILE
*/
&ANALYZE-RESUME _END-PROCEDURE-SETTINGS

/* ************************* Create Window ************************** */

&ANALYZE-SUSPEND _CREATE-WINDOW
IF SESSION
biggrin.gif
ISPLAY-TYPE = "GUI":U THEN
CREATE WINDOW C-Win ASSIGN
HIDDEN = YES
TITLE = "Find Services Status"
HEIGHT = 16.38
WIDTH = 116.6
MAX-HEIGHT = 18.48
MAX-WIDTH = 116.6
VIRTUAL-HEIGHT = 18.48
VIRTUAL-WIDTH = 116.6
RESIZE = yes
SCROLL-BARS = no
STATUS-AREA = no
BGCOLOR = ?
FGCOLOR = ?
KEEP-FRAME-Z-ORDER = yes
THREE-D = yes
MESSAGE-AREA = no
SENSITIVE = yes.
ELSE {&WINDOW-NAME} = CURRENT-WINDOW.
/* END WINDOW DEFINITION */
&ANALYZE-RESUME


/* *************** Runtime Attributes and UIB Settings ************** */

&ANALYZE-SUSPEND _RUN-TIME-ATTRIBUTES
/* SETTINGS FOR WINDOW C-Win
VISIBLE,,RUN-PERSISTENT */
/* SETTINGS FOR FRAME DEFAULT-FRAME
*/
/* BROWSE-TAB BROWSE-1 slServers DEFAULT-FRAME */
/* SETTINGS FOR BUTTON btnEnumServices IN FRAME DEFAULT-FRAME
NO-ENABLE */
/* SETTINGS FOR FILL-IN cSearchService IN FRAME DEFAULT-FRAME
ALIGN-L */
IF SESSION
biggrin.gif
ISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
THEN C-Win:HIDDEN = no.

/* _RUN-TIME-ATTRIBUTES-END */
&ANALYZE-RESUME


/* Setting information for Queries and Browse Widgets fields */

&ANALYZE-SUSPEND _QUERY-BLOCK BROWSE BROWSE-1
/* Query rebuild information for BROWSE BROWSE-1
_START_FREEFORM
OPEN QUERY {&SELF-NAME} FOR EACH ttService.
_END_FREEFORM
_Query is OPENED
*/ /* BROWSE BROWSE-1 */
&ANALYZE-RESUME




/* ************************ Control Triggers ************************ */

&Scoped-define SELF-NAME C-Win
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL C-Win C-Win
ON END-ERROR OF C-Win /* Find Services Status */
OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
/* This case occurs when the user presses the "Esc" key.
In a persistently run window, just ignore this. If we did not, the
application would exit. */
IF THIS-PROCEDURE:pERSISTENT THEN RETURN NO-APPLY.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL C-Win C-Win
ON WINDOW-CLOSE OF C-Win /* Find Services Status */
DO:
/* This event will close the window and terminate the procedure. */
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN NO-APPLY.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define BROWSE-NAME BROWSE-1
&Scoped-define SELF-NAME BROWSE-1
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL BROWSE-1 C-Win
ON ROW-DISPLAY OF BROWSE-1 IN FRAME DEFAULT-FRAME
DO:

case ttService.cStatus:
when 'STOPPED':U or
when 'Unavailable':U then
ttService.cStatus:FGCOLOR in browse browse-1 = 12.
when 'RUNNING':U THEN
ttService.cStatus:FGCOLOR = 10.
when 'PAUSED':U THEN
ttService.cStatus:FGCOLOR = 14.
otherwise
ttService.cStatus:FGCOLOR = 7.
end case.

END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME btnEnumServices
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL btnEnumServices C-Win
ON CHOOSE OF btnEnumServices IN FRAME DEFAULT-FRAME /* Enumerate Services */
DO:

CleanupServices().

hSCM = OpenSCManager(slServers:SCREEN-VALUE).

if hSCM > 0 then
GetServices(input hSCM,
input '':U,
input slServers:SCREEN-VALUE).

CloseSCManager(hSCM).

{&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}

END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME btnExit
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL btnExit C-Win
ON CHOOSE OF btnExit IN FRAME DEFAULT-FRAME /* Exit */
DO:

apply 'WINDOW-CLOSE':U to {&WINDOW-NAME}.
return no-apply.

END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME btnSearch
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL btnSearch C-Win
ON CHOOSE OF btnSearch IN FRAME DEFAULT-FRAME /* Search */
DO:

define variable i as integer no-undo.

/* delete ttServices */
CleanupServices().

/* do for all Servers selected in slServers */
do i = 1 to num-entries(slServers:SCREEN-VALUE):

hSCM = OpenSCManager(replace(entry(i,slServers:SCREEN-VALUE),' (Local)':U, '':U)).

GetServices(input hSCM,
input cSearchService:SCREEN-VALUE,
input entry(i,slServers:SCREEN-VALUE)).

CloseSCManager(hSCM).

find ttService WHERE ttService.cServiceName = cSearchService:SCREEN-VALUE
AND ttService.cServerName = entry(i,slServers:SCREEN-VALUE)
NO-LOCK NO-ERROR.

if not avail(ttService) then
do:
create ttService.
assign ttService.cServiceName = cSearchService:SCREEN-VALUE
ttService.cServerName = entry(i,slServers:SCREEN-VALUE)
ttService.cDisplayName = cSearchService:SCREEN-VALUE
ttService.cDriverType = 'Not Found' /* EnumDriverType(0)*/ /* Service Type */
ttService.cStatus = EnumCurrentState(0). /* CurrentState */
end.

{&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}


/*
slServiceStatus:add-last(substitute('&1 &2':U,
entry(i,slServers:SCREEN-VALUE),
if avail(ttService) then
ttService.cStatus
else 'Unavailable':U)).

CleanupServices().
*/

end.

END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME slServers
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL slServers C-Win
ON VALUE-CHANGED OF slServers IN FRAME DEFAULT-FRAME
DO:
btnEnumServices:sensitive = num-entries(self:screen-value) = 1.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&UNDEFINE SELF-NAME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _MAIN-BLOCK C-Win


/* *************************** Main Block *************************** */

/* Set CURRENT-WINDOW: this will parent dialog-boxes and frames. */
ASSIGN CURRENT-WINDOW = {&WINDOW-NAME}
THIS-PROCEDURE:CURRENT-WINDOW = {&WINDOW-NAME}.

/* The CLOSE event can be used from inside or outside the procedure to */
/* terminate it. */
ON CLOSE OF THIS-PROCEDURE
RUN disable_UI.

/* Best default for GUI applications is... */
PAUSE 0 BEFORE-HIDE.


/* Now enable the interface and wait for the exit condition. */
/* (NOTE: handle ERROR and END-KEY so cleanup code will always fire. */
MAIN-BLOCK:
DO ON ERROR UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK:
RUN enable_UI.

/* Initialize the Servers and Services */
Initialize().

IF NOT THIS-PROCEDURE:pERSISTENT THEN
WAIT-FOR CLOSE OF THIS-PROCEDURE.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


/* ********************** Internal Procedures *********************** */

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE disable_UI C-Win _DEFAULT-DISABLE
PROCEDURE disable_UI :
/*------------------------------------------------------------------------------
Purpose: DISABLE the User Interface
Parameters:
Notes: Here we clean-up the user-interface by deleting
dynamic widgets we have created and/or hide
frames. This procedure is usually called when
we are ready to "clean-up" after running.
------------------------------------------------------------------------------*/
/* Delete the WINDOW we created */
IF SESSION
biggrin.gif
ISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
THEN DELETE WIDGET C-Win.
IF THIS-PROCEDURE:pERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE enable_UI C-Win _DEFAULT-ENABLE
PROCEDURE enable_UI :
/*------------------------------------------------------------------------------
Purpose: ENABLE the User Interface
Parameters:
Notes: Here we display/view/enable the widgets in the
user-interface. In addition, OPEN all queries
associated with each FRAME and BROWSE.
These statements here are based on the "Other
Settings" section of the widget Property Sheets.
------------------------------------------------------------------------------*/
DISPLAY slServers TOGGLE-1 TOGGLE-2 TOGGLE-3 TOGGLE-4 cSearchService
WITH FRAME DEFAULT-FRAME IN WINDOW C-Win.
ENABLE RECT-1 slServers BROWSE-1 TOGGLE-1 TOGGLE-2 TOGGLE-3 TOGGLE-4
cSearchService btnSearch btnExit
WITH FRAME DEFAULT-FRAME IN WINDOW C-Win.
{&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}
VIEW C-Win.
END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


/* ************************ Function Implementations ***************** */

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION CleanupServices C-Win
FUNCTION CleanupServices RETURNS LOGICAL
( /* parameter-definitions */ ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
/* delete ttServices */
for each ttService exclusive:
delete ttService.
end.

{&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}

RETURN TRUE. /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION CloseSCManager C-Win
FUNCTION CloseSCManager RETURNS CHARACTER
( input phSCManager as integer ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/

RUN CloseServiceHandle(input phSCManager,
output iRetCode).


RETURN "". /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION EnumCurrentState C-Win
FUNCTION EnumCurrentState RETURNS CHARACTER
( input piCurrentState as integer ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/

define var cRetStr as char no-undo.

case piCurrentState:
when {&SERVICE_STOPPED} then
cRetStr = 'Stopped'.
when {&SERVICE_START_PENDING} then
cRetStr = 'Start Pending'.
when {&SERVICE_STOP_PENDING} then
cRetStr = 'Stop Pending'.
when {&SERVICE_RUNNING} then
cRetStr = 'Running'.
when {&SERVICE_CONTINUE_PENDING} then
cRetStr = 'Continue Pending'.
when {&SERVICE_PAUSE_PENDING} then
cRetStr = 'Pause Pending'.
when {&SERVICE_PAUSED} then
cRetStr = 'Paused'.
otherwise
cRetStr = 'Unavailable'.
end case.

RETURN cRetStr. /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION EnumDriverType C-Win
FUNCTION EnumDriverType RETURNS CHARACTER
( input piDriver as integer ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
define var cRetStr as char no-undo.

case piDriver:
when {&SERVICE_KERNEL_DRIVER} then
cRetStr = 'Kernel Driver'.
when {&SERVICE_FILE_SYSTEM_DRIVER} then
cRetStr = 'File System Driver'.
when {&SERVICE_ADAPTER} then
cRetStr = 'Service Adapter'.
when {&SERVICE_RECOGNIZER_DRIVER} then
cRetStr = 'Recognizer Driver'.
otherwise
cRetStr = 'Unknown'.
end case.

RETURN cRetStr. /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION GetComputerName C-Win
FUNCTION GetComputerName RETURNS CHARACTER
( /* parameter-definitions */ ) :
/*------------------------------------------------------------------------

Function: GetComputerName

Description: Returns a character string of the computer name.

History:

------------------------------------------------------------------------*/
&SCOPE MAX_COMPUTERNAME_LENGTH 16

def var iResult as integer no-undo.
def var iBufferSize as integer no-undo init {&MAX_COMPUTERNAME_LENGTH}.
def var lpToString as memptr no-undo.
def var cComputerName as char no-undo.

set-size(lpToString) = {&MAX_COMPUTERNAME_LENGTH}.

run GetComputerNameA (output lpToString,
input-output iBufferSize,
output iResult).

if iResult = 1 then
assign
cComputerName = GET-STRING(lpToString,1).

set-size(lpToString) = 0.

return ( cComputerName ).

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION GetServers C-Win
FUNCTION GetServers RETURNS CHARACTER
( input phSelectionList as handle ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
define variable cLocalComputerName as char no-undo.
define variable iRetCode as integer no-undo.
define variable iOffset as integer no-undo.
define variable i as integer no-undo.
define variable iTotalEntries as integer no-undo.
define variable iEntriesRead as integer no-undo.
define variable iServerInfo as integer no-undo.
define variable lpServerInfo as memptr no-undo.
define variable lpPerfMaxLen as memptr no-undo.
define variable lpTotalEntries as memptr no-undo.
define variable lpServerName as memptr no-undo.
define variable cServerName as char no-undo.
define variable iPos as int no-undo.

cLocalComputerName = GetComputerName().

RUN NetServerEnum( input 0, /* pointer to string containing the server name to execute this function on */
input 101, /* SERVER_INFO to return, 100 or 101 */
output iServerInfo, /* pointer to the SERVER_INFO Structure base on 100 or 101 */
input {&MAX_PREFERRED_LENGTH}, /* max perfered lenth, if set to -1 it will allocate necessary space */
output iEntriesRead, /* total number of entries returned */
output iTotalEntries, /* total number of entries */
input {&SV_TYPE_ALL}, /* servier type to enumerate */
input 0, /* ptr to string containing Domain Name */
input 0, /* reserved, must be 0 */
output iRetCode). /* non 0 on success */

set-pointer-value(lpServerInfo) = iServerInfo.

iOffSet = 1.

set-size(lpServerName) = 0.
set-size(lpServerName) = 512.

do i = 1 to iEntriesRead:

run WideCharToMultiByte( input 0, /* use ANSI code page */
input 0, /* flags that specify the handling of unmapped characters */
input get-long(lpServerInfo, iOffset + 4), /* pointer to wide-character string (unicode) */
input -1, /* count of bytes of the wide-character string, if -1 calculate on the fly */
input get-pointer-value(lpServerName), /* address of buffer for new string */
input get-size(lpServerName),
input 0,
input 0,
output iRetCode).

if iRetCode <> 0 then
phSelectionList:ADD-LAST(get-string(lpServerName,1) + (if cLocalComputerName = get-string(lpServerName,1) then ' (Local)':U else '':U)).
iOffset = iOffset + 24.

end.

RUN NetApiBufferFree( input get-pointer-value(lpServerInfo),
output iRetCode ).

set-size(lpServerName) = 0.

RETURN "". /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION GetServices C-Win
FUNCTION GetServices RETURNS LOGICAL
( input phSCM as integer,
input pcSearchService as char,
input pcServerName as char) :
/*------------------------------------------------------------------------------
Purpose: Enumerate System Services
Notes:
------------------------------------------------------------------------------*/
define var lpEnumService as memptr no-undo. /* Enum_Service_Status */
define var lpServiceConfig as memptr no-undo. /* Query_Service_Config */
define var lpBytesNeeded as memptr no-undo. /* pointer to bytes required */
define var lpServicesReturned as memptr no-undo.
define var lpResumeHandle as memptr no-undo.
define var lpServiceStatus as memptr no-undo. /* Service_Status */
define var lpServiceName as memptr no-undo. /* pointer to service name string */
define var lpDisplayName as memptr no-undo. /* pointer to display name string */
define var iServiceCnt as integer no-undo.
define var iOffset as integer no-undo.
define var hService as integer no-undo. /* handle to service */
define var iQueryBytesNeeded as integer no-undo. /* bytes needed for QuerySericeConfig */
define var lError as logical no-undo.
define var lServiceFound as logical no-undo.

/*---------------------------------------------------------------------------
The first call will return the size of the byte array with an error
code of {&ERROR_MORE_DATA}.
----------------------------------------------------------------------------*/

assign
set-size(lpBytesNeeded) = 4
set-size(lpServicesReturned) = 4
set-size(lpResumeHandle) = 4
set-size(lpServiceStatus) = 32.

RUN EnumServicesStatusA( input phSCM, /* handle to SCM database */
input {&SERVICE_WIN32} + {&SERVICE_DRIVER}, /* type of services to enum */
input {&SERVICE_STATE_ALL}, /* state of services to enum */
input 0, /* pointer to service status buffer */
input 0, /* size of service status buffer */
input get-pointer-value(lpBytesNeeded), /* ptr to var for bytes needed */
input get-pointer-value(lpServicesReturned), /* ptr to var for number returned */
input get-pointer-value(lpResumeHandle), /* ptr to var for next entry */
output iRetCode). /* non 0 on success */

If iRetCode = 0 and get-long(lpBytesNeeded,1) = 0 Then
Do:
Message 'Error obtaining size information from EnumServicesStatusA' view-as alert-box.
assign
set-size(lpBytesNeeded) = 0
set-size(lpServicesReturned) = 0
set-size(lpResumeHandle) = 0.
Return FALSE.
End.

/*-----------------------------------------------------------------------------------------
Now set the size of lpEnumService to the size of lpBytesNeeded and start walking through
the services available.
------------------------------------------------------------------------------------------*/
set-size(lpEnumService) = get-long(lpBytesNeeded,1).

RUN EnumServicesStatusA( input phSCM, /* handle to SCM database */
input {&SERVICE_WIN32} + {&SERVICE_DRIVER}, /* type of services to enum */
input {&SERVICE_STATE_ALL}, /* state of services to enum */
input get-pointer-value(lpEnumService), /* pointer to service status buffer */
input get-size(lpEnumService), /* size of service status buffer */
input get-pointer-value(lpBytesNeeded), /* ptr to var for bytes needed */
input get-pointer-value(lpServicesReturned), /* ptr to var for number returned */
input get-pointer-value(lpResumeHandle), /* ptr to var for next entry */
output iRetCode). /* non 0 on success */

if iRetCode = 0 then
do:
Message 'Error encountered in EnumServicesStatusA().' view-as alert-box.
assign
set-size(lpEnumService) = 0
set-size(lpBytesNeeded) = 0
set-size(lpServicesReturned) = 0
set-size(lpResumeHandle) = 0.
Return FALSE.
end.

iOffset = 1.

ENUM_SERVICES:
do iServiceCnt = 1 to get-long(lpServicesReturned,1):
set-pointer-value(lpServiceName) = get-long(lpEnumService,iOffset).

/* Now get additioal inforamtion about the service */
Run OpenServiceA( input phSCM,
input get-pointer-value(lpServiceName),
input {&SERVICE_ALL_ACCESS},
output hService).

if hService = 0 then
do:
message substitute('Unable to open service &1.',
get-string(lpServiceName,1))
view-as alert-box.
lError = true.
LEAVE ENUM_SERVICES.
end.

/* Query the Status of the Service */
Run QueryServiceStatus(input hService,
input get-pointer-value(lpServiceStatus),
output iRetCode).

if iRetCode = 0 then
do:
message substitute('Unable to QueryServiceStatus for service &1.',
get-string(lpServiceName,1))
view-as alert-box.
RUN CloseServiceHandle(input hService,
output iRetCode).
lError = true.
LEAVE ENUM_SERVICES.
end.

/* Determine the number of bytes needed */
Run QueryServiceConfigA(input hService,
input 0,
input 0,
output iQueryBytesNeeded,
output iRetCode).

/* Now set the right size for the Query_Service_Config */
if iQueryBytesNeeded = 0 then
do:
message 'Error determining the size of the Query_Service_Config ' view-as alert-box.
RUN CloseServiceHandle(input hService,
output iRetCode).
leave ENUM_SERVICES.
/* deallocate memory */
end.

set-size(lpServiceConfig) = iQueryBytesNeeded.

Run QueryServiceConfigA(input hService,
input get-pointer-value(lpServiceConfig),
input get-size(lpServiceConfig),
output iQueryBytesNeeded,
output iRetCode).


set-pointer-value(lpDisplayName) = get-long(lpServiceConfig,33).

if pcSearchService = '':U or
pcSearchService = get-string(lpServiceName,1) then
do:
create ttService.
assign ttService.cServiceName = get-string(lpServiceName, 1)
ttService.cServerName = pcServerName
ttService.cDisplayName = get-string(lpDisplayName, 1)
ttService.cDriverType = EnumDriverType(get-long(lpServiceStatus,1)) /* Service Type */
ttService.cStatus = EnumCurrentState(get-long(lpServiceStatus,5)) /* CurrentState */
lServiceFound = pcSearchService = get-string(lpServiceName,1).
end.

/*
message 'lpDisplayName - ' get-string(lpDisplayName,1)
'Service Name -' get-string(lpServiceName, 1) skip
'dwServiceType -' get-long(lpServiceStatus,1 /* iOffset + 16 */ ) skip
'dwCurrentState -' get-long(lpServiceStatus,5 /* EnumService,iOffset + 20 */ ) skip
'dwWin32ExitCode -' get-long(lpEnumService, 13 /* iOffset + 28 */ )
view-as alert-box.
*/


/* step to next entry in array */
iOffSet = iOffset + 36.
set-size(lpServiceName) = 0.
set-size(lpDisplayName) = 0.
set-size(lpServiceConfig) = 0.

RUN CloseServiceHandle(input hService,
output iRetCode).
if lServiceFound then
leave ENUM_SERVICES.

end. /* ENUM_SERVICES */

assign
set-size(lpBytesNeeded) = 0
set-size(lpServicesReturned) = 0
set-size(lpResumeHandle) = 0
set-size(lpServiceStatus) = 0
set-size(lpEnumService) = 0
set-size(lpServiceName) = 0
set-size(lpDisplayName) = 0
set-size(lpServiceConfig) = 0.

RETURN lError = no. /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION Initialize C-Win
FUNCTION Initialize RETURNS LOGICAL
( /* parameter-definitions */ ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
/* default services to local computer */
hSCM = OpenSCManager('':U).

GetServices(input hSCM, /* handle to SCM */
input '':U, /* service to search for */
input GetComputerName()). /* local computer name */

CloseSCManager(input hSCM).

GetServers(slServers:handle in frame {&frame-name}).

/* select local computer in selection list by default */
slServers:SCREEN-VALUE = GetComputerName() + ' (Local)':U.

{&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}

RETURN TRUE. /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION OpenSCManager C-Win
FUNCTION OpenSCManager RETURNS INTEGER
( input pcComputerName as char ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
define variable hServiceControlMgr as integer no-undo.
define variable lpComputerName as memptr no-undo.
define variable lpDatabaseName as memptr no-undo.

if pcComputerName <> '':U then
assign set-size(lpComputerName) = length(pcComputerName) + 1
put-string(lpComputerName,1) = pcComputerName
set-size(lpDatabaseName) = length({&SERVICES_ACTIVE_DATABASE}) + 1
put-string(lpDatabaseName,1) = {&SERVICES_ACTIVE_DATABASE}.

RUN OpenSCManagerA( input if pcComputerName = '':U then
0
else
get-pointer-value(lpComputerName), /* computer name, '' for local machine */
input if pcComputerName = '':U then
0
else
get-pointer-value(lpDatabaseName), /* database name, '' for local machine */
input {&SC_MANAGER_ENUMERATE_SERVICE},
output hServiceControlMgr).

IF hServiceControlMgr = 0 THEN
MESSAGE 'Error on OpenSCManager' VIEW-AS ALERT-BOX.

if pcComputerName <> '':U then
assign
set-size(lpComputerName) = 0
set-size(lpDatabaseName) = 0.

RETURN hServiceControlMgr. /* Function return value. */

END FUNCTION.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME
[/code]
 
Top