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.

426 lines
12 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 + 1];
  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. rgFileName[MAX_PATH] = 0;
  43. //
  44. // Load localized strings.
  45. //
  46. ::LoadStringW( _Module.GetResourceInstance(), IDS_TASKNAME, rgTaskName, MAXSTRLEN(rgTaskName) );
  47. ::LoadStringW( _Module.GetResourceInstance(), IDS_COMMENT , rgComment , MAXSTRLEN(rgComment ) );
  48. bstrFileName = rgFileName;
  49. bstrTaskName = rgTaskName;
  50. bstrComments = rgComment;
  51. hr = pTaskScheduler->Delete( bstrTaskName );
  52. if(FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  53. {
  54. __MPC_TRACE_HRESULT(hr);
  55. __MPC_FUNC_LEAVE;
  56. }
  57. if(fActivate)
  58. {
  59. //
  60. // Create a new task and set its app name and parameters.
  61. //
  62. __MPC_EXIT_IF_METHOD_FAILS(hr, pTaskScheduler->NewWorkItem( bstrTaskName, CLSID_CTask, IID_ITask, (IUnknown**)&pTask ));
  63. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->QueryInterface( IID_IScheduledWorkItem, (void **)&pScheduledWorkItem ));
  64. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->SetApplicationName( bstrFileName ));
  65. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->SetParameters ( CComBSTR( L"-WakeUp" ) ));
  66. //
  67. // Set a NULL account information, so the task will be run as SYSTEM.
  68. //
  69. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetAccountInformation( L"", NULL ));
  70. //
  71. // Set the comment, so we know how this job got there.
  72. //
  73. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetComment( bstrComments ));
  74. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetFlags ( 0 ));
  75. //
  76. // Now, fill in the trigger as necessary.
  77. //
  78. {
  79. CComPtr<ITaskTrigger> pTaskTrigger;
  80. WORD wTrigNumber;
  81. TASK_TRIGGER ttTaskTrig;
  82. TRIGGER_TYPE_UNION ttu;
  83. DAILY daily;
  84. ::ZeroMemory( &ttTaskTrig, sizeof(ttTaskTrig) ); ttTaskTrig.cbTriggerSize = sizeof(ttTaskTrig);
  85. //
  86. // Let's create it.
  87. //
  88. __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->CreateTrigger( &wTrigNumber, &pTaskTrigger ));
  89. //
  90. // Calculate the exact time of next activation
  91. //
  92. {
  93. SYSTEMTIME stNow;
  94. DOUBLE dblNextScheduledTime;
  95. ::GetLocalTime ( &stNow );
  96. ::SystemTimeToVariantTime( &stNow, &dblNextScheduledTime );
  97. dblNextScheduledTime += (double)(g_Config.get_Timing_WakeUp()) / SECONDS_IN_A_DAY;
  98. ::VariantTimeToSystemTime( dblNextScheduledTime, &stNow );
  99. ttTaskTrig.wBeginYear = stNow.wYear;
  100. ttTaskTrig.wBeginMonth = stNow.wMonth;
  101. ttTaskTrig.wBeginDay = stNow.wDay;
  102. ttTaskTrig.wStartHour = stNow.wHour;
  103. ttTaskTrig.wStartMinute = stNow.wMinute;
  104. }
  105. ttTaskTrig.MinutesDuration = MINUTES_IN_A_DAY;
  106. ttTaskTrig.MinutesInterval = (double)(g_Config.get_Timing_WakeUp()) / SECONDS_IN_A_MINUTE;
  107. ttTaskTrig.TriggerType = TASK_TIME_TRIGGER_DAILY;
  108. daily.DaysInterval = 1;
  109. ttu.Daily = daily;
  110. ttTaskTrig.Type = ttu;
  111. //
  112. // Add this trigger to the task.
  113. //
  114. __MPC_EXIT_IF_METHOD_FAILS(hr, pTaskTrigger->SetTrigger( &ttTaskTrig ));
  115. }
  116. //
  117. // Make the changes permanent
  118. //
  119. {
  120. CComPtr<IPersistFile> pIPF;
  121. __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->QueryInterface( IID_IPersistFile, (void **)&pIPF ));
  122. __MPC_EXIT_IF_METHOD_FAILS(hr, pIPF->Save( NULL, FALSE ));
  123. }
  124. }
  125. hr = S_OK;
  126. __ULT_FUNC_CLEANUP;
  127. __ULT_FUNC_EXIT(hr);
  128. }
  129. /////////////////////////////////////////////////////////////////////////////
  130. BEGIN_OBJECT_MAP(ObjectMap)
  131. OBJECT_ENTRY(CLSID_MPCUploadReal , CMPCUploadWrapper)
  132. OBJECT_ENTRY(CLSID_MPCConnectionReal, CMPCConnection )
  133. END_OBJECT_MAP()
  134. static HRESULT ProcessArguments( int argc ,
  135. LPCWSTR* argv )
  136. {
  137. __ULT_FUNC_ENTRY( "ProcessArguments" );
  138. HRESULT hr;
  139. int i;
  140. LPCWSTR szSvcHostGroup = NULL;
  141. bool fCOM_reg = false;
  142. bool fCOM_unreg = false;
  143. bool fRunAsService = true;
  144. bool fRun = true;
  145. bool fWakeUp = false;
  146. for(i=1; i<argc; i++)
  147. {
  148. LPCWSTR szArg = argv[i];
  149. if(szArg[0] == '-' ||
  150. szArg[0] == '/' )
  151. {
  152. szArg++;
  153. if(_wcsicmp( szArg, L"SvcHost" ) == 0 && i < argc-1)
  154. {
  155. szSvcHostGroup = argv[++i];
  156. continue;
  157. }
  158. if(_wcsicmp( szArg, L"UnregServer" ) == 0)
  159. {
  160. fCOM_unreg = true;
  161. fRun = false;
  162. continue;
  163. }
  164. if(_wcsicmp( szArg, L"RegServer" ) == 0)
  165. {
  166. fCOM_reg = true;
  167. fRun = false;
  168. continue;
  169. }
  170. if(_wcsicmp( szArg, L"Embedding" ) == 0)
  171. {
  172. fRunAsService = false;
  173. continue;
  174. }
  175. if(_wcsicmp( szArg, L"WakeUp" ) == 0)
  176. {
  177. fWakeUp = true;
  178. fRun = false;
  179. continue;
  180. }
  181. }
  182. __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
  183. }
  184. //////////////////////////////////////////////////////////////////////
  185. if (fCOM_reg ) _Module.RegisterServer ( TRUE, (szSvcHostGroup != NULL), szSvcHostGroup );
  186. else if(fCOM_unreg) _Module.UnregisterServer( szSvcHostGroup );
  187. //////////////////////////////////////////////////////////////////////
  188. if(fWakeUp)
  189. {
  190. CComPtr<IMPCUpload> svc;
  191. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_MPCUpload, NULL, CLSCTX_ALL, IID_IMPCUpload, (void**)&svc ));
  192. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  193. }
  194. //////////////////////////////////////////////////////////////////////
  195. if(fRun)
  196. {
  197. #ifdef DEBUG
  198. _Module.ReadDebugSettings();
  199. #endif
  200. _Module.Start( fRunAsService ? TRUE : FALSE );
  201. }
  202. //////////////////////////////////////////////////////////////////////
  203. hr = S_OK;
  204. __ULT_FUNC_CLEANUP;
  205. __ULT_FUNC_EXIT(hr);
  206. }
  207. BOOL JettisonPrivileges()
  208. {
  209. HANDLE hToken;
  210. DWORD dwSize;
  211. DWORD dwError;
  212. DWORD dwIndex;
  213. VOID* TokenInformation = NULL;
  214. TOKEN_PRIVILEGES* pTokenPrivileges;
  215. BOOL fRet = FALSE;
  216. hToken = NULL;
  217. if (!OpenProcessToken(
  218. GetCurrentProcess(),
  219. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  220. &hToken))
  221. {
  222. goto LEnd;
  223. }
  224. if (!GetTokenInformation(
  225. hToken,
  226. TokenPrivileges,
  227. NULL, 0,
  228. &dwSize))
  229. {
  230. dwError = GetLastError();
  231. if (dwError != ERROR_INSUFFICIENT_BUFFER)
  232. {
  233. goto LEnd;
  234. }
  235. }
  236. TokenInformation = LocalAlloc(LPTR, dwSize);
  237. if (NULL == TokenInformation)
  238. {
  239. goto LEnd;
  240. }
  241. if (!GetTokenInformation(
  242. hToken,
  243. TokenPrivileges,
  244. TokenInformation, dwSize,
  245. &dwSize))
  246. {
  247. goto LEnd;
  248. }
  249. pTokenPrivileges = (TOKEN_PRIVILEGES*) TokenInformation;
  250. for (dwIndex = 0; dwIndex < pTokenPrivileges->PrivilegeCount; dwIndex++)
  251. {
  252. pTokenPrivileges->Privileges[dwIndex].Attributes = 4; //SE_PRIVILEGE_REMOVED;
  253. }
  254. if (!AdjustTokenPrivileges(
  255. hToken,
  256. FALSE,
  257. pTokenPrivileges, dwSize,
  258. NULL, NULL))
  259. {
  260. dwError = GetLastError();
  261. goto LEnd;
  262. }
  263. fRet = TRUE;
  264. LEnd:
  265. LocalFree(TokenInformation);
  266. return fRet;
  267. }
  268. extern "C" int WINAPI wWinMain( HINSTANCE hInstance ,
  269. HINSTANCE hPrevInstance,
  270. LPWSTR lpCmdLine ,
  271. int nShowCmd )
  272. {
  273. HRESULT hr;
  274. int argc;
  275. LPCWSTR* argv;
  276. if (!JettisonPrivileges())
  277. {
  278. return 10;
  279. }
  280. if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_MULTITHREADED ))) // We need to be a multi-threaded application.
  281. {
  282. if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
  283. -1 , // We don't care which authentication service we use.
  284. NULL ,
  285. NULL ,
  286. RPC_C_AUTHN_LEVEL_CONNECT , // We want to identify the callers.
  287. RPC_C_IMP_LEVEL_IDENTIFY ,
  288. NULL ,
  289. EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
  290. NULL )))
  291. {
  292. __MPC_TRACE_INIT();
  293. g_NTEvents.Init( L"UPLOADM" );
  294. //
  295. // Parse the command line.
  296. //
  297. if(SUCCEEDED(hr = MPC::CommandLine_Parse( argc, argv )))
  298. {
  299. //
  300. // Initialize ATL modules.
  301. //
  302. _Module.Init( ObjectMap, hInstance, L"uploadmgr", IDS_UPLOADM_DISPLAYNAME, IDS_UPLOADM_DESCRIPTION );
  303. //
  304. // Initialize MPC module.
  305. //
  306. if(SUCCEEDED(hr = MPC::_MPC_Module.Init()))
  307. {
  308. //
  309. // Process arguments.
  310. //
  311. hr = ProcessArguments( argc, argv );
  312. MPC::_MPC_Module.Term();
  313. }
  314. _Module.Term();
  315. MPC::CommandLine_Free( argc, argv );
  316. }
  317. __MPC_TRACE_TERM();
  318. }
  319. ::CoUninitialize();
  320. }
  321. return FAILED(hr) ? 10 : 0;
  322. }