daemonapp.pp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465
  1. {
  2. $Id: header,v 1.1 2000/07/13 06:33:45 michael Exp $
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit daemonapp;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. Custapp, Classes, SysUtils, eventlog, rtlconsts;
  16. Type
  17. TCustomDaemon = Class;
  18. TDaemonController = Class;
  19. TDaemonEvent = procedure(Sender: TCustomDaemon) of object;
  20. TDaemonOKEvent = procedure(Sender: TCustomDaemon; var OK: Boolean) of object;
  21. TDaemonOption = (doAllowStop,doAllowPause,doInteractive);
  22. TDaemonOptions = Set of TDaemonOption;
  23. TDaemonRunMode = (drmUnknown,drmInstall,drmUninstall,drmRun);
  24. { TCustomDaemonDescription }
  25. TDaemonDef = Class;
  26. TCurrentStatus =
  27. (csStopped, csStartPending, csStopPending, csRunning,
  28. csContinuePending, csPausePending, csPaused);
  29. TCustomDaemon = Class(TDataModule)
  30. private
  31. FController: TDaemonController;
  32. FDaemonDef: TDaemonDef;
  33. FThread : TThread;
  34. FStatus: TCurrentStatus;
  35. function GetLogger: TEventLog;
  36. procedure SetStatus(const AValue: TCurrentStatus);
  37. Protected
  38. Function Start : Boolean; virtual;
  39. Function Stop : Boolean; virtual;
  40. Function Pause : Boolean; virtual;
  41. Function Continue : Boolean; virtual;
  42. Function Execute : Boolean; virtual;
  43. Function ShutDown : Boolean; virtual;
  44. Function Install : Boolean; virtual;
  45. Function UnInstall: boolean; virtual;
  46. Function HandleCustomCode(ACode : DWord) : Boolean; Virtual;
  47. Public
  48. Procedure CheckControlMessages(Wait : Boolean);
  49. Procedure LogMessage(const Msg : String);
  50. Procedure ReportStatus;
  51. // Filled in at runtime by controller
  52. Property Definition : TDaemonDef Read FDaemonDef;
  53. Property DaemonThread : TThread Read FThread;
  54. Property Controller : TDaemonController Read FController;
  55. Property Status : TCurrentStatus Read FStatus Write SetStatus;
  56. Property Logger : TEventLog Read GetLogger;
  57. end;
  58. TCustomDaemonClass = Class of TCustomDaemon;
  59. { TDaemon }
  60. TCustomControlCodeEvent = Procedure(Sender : TCustomDaemon; ACode : DWord; Var Handled : Boolean) of object;
  61. TDaemon = Class(TCustomDaemon)
  62. private
  63. FAfterInstall: TDaemonEvent;
  64. FAfterUnInstall: TDaemonEvent;
  65. FBeforeInstall: TDaemonEvent;
  66. FBeforeUnInstall: TDaemonEvent;
  67. FOnContinue: TDaemonOKEvent;
  68. FOnCustomControl: TCustomControlCodeEvent;
  69. FOnExecute: TDaemonEvent;
  70. FOnPause: TDaemonOKEvent;
  71. FOnShutDown: TDaemonEvent;
  72. FOnStart: TDaemonOKEvent;
  73. FOnStop: TDaemonOKEvent;
  74. Protected
  75. Function Start : Boolean; override;
  76. Function Stop : Boolean; override;
  77. Function Pause : Boolean; override;
  78. Function Continue : Boolean; override;
  79. Function Execute : Boolean; override;
  80. Function ShutDown : Boolean; override;
  81. Function Install : Boolean; override;
  82. Function UnInstall: boolean; override;
  83. Function HandleCustomCode(ACode : DWord) : Boolean; Override;
  84. Public
  85. Property Definition;
  86. Property Status;
  87. Published
  88. Property OnStart : TDaemonOKEvent Read FOnStart Write FOnStart;
  89. Property OnStop : TDaemonOKEvent Read FOnStop Write FOnStop;
  90. Property OnPause : TDaemonOKEvent Read FOnPause Write FOnPause;
  91. Property OnContinue : TDaemonOKEvent Read FOnContinue Write FOnContinue;
  92. Property OnShutDown : TDaemonEvent Read FOnShutDown Write FOnShutDown;
  93. Property OnExecute : TDaemonEvent Read FOnExecute Write FOnExecute;
  94. Property BeforeInstall : TDaemonEvent Read FBeforeInstall Write FBeforeInstall;
  95. Property AfterInstall : TDaemonEvent Read FAfterInstall Write FAfterInstall;
  96. Property BeforeUnInstall : TDaemonEvent Read FBeforeUnInstall Write FBeforeUnInstall;
  97. Property AfterUnInstall : TDaemonEvent Read FAfterUnInstall Write FAfterUnInstall;
  98. Property OnControlCode : TCustomControlCodeEvent Read FOnCustomControl Write FOnCustomControl;
  99. end;
  100. { TDaemonController }
  101. TDaemonController = Class(TComponent)
  102. Private
  103. FDaemon : TCustomDaemon;
  104. FLastStatus: TCurrentStatus;
  105. FSysData : TObject;
  106. FParams : TStrings;
  107. FCheckPoint : DWord;
  108. Public
  109. Constructor Create(AOwner : TComponent); override;
  110. Destructor Destroy; override;
  111. Procedure StartService; virtual;
  112. Procedure Main(Argc : DWord; Args : PPChar); Virtual;
  113. Procedure Controller(ControlCode,EventType : DWord; EventData : Pointer); Virtual;
  114. Function ReportStatus : Boolean; virtual;
  115. Property Daemon : TCustomDaemon Read FDaemon;
  116. Property Params : TStrings Read FParams;
  117. Property LastStatus : TCurrentStatus Read FLastStatus;
  118. Property CheckPoint : DWord read FCheckPoint;
  119. end;
  120. TDaemonClass = Class of TDaemon;
  121. { Windows specific service registration types }
  122. TServiceType = (stWin32, stDevice, stFileSystem);
  123. TErrorSeverity = (esIgnore, esNormal, esSevere, esCritical);
  124. TStartType = (stBoot, stSystem, stAuto, stManual, stDisabled);
  125. { TDependency }
  126. TDependency = class(TCollectionItem)
  127. private
  128. FName: String;
  129. FIsGroup: Boolean;
  130. protected
  131. function GetDisplayName: string; override;
  132. Public
  133. Procedure Assign(Source : TPersistent); override;
  134. published
  135. property Name: String read FName write FName;
  136. property IsGroup: Boolean read FIsGroup write FIsGroup;
  137. end;
  138. { TDependencies }
  139. TDependencies = class(TCollection)
  140. private
  141. FOwner: TPersistent;
  142. function GetItem(Index: Integer): TDependency;
  143. procedure SetItem(Index: Integer; Value: TDependency);
  144. protected
  145. function GetOwner: TPersistent; override;
  146. public
  147. constructor Create(AOwner: TPersistent);
  148. property Items[Index: Integer]: TDependency read GetItem write SetItem; default;
  149. end;
  150. { TWinBindings }
  151. TWinBindings = class(TPersistent)
  152. private
  153. FDependencies: TDependencies;
  154. FErrCode: DWord;
  155. FErrorSeverity: TErrorSeverity;
  156. FLoadGroup: String;
  157. FPassWord: String;
  158. FServiceType: TServiceType;
  159. FStartType: TStartType;
  160. FTagID: DWord;
  161. FUserName: String;
  162. FWaitHint: Integer;
  163. FWin32ErrorCode: DWord;
  164. procedure SetDependencies(const AValue: TDependencies);
  165. Public
  166. Constructor Create;
  167. Destructor Destroy; override;
  168. Procedure Assign(Source : TPersistent); override;
  169. property ErrCode: DWord read FErrCode write FErrCode;
  170. property Win32ErrCode: DWord read FWin32ErrorCode write FWin32ErrorCode;
  171. Published
  172. Property Dependencies : TDependencies Read FDependencies Write SetDependencies;
  173. Property GroupName : String Read FLoadGroup Write FLoadGroup;
  174. Property Password : String Read FPassWord Write FPassword;
  175. Property UserName : String Read FUserName Write FUserName;
  176. Property StartType : TStartType Read FStartType Write FStartType;
  177. Property WaitHint : Integer Read FWaitHint Write FWaitHint;
  178. Property IDTag : DWord Read FTagID Write FTagID;
  179. Property ServiceType : TServiceType Read FServiceType Write FServiceType;
  180. Property ErrorSeverity : TErrorSeverity Read FErrorSeverity Write FErrorSeverity;
  181. end;
  182. { TDaemonDef }
  183. TDaemonDef = Class(TCollectionItem)
  184. private
  185. FDaemonClass: TCustomDaemonClass;
  186. FDaemonClassName: String;
  187. FDescription: String;
  188. FDisplayName: String;
  189. FEnabled: Boolean;
  190. FInstance: TCustomDaemon;
  191. FLogStatusReport: Boolean;
  192. FName: String;
  193. FOnCreateInstance: TNotifyEvent;
  194. FOptions: TDaemonOptions;
  195. FServiceName: String;
  196. FWinBindings: TWinBindings;
  197. FRunArgs : String;
  198. procedure SetName(const AValue: String);
  199. procedure SetWinBindings(const AValue: TWinBindings);
  200. Protected
  201. function GetDisplayName: string; override;
  202. Public
  203. Constructor Create(ACollection : TCollection); override;
  204. Destructor Destroy; override;
  205. Property DaemonClass : TCustomDaemonClass read FDaemonClass;
  206. Property Instance : TCustomDaemon Read FInstance Write FInstance;
  207. Published
  208. Property DaemonClassName : String Read FDaemonClassName Write FDaemonClassName;
  209. Property Name : String Read FName Write SetName;
  210. Property Description : String Read FDescription Write FDescription;
  211. Property DisplayName : String Read FDisplayName Write FDisplayName;
  212. Property RunArguments : String Read FRunArgs Write FRunArgs;
  213. Property Options : TDaemonOptions Read FOptions Write FOptions;
  214. Property Enabled : Boolean Read FEnabled Write FEnabled default true;
  215. Property WinBindings : TWinBindings Read FWinBindings Write SetWinBindings;
  216. Property OnCreateInstance : TNotifyEvent Read FOnCreateInstance Write FOnCreateInstance;
  217. Property LogStatusReport : Boolean Read FLogStatusReport Write FLogStatusReport;
  218. end;
  219. { TDaemonDefs }
  220. TDaemonDefs = Class(TCollection)
  221. private
  222. FOwner : TPersistent;
  223. function GetDaemonDef(Index : Integer): TDaemonDef;
  224. procedure SetDaemonDef(Index : Integer; const AValue: TDaemonDef);
  225. Protected
  226. Procedure BindClasses;
  227. Function GetOwner : TPersistent; override;
  228. Public
  229. Constructor Create(AOwner : TPersistent; AClass : TCollectionItemClass);
  230. Function IndexOfDaemonDef(Const DaemonName : String) : Integer;
  231. Function FindDaemonDef(Const DaemonName : String) : TDaemonDef;
  232. Function DaemonDefByName(Const DaemonName : String) : TDaemonDef;
  233. Property Daemons[Index : Integer] : TDaemonDef Read GetDaemonDef Write SetDaemonDef; default;
  234. end;
  235. { TCustomDaemonMapper }
  236. TCustomDaemonMapper = Class(TComponent)
  237. private
  238. FDaemonDefs: TDaemonDefs;
  239. FOnCreate: TNotifyEvent;
  240. FOnDestroy: TNotifyEvent;
  241. FOnInstall: TNotifyEvent;
  242. FOnRun: TNotifyEvent;
  243. FOnUnInStall: TNotifyEvent;
  244. procedure SetDaemonDefs(const AValue: TDaemonDefs);
  245. Protected
  246. Procedure CreateDefs; virtual;
  247. Procedure DoOnCreate; virtual;
  248. Procedure DoOnDestroy; virtual;
  249. Procedure DoOnInstall; virtual;
  250. Procedure DoOnUnInstall; virtual;
  251. Procedure DoOnRun; virtual;
  252. Public
  253. Constructor Create(AOwner : TComponent); override;
  254. Destructor Destroy; override;
  255. Published
  256. Property DaemonDefs : TDaemonDefs Read FDaemonDefs Write SetDaemonDefs;
  257. Property OnCreate : TNotifyEvent Read FOnCreate Write FOnCreate;
  258. Property OnDestroy : TNotifyEvent Read FOnDestroy Write FOnDestroy;
  259. Property OnRun : TNotifyEvent Read FOnRun Write FOnRun;
  260. Property OnInstall : TNotifyEvent Read FOnInstall Write FOnInstall;
  261. Property OnUnInstall : TNotifyEvent Read FOnUnInStall Write FOnUninStall;
  262. end;
  263. { TDaemonMapper }
  264. TDaemonMapper = Class(TCustomDaemonMapper)
  265. Constructor Create(AOwner : TComponent); override;
  266. Constructor CreateNew(AOwner : TComponent; Dummy : Integer = 0);
  267. end;
  268. TCustomDaemonMapperClass = Class of TCustomDaemonMapper;
  269. { TDaemonThread }
  270. TDaemonThread = Class(TThread)
  271. Private
  272. FDaemon : TCustomDaemon;
  273. Protected
  274. procedure StartServiceExecute; virtual;
  275. procedure HandleControlCode(ACode : DWord); virtual;
  276. Public
  277. Constructor Create(ADaemon : TCustomDaemon);
  278. Procedure Execute; override;
  279. Procedure CheckControlMessage(WaitForMessage : Boolean);
  280. Function StopDaemon : Boolean; virtual;
  281. Function PauseDaemon : Boolean; virtual;
  282. Function ContinueDaemon : Boolean; virtual;
  283. Function ShutDownDaemon : Boolean; virtual;
  284. Function InterrogateDaemon : Boolean; virtual;
  285. Property Daemon : TCustomDaemon Read FDaemon;
  286. end;
  287. { TCustomDaemonApplication }
  288. TGuiLoopEvent = Procedure Of Object;
  289. TCustomDaemonApplication = Class(TCustomApplication)
  290. private
  291. FGUIHandle: THandle;
  292. FGUIMainLoop: TGuiLoopEvent;
  293. FEventLog: TEventLog;
  294. FMapper : TCustomDaemonMapper;
  295. FOnRun: TNotifyEvent;
  296. FRunMode: TDaemonRunMode;
  297. FSysData: TObject;
  298. FControllerCount : Integer;
  299. FAutoRegisterMessageFile : Boolean;
  300. procedure BindDaemonDefs(AMapper: TCustomDaemonMapper);
  301. function InstallRun: Boolean;
  302. procedure SysInstallDaemon(Daemon: TCustomDaemon);
  303. procedure SysUnInstallDaemon(Daemon: TCustomDaemon);
  304. function UnInstallRun: Boolean;
  305. function RunDaemonsRun: Boolean;
  306. Procedure Main(Argc : DWord; Args : PPchar);
  307. Function RunGUIloop(P : Pointer) : integer;
  308. Protected
  309. // OS (System) dependent calls
  310. Procedure SysStartUnInstallDaemons;
  311. Procedure SysEndUnInstallDaemons;
  312. Procedure SysStartInstallDaemons;
  313. Procedure SysEndInstallDaemons;
  314. Procedure SysStartRunDaemons;
  315. Procedure SysEndRunDaemons;
  316. // Customizable behaviour
  317. procedure CreateDaemonController(Var AController : TDaemonController); virtual;
  318. Procedure CreateServiceMapper(Var AMapper : TCustomDaemonMapper); virtual;
  319. Procedure CreateDaemonInstance(Var ADaemon : TCustomDaemon; DaemonDef : TDaemonDef); virtual;
  320. Procedure RemoveController(AController : TDaemonController); virtual;
  321. Function GetEventLog: TEventLog; virtual;
  322. Procedure DoRun; override;
  323. procedure DoLog(EventType: TEventType; const Msg: String); override;
  324. Property SysData : TObject Read FSysData Write FSysData;
  325. Public
  326. Constructor Create(AOwner : TComponent); override;
  327. destructor Destroy; override;
  328. Procedure ShowException(E : Exception); override;
  329. Function CreateDaemon(DaemonDef : TDaemonDef) : TCustomDaemon;
  330. Procedure StopDaemons(Force : Boolean);
  331. procedure InstallDaemons;
  332. procedure RunDaemons;
  333. procedure UnInstallDaemons;
  334. procedure ShowHelp;
  335. procedure CreateForm(InstanceClass: TComponentClass; var Reference); virtual;
  336. Property OnRun : TNotifyEvent Read FOnRun Write FOnRun;
  337. Property EventLog : TEventLog Read GetEventLog;
  338. Property GUIMainLoop : TGuiLoopEvent Read FGUIMainLoop Write FGuiMainLoop;
  339. Property GuiHandle : THandle Read FGUIHandle Write FGUIHandle;
  340. Property RunMode : TDaemonRunMode Read FRunMode;
  341. Property AutoRegisterMessageFile : Boolean Read FAutoRegisterMessageFile Write FAutoRegisterMessageFile default true;
  342. end;
  343. TCustomDaemonApplicationClass = Class of TCustomDaemonApplication;
  344. TDaemonApplication = Class(TCustomDaemonApplication);
  345. EDaemon = Class(Exception);
  346. Function Application : TCustomDaemonApplication;
  347. Procedure RegisterDaemonMapper(AMapperClass : TCustomDaemonMapperClass);
  348. Procedure RegisterDaemonClass(AClass : TCustomDaemonClass);
  349. Procedure RegisterDaemonApplicationClass(AClass : TCustomDaemonApplicationClass);
  350. Procedure DaemonError(Msg : String);
  351. Procedure DaemonError(Fmt : String; Args : Array of const);
  352. Resourcestring
  353. SErrNoServiceMapper = 'No daemon mapper class registered.';
  354. SErrOnlyOneMapperAllowed = 'Not changing daemon mapper class %s with %s: Only 1 mapper allowed.';
  355. SErrNothingToDo = 'No command given, use ''%s -h'' for usage.';
  356. SErrDuplicateName = 'Duplicate daemon name: %s';
  357. SErrUnknownDaemonClass = 'Unknown daemon class name: %s';
  358. SErrDaemonStartFailed = 'Failed to start daemon %s : %s';
  359. SDaemonStatus = 'Daemon %s current status: %s';
  360. SControlFailed = 'Control code %s handling failed: %s';
  361. SCustomCode = '[Custom code %d]';
  362. SErrServiceManagerStartFailed = 'Failed to start service manager: %s';
  363. SErrNoDaemonForStatus = '%s: No daemon for status report';
  364. SErrNoDaemonDefForStatus = '%s: No daemon definition for status report';
  365. SErrWindowClass = 'Could not register window class';
  366. SErrApplicationAlreadyCreated = 'An application instance of class %s was already created.';
  367. SHelpUsage = 'Usage: %s [command]';
  368. SHelpCommand = 'Where command is one of the following:';
  369. SHelpInstall = 'To install the program as a service';
  370. SHelpUnInstall = 'To uninstall the service';
  371. SHelpRun = 'To run the service';
  372. { $define svcdebug}
  373. {$ifdef svcdebug}
  374. Procedure DebugLog(Msg : String);
  375. {$endif}
  376. Var
  377. CurrentStatusNames : Array[TCurrentStatus] of string =
  378. ('Stopped', 'Start Pending', 'Stop Pending', 'Running',
  379. 'Continue Pending', 'Pause Pending', 'Paused');
  380. SStatus : Array[1..5] of string =
  381. ('Stop','Pause','Continue','Interrogate','Shutdown');
  382. DefaultDaemonOptions : TDaemonOptions = [doAllowStop,doAllowPause];
  383. AppClass : TCustomDaemonApplicationClass;
  384. implementation
  385. // This must come first, so a uses clause can be added.
  386. {$i daemonapp.inc}
  387. Var
  388. AppInstance : TCustomDaemonApplication;
  389. MapperClass : TCustomDaemonMapperClass;
  390. DesignMapper : TCustomDaemonMapper;
  391. DaemonClasses : TStringList;
  392. {$ifdef svcdebug}
  393. Var
  394. FL : Text;
  395. LCS : TRTLCriticalSection;
  396. Procedure StartLog;
  397. begin
  398. {$ifdef win32}
  399. Assign(FL,'c:\service.log');
  400. {$else}
  401. Assign(FL,'/tmp/service.log');
  402. {$endif}
  403. Rewrite(FL);
  404. InitCriticalSection(LCS);
  405. DebugLog('Start logging');
  406. end;
  407. Procedure DebugLog(Msg : String);
  408. begin
  409. EnterCriticalSection(LCS);
  410. try
  411. Writeln(FL,Msg);
  412. Flush(FL);
  413. Finally
  414. LeaveCriticalSection(LCS);
  415. end;
  416. end;
  417. Procedure EndLog;
  418. begin
  419. DebugLog('Done logging');
  420. Close(FL);
  421. DoneCriticalSection(LCS);
  422. end;
  423. {$endif svcdebug}
  424. Procedure RegisterDaemonApplicationClass(AClass : TCustomDaemonApplicationClass);
  425. begin
  426. If (AppInstance<>Nil) then
  427. DaemonError(SErrApplicationAlreadyCreated,[AppInstance.ClassName]);
  428. AppClass:=AClass;
  429. end;
  430. Procedure RegisterDaemonClass(AClass : TCustomDaemonClass);
  431. Var
  432. DN : String;
  433. I : Integer;
  434. begin
  435. If Not Assigned(DaemonClasses) then
  436. begin
  437. DaemonClasses:=TStringList.Create;
  438. DaemonClasses.Sorted:=True;
  439. end;
  440. DN:=AClass.ClassName;
  441. I:=DaemonClasses.IndexOf(DN);
  442. If (I=-1) then
  443. I:=DaemonClasses.Add(DN);
  444. DaemonClasses.Objects[I]:=TObject(AClass);
  445. end;
  446. Procedure CreateDaemonApplication;
  447. begin
  448. If (AppClass=Nil) then
  449. AppClass:=TCustomDaemonApplication;
  450. AppInstance:=AppClass.Create(Nil);
  451. end;
  452. Procedure DoneDaemonApplication;
  453. begin
  454. FreeAndNil(AppInstance);
  455. FreeAndNil(DaemonClasses);
  456. end;
  457. function Application: TCustomDaemonApplication;
  458. begin
  459. {$ifdef svcdebug}Debuglog('Application');{$endif}
  460. If (AppInstance=Nil) then
  461. begin
  462. {$ifdef svcdebug}Debuglog('Application creating instance');{$endif}
  463. CreateDaemonApplication;
  464. end;
  465. Result:=AppInstance;
  466. end;
  467. Procedure RegisterDaemonMapper(AMapperClass : TCustomDaemonMapperClass);
  468. begin
  469. If Assigned(MapperClass) then
  470. DaemonError(SErrOnlyOneMapperAllowed,[MapperClass.ClassName,AMapperClass.ClassName]);
  471. MapperClass:=AMapperClass;
  472. end;
  473. procedure DaemonError(Msg: String);
  474. begin
  475. Raise EDaemon.Create(MSg);
  476. end;
  477. procedure DaemonError(Fmt: String; Args: array of const);
  478. begin
  479. Raise EDaemon.CreateFmt(Fmt,Args);
  480. end;
  481. { TDaemon }
  482. function TDaemon.Start: Boolean;
  483. begin
  484. Result:=inherited Start;
  485. If assigned(FOnStart) then
  486. FOnStart(Self,Result);
  487. end;
  488. function TDaemon.Stop: Boolean;
  489. begin
  490. Result:=inherited Stop;
  491. If assigned(FOnStop) then
  492. FOnStop(Self,Result);
  493. end;
  494. function TDaemon.Pause: Boolean;
  495. begin
  496. Result:=inherited Pause;
  497. If assigned(FOnPause) then
  498. FOnPause(Self,Result);
  499. end;
  500. function TDaemon.Continue: Boolean;
  501. begin
  502. Result:=inherited Continue;
  503. If assigned(FOnContinue) then
  504. FOnContinue(Self,Result);
  505. end;
  506. function TDaemon.Execute: Boolean;
  507. begin
  508. Result:=Assigned(FOnExecute);
  509. If Result Then
  510. FOnExecute(Self);
  511. end;
  512. function TDaemon.ShutDown: Boolean;
  513. begin
  514. Result:=Inherited ShutDown;
  515. If Assigned(FOnShutDown) then
  516. FOnShutDown(Self);
  517. end;
  518. function TDaemon.Install: Boolean;
  519. begin
  520. If Assigned(FBeforeInstall) then
  521. FBeforeInstall(Self);
  522. Result:=inherited Install;
  523. If Assigned(FAfterInstall) then
  524. FAfterInstall(Self)
  525. end;
  526. function TDaemon.UnInstall: boolean;
  527. begin
  528. If Assigned(FBeforeUnInstall) then
  529. FBeforeUnInstall(Self);
  530. Result:=inherited UnInstall;
  531. If Assigned(FAfterUnInstall) then
  532. FAfterUnInstall(Self)
  533. end;
  534. function TDaemon.HandleCustomCode(ACode: DWord): Boolean;
  535. begin
  536. Result:=Assigned(FOnCustomControl);
  537. If Result then
  538. FOnCustomControl(Self,ACode,Result);
  539. end;
  540. { TCustomDaemon }
  541. Function TCustomDaemon.Start : Boolean;
  542. begin
  543. Result:=True;
  544. end;
  545. Function TCustomDaemon.Stop : Boolean;
  546. begin
  547. Result:=True;
  548. end;
  549. Function TCustomDaemon.Pause : Boolean;
  550. begin
  551. Result:=True;
  552. end;
  553. Function TCustomDaemon.Continue : Boolean;
  554. begin
  555. Result:=True;
  556. end;
  557. function TCustomDaemon.Execute: Boolean;
  558. begin
  559. Result:=False;
  560. end;
  561. Function TCustomDaemon.ShutDown : Boolean;
  562. begin
  563. Result:=True;
  564. end;
  565. Procedure TCustomDaemon.ReportStatus;
  566. begin
  567. Controller.ReportStatus;
  568. end;
  569. procedure TCustomDaemon.LogMessage(const Msg: String);
  570. begin
  571. Application.Log(etInfo,Msg);
  572. end;
  573. function TCustomDaemon.GetLogger: TEventLog;
  574. begin
  575. Result:=Application.EventLog;
  576. end;
  577. procedure TCustomDaemon.SetStatus(const AValue: TCurrentStatus);
  578. begin
  579. FStatus:=AValue;
  580. Controller.ReportStatus;
  581. end;
  582. Function TCustomDaemon.Install : Boolean;
  583. begin
  584. Result:=True;
  585. Application.SysInstallDaemon(Self);
  586. end;
  587. Function TCustomDaemon.UnInstall : Boolean;
  588. begin
  589. Result:=True;
  590. Application.SysUnInstallDaemon(Self);
  591. end;
  592. function TCustomDaemon.HandleCustomCode(ACode: DWord): Boolean;
  593. begin
  594. Result:=False
  595. end;
  596. Procedure TCustomDaemon.CheckControlMessages(Wait : Boolean);
  597. begin
  598. If Assigned(FThread) then
  599. TDaemonThread(FThread).CheckControlMessage(Wait);
  600. end;
  601. { TCustomServiceApplication }
  602. procedure TCustomDaemonApplication.CreateServiceMapper(Var AMapper : TCustomDaemonMapper);
  603. begin
  604. AMapper:=MapperClass.Create(Self);
  605. BindDaemonDefs(Amapper);
  606. end;
  607. procedure TCustomDaemonApplication.BindDaemonDefs(AMapper : TCustomDaemonMapper);
  608. begin
  609. AMApper.DaemonDefs.BindClasses;
  610. end;
  611. procedure TCustomDaemonApplication.CreateDaemonController(Var AController : TDaemonController);
  612. begin
  613. ACOntroller:=TDaemonController.Create(Self);
  614. end;
  615. Function TCustomDaemonApplication.RunDaemonsRun : Boolean;
  616. begin
  617. Result:=HasOption('r','run');
  618. // No Borland compatibility needed, as the install will take care of the -r
  619. end;
  620. procedure TCustomDaemonApplication.Main(Argc: DWord; Args: PPchar);
  621. Var
  622. SN : String;
  623. DD : TDaemonDef;
  624. begin
  625. {$ifdef svcdebug}DebugLog('Application.Main');{$endif svcdebug}
  626. If (Argc=0) then
  627. begin
  628. {$ifdef svcdebug}DebugLog('Using Default daemon');{$endif svcdebug}
  629. if FMapper.DaemonDefs.Count=1 then
  630. DD:=FMapper.DaemonDefs[0]
  631. else
  632. DD:=Nil
  633. end
  634. else
  635. begin
  636. {$ifdef svcdebug}DebugLog('Application.Main 2 : '+IntToStr(Argc));{$endif svcdebug}
  637. DD:=Nil;
  638. SN:='';
  639. If (Args<>Nil) then
  640. begin
  641. If (Args^<>Nil) then
  642. SN:=StrPas(Args^)
  643. else
  644. SN:='';
  645. end;
  646. {$ifdef svcdebug}DebugLog('Looking for daemon '+SN);{$endif svcdebug}
  647. DD:=FMapper.DaemonDefs.FindDaemonDef(SN);
  648. end;
  649. If (DD<>Nil) then
  650. begin
  651. {$ifdef svcdebug}DebugLog('Found daemon '+SN);{$endif svcdebug}
  652. DD.Instance.Controller.Main(Argc,Args);
  653. end
  654. else
  655. begin
  656. {$ifdef svcdebug}DebugLog('Did not fin daemon '+SN);{$endif svcdebug}
  657. end;
  658. end;
  659. Function TCustomDaemonApplication.InstallRun : Boolean;
  660. begin
  661. Result:=HasOption('i','install');
  662. // Borland compatibility.
  663. If not Result then
  664. Result:=FindCmdLineSwitch ('install',['/'],True);
  665. end;
  666. Function TCustomDaemonApplication.UnInstallRun : Boolean;
  667. begin
  668. Result:=HasOption('u','uninstall');
  669. // Borland compatibility.
  670. If not Result then
  671. Result:=FindCmdLineSwitch ('uninstall',['/'],True);
  672. end;
  673. Procedure TCustomDaemonApplication.InstallDaemons;
  674. Var
  675. D : TCustomDaemon;
  676. DD : TDaemonDef;
  677. C : TDaemonController;
  678. I : Integer;
  679. begin
  680. FrunMode:=drmInstall;
  681. SysStartInstallDaemons;
  682. try
  683. FMapper.DoOnInstall;
  684. For I:=0 to FMapper.DaemonDefs.Count-1 do
  685. begin
  686. DD:=FMapper.DaemonDefs[i];
  687. If DD.Enabled then
  688. begin
  689. D:=CreateDaemon(DD);
  690. Try
  691. // Need to call this because of the before/after events.
  692. D.Install;
  693. Finally
  694. D.Free;
  695. end;
  696. end;
  697. end;
  698. Finally
  699. SysEndInstallDaemons;
  700. end;
  701. end;
  702. Procedure TCustomDaemonApplication.UnInstallDaemons;
  703. Var
  704. D : TCustomDaemon;
  705. DD : TDaemonDef;
  706. I : Integer;
  707. begin
  708. FrunMode:=drmUnInstall;
  709. if FAutoRegisterMessageFile then
  710. EventLog.UnRegisterMessageFile;
  711. SysStartUnInstallDaemons;
  712. Try
  713. FMapper.DoOnUnInstall;
  714. // Uninstall in reverse order. One never knows.
  715. For I:=FMapper.DaemonDefs.Count-1 downto 0 do
  716. begin
  717. DD:=FMapper.DaemonDefs[i];
  718. If DD.Enabled then
  719. begin
  720. D:=CreateDaemon(FMapper.DaemonDefs[i]);
  721. Try
  722. // Need to call this because of the before/after events.
  723. D.UnInstall
  724. Finally
  725. D.Free;
  726. end;
  727. end;
  728. end;
  729. Finally
  730. SysEndUnInstallDaemons;
  731. end;
  732. end;
  733. procedure TCustomDaemonApplication.ShowHelp;
  734. begin
  735. if IsConsole then
  736. begin
  737. writeln(Format(SHelpUsage,[ParamStr(0)]));
  738. writeln(SHelpCommand);
  739. writeln(' -i --install '+SHelpInstall);
  740. writeln(' -u --uninstall '+SHelpUnInstall);
  741. writeln(' -r --run '+SHelpRun);
  742. end
  743. end;
  744. procedure TCustomDaemonApplication.CreateForm(InstanceClass: TComponentClass;
  745. var Reference);
  746. Var
  747. Instance: TComponent;
  748. begin
  749. // Allocate the instance, without calling the constructor
  750. Instance := TComponent(InstanceClass.NewInstance);
  751. // set the Reference before the constructor is called, so that
  752. // events and constructors can refer to it
  753. TComponent(Reference) := Instance;
  754. try
  755. Instance.Create(Self);
  756. except
  757. TComponent(Reference) := nil;
  758. Raise;
  759. end;
  760. end;
  761. procedure TCustomDaemonApplication.DoLog(EventType: TEventType; const Msg: String);
  762. begin
  763. EventLog.Log(EventType,Msg);
  764. end;
  765. Procedure TCustomDaemonApplication.RunDaemons;
  766. Var
  767. D : TCustomDaemon;
  768. DD : TDaemonDef;
  769. I : Integer;
  770. begin
  771. FRunMode:=drmRun;
  772. SysStartRunDaemons;
  773. FMapper.DoOnRun;
  774. For I:=0 to FMapper.DaemonDefs.Count-1 do
  775. begin
  776. DD:=FMapper.DaemonDefs[i];
  777. If DD.Enabled then
  778. D:=CreateDaemon(FMapper.DaemonDefs[i]);
  779. end;
  780. try
  781. SysEndRunDaemons;
  782. except
  783. HandleException(Self);
  784. Terminate;
  785. end;
  786. end;
  787. function TCustomDaemonApplication.GetEventLog: TEventLog;
  788. begin
  789. if not assigned(FEventLog) then
  790. begin
  791. FEventLog:=TEventlog.Create(Self);
  792. FEventLog.RaiseExceptionOnError:=False;
  793. if FAutoRegisterMessageFile then
  794. FEventLog.RegisterMessageFile('');
  795. end;
  796. result := FEventLog;
  797. end;
  798. destructor TCustomDaemonApplication.Destroy;
  799. begin
  800. if assigned(FEventLog) then
  801. FEventLog.Free;
  802. inherited Destroy;
  803. end;
  804. constructor TCustomDaemonApplication.Create(AOwner : TComponent);
  805. begin
  806. inherited;
  807. FAutoRegisterMessageFile:=True;
  808. end;
  809. procedure TCustomDaemonApplication.DoRun;
  810. begin
  811. try
  812. If Not Assigned(MapperClass) then
  813. DaemonError(SErrNoServiceMapper);
  814. CreateServiceMapper(FMapper);
  815. if InstallRun then
  816. InstallDaemons
  817. else If UnInstallRun then
  818. UnInstallDaemons
  819. else if RunDaemonsRun then
  820. RunDaemons
  821. else if Assigned(OnRun) then
  822. OnRun(Self)
  823. else if HasOption('h','help') then
  824. begin
  825. if IsConsole then
  826. ShowHelp;
  827. end
  828. else
  829. begin
  830. if IsConsole then
  831. ShowHelp
  832. else
  833. DaemonError(SErrNothingToDo,[ParamStr(0)]);
  834. end;
  835. {$ifdef svcdebug}DebugLog('Terminating');{$endif svcdebug}
  836. Terminate;
  837. {$ifdef svcdebug}DebugLog('Terminated');{$endif svcdebug}
  838. except
  839. Terminate;
  840. Raise
  841. end;
  842. end;
  843. procedure TCustomDaemonApplication.ShowException(E: Exception);
  844. begin
  845. Log(etError,E.Message);
  846. inherited ShowException(E)
  847. end;
  848. Procedure TCustomDaemonApplication.CreateDaemonInstance(Var ADaemon : TCustomDaemon; DaemonDef : TDaemonDef);
  849. begin
  850. ADaemon:=DaemonDef.DaemonClass.CreateNew(Self,0);
  851. end;
  852. function TCustomDaemonApplication.CreateDaemon(DaemonDef: TDaemonDef): TCustomDaemon;
  853. Var
  854. C : TDaemonController;
  855. begin
  856. CreateDaemonInstance(Result,DaemonDef);
  857. CreateDaemonController(C);
  858. C.FDaemon:=Result;
  859. Result.FController:=C;
  860. Result.FDaemonDef:=DaemonDef;
  861. If (Daemondef.Instance=Nil) then
  862. DaemonDef.Instance:=Result;
  863. end;
  864. procedure TCustomDaemonApplication.StopDaemons(Force: Boolean);
  865. Const
  866. ControlCodes : Array[Boolean] of DWord
  867. = (SERVICE_CONTROL_STOP,SERVICE_CONTROL_SHUTDOWN);
  868. Var
  869. L : TFPList;
  870. I : Integer;
  871. begin
  872. L:=TFPList.Create;
  873. try
  874. For I:=0 to ComponentCount-1 do
  875. If Components[i] is TDaemonController then
  876. L.Add(Components[i]);
  877. For I:=L.Count-1 downto 0 do
  878. TDaemonController(L[i]).Controller(ControlCodes[Force],0,Nil);
  879. finally
  880. L.Free;
  881. end;
  882. end;
  883. { TDaemonDefs }
  884. function TDaemonDefs.GetDaemonDef(Index : Integer): TDaemonDef;
  885. begin
  886. Result:=TDaemonDef(Items[index]);
  887. end;
  888. procedure TDaemonDefs.SetDaemonDef(Index : Integer; const AValue: TDaemonDef);
  889. begin
  890. Items[Index]:=AValue;
  891. end;
  892. procedure TDaemonDefs.BindClasses;
  893. Var
  894. D : TDaemonDef;
  895. I,J : Integer;
  896. begin
  897. For I:=0 to Count-1 do
  898. begin
  899. D:=GetDaemonDef(I);
  900. J:=DaemonClasses.IndexOf(D.DaemonClassName);
  901. If (J=-1) then
  902. DaemonError(SErrUnknownDaemonClass,[D.DaemonClassName])
  903. else
  904. D.FDaemonClass:=TCustomDaemonClass(DaemonClasses.Objects[J]);
  905. end;
  906. end;
  907. function TDaemonDefs.GetOwner: TPersistent;
  908. begin
  909. Result:=FOwner;
  910. end;
  911. constructor TDaemonDefs.Create(AOwner: TPersistent; AClass : TCollectionItemClass);
  912. begin
  913. Inherited Create(AClass);
  914. FOwner:=AOwner;
  915. end;
  916. function TDaemonDefs.IndexOfDaemonDef(Const DaemonName: String): Integer;
  917. begin
  918. Result:=Count-1;
  919. While (Result>=0) and (CompareText(GetDaemonDef(Result).Name,DaemonName)<>0) do
  920. Dec(Result);
  921. end;
  922. function TDaemonDefs.FindDaemonDef(Const DaemonName: String): TDaemonDef;
  923. Var
  924. I : Integer;
  925. begin
  926. I:=IndexOfDaemonDef(DaemonName);
  927. If I<>-1 then
  928. Result:=GetDaemonDef(I)
  929. else
  930. Result:=Nil;
  931. end;
  932. function TDaemonDefs.DaemonDefByName(Const DaemonName: String): TDaemonDef;
  933. begin
  934. Result:=FindDaemonDef(DaemonName);
  935. end;
  936. { TDaemonDef }
  937. procedure TDaemonDef.SetName(const AValue: String);
  938. begin
  939. If (AValue<>FName) then
  940. begin
  941. If (AValue<>'') and (Collection<>Nil)
  942. and (Collection is TDaemonDefs)
  943. and ((Collection as TDaemonDefs).IndexOfDaemonDef(AValue)<>-1) then
  944. DaemonError(SErrDuplicateName,[Avalue]);
  945. FName:=AValue;
  946. end;
  947. end;
  948. procedure TDaemonDef.SetWinBindings(const AValue: TWinBindings);
  949. begin
  950. FWinBindings.Assign(AValue);
  951. end;
  952. function TDaemonDef.GetDisplayName: string;
  953. begin
  954. Result:=Name;
  955. end;
  956. constructor TDaemonDef.Create(ACollection: TCollection);
  957. begin
  958. inherited Create(ACollection);
  959. FWinBindings:=TWinBindings.Create;
  960. FEnabled:=True;
  961. FOptions:=DefaultDaemonOptions;
  962. end;
  963. destructor TDaemonDef.Destroy;
  964. begin
  965. FreeAndNil(FWinBindings);
  966. inherited Destroy;
  967. end;
  968. { TCustomDaemonMapper }
  969. procedure TCustomDaemonMapper.SetDaemonDefs(const AValue: TDaemonDefs);
  970. begin
  971. if (FDaemonDefs=AValue) then
  972. exit;
  973. FDaemonDefs.Assign(AValue);
  974. end;
  975. procedure TCustomDaemonMapper.CreateDefs;
  976. begin
  977. FDaemonDefs:=TDaemonDefs.Create(Self,TDaemonDef);
  978. end;
  979. procedure TCustomDaemonMapper.DoOnCreate;
  980. begin
  981. If Assigned(FOnCreate) then
  982. FOnCreate(Self);
  983. end;
  984. procedure TCustomDaemonMapper.DoOnDestroy;
  985. begin
  986. If Assigned(FOnDestroy) then
  987. FOnDestroy(Self);
  988. end;
  989. procedure TCustomDaemonMapper.DoOnInstall;
  990. begin
  991. If Assigned(FOnInstall) then
  992. FOnInstall(Self);
  993. end;
  994. procedure TCustomDaemonMapper.DoOnUnInstall;
  995. begin
  996. If Assigned(FOnUnInstall) then
  997. FOnUnInstall(Self);
  998. end;
  999. procedure TCustomDaemonMapper.DoOnRun;
  1000. begin
  1001. If Assigned(FOnRun) then
  1002. FOnRun(Self);
  1003. end;
  1004. constructor TCustomDaemonMapper.Create(AOwner: TComponent);
  1005. begin
  1006. CreateDefs; // First, otherwise streaming will fail.
  1007. inherited Create(AOwner);
  1008. DoOnCreate;
  1009. end;
  1010. destructor TCustomDaemonMapper.Destroy;
  1011. begin
  1012. DoOnDestroy;
  1013. FreeAndNil(FDaemonDefs);
  1014. inherited Destroy;
  1015. end;
  1016. { TDaemonThread }
  1017. constructor TDaemonThread.Create(ADaemon: TCustomDaemon);
  1018. begin
  1019. FDaemon:=ADAemon;
  1020. FDaemon.FThread:=Self;
  1021. FreeOnTerminate:=False;
  1022. Inherited Create(True);
  1023. end;
  1024. procedure TDaemonThread.Execute;
  1025. begin
  1026. If FDaemon.Start then
  1027. begin
  1028. FDaemon.Status:=csRunning;
  1029. StartServiceExecute;
  1030. if not FDaemon.Execute then
  1031. begin
  1032. While Not Terminated do
  1033. CheckControlMessage(True);
  1034. CheckControlMessage(False);
  1035. end;
  1036. end
  1037. else
  1038. begin
  1039. FDaemon.Status:=csStopped;
  1040. Application.Terminate;
  1041. end;
  1042. end;
  1043. procedure TDaemonThread.HandleControlCode(ACode : DWord);
  1044. Var
  1045. CS : TCurrentStatus;
  1046. CC,OK : Boolean;
  1047. S : String;
  1048. begin
  1049. {$ifdef svcdebug}DebugLog('Handling control code '+IntToStr(ACode));{$endif svcdebug}
  1050. CS:=FDaemon.Status;
  1051. Try
  1052. OK:=True;
  1053. CC:=False;
  1054. Case ACode of
  1055. SERVICE_CONTROL_STOP : OK:=StopDaemon;
  1056. SERVICE_CONTROL_PAUSE : OK:=PauseDaemon;
  1057. SERVICE_CONTROL_CONTINUE : OK:=ContinueDaemon;
  1058. SERVICE_CONTROL_SHUTDOWN : OK:=ShutDownDaemon;
  1059. SERVICE_CONTROL_INTERROGATE : OK:=InterrogateDaemon;
  1060. else
  1061. CC:=True;
  1062. FDaemon.HandleCustomCode(ACode);
  1063. end;
  1064. If not OK then
  1065. FDaemon.Status:=CS;
  1066. Except
  1067. On E : Exception do
  1068. begin
  1069. // Shutdown MUST be done, in all other cases roll back status.
  1070. If (ACode<>SERVICE_CONTROL_SHUTDOWN) then
  1071. FDaemon.Status:=CS;
  1072. If (ACode in [1..5]) then
  1073. S:=SStatus[ACode]
  1074. else
  1075. S:=Format(SCustomCode,[ACode]);
  1076. end;
  1077. end;
  1078. end;
  1079. function TDaemonThread.StopDaemon: Boolean;
  1080. begin
  1081. FDaemon.Status:=csStopPending;
  1082. Result:=FDaemon.Stop;
  1083. If Result then
  1084. begin
  1085. FDaemon.Status:=csStopped;
  1086. Terminate;
  1087. end;
  1088. end;
  1089. function TDaemonThread.PauseDaemon: Boolean;
  1090. begin
  1091. FDaemon.Status:=csPausePending;
  1092. Result:=FDaemon.Pause;
  1093. If Result then
  1094. begin
  1095. FDaemon.Status:=csPaused;
  1096. Suspend;
  1097. end;
  1098. end;
  1099. function TDaemonThread.ContinueDaemon: Boolean;
  1100. begin
  1101. FDaemon.Status:=csContinuePending;
  1102. Result:=FDaemon.Continue;
  1103. If Result then
  1104. FDaemon.Status:=csRunning;
  1105. end;
  1106. function TDaemonThread.ShutDownDaemon: Boolean;
  1107. begin
  1108. FDaemon.Status:=csStopPending;
  1109. Try
  1110. Result:=FDaemon.ShutDown;
  1111. finally
  1112. FDaemon.Status:=csStopped;
  1113. Terminate;
  1114. end;
  1115. end;
  1116. Function TDaemonThread.InterrogateDaemon: Boolean;
  1117. begin
  1118. FDaemon.ReportStatus;
  1119. Result:=True;
  1120. end;
  1121. { ---------------------------------------------------------------------
  1122. TDaemonController - Global implementation
  1123. ---------------------------------------------------------------------}
  1124. constructor TDaemonController.Create(AOwner: TComponent);
  1125. begin
  1126. inherited Create(AOwner);
  1127. FParams:=TStringList.Create;
  1128. end;
  1129. destructor TDaemonController.Destroy;
  1130. begin
  1131. FreeAndNil(FSysData);
  1132. FreeAndNil(FParams);
  1133. inherited Destroy;
  1134. end;
  1135. { TWinBindings }
  1136. procedure TWinBindings.SetDependencies(const AValue: TDependencies);
  1137. begin
  1138. if (FDependencies<>AValue) then
  1139. FDependencies.Assign(AValue);
  1140. end;
  1141. Constructor TWinBindings.Create;
  1142. begin
  1143. FDependencies:=TDependencies.Create(Self);
  1144. end;
  1145. destructor TWinBindings.Destroy;
  1146. begin
  1147. FreeAndNil(FDependencies);
  1148. inherited Destroy;
  1149. end;
  1150. procedure TWinBindings.Assign(Source: TPersistent);
  1151. Var
  1152. WB : TWinBindings;
  1153. begin
  1154. if Source is TWinBindings then
  1155. begin
  1156. WB:=Source as TWinBindings;
  1157. GroupName:=WB.GroupName;
  1158. Password:=WB.PassWord;
  1159. UserName:=WB.UserName;
  1160. StartType:=WB.StartType;
  1161. WaitHint:=WB.WaitHint;
  1162. IDTag:=WB.IDTag;
  1163. ServiceType:=WB.ServiceType;
  1164. ErrorSeverity:=WB.ErrorSeverity;
  1165. Dependencies.Assign(WB.Dependencies);
  1166. ErrCode:=WB.ErrCode;
  1167. Win32ErrCode:=WB.Win32ErrCode;
  1168. end
  1169. else
  1170. inherited Assign(Source);
  1171. end;
  1172. { TDependency }
  1173. function TDependency.GetDisplayName: string;
  1174. begin
  1175. Result:=Name;
  1176. end;
  1177. procedure TDependency.Assign(Source: TPersistent);
  1178. Var
  1179. D : TDependency;
  1180. begin
  1181. if Source is TDependency then
  1182. begin
  1183. D:=Source as TDependency;
  1184. Name:=D.Name;
  1185. IsGroup:=D.IsGroup;
  1186. end
  1187. else
  1188. inherited Assign(Source);
  1189. end;
  1190. { TDependencies }
  1191. function TDependencies.GetItem(Index: Integer): TDependency;
  1192. begin
  1193. Result:=TDependency(Inherited GetItem(Index));
  1194. end;
  1195. procedure TDependencies.SetItem(Index: Integer; Value: TDependency);
  1196. begin
  1197. Inherited SetItem(Index,Value);
  1198. end;
  1199. function TDependencies.GetOwner: TPersistent;
  1200. begin
  1201. Result:=FOwner;
  1202. end;
  1203. constructor TDependencies.Create(AOwner: TPersistent);
  1204. begin
  1205. Inherited Create(TDependency);
  1206. FOwner:=AOwner;
  1207. end;
  1208. { TDaemonMapper }
  1209. constructor TDaemonMapper.Create(AOwner: TComponent);
  1210. begin
  1211. CreateNew(AOwner,0);
  1212. if (ClassType<>TDaemonMapper) and not (csDesigning in ComponentState) then
  1213. begin
  1214. if not InitInheritedComponent(Self,TDaemonMapper) then
  1215. raise EStreamError.CreateFmt(SErrNoSTreaming, [ClassName]);
  1216. end;
  1217. end;
  1218. constructor TDaemonMapper.CreateNew(AOwner: TComponent; Dummy: Integer);
  1219. begin
  1220. inherited Create(AOwner);
  1221. end;
  1222. Initialization
  1223. {$ifdef svcdebug}
  1224. StartLog;
  1225. {$endif}
  1226. SysInitDaemonApp;
  1227. Finalization
  1228. SysDoneDaemonApp;
  1229. DoneDaemonApplication;
  1230. {$ifdef svcdebug}
  1231. EndLog;
  1232. {$endif}
  1233. end.