1 {
2 License Agreement
3
4 This content is subject to the Mozilla Public License Version 1.1 (the "License");
5 You may not use this plugin except in compliance with the License. You may
6 obtain a copy of the License at http://www.mozilla.org/MPL.
7
8 Alternatively, you may redistribute this library, use and/or modify it
9 under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2.1 of the License,
11 or (at your option) any later version. You may obtain a copy
12 of the LGPL at www.gnu.org/copyleft.
13
14 Software distributed under the License is distributed on an "AS IS" basis,
15 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 for the specific language governing rights and limitations under the License.
17
18 The original code is ServiceControl.pas, released April 16, 2007.
19
20 The initial developer of the original code is Rainer Budde (http://www.speed-soft.de).
21
22 SimpleSC - NSIS Service Control Plugin is written, published and maintaned by
23 Rainer Budde (rainer@speed-soft.de).
24 }
25 unit ServiceControl;
26
27 interface
28
29 uses
30 Windows, SysUtils, WinSvc;
31
InstallServicenull32 function InstallService(ServiceName, DisplayName: String; ServiceType: DWORD; StartType: DWORD; BinaryPathName: String; Dependencies: String; Username: String; Password: String): Integer;
RemoveServicenull33 function RemoveService(ServiceName: String): Integer;
GetServiceNamenull34 function GetServiceName(DisplayName: String; var Name: String): Integer;
GetServiceDisplayNamenull35 function GetServiceDisplayName(ServiceName: String; var Name: String): Integer;
GetServiceStatusnull36 function GetServiceStatus(ServiceName: String; var Status: DWORD): Integer;
GetServiceBinaryPathnull37 function GetServiceBinaryPath(ServiceName: String; var BinaryPath: String): Integer;
GetServiceStartTypenull38 function GetServiceStartType(ServiceName: String; var StartType: DWORD): Integer;
GetServiceDescriptionnull39 function GetServiceDescription(ServiceName: String; var Description: String): Integer;
GetServiceLogonnull40 function GetServiceLogon(ServiceName: String; var Username: String): Integer;
SetServiceStartTypenull41 function SetServiceStartType(ServiceName: String; StartType: DWORD): Integer;
SetServiceDescriptionnull42 function SetServiceDescription(ServiceName: String; Description: String): Integer;
SetServiceLogonnull43 function SetServiceLogon(ServiceName: String; Username: String; Password: String): Integer;
SetServiceBinaryPathnull44 function SetServiceBinaryPath(ServiceName: String; BinaryPath: String): Integer;
ServiceIsRunningnull45 function ServiceIsRunning(ServiceName: String; var IsRunning: Boolean): Integer;
ServiceIsStoppednull46 function ServiceIsStopped(ServiceName: String; var IsStopped: Boolean): Integer;
ServiceIsPausednull47 function ServiceIsPaused(ServiceName: String; var IsPaused: Boolean): Integer;
StartServicenull48 function StartService(ServiceName: String; ServiceArguments: String): Integer;
StopServicenull49 function StopService(ServiceName: String): Integer;
PauseServicenull50 function PauseService(ServiceName: String): Integer;
ContinueServicenull51 function ContinueService(ServiceName: String): Integer;
RestartServicenull52 function RestartService(ServiceName: String; ServiceArguments: String): Integer;
ExistsServicenull53 function ExistsService(ServiceName: String): Integer;
GetErrorMessagenull54 function GetErrorMessage(ErrorCode: Integer): String;
55
56 implementation
57
WaitForStatusnull58 function WaitForStatus(ServiceName: String; Status: DWord): Integer;
59 var
60 CurrentStatus: DWord;
61 StatusResult: Integer;
62 StatusReached: Boolean;
63 TimeOutReached: Boolean;
64 StartTickCount: Cardinal;
65 const
66 STATUS_TIMEOUT = 30000;
67 WAIT_TIMEOUT = 250;
68 begin
69 Result := 0;
70
71 StatusReached := False;
72 TimeOutReached := False;
73
74 StartTickCount := GetTickCount;
75
76 while not StatusReached and not TimeOutReached do
77 begin
78 StatusResult := GetServiceStatus(ServiceName, CurrentStatus);
79
80 if StatusResult = 0 then
81 begin
82 if Status = CurrentStatus then
83 StatusReached := True
84 else
85 Sleep(WAIT_TIMEOUT);
86 end
87 else
88 Result := StatusResult;
89
90 if (StartTickCount + STATUS_TIMEOUT) < GetTickCount then
91 begin
92 TimeOutReached := True;
93 Result := ERROR_SERVICE_REQUEST_TIMEOUT;
94 end;
95 end;
96
97 end;
98
ExistsServicenull99 function ExistsService(ServiceName: String): Integer;
100 var
101 ManagerHandle: SC_HANDLE;
102 ServiceHandle: SC_HANDLE;
103 begin
104 Result := 0;
105
106 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
107
108 if ManagerHandle > 0 then
109 begin
110 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_QUERY_CONFIG);
111
112 if ServiceHandle > 0 then
113 CloseServiceHandle(ServiceHandle)
114 else
115 Result := System.GetLastError;
116
117 CloseServiceHandle(ManagerHandle);
118 end
119 else
120 Result := System.GetLastError;
121 end;
122
StartServicenull123 function StartService(ServiceName: String; ServiceArguments: String): Integer;
124 type
125 TArguments = Array of PChar;
126 var
127 ManagerHandle: SC_HANDLE;
128 ServiceHandle: SC_HANDLE;
129 ServiceArgVectors: TArguments;
130 NumServiceArgs: DWORD;
131 const
132 ArgDelimitterQuote: String = '"';
133 ArgDelimitterWhiteSpace: String = ' ';
134
135 procedure GetServiceArguments(ServiceArguments: String; var NumServiceArgs: DWORD; var ServiceArgVectors: TArguments);
136 var
137 Param: String;
138 Split: Boolean;
139 Quoted: Boolean;
140 CharIsDelimitter: Boolean;
141 begin
142 ServiceArgVectors := nil;
143 NumServiceArgs := 0;
144
145 Quoted := False;
146
147 while Length(ServiceArguments) > 0 do
148 begin
149 Split := False;
150 CharIsDelimitter := False;
151
152 if ServiceArguments[1] = ' ' then
153 if not Quoted then
154 begin
155 CharIsDelimitter := True;
156 Split := True;
157 end;
158
159 if ServiceArguments[1] = '"' then
160 begin
161 Quoted := not Quoted;
162 CharIsDelimitter := True;
163
164 if not Quoted then
165 Split := True;
166 end;
167
168 if not CharIsDelimitter then
169 Param := Param + ServiceArguments[1];
170
171 if Split or (Length(ServiceArguments) = 1) then
172 begin
173 SetLength(ServiceArgVectors, Length(ServiceArgVectors) + 1);
174 GetMem(ServiceArgVectors[Length(ServiceArgVectors) -1], Length(Param) + 1);
175 StrPCopy(ServiceArgVectors[Length(ServiceArgVectors) -1], Param);
176
177 Param := '';
178
179 Delete(ServiceArguments, 1, 1);
180 ServiceArguments := Trim(ServiceArguments);
181 end
182 else
183 Delete(ServiceArguments, 1, 1);
184
185 end;
186
187 if Length(ServiceArgVectors) > 0 then
188 NumServiceArgs := Length(ServiceArgVectors);
189 end;
190
191 procedure FreeServiceArguments(ServiceArgVectors: TArguments);
192 var
193 i: Integer;
194 begin
195 if Length(ServiceArgVectors) > 0 then
196 for i := 0 to Length(ServiceArgVectors) -1 do
197 FreeMem(ServiceArgVectors[i]);
198 end;
199
200 begin
201 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
202
203 if ManagerHandle > 0 then
204 begin
205 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_START);
206
207 if ServiceHandle > 0 then
208 begin
209 GetServiceArguments(ServiceArguments, NumServiceArgs, ServiceArgVectors);
210
211 if WinSvc.StartService(ServiceHandle, NumServiceArgs, ServiceArgVectors[0]) then
212 Result := WaitForStatus(ServiceName, SERVICE_RUNNING)
213 else
214 Result := System.GetLastError;
215
216 FreeServiceArguments(ServiceArgVectors);
217
218 CloseServiceHandle(ServiceHandle);
219 end
220 else
221 Result := System.GetLastError;
222
223
224 CloseServiceHandle(ManagerHandle);
225 end
226 else
227 Result := System.GetLastError;
228 end;
229
StopServicenull230 function StopService(ServiceName: String): Integer;
231 var
232 ManagerHandle: SC_HANDLE;
233 ServiceHandle: SC_HANDLE;
234 ServiceStatus: TServiceStatus;
235 Dependencies: PEnumServiceStatus;
236 BytesNeeded: Cardinal;
237 ServicesReturned: Cardinal;
238 ServicesEnumerated: Boolean;
239 EnumerationSuccess: Boolean;
240 i: Cardinal;
241 begin
242 Result := 0;
243
244 BytesNeeded := 0;
245 ServicesReturned := 0;
246
247 Dependencies := nil;
248 ServicesEnumerated := False;
249
250 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT or SC_MANAGER_ENUMERATE_SERVICE);
251
252 if ManagerHandle > 0 then
253 begin
254 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_STOP or SERVICE_ENUMERATE_DEPENDENTS);
255
256 if ServiceHandle > 0 then
257 begin
258 if not EnumDependentServices(ServiceHandle, SERVICE_ACTIVE, Dependencies^, 0, BytesNeeded, ServicesReturned) then
259 begin
260 ServicesEnumerated := True;
261 GetMem(Dependencies, BytesNeeded);
262
263 EnumerationSuccess := EnumDependentServices(ServiceHandle, SERVICE_ACTIVE, Dependencies^, BytesNeeded, BytesNeeded, ServicesReturned);
264
265 if EnumerationSuccess and (ServicesReturned > 0) then
266 begin
267 for i := 1 to ServicesReturned do
268 begin
269 Result := StopService(Dependencies.lpServiceName);
270
271 if Result <> 0 then
272 Break;
273
274 Inc(Dependencies);
275 end;
276 end
277 else
278 Result := System.GetLastError;
279 end;
280
281 if (ServicesEnumerated and (Result = 0)) or not ServicesEnumerated then
282 begin
283 if ControlService(ServiceHandle, SERVICE_CONTROL_STOP, ServiceStatus) then
284 Result := WaitForStatus(ServiceName, SERVICE_STOPPED)
285 else
286 Result := System.GetLastError
287 end;
288
289 CloseServiceHandle(ServiceHandle);
290 end
291 else
292 Result := System.GetLastError;
293
294 CloseServiceHandle(ManagerHandle);
295 end
296 else
297 Result := System.GetLastError;
298 end;
299
PauseServicenull300 function PauseService(ServiceName: String): Integer;
301 var
302 ManagerHandle: SC_HANDLE;
303 ServiceHandle: SC_HANDLE;
304 ServiceStatus: TServiceStatus;
305 begin
306 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
307
308 if ManagerHandle > 0 then
309 begin
310 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_PAUSE_CONTINUE);
311
312 if ServiceHandle > 0 then
313 begin
314
315 if ControlService(ServiceHandle, SERVICE_CONTROL_PAUSE, ServiceStatus) then
316 Result := WaitForStatus(ServiceName, SERVICE_PAUSED)
317 else
318 Result := System.GetLastError;
319
320 CloseServiceHandle(ServiceHandle);
321 end
322 else
323 Result := System.GetLastError;
324
325 CloseServiceHandle(ManagerHandle);
326 end
327 else
328 Result := System.GetLastError;
329 end;
330
ContinueServicenull331 function ContinueService(ServiceName: String): Integer;
332 var
333 ManagerHandle: SC_HANDLE;
334 ServiceHandle: SC_HANDLE;
335 ServiceStatus: TServiceStatus;
336 begin
337 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
338
339 if ManagerHandle > 0 then
340 begin
341 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_PAUSE_CONTINUE);
342
343 if ServiceHandle > 0 then
344 begin
345
346 if ControlService(ServiceHandle, SERVICE_CONTROL_CONTINUE, ServiceStatus) then
347 Result := WaitForStatus(ServiceName, SERVICE_RUNNING)
348 else
349 Result := System.GetLastError;
350
351 CloseServiceHandle(ServiceHandle);
352 end
353 else
354 Result := System.GetLastError;
355
356 CloseServiceHandle(ManagerHandle);
357 end
358 else
359 Result := System.GetLastError;
360 end;
361
GetServiceNamenull362 function GetServiceName(DisplayName: String; var Name: String): Integer;
363 var
364 ManagerHandle: SC_HANDLE;
365 ServiceName: PChar;
366 ServiceBuffer: Cardinal;
367 begin
368 Result := 0;
369
370 ServiceBuffer := 255;
371 ServiceName := StrAlloc(ServiceBuffer+1);
372
373 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
374
375 if ManagerHandle > 0 then
376 begin
377 if WinSvc.GetServiceKeyName(ManagerHandle, PChar(DisplayName), ServiceName, ServiceBuffer) then
378 Name := ServiceName
379 else
380 Result := System.GetLastError;
381
382 CloseServiceHandle(ManagerHandle);
383 end
384 else
385 Result := System.GetLastError;
386 end;
387
GetServiceDisplayNamenull388 function GetServiceDisplayName(ServiceName: String; var Name: String): Integer;
389 var
390 ManagerHandle: SC_HANDLE;
391 DisplayName: PChar;
392 ServiceBuffer: Cardinal;
393 begin
394 Result := 0;
395
396 ServiceBuffer := 255;
397 DisplayName := StrAlloc(ServiceBuffer+1);
398
399 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
400
401 if ManagerHandle > 0 then
402 begin
403 if WinSvc.GetServiceDisplayName(ManagerHandle, PChar(ServiceName), DisplayName, ServiceBuffer) then
404 Name := DisplayName
405 else
406 Result := System.GetLastError;
407
408 CloseServiceHandle(ManagerHandle);
409 end
410 else
411 Result := System.GetLastError;
412 end;
413
GetServiceStatusnull414 function GetServiceStatus(ServiceName: String; var Status: DWORD): Integer;
415 var
416 ManagerHandle: SC_HANDLE;
417 ServiceHandle: SC_HANDLE;
418 ServiceStatus: TServiceStatus;
419 begin
420 Result := 0;
421
422 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
423
424 if ManagerHandle > 0 then
425 begin
426 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_QUERY_STATUS);
427
428 if ServiceHandle > 0 then
429 begin
430 if QueryServiceStatus(ServiceHandle, ServiceStatus) then
431 Status := ServiceStatus.dwCurrentState
432 else
433 Result := System.GetLastError;
434
435 CloseServiceHandle(ServiceHandle);
436 end
437 else
438 Result := System.GetLastError;
439
440 CloseServiceHandle(ManagerHandle);
441 end
442 else
443 Result := System.GetLastError;
444 end;
445
GetServiceBinaryPathnull446 function GetServiceBinaryPath(ServiceName: String; var BinaryPath: String): Integer;
447 var
448 ManagerHandle: SC_HANDLE;
449 ServiceHandle: SC_HANDLE;
450 BytesNeeded: DWORD;
451 ServiceConfig: PQueryServiceConfig;
452 begin
453 Result := 0;
454 ServiceConfig := nil;
455
456 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
457
458 if ManagerHandle > 0 then
459 begin
460 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_QUERY_CONFIG);
461
462 if ServiceHandle > 0 then
463 begin
464
465 if not QueryServiceConfig(ServiceHandle, ServiceConfig, 0, BytesNeeded) and (System.GetLastError = ERROR_INSUFFICIENT_BUFFER) then
466 begin
467 GetMem(ServiceConfig, BytesNeeded);
468
469 if QueryServiceConfig(ServiceHandle, ServiceConfig, BytesNeeded, BytesNeeded) then
470 BinaryPath := ServiceConfig^.lpBinaryPathName
471 else
472 Result := System.GetLastError;
473
474 FreeMem(ServiceConfig);
475 end
476 else
477 Result := System.GetLastError;
478
479 CloseServiceHandle(ServiceHandle);
480 end
481 else
482 Result := System.GetLastError;
483
484 CloseServiceHandle(ManagerHandle);
485 end
486 else
487 Result := System.GetLastError;
488 end;
489
GetServiceStartTypenull490 function GetServiceStartType(ServiceName: String; var StartType: DWORD): Integer;
491 var
492 ManagerHandle: SC_HANDLE;
493 ServiceHandle: SC_HANDLE;
494 BytesNeeded: DWORD;
495 ServiceConfig: PQueryServiceConfig;
496 begin
497 Result := 0;
498 ServiceConfig := nil;
499
500 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
501
502 if ManagerHandle > 0 then
503 begin
504 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_QUERY_CONFIG);
505
506 if ServiceHandle > 0 then
507 begin
508
509 if not QueryServiceConfig(ServiceHandle, ServiceConfig, 0, BytesNeeded) and (System.GetLastError = ERROR_INSUFFICIENT_BUFFER) then
510 begin
511 GetMem(ServiceConfig, BytesNeeded);
512
513 if QueryServiceConfig(ServiceHandle, ServiceConfig, BytesNeeded, BytesNeeded) then
514 StartType := ServiceConfig^.dwStartType
515 else
516 Result := System.GetLastError;
517
518 FreeMem(ServiceConfig);
519 end
520 else
521 Result := System.GetLastError;
522
523 CloseServiceHandle(ServiceHandle);
524 end
525 else
526 Result := System.GetLastError;
527
528 CloseServiceHandle(ManagerHandle);
529 end
530 else
531 Result := System.GetLastError;
532 end;
533
GetServiceDescriptionnull534 function GetServiceDescription(ServiceName: String; var Description: String): Integer;
535 const
536 SERVICE_CONFIG_DESCRIPTION = 1;
537 type
538 TServiceDescription = record
539 lpDescription: PAnsiChar;
540 end;
541 PServiceDescription = ^TServiceDescription;
542 var
Servicenull543 QueryServiceConfig2: function(hService: SC_HANDLE; dwInfoLevel: DWORD; pBuffer: Pointer; cbBufSize: DWORD; var cbBytesNeeded: Cardinal): BOOL; stdcall;
544 ManagerHandle: SC_HANDLE;
545 ServiceHandle: SC_HANDLE;
546 LockHandle: SC_LOCK;
547 ServiceDescription: PServiceDescription;
548 BytesNeeded: Cardinal;
549 begin
550 Result := 0;
551
552 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_LOCK);
553
554 if ManagerHandle > 0 then
555 begin
556 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_QUERY_CONFIG);
557
558 if ServiceHandle > 0 then
559 begin
560 LockHandle := LockServiceDatabase(ManagerHandle);
561
562 if LockHandle <> nil then
563 begin
564 @QueryServiceConfig2 := GetProcAddress(GetModuleHandle(advapi32), 'QueryServiceConfig2A');
565
566 if Assigned(@QueryServiceConfig2) then
567 begin
568
569 if not QueryServiceConfig2(ServiceHandle, SERVICE_CONFIG_DESCRIPTION, nil, 0, BytesNeeded) and (System.GetLastError = ERROR_INSUFFICIENT_BUFFER) then
570 begin
571 GetMem(ServiceDescription, BytesNeeded);
572
573 if QueryServiceConfig2(ServiceHandle, SERVICE_CONFIG_DESCRIPTION, ServiceDescription, BytesNeeded, BytesNeeded) then
574 Description := ServiceDescription.lpDescription
575 else
576 Result := System.GetLastError;
577
578 FreeMem(ServiceDescription);
579 end
580 else
581 Result := System.GetLastError;
582
583 end
584 else
585 Result := System.GetLastError;
586
587 UnlockServiceDatabase(LockHandle);
588 end
589 else
590 Result := System.GetLastError;
591
592 CloseServiceHandle(ServiceHandle);
593 end
594 else
595 Result := System.GetLastError;
596
597 CloseServiceHandle(ManagerHandle);
598 end
599 else
600 Result := System.GetLastError;
601 end;
602
GetServiceLogonnull603 function GetServiceLogon(ServiceName: String; var Username: String): Integer;
604 var
605 ManagerHandle: SC_HANDLE;
606 ServiceHandle: SC_HANDLE;
607 BytesNeeded: DWORD;
608 ServiceConfig: PQueryServiceConfig;
609 begin
610 Result := 0;
611 ServiceConfig := nil;
612
613 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_CONNECT);
614
615 if ManagerHandle > 0 then
616 begin
617 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_QUERY_CONFIG);
618
619 if ServiceHandle > 0 then
620 begin
621
622 if not QueryServiceConfig(ServiceHandle, ServiceConfig, 0, BytesNeeded) and (System.GetLastError = ERROR_INSUFFICIENT_BUFFER) then
623 begin
624 GetMem(ServiceConfig, BytesNeeded);
625
626 if QueryServiceConfig(ServiceHandle, ServiceConfig, BytesNeeded, BytesNeeded) then
627 Username := ServiceConfig^.lpServiceStartName
628 else
629 Result := System.GetLastError;
630
631 FreeMem(ServiceConfig);
632 end
633 else
634 Result := System.GetLastError;
635
636 CloseServiceHandle(ServiceHandle);
637 end
638 else
639 Result := System.GetLastError;
640
641 CloseServiceHandle(ManagerHandle);
642 end
643 else
644 Result := System.GetLastError;
645 end;
646
SetServiceDescriptionnull647 function SetServiceDescription(ServiceName: String; Description: String): Integer;
648 const
649 SERVICE_CONFIG_DESCRIPTION = 1;
650 var
Servicenull651 ChangeServiceConfig2: function(hService: SC_HANDLE; dwInfoLevel: DWORD; lpInfo: Pointer): BOOL; stdcall;
652 ManagerHandle: SC_HANDLE;
653 ServiceHandle: SC_HANDLE;
654 LockHandle: SC_LOCK;
655 begin
656 Result := 0;
657
658 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_LOCK);
659
660 if ManagerHandle > 0 then
661 begin
662 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_CHANGE_CONFIG);
663
664 if ServiceHandle > 0 then
665 begin
666 LockHandle := LockServiceDatabase(ManagerHandle);
667
668 if LockHandle <> nil then
669 begin
670 @ChangeServiceConfig2 := GetProcAddress(GetModuleHandle(advapi32), 'ChangeServiceConfig2A');
671
672 if Assigned(@ChangeServiceConfig2) then
673 begin
674 if not ChangeServiceConfig2(ServiceHandle, SERVICE_CONFIG_DESCRIPTION, @Description) then
675 Result := System.GetLastError;
676 end
677 else
678 Result := System.GetLastError;
679
680 UnlockServiceDatabase(LockHandle);
681 end
682 else
683 Result := System.GetLastError;
684
685 CloseServiceHandle(ServiceHandle);
686 end
687 else
688 Result := System.GetLastError;
689
690 CloseServiceHandle(ManagerHandle);
691 end
692 else
693 Result := System.GetLastError;
694 end;
695
SetServiceStartTypenull696 function SetServiceStartType(ServiceName: String; StartType: DWORD): Integer;
697 var
698 ManagerHandle: SC_HANDLE;
699 ServiceHandle: SC_HANDLE;
700 LockHandle: SC_LOCK;
701 begin
702 Result := 0;
703
704 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_LOCK);
705
706 if ManagerHandle > 0 then
707 begin
708 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_CHANGE_CONFIG);
709
710 if ServiceHandle > 0 then
711 begin
712 LockHandle := LockServiceDatabase(ManagerHandle);
713
714 if LockHandle <> nil then
715 begin
716 if not ChangeServiceConfig(ServiceHandle, SERVICE_NO_CHANGE, StartType, SERVICE_NO_CHANGE, nil, nil, nil, nil, nil, nil, nil) then
717 Result := System.GetLastError;
718
719 UnlockServiceDatabase(LockHandle);
720 end
721 else
722 Result := System.GetLastError;
723
724 CloseServiceHandle(ServiceHandle);
725 end
726 else
727 Result := System.GetLastError;
728
729 CloseServiceHandle(ManagerHandle);
730 end
731 else
732 Result := System.GetLastError;
733 end;
734
SetServiceLogonnull735 function SetServiceLogon(ServiceName: String; Username: String; Password: String): Integer;
736 var
737 ManagerHandle: SC_HANDLE;
738 ServiceHandle: SC_HANDLE;
739 LockHandle: SC_LOCK;
740 begin
741 Result := 0;
742
743 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_LOCK);
744
745 if Pos('\', Username) = 0 then
746 Username := '.\' + Username;
747
748 if ManagerHandle > 0 then
749 begin
750 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_CHANGE_CONFIG);
751
752 if ServiceHandle > 0 then
753 begin
754 LockHandle := LockServiceDatabase(ManagerHandle);
755
756 if LockHandle <> nil then
757 begin
758 if not ChangeServiceConfig(ServiceHandle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, nil, nil, nil, nil, PChar(Username), PChar(Password), nil) then
759 Result := System.GetLastError;
760
761 UnlockServiceDatabase(LockHandle);
762 end
763 else
764 Result := System.GetLastError;
765
766 CloseServiceHandle(ServiceHandle);
767 end
768 else
769 Result := System.GetLastError;
770
771 CloseServiceHandle(ManagerHandle);
772 end
773 else
774 Result := System.GetLastError;
775 end;
776
SetServiceBinaryPathnull777 function SetServiceBinaryPath(ServiceName: String; BinaryPath: String): Integer;
778 var
779 ManagerHandle: SC_HANDLE;
780 ServiceHandle: SC_HANDLE;
781 LockHandle: SC_LOCK;
782 begin
783 Result := 0;
784
785 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_LOCK);
786
787 if ManagerHandle > 0 then
788 begin
789 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_CHANGE_CONFIG);
790
791 if ServiceHandle > 0 then
792 begin
793 LockHandle := LockServiceDatabase(ManagerHandle);
794
795 if LockHandle <> nil then
796 begin
797 if not ChangeServiceConfig(ServiceHandle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, PChar(BinaryPath), nil, nil, nil, nil, nil, nil) then
798 Result := System.GetLastError;
799
800 UnlockServiceDatabase(LockHandle);
801 end
802 else
803 Result := System.GetLastError;
804
805 CloseServiceHandle(ServiceHandle);
806 end
807 else
808 Result := System.GetLastError;
809
810 CloseServiceHandle(ManagerHandle);
811 end
812 else
813 Result := System.GetLastError;
814 end;
815
ServiceIsRunningnull816 function ServiceIsRunning(ServiceName: String; var IsRunning: Boolean): Integer;
817 var
818 Status: DWORD;
819 begin
820 Result := GetServiceStatus(ServiceName, Status);
821
822 if Result = 0 then
823 IsRunning := Status = SERVICE_RUNNING
824 else
825 IsRunning := False;
826 end;
827
ServiceIsStoppednull828 function ServiceIsStopped(ServiceName: String; var IsStopped: Boolean): Integer;
829 var
830 Status: DWORD;
831 begin
832 Result := GetServiceStatus(ServiceName, Status);
833
834 if Result = 0 then
835 IsStopped := Status = SERVICE_STOPPED
836 else
837 IsStopped := False;
838 end;
839
ServiceIsPausednull840 function ServiceIsPaused(ServiceName: String; var IsPaused: Boolean): Integer;
841 var
842 Status: DWORD;
843 begin
844 Result := GetServiceStatus(ServiceName, Status);
845
846 if Result = 0 then
847 IsPaused := Status = SERVICE_PAUSED
848 else
849 IsPaused := False;
850 end;
851
RestartServicenull852 function RestartService(ServiceName: String; ServiceArguments: String): Integer;
853 begin
854 Result := StopService(ServiceName);
855
856 if Result = 0 then
857 Result := StartService(ServiceName, ServiceArguments);
858 end;
859
InstallServicenull860 function InstallService(ServiceName, DisplayName: String; ServiceType: DWORD;
861 StartType: DWORD; BinaryPathName: String; Dependencies: String;
862 Username: String; Password: String): Integer;
863 var
864 ManagerHandle: SC_HANDLE;
865 ServiceHandle: SC_HANDLE;
866 PDependencies: PChar;
867 PUsername: PChar;
868 PPassword: PChar;
869 const
870 ReplaceDelimitter: String = '/';
871
Replacenull872 function Replace(Value: String): String;
873 begin
874 while Pos(ReplaceDelimitter, Value) <> 0 do
875 begin
876 Result := Result + Copy(Value, 1, Pos(ReplaceDelimitter, Value) -1) + Chr(0);
877 Delete(Value, 1, Pos(ReplaceDelimitter, Value));
878 end;
879
880 Result := Result + Value + Chr(0) + Chr(0);
881 end;
882
883 begin
884 Result := 0;
885
886 if Dependencies = '' then
887 PDependencies := nil
888 else
889 PDependencies := PChar(Replace(Dependencies));
890
891 if UserName = '' then
892 PUsername := nil
893 else
894 PUsername := PChar(Username);
895
896 if Password = '' then
897 PPassword := nil
898 else
899 PPassword := PChar(Password);
900
901 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_ALL_ACCESS);
902
903 if ManagerHandle > 0 then
904 begin
905 ServiceHandle := CreateService(ManagerHandle,
906 PChar(ServiceName),
907 PChar(DisplayName),
908 SERVICE_START or SERVICE_QUERY_STATUS or _DELETE,
909 ServiceType,
910 StartType,
911 SERVICE_ERROR_NORMAL,
912 PChar(BinaryPathName),
913 nil,
914 nil,
915 PDependencies,
916 PUsername,
917 PPassword);
918
919 if ServiceHandle <> 0 then
920 CloseServiceHandle(ServiceHandle)
921 else
922 Result := System.GetLastError;
923
924 CloseServiceHandle(ManagerHandle);
925 end
926 else
927 Result := System.GetLastError;
928 end;
929
RemoveServicenull930 function RemoveService(ServiceName: String): Integer;
931 var
932 ManagerHandle: SC_HANDLE;
933 ServiceHandle: SC_HANDLE;
934 LockHandle: SC_LOCK;
935 IsStopped: Boolean;
936 Deleted: Boolean;
937 begin
938 IsStopped := False;
939
940 Result := ServiceIsStopped(ServiceName, IsStopped);
941
942 if Result = 0 then
943 if not IsStopped then
944 Result := StopService(ServiceName);
945
946 if Result = 0 then
947 begin
948 ManagerHandle := OpenSCManager('', nil, SC_MANAGER_ALL_ACCESS);
949
950 if ManagerHandle > 0 then
951 begin
952 ServiceHandle := OpenService(ManagerHandle, PChar(ServiceName), SERVICE_ALL_ACCESS);
953
954 if ServiceHandle > 0 then
955 begin
956 LockHandle := LockServiceDatabase(ManagerHandle);
957
958 if LockHandle <> nil then
959 begin
960 Deleted := DeleteService(ServiceHandle);
961
962 if not Deleted then
963 Result := System.GetLastError;
964
965 UnlockServiceDatabase(LockHandle);
966 end
967 else
968 Result := System.GetLastError;
969
970 CloseServiceHandle(ServiceHandle);
971 end
972 else
973 Result := System.GetLastError;
974
975 CloseServiceHandle(ManagerHandle);
976 end
977 else
978 Result := System.GetLastError;
979 end;
980 end;
981
GetErrorMessagenull982 function GetErrorMessage(ErrorCode: Integer): String;
983 begin
984 Result := SysErrorMessage(ErrorCode);
985 end;
986
987 end.
988