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.

347 lines
10 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. UploadManager.cpp
  5. Abstract:
  6. This file contains the initialization portion of the Upload Manager
  7. Revision History:
  8. Davide Massarenti (Dmassare) 04/15/99
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. #include <initguid.h>
  13. #include <mstask.h> // for task scheduler apis
  14. #include <msterr.h>
  15. #include "UploadManager_i.c"
  16. /////////////////////////////////////////////////////////////////////////////
  17. #define UL_RESCHEDULE_PERIOD (30*60) // Every thirty minutes.
  18. #define SECONDS_IN_A_DAY (24 * 60 * 60)
  19. #define SECONDS_IN_A_MINUTE ( 60)
  20. #define MINUTES_IN_A_DAY (24 * 60 )
  21. HRESULT Handle_TaskScheduler( bool fActivate )
  22. {
  23. __ULT_FUNC_ENTRY( "Handle_TaskScheduler" );
  24. HRESULT hr;
  25. WCHAR rgFileName[MAX_PATH];
  26. WCHAR rgTaskName[MAX_PATH];
  27. WCHAR rgComment [MAX_PATH];
  28. CComBSTR bstrFileName;
  29. CComBSTR bstrTaskName;
  30. CComBSTR bstrComments;
  31. CComPtr<ITaskScheduler> pTaskScheduler;
  32. CComPtr<ITask> pTask;
  33. CComPtr<IScheduledWorkItem> pScheduledWorkItem;
  34. //
  35. // First create the task scheduler.
  36. //
  37. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void**)&pTaskScheduler ));
  38. //
  39. // Get our complete filename -- needed to create a task in the task scheduler.
  40. //
  41. __MPC_EXIT_IF_CALL_RETURNS_ZERO(hr, ::GetModuleFileNameW( NULL, rgFileName, MAX_PATH ));
  42. //
  43. // Load localized strings.
  44. //
  45. ::LoadStringW( _Module.GetResourceInstance(), IDS_TASKNAME, rgTaskName, MAXSTRLEN(rgTaskName) );
  46. ::LoadStringW( _Module.GetResourceInstance(), IDS_COMMENT , rgComment , MAXSTRLEN(rgComment ) );
  47. bstrFileName = rgFileName;
  48. bstrTaskName = rgTaskName;
  49. bstrComments = rgComment;
  50. hr = pTaskScheduler->Delete( bstrTaskName );
  51. if(FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  52. {
  53. __MPC_TRACE_HRESULT(hr);
  54. __MPC_FUNC_LEAVE;
  55. }
  56. if(fActivate)
  57. {
  58. //
  59. // Create a new task and set its app name and parameters.
  60. //
  61. __MPC_EXIT_IF_METHOD_FAILS(hr, pTaskScheduler->NewWorkItem( bstrTaskName, CLSID_CTask, IID_ITask, (IUnknown**)&pTask ));
  62. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->QueryInterface( IID_IScheduledWorkItem, (void **)&pScheduledWorkItem ));
  63. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->SetApplicationName( bstrFileName ));
  64. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->SetParameters ( CComBSTR( L"-WakeUp" ) ));
  65. //
  66. // Set a NULL account information, so the task will be run as SYSTEM.
  67. //
  68. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetAccountInformation( L"", NULL ));
  69. //
  70. // Set the comment, so we know how this job got there.
  71. //
  72. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetComment( bstrComments ));
  73. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetFlags ( 0 ));
  74. //
  75. // Now, fill in the trigger as necessary.
  76. //
  77. {
  78. CComPtr<ITaskTrigger> pTaskTrigger;
  79. WORD wTrigNumber;
  80. TASK_TRIGGER ttTaskTrig;
  81. TRIGGER_TYPE_UNION ttu;
  82. DAILY daily;
  83. ::ZeroMemory( &ttTaskTrig, sizeof(ttTaskTrig) ); ttTaskTrig.cbTriggerSize = sizeof(ttTaskTrig);
  84. //
  85. // Let's create it.
  86. //
  87. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->CreateTrigger( &wTrigNumber, &pTaskTrigger ));
  88. //
  89. // Calculate the exact time of next activation
  90. //
  91. {
  92. SYSTEMTIME stNow;
  93. DOUBLE dblNextScheduledTime;
  94. ::GetLocalTime ( &stNow );
  95. ::SystemTimeToVariantTime( &stNow, &dblNextScheduledTime );
  96. dblNextScheduledTime += (double)(g_Config.get_Timing_WakeUp()) / SECONDS_IN_A_DAY;
  97. ::VariantTimeToSystemTime( dblNextScheduledTime, &stNow );
  98. ttTaskTrig.wBeginYear = stNow.wYear;
  99. ttTaskTrig.wBeginMonth = stNow.wMonth;
  100. ttTaskTrig.wBeginDay = stNow.wDay;
  101. ttTaskTrig.wStartHour = stNow.wHour;
  102. ttTaskTrig.wStartMinute = stNow.wMinute;
  103. }
  104. ttTaskTrig.MinutesDuration = MINUTES_IN_A_DAY;
  105. ttTaskTrig.MinutesInterval = (double)(g_Config.get_Timing_WakeUp()) / SECONDS_IN_A_MINUTE;
  106. ttTaskTrig.TriggerType = TASK_TIME_TRIGGER_DAILY;
  107. daily.DaysInterval = 1;
  108. ttu.Daily = daily;
  109. ttTaskTrig.Type = ttu;
  110. //
  111. // Add this trigger to the task.
  112. //
  113. __MPC_EXIT_IF_METHOD_FAILS(hr, pTaskTrigger->SetTrigger( &ttTaskTrig ));
  114. }
  115. //
  116. // Make the changes permanent
  117. //
  118. {
  119. CComPtr<IPersistFile> pIPF;
  120. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->QueryInterface( IID_IPersistFile, (void **)&pIPF ));
  121. __MPC_EXIT_IF_METHOD_FAILS(hr, pIPF->Save( NULL, FALSE ));
  122. }
  123. }
  124. hr = S_OK;
  125. __ULT_FUNC_CLEANUP;
  126. __ULT_FUNC_EXIT(hr);
  127. }
  128. /////////////////////////////////////////////////////////////////////////////
  129. BEGIN_OBJECT_MAP(ObjectMap)
  130. OBJECT_ENTRY(CLSID_MPCUploadReal , CMPCUploadWrapper)
  131. OBJECT_ENTRY(CLSID_MPCConnectionReal, CMPCConnection )
  132. END_OBJECT_MAP()
  133. static HRESULT ProcessArguments( int argc ,
  134. LPCWSTR* argv )
  135. {
  136. __ULT_FUNC_ENTRY( "ProcessArguments" );
  137. HRESULT hr;
  138. int i;
  139. LPCWSTR szSvcHostGroup = NULL;
  140. bool fCOM_reg = false;
  141. bool fCOM_unreg = false;
  142. bool fRunAsService = true;
  143. bool fRun = true;
  144. bool fWakeUp = false;
  145. for(i=1; i<argc; i++)
  146. {
  147. LPCWSTR szArg = argv[i];
  148. if(szArg[0] == '-' ||
  149. szArg[0] == '/' )
  150. {
  151. szArg++;
  152. if(_wcsicmp( szArg, L"SvcHost" ) == 0 && i < argc-1)
  153. {
  154. szSvcHostGroup = argv[++i];
  155. continue;
  156. }
  157. if(_wcsicmp( szArg, L"UnregServer" ) == 0)
  158. {
  159. fCOM_unreg = true;
  160. fRun = false;
  161. continue;
  162. }
  163. if(_wcsicmp( szArg, L"RegServer" ) == 0)
  164. {
  165. fCOM_reg = true;
  166. fRun = false;
  167. continue;
  168. }
  169. if(_wcsicmp( szArg, L"Embedding" ) == 0)
  170. {
  171. fRunAsService = false;
  172. continue;
  173. }
  174. if(_wcsicmp( szArg, L"WakeUp" ) == 0)
  175. {
  176. fWakeUp = true;
  177. fRun = false;
  178. continue;
  179. }
  180. }
  181. __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
  182. }
  183. //////////////////////////////////////////////////////////////////////
  184. if (fCOM_reg ) _Module.RegisterServer ( TRUE, (szSvcHostGroup != NULL), szSvcHostGroup );
  185. else if(fCOM_unreg) _Module.UnregisterServer( szSvcHostGroup );
  186. //////////////////////////////////////////////////////////////////////
  187. if(fWakeUp)
  188. {
  189. CComPtr<IMPCUpload> svc;
  190. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_MPCUpload, NULL, CLSCTX_ALL, IID_IMPCUpload, (void**)&svc ));
  191. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  192. }
  193. //////////////////////////////////////////////////////////////////////
  194. if(fRun)
  195. {
  196. #ifdef DEBUG
  197. _Module.ReadDebugSettings();
  198. #endif
  199. _Module.Start( fRunAsService ? TRUE : FALSE );
  200. }
  201. //////////////////////////////////////////////////////////////////////
  202. hr = S_OK;
  203. __ULT_FUNC_CLEANUP;
  204. __ULT_FUNC_EXIT(hr);
  205. }
  206. extern "C" int WINAPI wWinMain( HINSTANCE hInstance ,
  207. HINSTANCE hPrevInstance,
  208. LPWSTR lpCmdLine ,
  209. int nShowCmd )
  210. {
  211. HRESULT hr;
  212. int argc;
  213. LPCWSTR* argv;
  214. if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_MULTITHREADED ))) // We need to be a multi-threaded application.
  215. {
  216. if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
  217. -1 , // We don't care which authentication service we use.
  218. NULL ,
  219. NULL ,
  220. RPC_C_AUTHN_LEVEL_CONNECT , // We want to identify the callers.
  221. RPC_C_IMP_LEVEL_IDENTIFY ,
  222. NULL ,
  223. EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
  224. NULL )))
  225. {
  226. __MPC_TRACE_INIT();
  227. g_NTEvents.Init( L"UPLOADM" );
  228. //
  229. // Parse the command line.
  230. //
  231. if(SUCCEEDED(hr = MPC::CommandLine_Parse( argc, argv )))
  232. {
  233. //
  234. // Initialize ATL modules.
  235. //
  236. _Module.Init( ObjectMap, hInstance, L"uploadmgr", IDS_UPLOADM_DISPLAYNAME, IDS_UPLOADM_DESCRIPTION );
  237. //
  238. // Initialize MPC module.
  239. //
  240. if(SUCCEEDED(hr = MPC::_MPC_Module.Init()))
  241. {
  242. //
  243. // Process arguments.
  244. //
  245. hr = ProcessArguments( argc, argv );
  246. MPC::_MPC_Module.Term();
  247. }
  248. _Module.Term();
  249. MPC::CommandLine_Free( argc, argv );
  250. }
  251. __MPC_TRACE_TERM();
  252. }
  253. ::CoUninitialize();
  254. }
  255. return FAILED(hr) ? 10 : 0;
  256. }