need help to convert powerbasic enum services

Windows specific forum
Starter
New User
New User
Posts: 3
Joined: Thu Apr 22, 2004 10:47 pm

need help to convert powerbasic enum services

Post by Starter »

Hello.
I found this ppiece of code on the powerbasic forums, can someone help me to convert to purebasic ? I'm a beginner and not understand very well pointers, i tried to convert to pb by myself but what i had is just errors...

Here's the code

Code: Select all

#COMPILE EXE
#INCLUDE "WIN32API.INC"
'----------------------------------------------------------------------------------------------------------------------------------------
' this code is based on Microsoft MSKB Q183478
'----------------------------------------------------------------------------------------------------------------------------------------
FUNCTION IsServiceRunning(lngServiceType AS LONG, BYVAL strText AS STRING, lstServiceName AS LONG, lstDisplayName AS LONG) AS LONG
    LOCAL hSCManager                    AS DWORD
    LOCAL x                             AS LONG
    LOCAL dx                            AS ENUM_SERVICE_STATUS
    LOCAL lpEnumServiceStatus()         AS ENUM_SERVICE_STATUS
    LOCAL lngBytesNeeded                AS LONG
    LOCAL lpServicesReturned            AS DWORD
    LOCAL hNextUnreadEntry              AS DWORD
    LOCAL lngStructsNeeded              AS LONG
    LOCAL lngServiceStatusInfoBuffer    AS LONG
    LOCAL strServiceName                AS ASCIIZ * 250
    LOCAL i                             AS LONG
    'local lngServiceType as long (either %SERVICE_ACTIVE or
    '                                       %SERVICE_ACTIVE Or %SERVICE_INACTIVE
    'strText is the name to search, it is always the ServiceName
    hSCManager = OpenSCManager(BYVAL 0, BYVAL 0, %SC_MANAGER_ENUMERATE_SERVICE)
    IF hSCManager THEN
        hNextUnreadEntry = 0
        x = EnumServicesStatus(hSCManager, %SERVICE_WIN32, lngServiceType, dx, &H0, _
                 lngBytesNeeded, lpServicesReturned, hNextUnreadEntry)
       'We should receive %MORE_DATA error.
       IF NOT GetLastError() = %ERROR_MORE_DATA THEN
            EXIT FUNCTION
       ELSE
            'Calculate the number of structures needed
            lngStructsNeeded = lngBytesNeeded / LEN(lpEnumServiceStatus(0)) + 1
            'Redimension the array according to our calculation
            REDIM lpEnumServiceStatus(lngStructsNeeded - 1)
            'Get buffer size in bytes
            lngServiceStatusInfoBuffer = lngStructsNeeded * LEN(lpEnumServiceStatus(0))
            'Get services information starting entry 0
            hNextUnreadEntry = 0
            x = EnumServicesStatus(hSCManager, _
                                   %SERVICE_WIN32, _
                                   lngServiceType, _
                                   lpEnumServiceStatus(0), _
                                   lngServiceStatusInfoBuffer, _
                                   lngBytesNeeded, _
                                   lpServicesReturned, _
                                   hNextUnreadEntry)
            IF x = 0 THEN
                'failed, call GetLastError why
            ELSE
                'clear the listboxes
                IF lstServiceName > 0 THEN SendMessage lstServiceName, %LB_RESETCONTENT, 0, 0
                IF lstDisplayName > 0 THEN SendMessage lstDisplayName, %LB_RESETCONTENT, 0, 0
                FOR i = 0 TO lpServicesReturned - 1
                    x = lstrcpy(strServiceName, BYVAL lpEnumServiceStatus(i).lpDisplayName)
                    IF lstDisplayName > 0 THEN SendMessage lstDisplayName, %LB_ADDSTRING, 0, VARPTR(strServiceName)
                    x = lstrcpy(strServiceName, BYVAL lpEnumServiceStatus(i).lpServiceName)
                    IF lstServiceName > 0 THEN SendMessage lstServiceName, %LB_ADDSTRING, 0, VARPTR(strServiceName)
                    IF strText > "" THEN
                        IF LCASE$(strText) = LCASE$(strServiceName) THEN FUNCTION = %TRUE
                    END IF
                NEXT
            END IF
        END IF
        'Clean up.
        CloseServiceHandle hSCManager
    END IF
END FUNCTION
CALLBACK FUNCTION DlgProc()
    LOCAL hndl1 AS LONG
    LOCAL hndl2 AS LONG
    LOCAL strSearch AS STRING
    SELECT CASE CBMSG
        CASE %WM_COMMAND
            IF CBCTLMSG = %BN_CLICKED THEN
                SELECT CASE CBCTL
                    CASE 103    'active services only
                        CONTROL HANDLE CBHNDL, 101 TO hndl1
                        CONTROL HANDLE CBHNDL, 102 TO hndl2
                        IsServiceRunning %SERVICE_ACTIVE, "", hndl1, hndl2
                    CASE 104    'all services
                        CONTROL HANDLE CBHNDL, 101 TO hndl1
                        CONTROL HANDLE CBHNDL, 102 TO hndl2
                        IsServiceRunning %SERVICE_ACTIVE OR %SERVICE_INACTIVE, "", hndl1, hndl2
                    CASE 105    'is running
                       strSearch = INPUTBOX$("Search for this service name")
                        IF ISTRUE IsServiceRunning (%SERVICE_ACTIVE, strSearch, 0, 0) THEN
                            MSGBOX "Yes"
                        ELSE
                            MSGBOX "No"
                        END IF
                    CASE 106    'is installed
                        strSearch = INPUTBOX$("Search for this service name")
                        IF ISTRUE IsServiceRunning (%SERVICE_ACTIVE OR %SERVICE_INACTIVE, strSearch, 0, 0) THEN
                            MSGBOX "Yes"
                        ELSE
                            MSGBOX "No"
                        END IF
                END SELECT
            END IF
    END SELECT
END FUNCTION
FUNCTION PBMAIN()
    LOCAL hDlg AS LONG
    DIALOG NEW %NULL, "Enum Services", , , 300, 200, %WS_VISIBLE OR %WS_SYSMENU TO hDlg
    CONTROL ADD LISTBOX, hDlg, 101, , 2, 2, 140, 160
    CONTROL ADD LISTBOX, hDlg, 102, , 156, 2, 140, 160
    CONTROL ADD BUTTON, hDlg, 103, "Active Services", 5, 162, 60, 14
    CONTROL ADD BUTTON, hDlg, 104, "All Services", 233, 162, 60, 14
    CONTROL ADD BUTTON, hDlg, 105, "Is Running?", 70, 162, 60, 14
    CONTROL ADD BUTTON, hDlg, 106, "Is Installed?", 169, 162, 60, 14 
    DIALOG SHOW MODAL hDlg, CALL DlgProc
END FUNCTION
------------------
My particular problem is the EnumServicesStatus_ API, Is it possible that someone can help me to convert the part that enumerate services, No problem for the rest. But I had no success in using this api, as I i'm bit confused about the use of pointers...
In other words, what would be the PB code to enumerate the service in the servicedatabase ?

Thanx by advance if someone can help me.

Starter.

*edited*

I've found something that might be better to translate to obtain the services list: (Vb code)

Code: Select all

Const ERROR_MORE_DATA = 234
Const SERVICE_ACTIVE = &H1
Const SERVICE_INACTIVE = &H2
Const SC_MANAGER_ENUMERATE_SERVICE = &H4
Const SERVICE_WIN32_OWN_PROCESS As Long = &H10
Const SERVICE_WIN32_SHARE_PROCESS As Long = &H20
Const SERVICE_WIN32 As Long = SERVICE_WIN32_OWN_PROCESS + SERVICE_WIN32_SHARE_PROCESS
Private 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
Private Type ENUM_SERVICE_STATUS
    lpServiceName As Long
    lpDisplayName As Long
    ServiceStatus As SERVICE_STATUS
End Type
Private Declare Function OpenSCManager Lib "advapi32.dll" Alias "OpenSCManagerA" (ByVal lpMachineName As String, ByVal lpDatabaseName As String, ByVal dwDesiredAccess As Long) As Long
Private Declare Function EnumServicesStatus Lib "advapi32.dll" Alias "EnumServicesStatusA" (ByVal hSCManager As Long, ByVal dwServiceType As Long, ByVal dwServiceState As Long, lpServices As Any, ByVal cbBufSize As Long, pcbBytesNeeded As Long, lpServicesReturned As Long, lpResumeHandle As Long) As Long
Private Declare Function CloseServiceHandle Lib "advapi32.dll" (ByVal hSCObject As Long) As Long
Private Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (szDest As String, szcSource As Long) As Long
Private Sub Form_Load()
    'KPD-Team 2000
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    Dim hSCM As Long, lpEnumServiceStatus() As ENUM_SERVICE_STATUS, lngServiceStatusInfoBuffer As Long
    Dim strServiceName As String * 250, lngBytesNeeded As Long, lngServicesReturned As Long
    Dim hNextUnreadEntry As Long, lngStructsNeeded As Long, lngResult As Long, i As Long
    'Open connection to Service Control Manager.
    hSCM = OpenSCManager(vbNullString, vbNullString, SC_MANAGER_ENUMERATE_SERVICE)
    If hSCM = 0 Then
        MsgBox "OpenSCManager failed. LastDllError = " & CStr(Err.LastDllError)
        Exit Sub
    End If
    'Get buffer size (bytes) without passing a buffer
    'and make sure starts at 0th entry.
    hNextUnreadEntry = 0
    lngResult = EnumServicesStatus(hSCM, SERVICE_WIN32, SERVICE_ACTIVE Or SERVICE_INACTIVE, ByVal &H0, &H0, lngBytesNeeded, lngServicesReturned, hNextUnreadEntry)
    'We should receive MORE_DATA error.
    If Not Err.LastDllError = ERROR_MORE_DATA Then
        MsgBox "LastDLLError = " & CStr(Err.LastDllError)
        Exit Sub
    End If
    'Calculate the number of structures needed.
    lngStructsNeeded = lngBytesNeeded / Len(lpEnumServiceStatus(0)) + 1
    'Redimension the array according to our calculation.
    ReDim lpEnumServiceStatus(lngStructsNeeded - 1)
    'Get buffer size in bytes.
    lngServiceStatusInfoBuffer = lngStructsNeeded * Len(lpEnumServiceStatus(0))
    'Get services information starting entry 0.
    hNextUnreadEntry = 0
    lngResult = EnumServicesStatus(hSCM, SERVICE_WIN32, SERVICE_ACTIVE Or SERVICE_INACTIVE, lpEnumServiceStatus(0), lngServiceStatusInfoBuffer, lngBytesNeeded, lngServicesReturned, hNextUnreadEntry)
    If lngResult = 0 Then
        MsgBox "EnumServicesStatus failed. LastDllError = " & CStr(Err.LastDllError)
        Exit Sub
    End If
    'Get the strings and display them.
    Me.AutoRedraw = True
    Me.Print "All registered services:" + vbCrLf
    For i = 0 To lngServicesReturned - 1
        lngResult = lstrcpy(ByVal strServiceName, ByVal lpEnumServiceStatus(i).lpServiceName)
        Me.Print StripTerminator(strServiceName) + " - ";
        lngResult = lstrcpy(ByVal strServiceName, ByVal lpEnumServiceStatus(i).lpDisplayName)
        Me.Print StripTerminator(strServiceName)
    Next i
    'Clean up.
    CloseServiceHandle (hSCM)
End Sub
Function StripTerminator(sInput As String) As String
    Dim ZeroPos As Integer
    ZeroPos = InStr(1, sInput, Chr$(0))
    If ZeroPos > 0 Then
        StripTerminator = Left$(sInput, ZeroPos - 1)
    Else
        StripTerminator = sInput
    End If
End Function
Is someone able to translate that ?... thanks by advance.
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

Hi,

Do you have a budget for this code ?
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
Starter
New User
New User
Posts: 3
Joined: Thu Apr 22, 2004 10:47 pm

Post by Starter »

Huuu..Sorry no, i have no "budget" for this code, just try to make a little app that can retrieve the services list from the win service manager, and notify me if an undesirable service is installed. I'm trying to make it for myself, and of course I will share the source if I can do something "decent". So I have no budget for this one sorry :-/
But The only part where I need help is the part that enumerate services installed. I have found many examples of the use of the API to enumerate services, but it makes use of pointers and for the moment I'm not able to obtain a working translation of this part.(I'm a beginner you know)

So if someone can help me -just for fun, i have no budget for this as I said- to translate this part it will be great.
I have found the "NT-service" example on the forum, but can't succed in adapting to enumerate installed services names...

Well, today I found an other example of enumeration of services, in delphi this time, more comprenhesible I think, I'm actually trying to translate this one (un success for the moment):

Code: Select all

const
  //
  // Service Types
  //
  SERVICE_KERNEL_DRIVER       = $00000001;
  SERVICE_FILE_SYSTEM_DRIVER  = $00000002;
  SERVICE_ADAPTER             = $00000004;
  SERVICE_RECOGNIZER_DRIVER   = $00000008;

  SERVICE_DRIVER              =
    (SERVICE_KERNEL_DRIVER or
     SERVICE_FILE_SYSTEM_DRIVER or
     SERVICE_RECOGNIZER_DRIVER);

  SERVICE_WIN32_OWN_PROCESS   = $00000010;
  SERVICE_WIN32_SHARE_PROCESS = $00000020;
  SERVICE_WIN32               =
    (SERVICE_WIN32_OWN_PROCESS or
     SERVICE_WIN32_SHARE_PROCESS);

  SERVICE_INTERACTIVE_PROCESS = $00000100;

  SERVICE_TYPE_ALL            =
    (SERVICE_WIN32 or
     SERVICE_ADAPTER or
     SERVICE_DRIVER  or
     SERVICE_INTERACTIVE_PROCESS);

uses WinSvc;

//-------------------------------------
// Get a list of services
//
// return TRUE if successful
//
// sMachine:
//   machine name, ie: \SERVER
//   empty = local machine
//
// dwServiceType
//   SERVICE_WIN32,
//   SERVICE_DRIVER or
//   SERVICE_TYPE_ALL
//
// dwServiceState
//   SERVICE_ACTIVE,
//   SERVICE_INACTIVE or
//   SERVICE_STATE_ALL
//
// slServicesList
//   TStrings variable to storage
//
function ServiceGetList(
  sMachine : string;
  dwServiceType,
  dwServiceState : DWord;
  slServicesList : TStrings )
  : boolean;
const
  //
  // assume that the total number of
  // services is less than 4096.
  // increase if necessary
  cnMaxServices = 4096;

type
  TSvcA = array[0..cnMaxServices]
          of TEnumServiceStatus;
  PSvcA = ^TSvcA;
          
var
  //
  // temp. use
  j : integer;

  //
  // service control
  // manager handle
  schm          : SC_Handle;

  //
  // bytes needed for the
  // next buffer, if any
  nBytesNeeded,

  //
  // number of services
  nServices,

  //
  // pointer to the
  // next unread service entry
  nResumeHandle : DWord;

  //
  // service status array
  ssa : PSvcA;
begin
  Result := false;

  // connect to the service
  // control manager
  schm := OpenSCManager(
    PChar(sMachine),
    Nil,
    SC_MANAGER_ALL_ACCESS);

  // if successful...
  if(schm > 0)then
  begin
    nResumeHandle := 0;

    New(ssa);

    EnumServicesStatus(
      schm,
      dwServiceType,
      dwServiceState,
      ssa^[0],
      SizeOf(ssa^),
      nBytesNeeded,
      nServices,
      nResumeHandle );

    //
    // assume that our initial array
    // was large enough to hold all
    // entries. add code to enumerate
    // if necessary.
    //
    
    for j := 0 to nServices-1 do
    begin
      slServicesList.
        Add( StrPas(
          ssa^[j].lpDisplayName ) );
    end;

    Result := true;

    Dispose(ssa);

    // close service control
    // manager handle
    CloseServiceHandle(schm);
  end;
end;
It seems to be "closer" to the purebasic use of pointers, well, by the way I understand better this one, so if someone have an idea ?

THanx for the help.

Starter.

Note: sorry for my poor english, it's not my native language...But I try to improve...
dmoc
Enthusiast
Enthusiast
Posts: 739
Joined: Sat Apr 26, 2003 12:40 am

Post by dmoc »

fweil:
Do you have a budget for this code ?
:lol: :lol: :lol:
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

So you prefer a free working code I guess

Should be posted in half an hour .... more or less working well.[/code]
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

hey! the half hour has gone by! and now?

:-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

Sorry I am late ... but tell me if you feel happy with this !

Code: Select all

#ERROR_MORE_DATA = $EA
#SERVICE_ACTIVE = $1
#SERVICE_INACTIVE = $2
#SC_MANAGER_ENUMERATE_SERVICE = $4
#SERVICE_WIN32_OWN_PROCESS = $10
#SERVICE_WIN32_SHARE_PROCESS = $20
#SERVICE_WIN32 = #SERVICE_WIN32_OWN_PROCESS | #SERVICE_WIN32_SHARE_PROCESS
#GENERIC_READ = $80000000
#SERVICE_KERNEL_DRIVER = $1
#SERVICE_FILE_SYSTEM_DRIVER = $2
#SERVICE_ADAPTER = $4
#SERVICE_BOOT_START = $0
#SERVICE_SYSTEM_START = $1
#SERVICE_AUTO_START = $2
#SERVICE_DEMAND_START = $3
#SERVICE_DISABLE = $4
#SERVICE_ERROR_IGNORE = $0
#SERVICE_ERROR_NORMAL = $1
#SERVICE_ERROR_SEVERE = $2
#SERVICE_ERROR_CRITICAL = $3
#SERVICE_DRIVER = #SERVICE_KERNEL_DRIVER + #SERVICE_FILE_SYSTEM_DRIVER
#SERVICE_INTERACTIVE_PROCESS = $100

#Window_Main = 0
#Gadget_ListIcon = 0
#Escape = 99

#NM_CUSTOMDRAW = #NM_FIRST - 12

#CDDS_ITEM = $10000 
#CDDS_PREPAINT = $1 
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT 
#CDRF_DODEFAULT = $0 
#CDRF_NOTIFYITEMDRAW = $20 

Global hListIconGadget.l 

#LVM_SETEXTENDEDLISTVIEWSTYLE = #LVM_FIRST + 54
#LVM_GETEXTENDEDLISTVIEWSTYLE = #LVM_FIRST + 55
#ListIconTextColor1 = $5F0000
#ListIconBackgroundColor1 = $D0FFFF
#ListIconTextColor2 = $D0FFFF
#ListIconBackgroundColor2 = $5F0000

Global Buffer1.l, Buffer2.l, lvi.LV_ITEM, updown.l, lastcol.l

Buffer1 = AllocateMemory(128)
Buffer2 = AllocateMemory(128)

;
; As I found some issues using standard API structures provided with PB, I prefered to define my own structures.
; SERVICE_STATUS and ENUM_SERVICES_STATUS exist both but I was not able to join variables ie using EnumServices(i)\ServiceStatus\dwServiceType
; I don't know why it does not work with regular structures, but by defining my own clones works.
;
Structure MySERVICE_STATUS
  dwServiceType.l
  dwCurrentState.l
  dwControlsAccepted.l
  dwWin32ExitCode.l
  dwServiceSpecificExitCode.l
  dwCheckPoint.l
  dwWaitHint.l
EndStructure

Structure MyENUM_SERVICE_STATUS
  lpServiceName.l
  lpDisplayName.l
  ServiceStatus.MySERVICE_STATUS
EndStructure

Dim EnumServices.MyENUM_SERVICE_STATUS(10000)
  
Procedure EnumServicesProc(Service_To_Enum)
  hSCM = OpenSCManager_(MachineName, DataBaseName, #SC_MANAGER_ENUMERATE_SERVICE | #GENERIC_READ)
  If hSCM
      hNextUnreadEntry = #FALSE
      Resume.l = #FALSE
      Length.l = 10000
      BytesNeeded.l = 0
      ServicesReturned.l = 0
      lngResult = EnumServicesStatus_(hSCM, SERVICE_TO_ENUM, #SERVICE_ACTIVE | #SERVICE_INACTIVE, 0, 0, @BytesNeeded, @ServicesReturned, @Resume)
      Resume = #FALSE
      i = 0
      Repeat
        lngResult = EnumServicesStatus_(hSCM, SERVICE_TO_ENUM, #SERVICE_ACTIVE | #SERVICE_INACTIVE, @EnumServices(0), Length, @BytesNeeded, @ServicesReturned, @Resume)
        Select Service_To_Enum
          Case #SERVICE_DRIVER
            Result.s = "SERVICE_DRIVER" + Chr(10) + Str(i) + Chr(10)
          Case #SERVICE_WIN32
            Result.s = "SERVICE_WIN32" + Chr(10) + Str(i) + Chr(10)
        EndSelect
        If EnumServices(i)\lpServiceName
            Result = Result + PeekS(EnumServices(i)\lpServiceName) + Chr(10)
          Else
            Result = Result + Chr(10)
        EndIf
        If EnumServices(i)\lpServiceName
            Result = Result + PeekS(EnumServices(i)\lpDisplayName) + Chr(10)
          Else
            Result = Result + Chr(10)
        EndIf
        Select EnumServices(i)\ServiceStatus\dwServiceType
          Case #SERVICE_WIN32_OWN_PROCESS ; A service type flag that indicates a Win32 service that runs in its own process.
            Result = Result + "SERVICE_WIN32_OWN_PROCESS" + Chr(10)
          Case #SERVICE_WIN32_SHARE_PROCESS ; A service type flag that indicates a Win32 service that shares a process with other services.
            Result = Result + "SERVICE_WIN32_SHARE_PROCESS" + Chr(10)
          Case #SERVICE_KERNEL_DRIVER ; A service type flag that indicates a Windows NT device driver.
            Result = Result + "SERVICE_KERNEL_DRIVER" + Chr(10)
          Case #SERVICE_FILE_SYSTEM_DRIVER ; A service type flag that indicates a Windows NT file system driver.
            Result = Result + "SERVICE_FILE_SYSTEM_DRIVER" + Chr(10)
          Case #SERVICE_INTERACTIVE_PROCESS ; A flag that indicates a Win32 service process that can interact with the desktop.
            Result = Result + "SERVICE_INTERACTIVE_PROCESS" + Chr(10)
        EndSelect
        Select EnumServices(i)\ServiceStatus\dwCurrentState
          Case #SERVICE_STOPPED ; The service is not running.
            Result = Result + "SERVICE_STOPPED" + Chr(10)
          Case #SERVICE_START_PENDING ; The service is starting.
            Result = Result + "SERVICE_START_PENDING" + Chr(10)
          Case #SERVICE_STOP_PENDING ; The service is stopping.
            Result = Result + "SERVICE_STOP_PENDING" + Chr(10)
          Case #SERVICE_RUNNING ; The service is running.
            Result = Result + "SERVICE_RUNNING" + Chr(10)
          Case #SERVICE_CONTINUE_PENDING ; The service continue is pending.
            Result = Result + "SERVICE_CONTINUE_PENDING" + Chr(10)
          Case #SERVICE_PAUSE_PENDING ; The service pause is pending.
            Result = Result + "SERVICE_PAUSE_PENDING" + Chr(10)
          Case #SERVICE_PAUSED ; The service is paused.
            Result = Result + "SERVICE_PAUSED" + Chr(10)
        EndSelect
        Select EnumServices(i)\ServiceStatus\dwControlsAccepted
          Case #SERVICE_ACCEPT_STOP ; The service can be stopped. This enables the SERVICE_CONTROL_STOP value.
            Result = Result + "SERVICE_ACCEPT_STOP" + Chr(10)
          Case #SERVICE_ACCEPT_PAUSE_CONTINUE ; The service can be paused and continued. This enables the SERVICE_CONTROL_PAUSE And SERVICE_CONTROL_CONTINUE values.
            Result = Result + "SERVICE_ACCEPT_PAUSE_CONTINUE" + Chr(10)
          Case #SERVICE_ACCEPT_SHUTDOWN ; The service is notified when system shutdown occurs. This enables the system to send a SERVICE_CONTROL_SHUTDOWN value to the service. The ControlService function cannot send this control code.
            Result = Result + "SERVICE_ACCEPT_SHUTDOWN" + Chr(10)
        EndSelect
        Result = Result + Str(EnumServices(i)\ServiceStatus\dwWin32ExitCode) + Chr(10)
        Result = Result + Str(EnumServices(i)\ServiceStatus\dwServiceSpecificExitCode) + Chr(10)
        Result = Result + Str(EnumServices(i)\ServiceStatus\dwCheckPoint) + Chr(10)
        Result = Result + Str(EnumServices(i)\ServiceStatus\dwWaitHint)
        If EnumServices(i)\lpServiceName And EnumServices(i)\lpDisplayName
            AddGadgetItem(#Gadget_ListIcon, -1, Result)
            While WindowEvent()
            Wend
          Else
            ;
            ; I placed this test because it seems that some extra returned buffers are unavailable
            ; May one forum's user be more clever than I am to understand what occurs because the number of returned buffers exceeds the value of ServicesReturned
            ;
            Debug "===>" + Result
        EndIf
        i + 1
      Until i >= ServicesReturned And EnumServices(i)\lpServiceName <> 0
      CloseServiceHandle_(hSCM)
      ProcedureReturn lngResult
    Else
      ;
      ; In case something goes wrong ... !
      Debug "0" +  " " + Str(GetLastError_())
      ProcedureReturn -1
  EndIf
EndProcedure

Procedure CompareFunc(item1, item2, lParamSort) ; duno whom code it is, but from Code archive
  result = 0
  lvi\iSubItem = lParamSort
  lvi\pszText = Buffer1
  lvi\cchTextMax = 128
  lvi\mask = #LVIF_TEXT
  SendMessage_(hListIconGadget, #LVM_GETITEMTEXT, item1, @lvi)
  lvi\pszText = Buffer2
  SendMessage_(hListIconGadget, #LVM_GETITEMTEXT, item2, @lvi)
  Seeker1 = Buffer1
  Seeker2 = Buffer2
  done = #FALSE
  Repeat
    char1 = Asc(UCase(Chr(PeekB(Seeker1))))
    char2 = Asc(UCase(Chr(PeekB(Seeker2))))
    result = (char1-char2)*updown
    If result<>0 Or (Seeker1-Buffer1)>127
        done = #TRUE
    EndIf
    Seeker1+1
    Seeker2+1
  Until Done
  ProcedureReturn result
EndProcedure

Procedure UpdatelParam() ; duno whom code it is, but from Code archive
  ItemCount = SendMessage_(hListIconGadget, #LVM_GETITEMCOUNT, 0, 0)
  lvi\mask = #LVIF_PARAM
  lvi\iItem = 0
  While ItemCount>0
    lvi\lParam = lvi\iItem
    For SubItem = 0 To 3
      lvi\iSubItem = SubItem 
      SendMessage_(hListIconGadget, #LVM_SETITEM, 0, @lvi)
    Next SubItem
    lvi\iItem = lvi\iItem+1
    ItemCount = ItemCount-1
  Wend
EndProcedure

Procedure ColumnClickCallback(hWnd, Message, wParam, lParam) ; duno whom code it is, but from Code archive and original ebs code
  result = #PB_ProcessPureBasicEvents
  Select Message
    Case #WM_NOTIFY
      *msg.NMHDR = lParam
      If *msg\hwndFrom = hListIconGadget And *msg\code = #LVN_COLUMNCLICK
          *pnmv.NM_LISTVIEW = lParam
          If lastcol<>*pnmv\iSubItem
              updown = 1
          EndIf
          SendMessage_(hListIconGadget, #LVM_SORTITEMS, *pnmv\iSubItem, @CompareFunc())
          UpdatelParam()
          UpdateWindow_(hListIconGadget)
          lastcol = *pnmv\iSubItem
          updown = -updown
      EndIf
      *LVCDHeader.NMLVCUSTOMDRAW = lParam
      If *LVCDHeader\nmcd\hdr\hWndFrom = hListIconGadget And *LVCDHeader\nmcd\hdr\code = #NM_CUSTOMDRAW
          Select *LVCDHeader\nmcd\dwDrawStage
            Case #CDDS_PREPAINT
              ProcedureReturn #CDRF_NOTIFYITEMDRAW
            Case #CDDS_ITEMPREPAINT
              Row.l = *LVCDHeader\nmcd\dwItemSpec
              If (Row/2) * 2 = Row
                  *LVCDHeader\clrText = #ListIconTextColor1
                  *LVCDHeader\clrTextBk = #ListIconBackgroundColor1
                Else
                  *LVCDHeader\clrText = #ListIconTextColor2
                  *LVCDHeader\clrTextBk = #ListIconBackgroundColor2
              EndIf
              ProcedureReturn #CDRF_DODEFAULT
          EndSelect
      EndIf
    Case #WM_SIZE
      If hWnd = WindowID() And IsIconic_(hWnd)=0
          WindowWidth = lParam & $ffff
          WindowHeight = lParam>>16
          ResizeGadget(0, 0, 0, WindowWidth, WindowHeight)
          result = 1
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure

;
; Main starts here
;
  MachineName.s = "fweil"
  DataBaseName.s = "ServicesActive"
  WindowXSize.l = 800
  WindowYSize.l = 600
  Quit.l = #FALSE
  If OpenWindow(#Window_Main, 0, 0, WindowXSize, WindowYSize, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered, "Enum Services")
      AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Escape, #Escape)
      If CreateGadgetList(WindowID())
          SetGadgetFont(#PB_Default, LoadFont(0, "Verdana", 7, #PB_Font_HighQuality))
          hListIconGadget = ListIconGadget(#Gadget_ListIcon, 0, 0, WindowXSize, WindowYSize, "Type", 120, #PB_ListIcon_MultiSelect | #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_HeaderDragDrop | #PB_ListIcon_AlwaysShowSelection)
          AddGadgetColumn(#Gadget_ListIcon, 1, "Item", 120)
          AddGadgetColumn(#Gadget_ListIcon, 2, "Name", 120)
          AddGadgetColumn(#Gadget_ListIcon, 3, "Display name", 120)
          AddGadgetColumn(#Gadget_ListIcon, 4, "Service type", 120)
          AddGadgetColumn(#Gadget_ListIcon, 5, "CurrentState", 120)
          AddGadgetColumn(#Gadget_ListIcon, 6, "ControlsAccepted", 120)
      EndIf
      updown = 1
      lastcol = 0
      UpdatelParam()
      SetWindowCallback(@ColumnClickCallback())
      Debug EnumServicesProc(#SERVICE_DRIVER)
      Debug EnumServicesProc(#SERVICE_WIN32)
      For i = 0 To 6
        Select i
          Case 0
            SendMessage_(hListIconGadget, #LVM_SETCOLUMNWIDTH, i, #LVSCW_AUTOSIZE)
          Case 3
            SendMessage_(hListIconGadget, #LVM_SETCOLUMNWIDTH, i, 120)
          Default
            SendMessage_(hListIconGadget, #LVM_SETCOLUMNWIDTH, i, #LVSCW_AUTOSIZE)
        EndSelect
      Next
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_CloseWindow
            Quit = #TRUE
          Case #PB_Event_Menu
            Select EventMenuID()
              Case #Escape
                Quit = #TRUE
            EndSelect
          Case #PB_Event_Gadget
        EndSelect
      Until Quit
  EndIf
  TerminateProcess_(GetCurrentProcess_(), 0)
End
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

Well I was 24 minutes late, if I am not wrong ... does my efforts apply to your question hours later ?
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Works fine on NT4sp5
Kris_a
User
User
Posts: 92
Joined: Sun Feb 15, 2004 8:04 pm
Location: Manchester, UK

Post by Kris_a »

Only works for me when debug mode is on 8O, just shows an empty table otherwise (XP pro, SP1)
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

You are right : I have only tested it in debug mode :oops:
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

As far as I understand, the issue comes from that I did a ProcedureReturn value to the EnumServicesProc using Debug in the main code.

Change lines :

Debug EnumServicesProc(#SERVICE_DRIVER)
Debug EnumServicesProc(#SERVICE_WIN32)

with

Result = EnumServicesProc(#SERVICE_DRIVER)
Result = EnumServicesProc(#SERVICE_WIN32)

and it should work fine.

Rgrds
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Thanks !
Works now.
Starter
New User
New User
Posts: 3
Joined: Thu Apr 22, 2004 10:47 pm

thanks a LOT :-)

Post by Starter »

Thanks a lot Fweil, as I had problems with my ISP I had not seen your answer sooner. I tested your code, works pretty fine :-)
Once again, thanks a lot as I wasn't able to understand the pointers part of the code I found. So I can continue my little 'security' prog, be sure I will post it (& source) as soon as it will be finished.

starter.
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

thnx to share with the community ...
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
Post Reply