Source code of Windows XP (NT5)
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.

403 lines
9.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1996.
  5. //
  6. // File: main.cxx
  7. //
  8. // Contents: Entry point
  9. //
  10. // History: 10-31-96 Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #ifdef _CHICAGO_
  14. #ifdef UNICODE
  15. #undef UNICODE
  16. #endif
  17. #endif
  18. #include <windows.h>
  19. #include <mstask.h>
  20. #include <msterr.h>
  21. #include <stdio.h>
  22. #include <tchar.h>
  23. #include "tint.hxx"
  24. //
  25. // Forward references
  26. //
  27. HRESULT Init();
  28. VOID Cleanup();
  29. HRESULT StartSchedAgent();
  30. HRESULT EndSchedAgent();
  31. //
  32. // Global variables
  33. //
  34. BOOL g_fSchedAgentRunning = FALSE;
  35. SC_HANDLE g_hSCM, g_hSchedule;
  36. //+---------------------------------------------------------------------------
  37. //
  38. // Function: main
  39. //
  40. // Synopsis: Entry point for DRT.
  41. //
  42. // Arguments: See DisplayUsage().
  43. //
  44. // Returns: 1 on success, 0 on failure
  45. //
  46. // History: 10-31-96 (cribbed)
  47. //
  48. //----------------------------------------------------------------------------
  49. ULONG __cdecl main(int argc, char *argv[])
  50. {
  51. HRESULT hr = S_OK;
  52. hr = StartSchedAgent();
  53. if (FAILED(hr))
  54. {
  55. printf("Failure to start the scheduling agent. hr = %x\n",hr);
  56. EndSchedAgent();
  57. return hr;
  58. }
  59. do
  60. {
  61. hr = Init();
  62. if (hr == E_FAIL)
  63. {
  64. printf("Initialization Failed with %x\n",hr);
  65. break;
  66. };
  67. TestISchedAgent();
  68. TestITask();
  69. TestITaskTrigger();
  70. // wprintf(L"Pausing 3 seconds to allow service to catch up\n");
  71. Sleep(3000);
  72. TestIEnum();
  73. } while (0);
  74. // TestGRT();
  75. Cleanup();
  76. hr = EndSchedAgent();
  77. if (FAILED(hr))
  78. {
  79. printf("Failure to stop the scheduling agent. hr = %x\n",hr);
  80. }
  81. return hr;
  82. }
  83. //+---------------------------------------------------------------------------
  84. //
  85. // Function: Init
  86. //
  87. // Synopsis: Initialize OLE and globals.
  88. //
  89. // Returns: S_OK - initialization successful
  90. // E_* - error logged
  91. //
  92. // Modifies: [g_pITask], [g_pISchedAgent]
  93. //
  94. // History: 10-31-96 cribbed
  95. //
  96. //----------------------------------------------------------------------------
  97. HRESULT Init()
  98. {
  99. HRESULT hr = S_OK;
  100. do
  101. {
  102. hr = CoInitialize(NULL);
  103. if(hr == E_FAIL)
  104. {
  105. break;
  106. }
  107. hr = CoCreateInstance(
  108. CLSID_CTask,
  109. NULL,
  110. CLSCTX_INPROC_SERVER,
  111. IID_ITask,
  112. (void **)&g_pITask);
  113. hr = CoCreateInstance(
  114. CLSID_CSchedulingAgent,
  115. NULL,
  116. CLSCTX_INPROC_SERVER,
  117. IID_ITaskScheduler,
  118. (void **)&g_pISchedAgent);
  119. }
  120. while (0);
  121. return hr;
  122. }
  123. //+---------------------------------------------------------------------------
  124. //
  125. // Function: Cleanup
  126. //
  127. // Synopsis: Do shutdown processing.
  128. //
  129. // History: 10-31-96 created
  130. //
  131. //----------------------------------------------------------------------------
  132. VOID Cleanup()
  133. {
  134. if (g_pITask)
  135. {
  136. g_pITask->Release();
  137. g_pITask = NULL;
  138. }
  139. if (g_pISchedAgent)
  140. {
  141. g_pISchedAgent -> Release();
  142. g_pISchedAgent = NULL;
  143. }
  144. if (g_pIUnknown)
  145. {
  146. g_pIUnknown -> Release();
  147. g_pIUnknown = NULL;
  148. }
  149. if (g_pIEnumTasks)
  150. {
  151. g_pIEnumTasks->Release();
  152. }
  153. CoUninitialize();
  154. }
  155. //+---------------------------------------------------------------------
  156. //
  157. // Function: StartSchedAgent()
  158. //
  159. // Arguments/Returns: nothing
  160. //
  161. // Starts the service IF it is not running. Modifies global flag
  162. // g_fSchedAgentRunning with initial service state.
  163. //
  164. //-----------------------------------------------------------------------
  165. HRESULT StartSchedAgent()
  166. {
  167. HRESULT hr = S_OK;
  168. #ifdef _CHICAGO_
  169. // We are the inferior on Win9x - it has no system service
  170. // daemon, no service control manager, no nothing. We have
  171. // to make extra work for ourselves and fake it with a hidden window.
  172. const char SCHED_CLASS[16] = "SAGEWINDOWCLASS";
  173. const char SCHED_TITLE[24] = "SYSTEM AGENT COM WINDOW";
  174. const char SCHED_SERVICE_APP_NAME[11] = "mstask.exe";
  175. // is it running?
  176. HWND hwnd = FindWindow(SCHED_CLASS, SCHED_TITLE);
  177. if (hwnd != NULL)
  178. {
  179. // Already up
  180. g_fSchedAgentRunning = TRUE;
  181. return S_OK;
  182. }
  183. else
  184. {
  185. hr = GetLastError();
  186. g_fSchedAgentRunning = FALSE;
  187. }
  188. // Start me up...
  189. STARTUPINFO sui;
  190. PROCESS_INFORMATION pi;
  191. ZeroMemory(&sui, sizeof(sui));
  192. sui.cb = sizeof(STARTUPINFO);
  193. char szApp[MAX_PATH];
  194. LPSTR pszPath;
  195. DWORD dwRet = SearchPath(NULL,
  196. SCHED_SERVICE_APP_NAME,
  197. NULL, MAX_PATH, szApp, &pszPath);
  198. if (dwRet == 0)
  199. return GetLastError();
  200. BOOL fRet = CreateProcess(szApp, NULL, NULL, NULL, FALSE,
  201. CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
  202. NULL, NULL, &sui, &pi);
  203. if (fRet == FALSE)
  204. return GetLastError();
  205. CloseHandle(pi.hProcess);
  206. CloseHandle(pi.hThread);
  207. return S_OK;
  208. #else
  209. // It's NT! Do the smart thing and use a service control manager
  210. LPTSTR lpszMachineName;
  211. SERVICE_STATUS svcStatus;
  212. lpszMachineName = new TCHAR[9999];
  213. hr = GetEnvironmentVariable(_T("COMPUTERNAME"),lpszMachineName, 9999);
  214. if (FAILED(hr))
  215. {
  216. printf("Failed to get machine name\n");
  217. return hr;
  218. }
  219. g_hSCM = OpenSCManager(lpszMachineName, NULL,
  220. SC_MANAGER_CONNECT | STANDARD_RIGHTS_REQUIRED |
  221. GENERIC_READ | GENERIC_EXECUTE);
  222. if (g_hSCM == NULL)
  223. {
  224. hr = (HRESULT)GetLastError();
  225. printf("Service control manager handle not obtained. hr = %x\n",hr);
  226. return hr;
  227. }
  228. delete lpszMachineName;
  229. g_hSchedule = OpenService(g_hSCM, _T("Schedule"),
  230. SERVICE_INTERROGATE | SERVICE_STOP | SERVICE_QUERY_STATUS |
  231. SERVICE_START | STANDARD_RIGHTS_REQUIRED);
  232. if (g_hSchedule == NULL)
  233. {
  234. hr = (HRESULT)GetLastError();
  235. printf("Schedule Service handle not obtained. hr = %x\n",hr);
  236. return hr;
  237. }
  238. if (QueryServiceStatus(g_hSchedule, &svcStatus) == 0)
  239. {
  240. hr = (HRESULT)GetLastError();
  241. printf("Failed to get service status, hr = %x\n",hr);
  242. return hr;
  243. }
  244. if (svcStatus.dwCurrentState == SERVICE_RUNNING)
  245. {
  246. g_fSchedAgentRunning = TRUE;
  247. return S_OK;
  248. }
  249. else
  250. g_fSchedAgentRunning = FALSE;
  251. // Start the service
  252. if (StartService(g_hSchedule, 0, NULL) == 0)
  253. {
  254. printf("Failed to start the service!\n");
  255. hr = (HRESULT)GetLastError();
  256. return hr;
  257. }
  258. // Got to wait for the service to fully start, though
  259. // or things will fail.
  260. int nCounter = 0;
  261. while (svcStatus.dwCurrentState != SERVICE_RUNNING)
  262. {
  263. QueryServiceStatus(g_hSchedule, &svcStatus);
  264. Sleep(250);
  265. nCounter++;
  266. if (nCounter > 80)
  267. {
  268. // It's been 20 seconds and we're still not
  269. // running. Fail out.
  270. printf("FAILURE - unable to start service after 20 seconds.");
  271. return E_FAIL;
  272. }
  273. }
  274. return S_OK;
  275. #endif
  276. }
  277. //+----------------------------------------------------------------
  278. //
  279. // Funtion: EndSchedAgent()
  280. //
  281. // No arguments, but depends on globals g_hSCM, g_hSchedule, and
  282. // g_fSchedAgentRunning
  283. //
  284. //-----------------------------------------------------------------
  285. HRESULT EndSchedAgent()
  286. {
  287. HRESULT hr = S_OK;
  288. #ifdef _CHICAGO_
  289. // Memphis/Win9x. No support for an SCM, must use cheap window tricks
  290. // to spoof around it.
  291. const char SCHED_CLASS[16] = "SAGEWINDOWCLASS";
  292. const char SCHED_TITLE[24] = "SYSTEM AGENT COM WINDOW";
  293. if (! g_fSchedAgentRunning)
  294. {
  295. // Service was stopped, so we must stop it.
  296. HWND hwnd = FindWindow(SCHED_CLASS, SCHED_TITLE);
  297. if (hwnd)
  298. {
  299. // It is up and going. Nuke it.
  300. SendMessage(hwnd, (WM_USER + 201), NULL, NULL);
  301. }
  302. }
  303. #else
  304. // NT. SCM is cool.
  305. SERVICE_STATUS svcStatus;
  306. if (! g_fSchedAgentRunning)
  307. {
  308. // Service was stopped.
  309. if (ControlService(g_hSchedule, SERVICE_CONTROL_STOP,
  310. &svcStatus) == 0)
  311. {
  312. hr = (HRESULT)GetLastError();
  313. printf("Failed to stop the service - hr = %x\n",hr);
  314. }
  315. }
  316. if (g_hSchedule)
  317. {
  318. if (CloseServiceHandle(g_hSchedule) == 0)
  319. {
  320. hr = (HRESULT)GetLastError();
  321. printf("Failed to close service handle - hr = %x\n",hr);
  322. }
  323. }
  324. if (g_hSCM)
  325. {
  326. if (CloseServiceHandle(g_hSCM) == 0)
  327. {
  328. hr = (HRESULT)GetLastError();
  329. printf("Failed to close service controller handle - hr = %x\n",hr);
  330. }
  331. }
  332. #endif
  333. return hr;
  334. }