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.

239 lines
7.7 KiB

  1. /************************************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name: ServiceSetup.cpp.
  4. Abstract: Implements the CServiceSetup class. See ServiceSetup.h for details.
  5. Notes:
  6. History: 01/24/2001 - created, Luciano Passuello (lucianop).
  7. ************************************************************************************************/
  8. #include "stdafx.h"
  9. #include "ServiceSetup.h"
  10. /************************************************************************************************
  11. Member: CServiceSetup::CServiceSetup, constructor, public.
  12. Synopsis: Copies initialization data to member variables.
  13. Arguments: [szServiceName] - the SCM short name for the service.
  14. This will identify uniquely each service in the system.
  15. [szDisplayName] - the name that's displayed for the users in the SCM.
  16. Notes: The display name would only be necessary in the install case. May change that
  17. later.
  18. History: 01/24/2001 - created, Luciano Passuello (lucianop).
  19. ************************************************************************************************/
  20. CServiceSetup::CServiceSetup(LPCTSTR szServiceName, LPCTSTR szDisplay)
  21. {
  22. ASSERT(!(NULL == szServiceName));
  23. ASSERT(!(NULL == szDisplay));
  24. _tcsncpy(m_szServiceName, szServiceName, _MAX_PATH-1);
  25. _tcsncpy(m_szDisplayName, szDisplay,_MAX_PATH-1);
  26. m_szServiceName[_MAX_PATH-1]=0;
  27. m_szDisplayName[_MAX_PATH-1]=0;
  28. }
  29. /************************************************************************************************
  30. Member: CServiceSetup::Install, public.
  31. Synopsis: Install service in the SCM.
  32. Arguments: [szDescription] - the service description as it will appear in the SCM.
  33. [dwType, dwStart, lpDepends, lpName, lpPassword] - see CreateService API call
  34. documentation.
  35. Notes: If the service is already installed, Install() does nothing. It must be
  36. removed first to be reinstalled.
  37. History: 01/24/2001 - created, Luciano Passuello (lucianop).
  38. ************************************************************************************************/
  39. void CServiceSetup::Install(LPCTSTR szDescription, DWORD dwType, DWORD dwStart,
  40. LPCTSTR lpDepends, LPCTSTR lpName, LPCTSTR lpPassword)
  41. {
  42. SC_HANDLE hSCM = NULL;
  43. SC_HANDLE hService = NULL;
  44. if(IsInstalled())
  45. {
  46. return;
  47. }
  48. hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
  49. if(!hSCM)
  50. {
  51. ErrorPrinter(_T("OpenSCManager"));
  52. goto cleanup;
  53. }
  54. // get the service executable path (this executable)
  55. TCHAR szFilePath[_MAX_PATH+1];
  56. szFilePath[_MAX_PATH]=0;
  57. if(0==::GetModuleFileName(NULL, szFilePath, _MAX_PATH))
  58. {
  59. goto cleanup;
  60. }
  61. hService = CreateService(hSCM, m_szServiceName, m_szDisplayName, SERVICE_ALL_ACCESS, dwType, dwStart, SERVICE_ERROR_NORMAL,
  62. szFilePath, NULL, NULL, lpDepends, lpName, lpPassword);
  63. if (!hService)
  64. {
  65. ErrorPrinter(_T("CreateService"));
  66. goto cleanup;
  67. }
  68. else
  69. {
  70. _tprintf(_T("%s Created\n"), m_szServiceName);
  71. }
  72. // change service description
  73. SERVICE_DESCRIPTION sd;
  74. sd.lpDescription = const_cast<LPTSTR>(szDescription);
  75. ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, static_cast<LPVOID>(&sd));
  76. SERVICE_FAILURE_ACTIONS sfa;
  77. SC_ACTION saArray[3];
  78. saArray[0].Type=SC_ACTION_RESTART;
  79. saArray[0].Delay=60000;//One minute in milliseconds
  80. saArray[1].Type=SC_ACTION_RESTART;
  81. saArray[1].Delay=60000;//One minute in milliseconds
  82. saArray[2].Type=SC_ACTION_NONE;
  83. saArray[2].Delay=0;
  84. sfa.dwResetPeriod=24*60*60;//One day in seconds
  85. sfa.lpRebootMsg=NULL;
  86. sfa.lpCommand=NULL;
  87. sfa.cActions=3;
  88. sfa.lpsaActions=saArray;
  89. ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &sfa);
  90. cleanup:
  91. if (hService)
  92. {
  93. CloseServiceHandle(hService);
  94. }
  95. if (hSCM)
  96. {
  97. CloseServiceHandle(hSCM);
  98. }
  99. return;
  100. }
  101. /************************************************************************************************
  102. Member: CServiceSetup::Remove, public.
  103. Synopsis: Unregisters the service in the SCM.
  104. Arguments: [bForce] - if the service is running, force it to stop and then remove.
  105. Notes:
  106. History: 01/24/2001 - created, Luciano Passuello (lucianop).
  107. ************************************************************************************************/
  108. void CServiceSetup::Remove(bool bForce)
  109. {
  110. SC_HANDLE hSCM = NULL;
  111. SC_HANDLE hService = NULL;
  112. BOOL bSuccess = FALSE;
  113. hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
  114. if (!hSCM)
  115. {
  116. ErrorPrinter(_T("OpenSCManager"));
  117. return;
  118. }
  119. hService = ::OpenService(hSCM, m_szServiceName, DELETE | SERVICE_STOP);
  120. if (!hService)
  121. {
  122. ErrorPrinter(_T("OpenService"));
  123. goto cleanup;
  124. }
  125. // force the service to stop
  126. if(TRUE == bForce)
  127. {
  128. SERVICE_STATUS status;
  129. ::ControlService(hService, SERVICE_CONTROL_STOP, &status);
  130. _tprintf(_T("%s stopped\n"), m_szServiceName);
  131. Sleep(2000);
  132. }
  133. bSuccess = ::DeleteService(hService);
  134. if(bSuccess)
  135. {
  136. _tprintf(_T("%s removed\n"), m_szServiceName);
  137. }
  138. else
  139. {
  140. ErrorPrinter(_T("DeleteService"));
  141. }
  142. cleanup:
  143. if (hService)
  144. {
  145. CloseServiceHandle(hService);
  146. }
  147. if(hSCM)
  148. {
  149. CloseServiceHandle(hSCM);
  150. }
  151. return;
  152. }
  153. /************************************************************************************************
  154. Member: CServiceSetup::IsInstalled, public.
  155. Synopsis: Checks for the existence of the service in the system.
  156. Notes:
  157. History: 01/24/2001 - created, Luciano Passuello (lucianop).
  158. ************************************************************************************************/
  159. bool CServiceSetup::IsInstalled()
  160. {
  161. bool bInstalled = false;
  162. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
  163. if(NULL != hSCM)
  164. {
  165. // try to open the service for configuration, if it succeeds, then the service exists
  166. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_QUERY_CONFIG);
  167. if(NULL != hService)
  168. {
  169. bInstalled = true;
  170. ::CloseServiceHandle(hService);
  171. }
  172. ::CloseServiceHandle(hSCM);
  173. }
  174. return bInstalled;
  175. }
  176. /************************************************************************************************
  177. Member: CServiceSetup::ErrorPrinter, public.
  178. Synopsis: Message printing for class error handling.
  179. Arguments: [bForce] - if the service is running, force it to stop and then remove.
  180. Notes: ISSUE: Standarlize all error printing and handling among classes.
  181. History: 01/24/2001 - created, Luciano Passuello (lucianop).
  182. ************************************************************************************************/
  183. DWORD CServiceSetup::ErrorPrinter(LPCTSTR psz, DWORD dwErr)
  184. {
  185. LPVOID lpvMsgBuf=NULL;
  186. if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, dwErr,
  187. MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpvMsgBuf, 0, 0))
  188. {
  189. _tprintf(_T("%s failed: Unknown error %x\n"), psz, dwErr);
  190. }
  191. else
  192. {
  193. _tprintf(_T("%s failed: %s\n"), psz, (LPTSTR)lpvMsgBuf);
  194. }
  195. LocalFree(lpvMsgBuf);
  196. return dwErr;
  197. }
  198. // End of file ServiceSetup.cpp.