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.

575 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. addsrvc.c
  5. Abstract:
  6. Create the file replication service (ntfrs):
  7. addsrvc <full path to exe>
  8. Author:
  9. Billy J. Fuller 2-Sep-1997
  10. Environment
  11. User mode winnt
  12. --*/
  13. #include <windows.h>
  14. #include <string.h>
  15. #include <winsvc.h>
  16. #include <stdio.h>
  17. #include <config.h>
  18. #include <malloc.h>
  19. //
  20. // Lower case
  21. //
  22. #define FRS_WCSLWR(_s_) \
  23. { \
  24. if (_s_) { \
  25. _wcslwr(_s_); \
  26. } \
  27. }
  28. SC_HANDLE
  29. OpenServiceHandle(
  30. IN PWCHAR ServiceName
  31. )
  32. /*++
  33. Routine Description:
  34. Open a service on a machine.
  35. Arguments:
  36. ServiceName - the service to open
  37. Return Value:
  38. The service's handle or NULL.
  39. --*/
  40. {
  41. SC_HANDLE SCMHandle;
  42. SC_HANDLE ServiceHandle;
  43. //
  44. // Attempt to contact the SC manager.
  45. //
  46. SCMHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
  47. if (SCMHandle == NULL) {
  48. printf("Couldn't open service control manager; error %d\n",
  49. GetLastError());
  50. return NULL;
  51. }
  52. //
  53. // Contact the service.
  54. //
  55. ServiceHandle = OpenService(SCMHandle, ServiceName, SERVICE_ALL_ACCESS);
  56. CloseServiceHandle(SCMHandle);
  57. return ServiceHandle;
  58. }
  59. DWORD
  60. FrsGetServiceState(
  61. IN PWCHAR ServiceName
  62. )
  63. /*++
  64. Routine Description:
  65. Return the service's state
  66. Arguments:
  67. ServiceName - the service to check
  68. Return Value:
  69. The service's state or 0 if the state could not be obtained.
  70. --*/
  71. {
  72. BOOL Status;
  73. SC_HANDLE ServiceHandle;
  74. SERVICE_STATUS ServiceStatus;
  75. //
  76. // Open the service.
  77. //
  78. ServiceHandle = OpenServiceHandle(ServiceName);
  79. if (ServiceHandle == NULL)
  80. return 0;
  81. //
  82. // Get the service's status
  83. //
  84. if (!ControlService(ServiceHandle,
  85. SERVICE_CONTROL_INTERROGATE,
  86. &ServiceStatus)) {
  87. CloseServiceHandle(ServiceHandle);
  88. return GetLastError();
  89. }
  90. return ServiceStatus.dwCurrentState;
  91. }
  92. VOID
  93. FrsWaitServicePending(
  94. IN PWCHAR ServiceName,
  95. IN ULONG IntervalMS,
  96. IN ULONG TotalMS
  97. )
  98. /*++
  99. Routine Description:
  100. Wait for a service to leave any "pending" state. Check every so often,
  101. up to a maximum time.
  102. Arguments:
  103. ServiceName - Name of the NT service to interrogate.
  104. IntervalMS - Check every IntervalMS milliseconds.
  105. TotalMS - Stop checking after this long.
  106. Return Value:
  107. TRUE - Service is not in a pending state
  108. FALSE - Service is still in a pending state
  109. --*/
  110. {
  111. DWORD State;
  112. do {
  113. State = FrsGetServiceState(ServiceName);
  114. if (State == 0)
  115. return;
  116. switch (State) {
  117. case ERROR_IO_PENDING:
  118. printf("IO is pending for %ws; waiting\n", ServiceName);
  119. break;
  120. case SERVICE_START_PENDING:
  121. printf("Start is pending for %ws; waiting\n", ServiceName);
  122. break;
  123. case SERVICE_STOP_PENDING:
  124. printf("Stop is pending for %ws; waiting\n", ServiceName);
  125. break;
  126. case SERVICE_CONTINUE_PENDING:
  127. printf("Continue is pending for %ws; waiting\n", ServiceName);
  128. break;
  129. case SERVICE_PAUSE_PENDING:
  130. printf("Pause is pending for %ws; waiting\n", ServiceName);
  131. break;
  132. default:;
  133. return;
  134. }
  135. Sleep(IntervalMS);
  136. } while ((TotalMS -= IntervalMS) > 0);
  137. }
  138. VOID
  139. FrsStartService(
  140. IN PWCHAR ServiceName
  141. )
  142. /*++
  143. Routine Description:
  144. Start a service on a machine.
  145. Arguments:
  146. ServiceName - the service to start
  147. Return Value:
  148. None.
  149. --*/
  150. {
  151. SC_HANDLE ServiceHandle;
  152. //
  153. // Open the service.
  154. //
  155. ServiceHandle = OpenServiceHandle(ServiceName);
  156. if (ServiceHandle == NULL) {
  157. printf("Couldn't open %ws\n", ServiceName);
  158. return;
  159. }
  160. //
  161. // Start the service
  162. //
  163. if (!StartService(ServiceHandle, 0, NULL)) {
  164. printf("Couldn't start %ws; error %d\n",
  165. ServiceName, GetLastError());
  166. CloseServiceHandle(ServiceHandle);
  167. return;
  168. }
  169. CloseServiceHandle(ServiceHandle);
  170. printf("Started %ws\n", ServiceName);
  171. }
  172. VOID
  173. FrsStopService(
  174. IN PWCHAR ServiceName
  175. )
  176. /*++
  177. Routine Description:
  178. Stop a service on a machine.
  179. Arguments:
  180. ServiceName - the service to stop
  181. Return Value:
  182. None.
  183. --*/
  184. {
  185. BOOL Status;
  186. SC_HANDLE ServiceHandle;
  187. SERVICE_STATUS ServiceStatus;
  188. //
  189. // Open the service.
  190. //
  191. ServiceHandle = OpenServiceHandle(ServiceName);
  192. if (ServiceHandle == NULL) {
  193. printf("Couldn't open %ws\n", ServiceName);
  194. return;
  195. }
  196. //
  197. // Stop the service
  198. //
  199. Status = ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus);
  200. if (!Status) {
  201. printf("Couldn't stop %ws; error %d\n",
  202. ServiceName, GetLastError());
  203. CloseServiceHandle(ServiceHandle);
  204. return;
  205. }
  206. CloseServiceHandle(ServiceHandle);
  207. printf("Stopped %ws\n", ServiceName);
  208. }
  209. VOID
  210. FrsPauseService(
  211. IN PWCHAR ServiceName
  212. )
  213. /*++
  214. Routine Description:
  215. Pause a service on a machine.
  216. Arguments:
  217. ServiceName - the service to pause
  218. Return Value:
  219. None.
  220. --*/
  221. {
  222. BOOL Status;
  223. SC_HANDLE ServiceHandle;
  224. SERVICE_STATUS ServiceStatus;
  225. //
  226. // Open the service.
  227. //
  228. ServiceHandle = OpenServiceHandle(ServiceName);
  229. if (ServiceHandle == NULL) {
  230. printf("Couldn't open %ws\n", ServiceName);
  231. return;
  232. }
  233. //
  234. // Stop the service
  235. //
  236. Status = ControlService(ServiceHandle, SERVICE_CONTROL_PAUSE, &ServiceStatus);
  237. if (!Status) {
  238. printf("Couldn't pause %ws; error %d\n",
  239. ServiceName, GetLastError());
  240. CloseServiceHandle(ServiceHandle);
  241. return;
  242. }
  243. CloseServiceHandle(ServiceHandle);
  244. printf("Paused %ws\n", ServiceName);
  245. }
  246. VOID
  247. FrsContinueService(
  248. IN PWCHAR ServiceName
  249. )
  250. /*++
  251. Routine Description:
  252. Continue a service on a machine.
  253. Arguments:
  254. ServiceName - the service to continue
  255. Return Value:
  256. None.
  257. --*/
  258. {
  259. BOOL Status;
  260. SC_HANDLE ServiceHandle;
  261. SERVICE_STATUS ServiceStatus;
  262. //
  263. // Open the service.
  264. //
  265. ServiceHandle = OpenServiceHandle(ServiceName);
  266. if (ServiceHandle == NULL) {
  267. printf("Couldn't open %ws\n", ServiceName);
  268. return;
  269. }
  270. //
  271. // Stop the service
  272. //
  273. Status = ControlService(ServiceHandle, SERVICE_CONTROL_CONTINUE, &ServiceStatus);
  274. if (!Status) {
  275. printf("Couldn't continue %ws; error %d\n",
  276. ServiceName, GetLastError());
  277. CloseServiceHandle(ServiceHandle);
  278. return;
  279. }
  280. CloseServiceHandle(ServiceHandle);
  281. printf("Continued %ws\n", ServiceName);
  282. }
  283. VOID
  284. FrsDeleteService(
  285. IN PWCHAR ServiceName
  286. )
  287. /*++
  288. Routine Description:
  289. Delete a service on a machine.
  290. Arguments:
  291. ServiceName - the service to delete
  292. Return Value:
  293. None.
  294. --*/
  295. {
  296. SC_HANDLE ServiceHandle;
  297. // FrsWaitServicePending(ServiceName, 5000, 20000);
  298. //
  299. // Open the service
  300. //
  301. ServiceHandle = OpenServiceHandle(ServiceName);
  302. if (ServiceHandle == NULL) {
  303. return;
  304. }
  305. //
  306. // Delete the service
  307. //
  308. if (!DeleteService(ServiceHandle) &&
  309. GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) {
  310. printf("Couldn't delete %ws; error %d\n",
  311. ServiceName,
  312. GetLastError());
  313. }
  314. CloseServiceHandle(ServiceHandle);
  315. printf("Deleted %ws\n", ServiceName);
  316. }
  317. VOID
  318. FrsCreateService(
  319. IN PWCHAR ServiceName,
  320. IN PWCHAR PathName,
  321. IN PWCHAR DisplayName
  322. )
  323. /*++
  324. Routine Description:
  325. If the service doesn't exist on the machine, create it.
  326. Arguments:
  327. ServiceName - the service to create
  328. PathName - the path of the service's .exe
  329. DisplayName - the display name of the service
  330. Return Value:
  331. TRUE - Service was created (or already existed)
  332. FALSE - Service was not created and didn't already exist
  333. --*/
  334. {
  335. SC_HANDLE SCMHandle;
  336. SC_HANDLE ServiceHandle;
  337. //
  338. // Attempt to contact the SC manager.
  339. //
  340. SCMHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
  341. if (SCMHandle == NULL) {
  342. printf("Couldn't open service control manager; error %d\n",
  343. GetLastError());
  344. return;
  345. }
  346. //
  347. // Create the service
  348. //
  349. ServiceHandle = CreateService(
  350. SCMHandle,
  351. ServiceName,
  352. DisplayName,
  353. SERVICE_ALL_ACCESS, // XXX is this right!!!
  354. SERVICE_WIN32_OWN_PROCESS,
  355. SERVICE_DEMAND_START,
  356. SERVICE_ERROR_NORMAL,
  357. PathName,
  358. NULL, // No load order group
  359. NULL, // No Tag Id required
  360. L"eventlog\0rpcss\0",
  361. NULL,
  362. NULL); // No password
  363. if (ServiceHandle == NULL) {
  364. FrsWaitServicePending(ServiceName, 5000, 20000);
  365. //
  366. // Create the service
  367. //
  368. ServiceHandle = CreateService(SCMHandle,
  369. ServiceName,
  370. DisplayName,
  371. SERVICE_ALL_ACCESS,
  372. SERVICE_WIN32_OWN_PROCESS,
  373. SERVICE_DEMAND_START,
  374. SERVICE_ERROR_NORMAL,
  375. PathName,
  376. NULL,
  377. NULL,
  378. L"eventlog\0rpcss\0",
  379. NULL,
  380. NULL);
  381. }
  382. CloseServiceHandle(SCMHandle);
  383. //
  384. // Couldn't create the service
  385. //
  386. if (ServiceHandle == NULL) {
  387. printf("Couldn't create %ws; error %d\n",
  388. ServiceName, GetLastError());
  389. } else {
  390. CloseServiceHandle(ServiceHandle);
  391. printf("Created %ws\n", ServiceName);
  392. }
  393. }
  394. PWCHAR *
  395. ConvertArgv(
  396. DWORD argc,
  397. PCHAR *argv
  398. )
  399. /*++
  400. Routine Description:
  401. Convert short char argv into wide char argv
  402. Arguments:
  403. argc - From main
  404. argv - From main
  405. Return Value:
  406. Address of the new argv
  407. --*/
  408. {
  409. PWCHAR *newargv;
  410. newargv = malloc((argc + 1) * sizeof(PWCHAR));
  411. newargv[argc] = NULL;
  412. while (argc-- >= 1) {
  413. newargv[argc] = malloc((strlen(argv[argc]) + 1) * sizeof(WCHAR));
  414. wsprintf(newargv[argc], L"%hs", argv[argc]);
  415. FRS_WCSLWR(newargv[argc]);
  416. }
  417. return newargv;
  418. }
  419. VOID
  420. _cdecl
  421. main(
  422. IN DWORD argc,
  423. IN PCHAR *argv
  424. )
  425. /*++
  426. Routine Description:
  427. Create the file replication service:
  428. addsrvc <full path to exe>
  429. Arguments:
  430. None.
  431. Return Value:
  432. None.
  433. --*/
  434. {
  435. DWORD i;
  436. PWCHAR *NewArgv;
  437. if (argc == 1) {
  438. printf("service create [full path to exe]\n");
  439. printf("service delete\n");
  440. printf("service start\n");
  441. printf("service stop\n");
  442. printf("service pause\n");
  443. printf("service continue\n");
  444. return;
  445. }
  446. NewArgv = ConvertArgv(argc, argv);
  447. //
  448. // CLI overrides registry
  449. //
  450. for (i = 1; i < argc; ++i) {
  451. //
  452. // create
  453. //
  454. if (wcsstr(NewArgv[i], L"create")) {
  455. FrsDeleteService(SERVICE_NAME);
  456. FrsCreateService(SERVICE_NAME,
  457. NewArgv[2],
  458. SERVICE_LONG_NAME);
  459. break;
  460. //
  461. // delete
  462. //
  463. } else if (wcsstr(NewArgv[i], L"delete")) {
  464. FrsDeleteService(SERVICE_NAME);
  465. break;
  466. //
  467. // start
  468. //
  469. } else if (wcsstr(NewArgv[i], L"start")) {
  470. FrsStartService(SERVICE_NAME);
  471. break;
  472. //
  473. // stop
  474. //
  475. } else if (wcsstr(NewArgv[i], L"stop")) {
  476. FrsStopService(SERVICE_NAME);
  477. break;
  478. //
  479. // pause
  480. //
  481. } else if (wcsstr(NewArgv[i], L"pause")) {
  482. FrsPauseService(SERVICE_NAME);
  483. break;
  484. //
  485. // continue
  486. //
  487. } else if (wcsstr(NewArgv[i], L"continue")) {
  488. FrsContinueService(SERVICE_NAME);
  489. break;
  490. //
  491. // unknown
  492. //
  493. } else {
  494. printf("Don't understand \"%ws\"\n", NewArgv[i]);
  495. }
  496. }
  497. }