' Windows service control: start, stop, query via DECLARE
#COMPILE EXE
#DIM ALL

DECLARE FUNCTION OpenSCManager LIB "ADVAPI32.DLL" ALIAS "OpenSCManagerA" (BYVAL lpMachineName AS ASCIIZ, BYVAL lpDatabaseName AS ASCIIZ, BYVAL dwDesiredAccess AS LONG) AS LONG
DECLARE FUNCTION OpenService LIB "ADVAPI32.DLL" ALIAS "OpenServiceA" (BYVAL hSCManager AS LONG, BYVAL lpServiceName AS ASCIIZ, BYVAL dwDesiredAccess AS LONG) AS LONG
DECLARE FUNCTION QueryServiceStatus LIB "ADVAPI32.DLL" (BYVAL hService AS LONG, BYREF lpServiceStatus As LongPtr) AS LONG
DECLARE FUNCTION StartService LIB "ADVAPI32.DLL" (BYVAL hService AS LONG, BYVAL dwNumServiceArgs AS LONG, BYVAL lpServiceArgVectors AS LONG) AS LONG
DECLARE FUNCTION ControlService LIB "ADVAPI32.DLL" (BYVAL hService AS LONG, BYVAL dwControl AS LONG, BYREF lpServiceStatus As LongPtr) AS LONG
DECLARE FUNCTION CloseServiceHandle LIB "ADVAPI32.DLL" (BYVAL hSCObject AS LONG) AS LONG
DECLARE FUNCTION EnumServicesStatus LIB "ADVAPI32.DLL" ALIAS "EnumServicesStatusA" (BYVAL hSCManager AS LONG, BYVAL dwServiceType AS LONG, BYVAL dwServiceState AS LONG, BYVAL lpServices AS ASCIIZ, BYVAL cbBufSize AS LONG, BYREF pcbBytesNeeded AS LONG, BYREF lpServicesReturned AS LONG, BYREF lpResumeHandle AS LONG) AS LONG

%SERVICE_STOPPED      = 1
%SERVICE_START_PENDING = 2
%SERVICE_STOP_PENDING  = 3
%SERVICE_RUNNING       = 4
%SERVICE_CONTROL_STOP  = 1
%SERVICE_CONTROL_PAUSE = 2
%SERVICE_CONTROL_CONTINUE = 3
%SC_MANAGER_ALL_ACCESS = &HF003F
%SERVICE_ALL_ACCESS    = &HF01FF

TYPE ServiceEntry
    name AS STRING
    displayName AS STRING
    status AS LONG
    pid AS LONG
END TYPE

FUNCTION ServiceStatusText(BYVAL status AS LONG) AS STRING
    IF status = %SERVICE_STOPPED THEN FUNCTION = "Stopped"
    IF status = %SERVICE_START_PENDING THEN FUNCTION = "Starting"
    IF status = %SERVICE_STOP_PENDING THEN FUNCTION = "Stopping"
    IF status = %SERVICE_RUNNING THEN FUNCTION = "Running"
    FUNCTION = "Unknown"
END FUNCTION

SUB PrintService(BYREF svc AS ServiceEntry)
    PRINT "  "; svc.name; " ("
    PRINT svc.displayName; "): "
    PRINT ServiceStatusText(svc.status)
    PRINT " (PID "; svc.pid; ")"
END SUB

SUB ListCommonServices()
    PRINT "Common Windows services:"
    DIM svcs(0:4) AS ServiceEntry
    svcs(0).name = "Spooler"
    svcs(0).displayName = "Print Spooler"
    svcs(0).status = %SERVICE_RUNNING
    svcs(0).pid = 1200
    svcs(1).name = "W3SVC"
    svcs(1).displayName = "World Wide Web Publishing"
    svcs(1).status = %SERVICE_STOPPED
    svcs(1).pid = 0
    svcs(2).name = "DHCP"
    svcs(2).displayName = "DHCP Client"
    svcs(2).status = %SERVICE_RUNNING
    svcs(2).pid = 1400
    svcs(3).name = "Dnscache"
    svcs(3).displayName = "DNS Client"
    svcs(3).status = %SERVICE_RUNNING
    svcs(3).pid = 1600
    svcs(4).name = "MSSQLSERVER"
    svcs(4).displayName = "SQL Server"
    svcs(4).status = %SERVICE_RUNNING
    svcs(4).pid = 3400
    LOCAL i AS LONG
    FOR i = 0 TO 4
        PrintService(svcs(i))
    NEXT i
END SUB

SUB ServiceControlSimulation()
    PRINT ""
    PRINT "Service control simulation:"
    PRINT ""
    PRINT "1. OpenSCManager -> manager handle"
    PRINT "2. OpenService('Spooler') -> service handle"
    PRINT "3. QueryServiceStatus -> Running"
    PRINT "4. ControlService(STOP) -> Stoppping..."
    PRINT "5. QueryServiceStatus -> Stopped"
    PRINT "6. StartService('Spooler') -> Starting..."
    PRINT "7. QueryServiceStatus -> Running"
    PRINT ""
    LOCAL s AS ServiceEntry
    s.name = "Spooler"
    s.displayName = "Print Spooler"
    s.status = %SERVICE_RUNNING
    s.pid = 1200
    PrintService(s)
    PRINT "  -> Sending STOP..."
    s.status = %SERVICE_STOP_PENDING
    PrintService(s)
    s.status = %SERVICE_STOPPED
    s.pid = 0
    PrintService(s)
    PRINT "  -> Sending START..."
    s.status = %SERVICE_START_PENDING
    PrintService(s)
    s.status = %SERVICE_RUNNING
    s.pid = 3400
    PrintService(s)
    PRINT "  Service restarted with new PID"
END SUB

SUB DependentServices()
    PRINT ""
    PRINT "Service dependency chain:"
    PRINT "  DHCP Client"
    PRINT "    depends on: AFD, NetBIOS, TCP/IP"
    PRINT "  TCP/IP"
    PRINT "    depends on: AFD"
    PRINT "  SQL Server"
    PRINT "    depends on: Remote Procedure Call (RPC)"
    PRINT "    depends on: Windows Management Instrumentation"
    PRINT ""
    PRINT "When stopping a service, dependents"
    PRINT "must be stopped first."
END SUB

FUNCTION PBMAIN() AS LONG
    PRINT "=== Service Control Demo ==="
    PRINT "Win32: OpenSCManager, OpenService via DECLARE"
    PRINT ""
    ListCommonServices()
    ServiceControlSimulation()
    DependentServices()
    PRINT ""
    PRINT "=== End Service Control ==="
    FUNCTION = 0
END FUNCTION
