Title: TServiceManager
Question: Start/Stop device/user services
Answer:
download complete project:
http://web.vip.hr/inga.vip/tsvc.zip
unit kservice;
interface
uses windows;
const SERVICE_ALL_ACCESS=$f003f;
const SERVICE_ERROR_NORMAL=1;
Const SERVICE_CONTROL_STOP = 1;
Const SERVICE_CONTROL_PAUSE = 2;
Const SERVICE_CONTROL_CONTINUE = 3;
Const SERVICE_CONTROL_INTERROGATE = 4;
const SERVICE_ACTIVE = 1;
Const SERVICE_INACTIVE = 2;
Const SERVICE_START = $10;
Const SERVICE_STOP = $20;
const DELETE=2 shl 16;
const READ_CONTROL=2 shl 17;
const WRITE_DAC=2 shl 18;
const WRITE_OWNER=2 shl 19;
const SYNCHRONIZE=2 shl 20;
const OWNER_SECURITY_INFORMATION =1 ;
const GROUP_SECURITY_INFORMATION =2;
const DACL_SECURITY_INFORMATION =4 ;
const SACL_SECURITY_INFORMATION =8;
const PROTECTED_DACL_SECURITY_INFORMATION =$80000000;
const PROTECTED_SACL_SECURITY_INFORMATION =$40000000;
const UNPROTECTED_DACL_SECURITY_INFORMATION =$20000000;
const UNPROTECTED_SACL_SECURITY_INFORMATION =$10000000;
type
SERVICE_CMD=(CMD_START=1,CMD_STOP=2);
SERVICE_TYPES=(SERVICE_KERNEL_DRIVER=1,SERVICE_FILE_SYSTEM_DRIVER=2,SERVICE_WIN32_OWN_PROCESS=$10,SERVICE_WIN32_SHARE_PROCESS=$20,SERVICE_INTERACTIVE_PROCESS=$100);
SERVICE_STARTS=(SERVICE_BOOT_START=0,SERVICE_SYSTEM_START = 1,SERVICE_AUTO_START=2,SERVICE_DEMAND_START =3, SERVICE_DISABLED = 4);
SERVICE_STATE=(SERVICE_STOPPED = 1, SERVICE_START_PENDING=2,SERVICE_STOP_PENDING =3,SERVICE_RUNNING = 4,SERVICE_CONTINUE_PENDING =5 ,SERVICE_PAUSE_PENDING = 6,SERVICE_PAUSED = 7);
SERVICE_STATUS=record
dwServiceType,dwCurrentState,dwControlsAccepted,
dwWin32ExitCode,dwServiceSpecificExitCode,dwCheckPoint,dwWaitHint:cardinal ;
end;
pSERVICE_STATUS=^SERVICE_STATUS;
SERVICE_STATUS_PROCESS =record
dwServiceType,dwCurrentState,dwControlsAccepted,dwWin32ExitCode,dwServiceSpecificExitCode,dwCheckPoint,dwWaitHint,dwProcessId,dwServiceFlags:cardinal;
end;
pSERVICE_STATUS_PROCESS=^SERVICE_STATUS_PROCESS;
ENUM_SERVICE_STATUS_PROCESS=record //
pServiceName,pDisplayName:pansichar;
SSP:SERVICE_STATUS_PROCESS ;
end;
pENUM_SERVICE_STATUS_PROCESS=^ENUM_SERVICE_STATUS_PROCESS;
eEnumKernel=procedure (var UserData) of object; //enumeration interface
TRUSTEE_A=record
pMultipleTrustee, // DWORD ? ; PTR TRUSTEE_A
MultipleTrusteeOperation, // DWORD ? ; MULTIPLE_TRUSTEE_OPERATION
TrusteeForm, // DWORD ? ; TRUSTEE_FORM
TrusteeType:cardinal; // // DWORD ? ; TRUSTEE_TYPE
case integer of
1:(ptstrName:pansichar);
2:(psid:^cardinal);
end;
pTRUSTEE_A=^TRUSTEE_A;
EXPLICIT_ACCESS_A=record
grfAccessPermissions,
grfAccessMode,
grfInheritance:Cardinal;
Trustee:TRUSTEE_A;
end;
pEXPLICIT_ACCESS_A=^EXPLICIT_ACCESS_A;
ACCESS_MODE =(NOT_USED_ACCESS,GRANT_ACCESS,SET_ACCESS,DENY_ACCESS,REVOKE_ACCESS,SET_AUDIT_SUCCESS,SET_AUDIT_FAILURE);
//externals
function OpenSCManagerA(MachineName,DataBaseName:pansichar;Access:cardinal):cardinal;stdcall;external 'advapi32.dll';
function CloseServiceHandle(SCHandle:cardinal):cardinal;stdcall;external 'advapi32.dll';
function OpenServiceA (SCHandle:cardinal;ServiceName:pansichar;Access:cardinal):cardinal;stdcall;external 'advapi32.dll';
function CreateServiceA (SCHandle:cardinal;ServiceName,DisplayName:pansichar;Access,ServiceType,StartType,
ErrorControl:cardinal;BinaryPathName,LoadOrderGroup:pansichar;TagId:cardinal;Dependencies,ServiceStartName,Password:pansichar):cardinal;stdcall;external 'advapi32.dll';
function StartServiceA (SHandle,ArgCount:cardinal;Args:pointer):longbool;stdcall;external 'advapi32.dll';
function DelService (SHandle:cardinal):longbool;stdcall;external 'advapi32.dll' name 'DeleteService';
function ControlService (SHandle,Control:cardinal;Var SVR_status:SERVICE_STATUS):longbool;stdcall;external 'advapi32.dll' ;
function QueryServiceStatus (SHandle:cardinal;var SVR_status:SERVICE_STATUS):longbool;stdcall;external 'advapi32.dll';
function EnumServicesStatusExA (SCHandle,InfoLevel,dServiceType,dServiceState:cardinal;bfrServices:pointer;
bfrLength:cardinal;var BytesNeeded,ServiceReturned,ResumeHandle:cardinal;GroupName:pansichar):longbool;stdcall;external 'advapi32.dll';
function QueryServiceObjectSecurity(hService,secInfo:cardinal;srBuffer:pointer;buffersz:cardinal;var BytesNeeded:cardinal):longbool;stdcall;external 'advapi32.dll';
function BuildExplicitAccessWithNameA (var ea:EXPLICIT_ACCESS_A;sTrustee:pansichar;accessPermission,
accessMode,inheritance:cardinal):longbool;stdcall;external 'advapi32.dll';
function SetEntriesInAclA(cCountOfExplicitEntries:cardinal;pListOfExplicitEntries:pointer;OldAcl:pacl;var NewAcl:pacl):longbool;stdcall;external 'advapi32.dll';
function SetServiceObjectSecurity(hService,secInfo:cardinal;srBuffer:pointer):longbool;stdcall;external 'advapi32.dll';
function SleepEx (dwTime:cardinal;Allertable:longbool):longbool;stdcall ;external 'kernel32.dll';
function GlobalAlloc (uFlags,dwSize:cardinal):cardinal; stdcall;external 'kernel32.dll';
function GlobalFree (hMemory:cardinal):cardinal; stdcall;external 'kernel32.dll';
//TSERVICE CLASS BY VANJA FUCKAR!
type
TServiceManager=class
private
hServiceManager,hService:cardinal;
SvrName:string;
EnPrc:pENUM_SERVICE_STATUS_PROCESS;
kd:eEnumKernel;
private
function GetSvc(var SStatus:SERVICE_STATUS):longbool;
public
constructor Create;
destructor Destroy;
function OpenService(ServiceName:pansichar):longbool;
function CreateService(ServiceName,FullServicePath:pansichar;ServiceType:SERVICE_TYPES;ServiceStart:SERVICE_STARTS):longbool;
function StartService(Args:pointer;ArgsCount:cardinal):longbool;
function DeleteService:longbool;
function CloseService:longbool;
property ServiceName:string read SvrName;
property ServiceState[var SStatus:SERVICE_STATUS]:longbool read GetSvc;
function StopService:longbool;
function PauseService:longbool;
function ContinueService:longbool;
function EnumServices(var UserData):longbool;
property EnumNotification:eEnumKernel read kd write kd;
property EnumeratedService:pENUM_SERVICE_STATUS_PROCESS read EnPrc;
end;
implementation
constructor TServiceManager.Create;
begin
hServiceManager:=OpenSCManagerA(0,0,SERVICE_ALL_ACCESS);
end;
destructor TServiceManager.Destroy;
begin
if hService0 then CloseServiceHandle(hService);
if hServiceManager0 then CloseServiceHandle(hServiceManager);
end;
function TServiceManager.OpenService(ServiceName: pansichar): longbool;
var
nBytes:cardinal;
pM:pSECURITY_DESCRIPTOR;
sd:_SECURITY_DESCRIPTOR;
dPresent,dfPresent:longbool;
pA:pACL;
nA:pACL;
ea:EXPLICIT_ACCESS_A;
begin
result:=false;
if (hServiceManager0) and (hService=0) then begin
hService:=OpenServiceA(hServiceManager,ServiceName,$f01ff);
result:=longbool(hService);
if result then SvrName:=string(ServiceName);
GetMem(Pm,1024);
//ADJUST ACL assigned with service!
QueryServiceObjectSecurity(hService,DACL_SECURITY_INFORMATION,pm,0,nBytes);
QueryServiceObjectSecurity(hService,DACL_SECURITY_INFORMATION,pm,nBytes,nBytes);
GetSecurityDescriptorDacl(pM,dPresent,pA,dfPresent);
BuildExplicitAccessWithNameA(ea,pansichar('Guest'),SERVICE_START or SERVICE_STOP or READ_CONTROL or DELETE,cardinal(SET_ACCESS),0);
SetEntriesInAclA(1,addr(ea), pa,na);
InitializeSecurityDescriptor(addr(sd),SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(addr(sd),true,na,false);
SetServiceObjectSecurity(hService,DACL_SECURITY_INFORMATION,addr(sd));
localfree(cardinal(na));
FreeMem(pm);
end;
end;
function TServiceManager.CreateService(ServiceName,FullServicePath:pansichar;ServiceType:SERVICE_TYPES;ServiceStart:SERVICE_STARTS):longbool;
begin
result:=false;
if (hServiceManager0) and (hService=0) then begin
hService:=CreateServiceA(hServiceManager,ServiceName,ServiceName,$f01ff,cardinal(ServiceType),cardinal(ServiceStart),SERVICE_ERROR_NORMAL,
FullServicePath,0,0,0,0,0);
result:=longbool(hService);
if result then SvrName:=string(ServiceName);
end;
end;
function TServiceManager.StartService(Args:pointer;ArgsCount:cardinal): longbool;
begin
result:=false;
if (hService0) then begin
result:=StartServiceA(hService,ArgsCount,Args);
SleepEx(100,false); //YIELD EXECUTION
end;
end;
function TServiceManager.DeleteService: longbool;
var
SS:SERVICE_STATUS;
begin
result:=false;
if (hService0) then begin
result:=DelService(hService);
SleepEx(100,false);
if result then hService:=0;
end;
end;
function TServiceManager.GetSvc (var SStatus:SERVICE_STATUS):longbool;
begin
result:=false;
if hService0 then result:=QueryServiceStatus(hService,SStatus);
end;
function TServiceManager.StopService: longbool;
var
SS:SERVICE_STATUS;
begin
result:=false;
if hService0 then begin
if ControlService(hService,SERVICE_CONTROL_STOP,SS) then begin
SleepEx(100,false); //YIELD EXECUTION
if (SS.dwCurrentState=1) or (SS.dwCurrentState=3) then result:=true;
end
end;
end;
function TServiceManager.ContinueService: longbool;
var
SS:SERVICE_STATUS;
begin
result:=false;
if hService0 then begin
if ControlService(hService,SERVICE_CONTROL_CONTINUE,SS) then begin
SleepEx(100,false); //YIELD EXECUTION
if (SS.dwCurrentState=4) or (SS.dwCurrentState=5) then result:=true;
end
end;
end;
function TServiceManager.PauseService: longbool;
var
SS:SERVICE_STATUS;
begin
result:=false;
if hService0 then begin
if ControlService(hService,SERVICE_CONTROL_PAUSE,SS) then begin
SleepEx(100,false); //YIELD EXECUTION
if (SS.dwCurrentState=6) or (SS.dwCurrentState=7) then result:=true;
end
end;
end;
function TServiceManager.EnumServices(var UserData):longbool;
label oOut;
var
BF:cardinal;
cRet,cLen,bNeed,sRet,RH:cardinal;
x:cardinal;
xp:pointer;
begin
if (hServiceManager0) and (Assigned(kd)) then begin
RH:=0;
EnumServicesStatusExA(hServiceManager,0,$33,SERVICE_ACTIVE or SERVICE_INACTIVE,pointer(0),
0,bNeed,Sret,RH,0) ;
BF:=GlobalAlloc($40,bNeed);
if not EnumServicesStatusExA(hServiceManager,0,$33,SERVICE_ACTIVE or SERVICE_INACTIVE,pointer(bf),bNeed,bNeed,Sret,RH,0) then goto oOut;
xp:=pointer(BF);
for x:=0 to Sret-1 do begin
EnPrc:=xp;
kd(UserData);
xp:=pointer(cardinal(xp)+sizeof (ENUM_SERVICE_STATUS_PROCESS));
end;
result:=true;
oOut:
GlobalFree(bf);
end;
end;
function TServiceManager.CloseService: longbool;
begin
result:=false;
if hService0 then begin
result:=longbool(CloseServiceHandle(hService));
hService:=0;
end;
end;
end.