Mega Code Archive

 
Categories / Delphi / Examples
 

List all installed services and drivers

In order to enumerate all installed drivers and/or services on either your local computer or even a remote machine, you need to use EnumServicesStatus(). This function doesn't work with a callback function; instead it expects a static array in which it will return the information. The example below implements a wrapper function ServiceGetList() that keeps this static array on the stack and returns the result in TStrings string list. The FormCreate() event shows how to call the function. You can download a complete sample Delphi project here (5 kB). unit fMain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) ListBox1: TListBox; ListBox2: TListBox; Label1: TLabel; Label2: TLabel; procedure FormCreate(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; implementation {$R *.DFM} uses WinSvc; 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); //------------------------------------- // 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 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 { ServiceGetList } 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; { for j } Result := true; Dispose(ssa); // close service control manager handle CloseServiceHandle(schm); end; { (schm>0) } end; { ServiceGetList } procedure TForm1.FormCreate(Sender: TObject); begin { TForm1.FormCreate } ServiceGetList('', SERVICE_TYPE_ALL, SERVICE_ACTIVE, ListBox1.Items); ServiceGetList('', SERVICE_TYPE_ALL, SERVICE_INACTIVE, ListBox2.Items); end; { TForm1.FormCreate } end.