Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
8.0 KiB

  1. /************************************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name: Service.h
  4. Abstract: Defines the CService class and related macros. See description below.
  5. Notes:
  6. History: 01/25/2001 - created, Luciano Passuello (lucianop).
  7. ************************************************************************************************/
  8. #pragma once
  9. // global constants
  10. const int nMaxServiceLen = 256;
  11. const int nMaxServiceDescLen = 1024;
  12. /************************************************************************************************
  13. Class: CService
  14. Purpose: Abstract class that implements the service-related code, such as
  15. threads creating, SCM registering, status retrieval, etc..
  16. Notes: (1) Class design based on the CService class described in the book:
  17. Professional NT Services, by Kevin Miller.
  18. (2) Each derived class must be instantiated one and only time.
  19. History: 01/25/2001 - created, Luciano Passuello (lucianop)
  20. ************************************************************************************************/
  21. class CService
  22. {
  23. protected:
  24. // actions that services respond to
  25. const static DWORD dwStateNoChange;
  26. enum SERVICE_NUMBER_EVENTS { nNumServiceEvents = 4 };
  27. enum SERVICE_EVENTS {STOP, PAUSE, CONTINUE, SHUTDOWN};
  28. DWORD m_dwDefaultEventID;
  29. WORD m_wDefaultCategory;
  30. public:
  31. CService(LPCTSTR szName, LPCTSTR szDisplay, DWORD dwType);
  32. virtual ~CService();
  33. DWORD GetStatus() { return m_dwState; }
  34. DWORD GetControls() { return m_dwControlsAccepted; }
  35. LPCTSTR GetName() { return m_szName; }
  36. LPCTSTR GetDisplayName() { return m_szDisplay; }
  37. protected:
  38. void ServiceMainMember(DWORD argc, LPTSTR* argv, LPHANDLER_FUNCTION pf, LPTHREAD_START_ROUTINE pfnWTP);
  39. void HandlerMember(DWORD dwControl);
  40. virtual void LaunchWatcherThread(LPTHREAD_START_ROUTINE pfnWTP);
  41. virtual DWORD WatcherThreadMemberProc();
  42. bool SetupHandlerInside(LPHANDLER_FUNCTION lpHandlerProc);
  43. void SetStatus(DWORD dwNewState, DWORD dwNewCheckpoint = dwStateNoChange, DWORD dwNewHint = dwStateNoChange,
  44. DWORD dwNewControls = dwStateNoChange, DWORD dwExitCode = NO_ERROR, DWORD dwSpecificExit = 0);
  45. void AbortService(DWORD dwErrorNum = GetLastError());
  46. // Overrideables
  47. protected:
  48. virtual void PreInit(); // if you override, call the base class version
  49. virtual void Init();
  50. virtual void DeInit(); // If you override, call the base class version
  51. virtual void ParseArgs(DWORD argc, LPTSTR* argv);
  52. virtual void OnPause();
  53. virtual void OnContinue();
  54. virtual void OnShutdown();
  55. virtual void HandleUserDefined(DWORD dwControl);
  56. // service events handling
  57. virtual void OnStopRequest();
  58. virtual void OnPauseRequest();
  59. virtual void OnContinueRequest();
  60. virtual void OnShutdownRequest();
  61. virtual void OnBeforeStart();
  62. virtual void OnAfterStart();
  63. virtual void Run() = 0;
  64. virtual void OnStop(DWORD dwErrorCode) = 0;
  65. // Attributes
  66. protected:
  67. CRITICAL_SECTION m_cs;
  68. // Status info
  69. SERVICE_STATUS_HANDLE m_hServiceStatus;
  70. DWORD m_dwState;
  71. DWORD m_dwControlsAccepted;
  72. DWORD m_dwCheckpoint;
  73. DWORD m_dwWaitHint;
  74. // Tracks state currently being worked on in Handler
  75. DWORD m_dwRequestedControl;
  76. // Control Events
  77. HANDLE m_hServiceEvent[nNumServiceEvents];
  78. HANDLE m_hWatcherThread;
  79. TCHAR m_szName[nMaxServiceLen + 1];
  80. TCHAR m_szDisplay[nMaxServiceLen + 1];
  81. DWORD m_dwType;
  82. };
  83. /************************************************************************************************
  84. Macro: DECLARE_SERVICE
  85. Synopsis: declares the static functions that will be used as thread-entry points.
  86. Effects: These functions need to be static because they will be used as thread
  87. entry-points. Since static functions don't have access to the this pointer, it
  88. have to be explicitly passed to them (m_pThis). That's why this code need to be
  89. put in derived classes, otherwise we could have just one CService around at a
  90. time. We can only have one specific CService-derived class at a time.
  91. Arguments: [class_name] - the name of the CService-derived class.
  92. [service_name] - the SCM short service name.
  93. Notes: to be used in CService-derived class declaration.
  94. History: 01/25/2001 - created, Luciano Passuello (lucianop).
  95. ************************************************************************************************/
  96. #define DECLARE_SERVICE(class_name, service_name) \
  97. public: \
  98. static class_name##* m_pThis; \
  99. static void WINAPI service_name##Main(DWORD argc, LPTSTR* argv); \
  100. static void WINAPI service_name##Handler(DWORD dwControl); \
  101. static DWORD WINAPI service_name##WatcherThreadProc(LPVOID lpParameter);
  102. /************************************************************************************************
  103. Macro: IMPLEMENT_SERVICE
  104. Synopsis: implements the static functions that will be used as thread-entry points.
  105. Effects: Using the explicit "this" pointer, it just delegates the work to the member
  106. functions.
  107. Arguments: [class_name] - the name of the CService-derived class.
  108. [service_name] - the SCM short service name.
  109. Notes: to be used in CService-derived class implementation.
  110. History: 01/25/2001 - created, Luciano Passuello (lucianop).
  111. ************************************************************************************************/
  112. #define IMPLEMENT_SERVICE(class_name, service_name) \
  113. class_name##* class_name::m_pThis = NULL; \
  114. void WINAPI class_name::service_name##Main(DWORD argc, LPTSTR* argv) \
  115. { \
  116. m_pThis->ServiceMainMember(argc, argv, (LPHANDLER_FUNCTION)service_name##Handler, \
  117. (LPTHREAD_START_ROUTINE)service_name##WatcherThreadProc); \
  118. } \
  119. void WINAPI class_name::service_name##Handler(DWORD dwControl) \
  120. { \
  121. m_pThis->HandlerMember(dwControl); \
  122. } \
  123. DWORD WINAPI class_name::service_name##WatcherThreadProc(LPVOID /*lpParameter*/) \
  124. { \
  125. return m_pThis->WatcherThreadMemberProc(); \
  126. }
  127. /************************************************************************************************
  128. Macro: BEGIN_SERVICE_MAP, SERVICE_MAP_ENTRY, END_SERVICE_MAP
  129. Synopsis: creates the service map and registers it with the SCM.
  130. Effects: Using the explicit "this" pointer, it just delegates the work to the member
  131. functions.
  132. Arguments: [class_name] - the name of the CService-derived class.
  133. [service_name] - the SCM short service name.
  134. Notes: to be used in the entry-point where the CService-derived class is used.
  135. History: 01/25/2001 - created, Luciano Passuello (lucianop).
  136. ************************************************************************************************/
  137. #define BEGIN_SERVICE_MAP \
  138. SERVICE_TABLE_ENTRY svcTable[] = {
  139. #define SERVICE_MAP_ENTRY(class_name, service_name) \
  140. {_T(#service_name), (LPSERVICE_MAIN_FUNCTION)class_name::service_name##Main},
  141. #define END_SERVICE_MAP \
  142. {NULL, NULL}}; \
  143. StartServiceCtrlDispatcher(svcTable);
  144. /************************************************************************************************
  145. Macro: IMPLEMENT_STATIC_REFERENCE()
  146. Synopsis: assigns the "this" pointer to an explicit m_pThis member.
  147. Effects: makes the static member functions know explicitly about the data in the class,
  148. since static functions don't have access to the "this" pointer.
  149. Notes: to be used in CService-derived constructors.
  150. History: 01/25/2001 - created, Luciano Passuello (lucianop).
  151. ************************************************************************************************/
  152. #define IMPLEMENT_STATIC_REFERENCE() m_pThis = this
  153. // End of file Service.h.