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.

293 lines
10 KiB

  1. #include "stdafx.h"
  2. #include "common.h"
  3. #include "svc.h"
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. //----------------------------------------------------------------------------------------
  10. //Routine Description:
  11. // This routine allocates a buffer for the specified service's configuration parameters,
  12. // and retrieves those parameters into the buffer. The caller is responsible for freeing
  13. // the buffer.
  14. //Remarks:
  15. // The pointer whose address is contained in ServiceConfig is guaranteed to be NULL upon
  16. // return if any error occurred.
  17. //-----------------------------------------------------------------------------------------
  18. DWORD RetrieveServiceConfig(IN SC_HANDLE ServiceHandle,OUT LPQUERY_SERVICE_CONFIG *ServiceConfig)
  19. {
  20. DWORD ServiceConfigSize = 0, Err;
  21. if (NULL == ServiceConfig)
  22. {
  23. return ERROR_INVALID_PARAMETER;
  24. }
  25. *ServiceConfig = NULL;
  26. while(TRUE) {
  27. if(QueryServiceConfig(ServiceHandle, *ServiceConfig, ServiceConfigSize, &ServiceConfigSize))
  28. {
  29. //assert(*ServiceConfig);
  30. return NO_ERROR;
  31. }
  32. else
  33. {
  34. Err = GetLastError();
  35. if(*ServiceConfig) {free(*ServiceConfig);*ServiceConfig=NULL;}
  36. if(Err == ERROR_INSUFFICIENT_BUFFER)
  37. {
  38. // Allocate a larger buffer, and try again.
  39. if(!(*ServiceConfig = (LPQUERY_SERVICE_CONFIG) malloc(ServiceConfigSize)))
  40. {
  41. return ERROR_NOT_ENOUGH_MEMORY;
  42. }
  43. }
  44. else
  45. {
  46. if (ServiceConfig)
  47. {
  48. *ServiceConfig = NULL;
  49. }
  50. return Err;
  51. }
  52. }
  53. }
  54. }
  55. // returns SVC_NOTEXIST if the service does not exist
  56. // returns SVC_DISABLED if the service is disabled
  57. // returns SVC_AUTO_START if the the service is auto start
  58. // returns SVC_MANUAL_START if the the service is not auto start
  59. int GetServiceStartupMode(LPCTSTR lpMachineName, LPCTSTR lpServiceName)
  60. {
  61. int iReturn = SVC_NOTEXIST;
  62. SC_HANDLE hScManager = NULL;
  63. SC_HANDLE hService = NULL;
  64. LPQUERY_SERVICE_CONFIG ServiceConfig=NULL;
  65. // check if lpMachineName starts with \\
  66. // if it doesn't then make sure it does, or it's null (for local machine)
  67. LPTSTR lpNewMachineName = NULL;
  68. if (_tcsicmp(lpMachineName, _T("")) != 0)
  69. {
  70. DWORD dwSize = 0;
  71. // Check if it starts with "\\"
  72. if (_tcsncmp(lpMachineName, _T("\\\\"), 2) == 0)
  73. {
  74. dwSize = (_tcslen(lpMachineName) * sizeof(TCHAR)) + (1 * sizeof(TCHAR));
  75. lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize);
  76. if(lpNewMachineName != NULL)
  77. {
  78. _tcscpy(lpNewMachineName, lpMachineName);
  79. }
  80. }
  81. else
  82. {
  83. dwSize = ((_tcslen(lpMachineName) * sizeof(TCHAR)) + (3 * sizeof(TCHAR)));
  84. lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize);
  85. if(lpNewMachineName != NULL)
  86. {
  87. _tcscpy(lpNewMachineName, _T("\\\\"));
  88. _tcscat(lpNewMachineName, lpMachineName);
  89. }
  90. }
  91. }
  92. if ((hScManager = OpenSCManager(lpNewMachineName, NULL, GENERIC_ALL )) == NULL || (hService = OpenService( hScManager, lpServiceName, GENERIC_ALL )) == NULL )
  93. {
  94. // Failed, or more likely the service doesn't exist
  95. iReturn = SVC_NOTEXIST;
  96. goto IsThisServiceAutoStart_Exit;
  97. }
  98. if(RetrieveServiceConfig(hService, &ServiceConfig) != NO_ERROR)
  99. {
  100. iReturn = SVC_NOTEXIST;
  101. goto IsThisServiceAutoStart_Exit;
  102. }
  103. if(!ServiceConfig)
  104. {
  105. iReturn = SVC_NOTEXIST;
  106. goto IsThisServiceAutoStart_Exit;
  107. }
  108. // SERVICE_AUTO_START Specifies a device driver or service started by the service control manager automatically during system startup.
  109. // SERVICE_BOOT_START Specifies a device driver started by the system loader. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
  110. // SERVICE_DEMAND_START Specifies a device driver or service started by the service control manager when a process calls the StartService function.
  111. // SERVICE_DISABLED Specifies a device driver or service that can no longer be started.
  112. // SERVICE_SYSTEM_START Specifies a device driver started by the IoInitSystem function. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
  113. if (SERVICE_DISABLED == ServiceConfig->dwStartType)
  114. {
  115. iReturn = SVC_DISABLED;
  116. }
  117. else if (SERVICE_DEMAND_START == ServiceConfig->dwStartType)
  118. {
  119. iReturn = SVC_MANUAL_START;
  120. }
  121. else
  122. {
  123. iReturn = SVC_AUTO_START;
  124. }
  125. IsThisServiceAutoStart_Exit:
  126. if (ServiceConfig) {free(ServiceConfig);}
  127. if (hService) {CloseServiceHandle(hService);}
  128. if (hScManager) {CloseServiceHandle(hScManager);}
  129. if (lpNewMachineName) {LocalFree(lpNewMachineName);}
  130. return iReturn;
  131. }
  132. // SERVICE_DISABLED
  133. // SERVICE_AUTO_START
  134. // SERVICE_DEMAND_START
  135. INT ConfigServiceStartupType(LPCTSTR lpMachineName, LPCTSTR lpServiceName, int iNewType)
  136. {
  137. INT err = 0;
  138. SC_HANDLE hScManager = NULL;
  139. SC_HANDLE hService = NULL;
  140. LPQUERY_SERVICE_CONFIG ServiceConfig = NULL;
  141. DWORD dwNewServiceStartupType = 0;
  142. BOOL bDoStuff = FALSE;
  143. // check if lpMachineName starts with \\
  144. // if it doesn't then make sure it does, or it's null (for local machine)
  145. LPTSTR lpNewMachineName = NULL;
  146. if (_tcsicmp(lpMachineName, _T("")) != 0)
  147. {
  148. DWORD dwSize = 0;
  149. // Check if it starts with "\\"
  150. if (_tcsncmp(lpMachineName, _T("\\\\"), 2) == 0)
  151. {
  152. dwSize = (_tcslen(lpMachineName) * sizeof(TCHAR)) + (1 * sizeof(TCHAR));
  153. lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize);
  154. if(lpNewMachineName != NULL)
  155. {
  156. _tcscpy(lpNewMachineName, lpMachineName);
  157. }
  158. }
  159. else
  160. {
  161. dwSize = ((_tcslen(lpMachineName) * sizeof(TCHAR)) + (3 * sizeof(TCHAR)));
  162. lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize);
  163. if(lpNewMachineName != NULL)
  164. {
  165. _tcscpy(lpNewMachineName, _T("\\\\"));
  166. _tcscat(lpNewMachineName, lpMachineName);
  167. }
  168. }
  169. }
  170. do {
  171. if ((hScManager = ::OpenSCManager( lpMachineName, NULL, GENERIC_ALL )) == NULL ||
  172. (hService = ::OpenService( hScManager, lpServiceName, GENERIC_ALL )) == NULL )
  173. {
  174. err = GetLastError();
  175. if (ERROR_SERVICE_DOES_NOT_EXIST != err)
  176. {
  177. }
  178. break;
  179. }
  180. if(RetrieveServiceConfig(hService, &ServiceConfig) != NO_ERROR)
  181. {
  182. err = GetLastError();
  183. break;
  184. }
  185. if(!ServiceConfig)
  186. {
  187. err = GetLastError();
  188. break;
  189. }
  190. // only set this on non-kernel drivers
  191. if ( (ServiceConfig->dwServiceType & SERVICE_WIN32_OWN_PROCESS) || (ServiceConfig->dwServiceType & SERVICE_WIN32_SHARE_PROCESS))
  192. {
  193. // default it incase someone changes code below and logic gets messed up
  194. dwNewServiceStartupType = ServiceConfig->dwStartType;
  195. // if this service is disabled,
  196. // they don't do anything, just leave it alone.
  197. if (!(dwNewServiceStartupType == SERVICE_DISABLED))
  198. {
  199. if (iNewType == SERVICE_DISABLED)
  200. {
  201. dwNewServiceStartupType = SERVICE_DISABLED;
  202. bDoStuff = TRUE;
  203. }
  204. else if (iNewType == SERVICE_AUTO_START)
  205. {
  206. // if the service is already the type we want then don't do jack
  207. // SERVICE_AUTO_START
  208. // SERVICE_BOOT_START
  209. // SERVICE_DEMAND_START
  210. // SERVICE_DISABLED
  211. // SERVICE_SYSTEM_START
  212. if (SERVICE_AUTO_START == dwNewServiceStartupType ||
  213. SERVICE_BOOT_START == dwNewServiceStartupType ||
  214. SERVICE_SYSTEM_START == dwNewServiceStartupType
  215. )
  216. {
  217. // it's already auto start
  218. // we don't have to do anything
  219. }
  220. else
  221. {
  222. dwNewServiceStartupType = SERVICE_AUTO_START;
  223. bDoStuff = TRUE;
  224. }
  225. }
  226. else
  227. {
  228. // we want to make it manual start
  229. // check if it's already that way
  230. if (!(SERVICE_DEMAND_START == dwNewServiceStartupType))
  231. {
  232. dwNewServiceStartupType = SERVICE_DEMAND_START;
  233. bDoStuff = TRUE;
  234. }
  235. }
  236. }
  237. else
  238. {
  239. if (iNewType == SERVICE_AUTO_START)
  240. {
  241. dwNewServiceStartupType = SERVICE_AUTO_START;
  242. bDoStuff = TRUE;
  243. }
  244. else
  245. {
  246. dwNewServiceStartupType = SERVICE_DEMAND_START;
  247. bDoStuff = TRUE;
  248. }
  249. }
  250. if (TRUE == bDoStuff)
  251. {
  252. if ( !::ChangeServiceConfig(hService, SERVICE_NO_CHANGE, dwNewServiceStartupType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL) )
  253. {
  254. err = GetLastError();
  255. break;
  256. }
  257. }
  258. else
  259. {
  260. break;
  261. }
  262. }
  263. else
  264. {
  265. break;
  266. }
  267. } while ( FALSE );
  268. if (ServiceConfig) {free(ServiceConfig);}
  269. if (hService) {CloseServiceHandle(hService);}
  270. if (hScManager) {CloseServiceHandle(hScManager);}
  271. if (lpNewMachineName) {LocalFree(lpNewMachineName);}
  272. return(err);
  273. }