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.

812 lines
21 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. service.cpp
  5. Abstract:
  6. This file provides access to the service control
  7. manager for starting, stopping, adding, and removing
  8. services.
  9. Environment:
  10. WIN32 User Mode
  11. Author:
  12. Vlad Sadovsky (vlads) 17-Apr-1998
  13. --*/
  14. //
  15. // Precompiled header
  16. //
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. //
  20. // Include
  21. //
  22. #include "sti_ci.h"
  23. #include "device.h"
  24. #include <regstr.h>
  25. #include <sti.h>
  26. #include <stiregi.h>
  27. #include <stilib.h>
  28. #include <stidebug.h>
  29. #include <stiapi.h>
  30. #include <stisvc.h>
  31. #include <eventlog.h>
  32. //
  33. // Extern
  34. //
  35. extern HINSTANCE g_hDllInstance;
  36. //
  37. // Prototype
  38. //
  39. DWORD
  40. SetServiceSecurity(
  41. LPTSTR AccountName
  42. );
  43. DLLEXPORT
  44. VOID
  45. CALLBACK
  46. InstallWiaService(
  47. HWND hwnd,
  48. HINSTANCE hinst,
  49. LPTSTR lpszCmdLine,
  50. int nCmdShow
  51. );
  52. //
  53. // Function
  54. //
  55. DWORD
  56. WINAPI
  57. StiServiceInstall(
  58. BOOL UseLocalSystem,
  59. BOOL DemandStart,
  60. LPTSTR lpszUserName,
  61. LPTSTR lpszUserPassword
  62. )
  63. /*++
  64. Routine Description:
  65. Service installation function.
  66. Calls SCM to install STI service, which is running in user security context
  67. Arguments:
  68. Return Value:
  69. None.
  70. --*/
  71. {
  72. DWORD dwError = NOERROR;
  73. SC_HANDLE hSCM = NULL;
  74. SC_HANDLE hService = NULL;
  75. SERVICE_DESCRIPTION ServiceDescroption;
  76. TCHAR szServiceDesc[MAX_PATH];
  77. TCHAR szServiceName[MAX_PATH];
  78. __try {
  79. hSCM = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  80. if (!hSCM) {
  81. dwError = GetLastError();
  82. __leave;
  83. }
  84. //
  85. // If service already exists change startup type, else CreateService.
  86. // NOTE: The service should already be installed - if it isn't, we're
  87. // patching it here because it MUST be installed in order to use WIA.
  88. //
  89. hService = OpenService(
  90. hSCM,
  91. STI_SERVICE_NAME,
  92. SERVICE_ALL_ACCESS
  93. );
  94. if (hService) {
  95. //
  96. // Change the service config parameters. Note: we're only changing StartType
  97. //
  98. if (!ChangeServiceConfig(hService, // handle to WIA service
  99. SERVICE_NO_CHANGE, // Don't change ServiceType
  100. DemandStart ? SERVICE_DISABLED : SERVICE_AUTO_START, // Change StartType
  101. SERVICE_NO_CHANGE, // Don't change ErrorControl
  102. NULL, // Don't change BinaryPathName
  103. NULL, // Don't change LoadOrderGroup
  104. NULL, // Don't change TagId
  105. NULL, // Don't change Dependencies
  106. NULL, // Don't change ServiceStartName
  107. NULL, // Don't change Password
  108. NULL)) { // Don't change DisplayName
  109. dwError = GetLastError();
  110. DebugTrace(TRACE_ERROR,(("StiServiceInstall: ChangeServiceConfig() failed. Err=0x%x.\r\n"), dwError));
  111. __leave;
  112. } // if (!ChangeServiceConfig(...))
  113. } else {
  114. //
  115. // If use local system - set security
  116. //
  117. if (!UseLocalSystem) {
  118. #ifdef LATER
  119. dwError = SetServiceSecurity( lpszUserName );
  120. if (dwError) {
  121. dwError = ERROR_SERVICE_LOGON_FAILED ;
  122. __leave;
  123. }
  124. #endif
  125. }
  126. //
  127. // Load service name.
  128. //
  129. if(0 == LoadString(g_hDllInstance, WiaServiceName, szServiceName, MAX_PATH)){
  130. dwError = GetLastError();
  131. __leave;
  132. } // if(0 != LoadString(g_hDllInstance, WiaServiceName, szServiceName, MAX_PATH))
  133. hService = CreateService(
  134. hSCM,
  135. STI_SERVICE_NAME,
  136. szServiceName,
  137. SERVICE_ALL_ACCESS,
  138. STI_SVC_SERVICE_TYPE,
  139. DemandStart ? SERVICE_DISABLED : SERVICE_AUTO_START,
  140. SERVICE_ERROR_NORMAL,
  141. STI_IMAGE_NAME_SVCHOST,
  142. NULL,
  143. NULL,
  144. STI_SVC_DEPENDENCIES, //STI_SERVICE_DEPENDENCY,
  145. UseLocalSystem ? NULL : lpszUserName,
  146. UseLocalSystem ? NULL : lpszUserPassword
  147. );
  148. if (!hService) {
  149. dwError = GetLastError();
  150. DebugTrace(TRACE_ERROR,(("StiServiceInstall: CreateService() failed. Err=0x%x.\r\n"), dwError));
  151. __leave;
  152. }
  153. //
  154. // Load service description.
  155. //
  156. if(0 != LoadString(g_hDllInstance, WiaServiceDescription, szServiceDesc, MAX_PATH)){
  157. //
  158. // Change service description.
  159. //
  160. ServiceDescroption.lpDescription = (LPTSTR)szServiceDesc;
  161. ChangeServiceConfig2(hService,
  162. SERVICE_CONFIG_DESCRIPTION,
  163. (LPVOID)&ServiceDescroption);
  164. } // if(0 != LoadString(g_hDllInstance, WiaServiceDescription, szServiceDesc, MAX_PATH))
  165. }
  166. //
  167. // Add registry settings for event logging
  168. //
  169. RegisterStiEventSources();
  170. //
  171. // Start service if AUTO_START.
  172. //
  173. if(FALSE == DemandStart){
  174. if(!StartService(hService,0,(LPCTSTR *)NULL)){
  175. dwError = GetLastError();
  176. } // if(!StartService(hService,0,(LPCTSTR *)NULL))
  177. } // if(FALSE == DemandStart)
  178. }
  179. __finally {
  180. //
  181. // Close service handle.
  182. //
  183. if (NULL != hService) {
  184. CloseServiceHandle(hService);
  185. } // if(NULL != hService)
  186. if(NULL != hSCM){
  187. CloseServiceHandle( hSCM );
  188. } // if(NULL != hSCM)
  189. }
  190. return dwError;
  191. } //StiServiceInstall
  192. DWORD
  193. WINAPI
  194. StiServiceRemove(
  195. VOID
  196. )
  197. /*++
  198. Routine Description:
  199. Service removal function. This function calls SCM to remove the STI service.
  200. Arguments:
  201. None.
  202. Return Value:
  203. Return code. Return zero for success
  204. --*/
  205. {
  206. DWORD dwError = NOERROR;
  207. SC_HANDLE hSCM = NULL;
  208. SC_HANDLE hService = NULL;
  209. SERVICE_STATUS ServiceStatus;
  210. UINT uiRetry = 10;
  211. HKEY hkRun;
  212. __try {
  213. hSCM = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  214. if (!hSCM) {
  215. dwError = GetLastError();
  216. DebugTrace(TRACE_ERROR,(("StiServiceRemove: OpenSCManager() failed. Err=0x%x.\r\n"), dwError));
  217. __leave;
  218. }
  219. hService = OpenService(
  220. hSCM,
  221. STI_SERVICE_NAME,
  222. SERVICE_ALL_ACCESS
  223. );
  224. if (!hService) {
  225. dwError = GetLastError();
  226. DebugTrace(TRACE_ERROR,(("StiServiceRemove: OpenService() failed. Err=0x%x.\r\n"), dwError));
  227. __leave;
  228. }
  229. //
  230. // Stop service first
  231. //
  232. if (ControlService( hService, SERVICE_CONTROL_STOP, &ServiceStatus )) {
  233. //
  234. // Wait a little
  235. //
  236. Sleep( STI_STOP_FOR_REMOVE_TIMEOUT );
  237. ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
  238. while( QueryServiceStatus( hService, &ServiceStatus ) &&
  239. (SERVICE_STOP_PENDING == ServiceStatus.dwCurrentState)) {
  240. Sleep( STI_STOP_FOR_REMOVE_TIMEOUT );
  241. if (!uiRetry--) {
  242. break;
  243. }
  244. }
  245. if (ServiceStatus.dwCurrentState != SERVICE_STOPPED) {
  246. dwError = GetLastError();
  247. DebugTrace(TRACE_ERROR,(("StiServiceRemove: Unable to stop service. Err=0x%x.\r\n"), dwError));
  248. if(ServiceStatus.dwCurrentState != ERROR_SERVICE_NOT_ACTIVE) {
  249. __leave;
  250. } // if(ServiceStatus.dwCurrentState != ERROR_SERVICE_NOT_ACTIVE)
  251. } // if (ServiceStatus.dwCurrentState != SERVICE_STOPPED)
  252. } else { // if (ControlService( hService, SERVICE_CONTROL_STOP, &ServiceStatus ))
  253. dwError = GetLastError();
  254. DebugTrace(TRACE_ERROR,(("StiServiceRemove: ControlService() failed. Err=0x%x.\r\n"), dwError));
  255. //
  256. // If service hasn't been started yet, just ignore.
  257. //
  258. if(ERROR_SERVICE_NOT_ACTIVE != dwError){
  259. __leave;
  260. }
  261. }
  262. if (!DeleteService( hService )) {
  263. dwError = GetLastError();
  264. DebugTrace(TRACE_ERROR,(("StiServiceRemove: DeleteService() failed. Err=0x%x.\r\n"), dwError));
  265. __leave;
  266. } else {
  267. dwError = NOERROR;
  268. }
  269. }
  270. __finally {
  271. if(NULL != hService){
  272. CloseServiceHandle( hService );
  273. }
  274. if(NULL != hSCM){
  275. CloseServiceHandle( hSCM );
  276. }
  277. } // __finally
  278. //
  279. // Leftovers from Win9x - remove STI monitor from Run section
  280. //
  281. if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUN, &hkRun) == NO_ERROR) {
  282. RegDeleteValue (hkRun, REGSTR_VAL_MONITOR);
  283. RegCloseKey(hkRun);
  284. }
  285. return dwError;
  286. } // StiServiceRemove
  287. BOOL
  288. SetServiceDependency(
  289. LPTSTR ServiceName,
  290. LPTSTR DependentServiceName
  291. )
  292. {
  293. BOOL rVal = FALSE;
  294. SC_HANDLE hSvcMgr = NULL;
  295. SC_HANDLE hService = NULL;
  296. hSvcMgr = OpenSCManager(
  297. NULL,
  298. NULL,
  299. SC_MANAGER_ALL_ACCESS
  300. );
  301. if (!hSvcMgr) {
  302. goto exit;
  303. }
  304. hService = OpenService(
  305. hSvcMgr,
  306. ServiceName,
  307. SERVICE_ALL_ACCESS
  308. );
  309. if (!hService) {
  310. goto exit;
  311. }
  312. if (!ChangeServiceConfig(
  313. hService, // handle to service
  314. SERVICE_NO_CHANGE, // type of service
  315. SERVICE_NO_CHANGE, // when to start service
  316. SERVICE_NO_CHANGE, // severity if service fails to start
  317. NULL, // pointer to service binary file name
  318. NULL, // pointer to load ordering group name
  319. NULL, // pointer to variable to get tag identifier
  320. DependentServiceName, // pointer to array of dependency names
  321. NULL, // pointer to account name of service
  322. NULL, // pointer to password for service account
  323. NULL // pointer to display name
  324. )) {
  325. goto exit;
  326. }
  327. rVal = TRUE;
  328. exit:
  329. if(NULL != hService){
  330. CloseServiceHandle( hService );
  331. }
  332. if(NULL != hSvcMgr){
  333. CloseServiceHandle( hSvcMgr );
  334. }
  335. return rVal;
  336. }
  337. BOOL
  338. SetServiceStart(
  339. LPTSTR ServiceName,
  340. DWORD StartType
  341. )
  342. {
  343. BOOL rVal = FALSE;
  344. BOOL bRetult = FALSE;
  345. SC_HANDLE hSvcMgr = NULL;
  346. SC_HANDLE hService = NULL;
  347. LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
  348. DWORD dwSize;
  349. hSvcMgr = OpenSCManager(
  350. NULL,
  351. NULL,
  352. SC_MANAGER_ALL_ACCESS
  353. );
  354. if (!hSvcMgr) {
  355. goto exit;
  356. }
  357. hService = OpenService(
  358. hSvcMgr,
  359. ServiceName,
  360. SERVICE_ALL_ACCESS
  361. );
  362. if (!hService) {
  363. goto exit;
  364. }
  365. //
  366. // Query service config to get current state.
  367. //
  368. dwSize = 0;
  369. bRetult = QueryServiceConfig(hService, NULL, dwSize, &dwSize);
  370. if(0 == dwSize){
  371. goto exit;
  372. }
  373. //
  374. // Allocate required memory.
  375. //
  376. pServiceConfig = (LPQUERY_SERVICE_CONFIG)new BYTE[dwSize];
  377. if(NULL == pServiceConfig){
  378. goto exit;
  379. } // if(NULL == pServiceConfig)
  380. if(!QueryServiceConfig(hService, pServiceConfig, dwSize, &dwSize)){
  381. goto exit;
  382. } // if(!QueryServiceConig(hService, pServiceConfig, dwSize, &dwSize))
  383. if(SERVICE_DISABLED == pServiceConfig->dwStartType){
  384. //
  385. // Service is disabled, we can't change the state here.
  386. //
  387. goto exit;
  388. } else if(StartType == pServiceConfig->dwStartType){
  389. //
  390. // We're already in the specified state.
  391. //
  392. rVal = TRUE;
  393. goto exit;
  394. }
  395. if (!ChangeServiceConfig(
  396. hService, // handle to service
  397. SERVICE_NO_CHANGE, // type of service
  398. StartType, // when to start service
  399. SERVICE_NO_CHANGE, // severity if service fails to start
  400. NULL, // pointer to service binary file name
  401. NULL, // pointer to load ordering group name
  402. NULL, // pointer to variable to get tag identifier
  403. NULL, // pointer to array of dependency names
  404. NULL, // pointer to account name of service
  405. NULL, // pointer to password for service account
  406. NULL // pointer to display name
  407. ))
  408. {
  409. goto exit;
  410. }
  411. rVal = TRUE;
  412. exit:
  413. if(NULL != pServiceConfig){
  414. delete[] pServiceConfig;
  415. pServiceConfig = NULL;
  416. } // if(NULL != pServiceConfig)
  417. if(NULL != hService){
  418. CloseServiceHandle( hService );
  419. }
  420. if(NULL != hSvcMgr){
  421. CloseServiceHandle( hSvcMgr );
  422. }
  423. return rVal;
  424. }
  425. BOOL
  426. StartWiaService(
  427. VOID
  428. )
  429. {
  430. BOOL rVal = FALSE;
  431. SC_HANDLE hSvcMgr = NULL;
  432. SC_HANDLE hService = NULL;
  433. SERVICE_STATUS ServiceStatus;
  434. UINT uiRetry = 40; // start time is much larger than stop time.
  435. // Setting 40 sec just to be safe.
  436. DebugTrace(TRACE_PROC_ENTER,(("StartWiaService: Enter... \r\n")));
  437. //
  438. // Open Service Control Manager.
  439. //
  440. hSvcMgr = OpenSCManager(
  441. NULL,
  442. NULL,
  443. SC_MANAGER_ALL_ACCESS
  444. );
  445. if (!hSvcMgr) {
  446. DebugTrace(TRACE_ERROR,(("StartWiaService: ERROR!! OpenSCManager failed. Err=0x%x\n"), GetLastError()));
  447. goto exit;
  448. }
  449. //
  450. // Open WIA service.
  451. //
  452. hService = OpenService(
  453. hSvcMgr,
  454. STI_SERVICE_NAME,
  455. SERVICE_ALL_ACCESS
  456. );
  457. if (!hService) {
  458. DebugTrace(TRACE_ERROR,(("StartWiaService: ERROR!! OpenService failed, re-creating Service Entry (Err=0x%x)\n"), GetLastError()));
  459. //
  460. // Attempt to re-install service
  461. //
  462. InstallWiaService(NULL,
  463. NULL,
  464. NULL,
  465. 0);
  466. Sleep(3000);
  467. //
  468. // Try to open it again
  469. //
  470. hService = OpenService(
  471. hSvcMgr,
  472. STI_SERVICE_NAME,
  473. SERVICE_ALL_ACCESS
  474. );
  475. if (!hService) {
  476. DebugTrace(TRACE_ERROR,(("StartWiaService: ERROR!! OpenService failed for the second time. Err=0x%x\n"), GetLastError()));
  477. goto exit;
  478. }
  479. }
  480. rVal = StartService(hService,
  481. 0,
  482. (LPCTSTR *)NULL);
  483. if(!rVal){
  484. DebugTrace(TRACE_STATUS,(("StartWiaService: ERROR!! StartService failed. Err=0x%x\n"), GetLastError()));
  485. goto exit;
  486. }
  487. //
  488. // Wait for WIA service to really start.
  489. //
  490. Sleep( STI_STOP_FOR_REMOVE_TIMEOUT );
  491. ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
  492. while( QueryServiceStatus( hService, &ServiceStatus ) &&
  493. (SERVICE_START_PENDING == ServiceStatus.dwCurrentState)) {
  494. Sleep( STI_STOP_FOR_REMOVE_TIMEOUT );
  495. if (!uiRetry--) {
  496. break;
  497. }
  498. }
  499. if (ServiceStatus.dwCurrentState != SERVICE_RUNNING) {
  500. DebugTrace(TRACE_ERROR,(("StartWiaService: ERROR!! Hit timeout to start service. Err=0x%x\n"), GetLastError()));
  501. }
  502. exit:
  503. if(NULL != hService){
  504. CloseServiceHandle( hService );
  505. }
  506. if(NULL != hSvcMgr){
  507. CloseServiceHandle( hSvcMgr );
  508. }
  509. DebugTrace(TRACE_PROC_LEAVE,(("StartWiaService: Leaving... Ret=0x%x\n"), rVal));
  510. return rVal;
  511. }
  512. BOOL
  513. StopWiaService(
  514. VOID
  515. )
  516. {
  517. BOOL rVal = FALSE;
  518. SC_HANDLE hSvcMgr = NULL;
  519. SC_HANDLE hService = NULL;
  520. SERVICE_STATUS ServiceStatus;
  521. UINT uiRetry = 10;
  522. DebugTrace(TRACE_PROC_ENTER,(("StopWiaService: Enter... \r\n")));
  523. //
  524. // Open Service Control Manager.
  525. //
  526. hSvcMgr = OpenSCManager(
  527. NULL,
  528. NULL,
  529. SC_MANAGER_ALL_ACCESS
  530. );
  531. if (!hSvcMgr) {
  532. DebugTrace(TRACE_ERROR,(("StopWiaService: ERROR!! OpenSCManager failed. Err=0x%x\n"), GetLastError()));
  533. goto exit;
  534. }
  535. //
  536. // Open WIA service.
  537. //
  538. hService = OpenService(
  539. hSvcMgr,
  540. STI_SERVICE_NAME,
  541. SERVICE_ALL_ACCESS
  542. );
  543. if (!hService) {
  544. DebugTrace(TRACE_ERROR,(("StopWiaService: ERROR!! OpenService failed. Err=0x%x\n"), GetLastError()));
  545. goto exit;
  546. }
  547. //
  548. // Stop WIA service.
  549. //
  550. rVal = ControlService(hService,
  551. SERVICE_CONTROL_STOP,
  552. &ServiceStatus);
  553. if(!rVal){
  554. DebugTrace(TRACE_ERROR,(("StopWiaService: ERROR!! ControlService failed. Err=0x%x\n"), GetLastError()));
  555. } else {
  556. //
  557. // Wait for WIA service really stops.
  558. //
  559. Sleep( STI_STOP_FOR_REMOVE_TIMEOUT );
  560. ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
  561. while( QueryServiceStatus( hService, &ServiceStatus ) &&
  562. (SERVICE_STOP_PENDING == ServiceStatus.dwCurrentState)) {
  563. Sleep( STI_STOP_FOR_REMOVE_TIMEOUT );
  564. if (!uiRetry--) {
  565. break;
  566. }
  567. }
  568. if (ServiceStatus.dwCurrentState != SERVICE_STOPPED) {
  569. DebugTrace(TRACE_ERROR,(("StopWiaService: ERROR!! Hit timeout to stop service. Err=0x%x\n"), GetLastError()));
  570. }
  571. }
  572. exit:
  573. if(NULL != hService){
  574. CloseServiceHandle( hService );
  575. }
  576. if(NULL != hSvcMgr){
  577. CloseServiceHandle( hSvcMgr );
  578. }
  579. DebugTrace(TRACE_PROC_LEAVE,(("StopWiaService: Leaving... Ret=0x%x\n"), rVal));
  580. return rVal;
  581. }
  582. /*
  583. BOOL
  584. SetServiceAccount(
  585. LPTSTR ServiceName,
  586. PSECURITY_INFO SecurityInfo
  587. )
  588. {
  589. BOOL rVal = FALSE;
  590. SC_HANDLE hSvcMgr;
  591. SC_HANDLE hService;
  592. hSvcMgr = OpenSCManager(
  593. NULL,
  594. NULL,
  595. SC_MANAGER_ALL_ACCESS
  596. );
  597. if (!hSvcMgr) {
  598. goto exit;
  599. }
  600. hService = OpenService(
  601. hSvcMgr,
  602. ServiceName,
  603. SERVICE_ALL_ACCESS
  604. );
  605. if (!hService) {
  606. goto exit;
  607. }
  608. if (!ChangeServiceConfig(
  609. hService, // handle to service
  610. SERVICE_NO_CHANGE, // type of service
  611. SERVICE_NO_CHANGE, // when to start service
  612. SERVICE_NO_CHANGE, // severity if service fails to start
  613. NULL, // pointer to service binary file name
  614. NULL, // pointer to load ordering group name
  615. NULL, // pointer to variable to get tag identifier
  616. NULL, // pointer to array of dependency names
  617. SecurityInfo->AccountName, // pointer to account name of service
  618. SecurityInfo->Password, // pointer to password for service account
  619. NULL // pointer to display name
  620. )) {
  621. goto exit;
  622. }
  623. rVal = TRUE;
  624. exit:
  625. CloseServiceHandle( hService );
  626. CloseServiceHandle( hSvcMgr );
  627. return rVal;
  628. }
  629. */