/****************************************************************************** Copyright (c) 2000 Microsoft Corporation Module Name: UploadManager.cpp Abstract: This file contains the initialization portion of the Upload Manager Revision History: Davide Massarenti (Dmassare) 04/15/99 created ******************************************************************************/ #include "stdafx.h" #include #include // for task scheduler apis #include #include "UploadManager_i.c" ///////////////////////////////////////////////////////////////////////////// #define UL_RESCHEDULE_PERIOD (30*60) // Every thirty minutes. #define SECONDS_IN_A_DAY (24 * 60 * 60) #define SECONDS_IN_A_MINUTE ( 60) #define MINUTES_IN_A_DAY (24 * 60 ) HRESULT Handle_TaskScheduler( bool fActivate ) { __ULT_FUNC_ENTRY( "Handle_TaskScheduler" ); HRESULT hr; WCHAR rgFileName[MAX_PATH + 1]; WCHAR rgTaskName[MAX_PATH]; WCHAR rgComment [MAX_PATH]; CComBSTR bstrFileName; CComBSTR bstrTaskName; CComBSTR bstrComments; CComPtr pTaskScheduler; CComPtr pTask; CComPtr pScheduledWorkItem; // // First create the task scheduler. // __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void**)&pTaskScheduler )); // // Get our complete filename -- needed to create a task in the task scheduler. // __MPC_EXIT_IF_CALL_RETURNS_ZERO(hr, ::GetModuleFileNameW( NULL, rgFileName, MAX_PATH )); rgFileName[MAX_PATH] = 0; // // Load localized strings. // ::LoadStringW( _Module.GetResourceInstance(), IDS_TASKNAME, rgTaskName, MAXSTRLEN(rgTaskName) ); ::LoadStringW( _Module.GetResourceInstance(), IDS_COMMENT , rgComment , MAXSTRLEN(rgComment ) ); bstrFileName = rgFileName; bstrTaskName = rgTaskName; bstrComments = rgComment; hr = pTaskScheduler->Delete( bstrTaskName ); if(FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { __MPC_TRACE_HRESULT(hr); __MPC_FUNC_LEAVE; } if(fActivate) { // // Create a new task and set its app name and parameters. // __MPC_EXIT_IF_METHOD_FAILS(hr, pTaskScheduler->NewWorkItem( bstrTaskName, CLSID_CTask, IID_ITask, (IUnknown**)&pTask )); __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->QueryInterface( IID_IScheduledWorkItem, (void **)&pScheduledWorkItem )); __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->SetApplicationName( bstrFileName )); __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->SetParameters ( CComBSTR( L"-WakeUp" ) )); // // Set a NULL account information, so the task will be run as SYSTEM. // __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetAccountInformation( L"", NULL )); // // Set the comment, so we know how this job got there. // __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetComment( bstrComments )); __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->SetFlags ( 0 )); // // Now, fill in the trigger as necessary. // { CComPtr pTaskTrigger; WORD wTrigNumber; TASK_TRIGGER ttTaskTrig; TRIGGER_TYPE_UNION ttu; DAILY daily; ::ZeroMemory( &ttTaskTrig, sizeof(ttTaskTrig) ); ttTaskTrig.cbTriggerSize = sizeof(ttTaskTrig); // // Let's create it. // __MPC_EXIT_IF_METHOD_FAILS(hr, pScheduledWorkItem->CreateTrigger( &wTrigNumber, &pTaskTrigger )); // // Calculate the exact time of next activation // { SYSTEMTIME stNow; DOUBLE dblNextScheduledTime; ::GetLocalTime ( &stNow ); ::SystemTimeToVariantTime( &stNow, &dblNextScheduledTime ); dblNextScheduledTime += (double)(g_Config.get_Timing_WakeUp()) / SECONDS_IN_A_DAY; ::VariantTimeToSystemTime( dblNextScheduledTime, &stNow ); ttTaskTrig.wBeginYear = stNow.wYear; ttTaskTrig.wBeginMonth = stNow.wMonth; ttTaskTrig.wBeginDay = stNow.wDay; ttTaskTrig.wStartHour = stNow.wHour; ttTaskTrig.wStartMinute = stNow.wMinute; } ttTaskTrig.MinutesDuration = MINUTES_IN_A_DAY; ttTaskTrig.MinutesInterval = (double)(g_Config.get_Timing_WakeUp()) / SECONDS_IN_A_MINUTE; ttTaskTrig.TriggerType = TASK_TIME_TRIGGER_DAILY; daily.DaysInterval = 1; ttu.Daily = daily; ttTaskTrig.Type = ttu; // // Add this trigger to the task. // __MPC_EXIT_IF_METHOD_FAILS(hr, pTaskTrigger->SetTrigger( &ttTaskTrig )); } // // Make the changes permanent // { CComPtr pIPF; __MPC_EXIT_IF_METHOD_FAILS(hr, pTask->QueryInterface( IID_IPersistFile, (void **)&pIPF )); __MPC_EXIT_IF_METHOD_FAILS(hr, pIPF->Save( NULL, FALSE )); } } hr = S_OK; __ULT_FUNC_CLEANUP; __ULT_FUNC_EXIT(hr); } ///////////////////////////////////////////////////////////////////////////// BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_MPCUploadReal , CMPCUploadWrapper) OBJECT_ENTRY(CLSID_MPCConnectionReal, CMPCConnection ) END_OBJECT_MAP() static HRESULT ProcessArguments( int argc , LPCWSTR* argv ) { __ULT_FUNC_ENTRY( "ProcessArguments" ); HRESULT hr; int i; LPCWSTR szSvcHostGroup = NULL; bool fCOM_reg = false; bool fCOM_unreg = false; bool fRunAsService = true; bool fRun = true; bool fWakeUp = false; for(i=1; i svc; __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_MPCUpload, NULL, CLSCTX_ALL, IID_IMPCUpload, (void**)&svc )); __MPC_SET_ERROR_AND_EXIT(hr, S_OK); } ////////////////////////////////////////////////////////////////////// if(fRun) { #ifdef DEBUG _Module.ReadDebugSettings(); #endif _Module.Start( fRunAsService ? TRUE : FALSE ); } ////////////////////////////////////////////////////////////////////// hr = S_OK; __ULT_FUNC_CLEANUP; __ULT_FUNC_EXIT(hr); } BOOL JettisonPrivileges() { HANDLE hToken; DWORD dwSize; DWORD dwError; DWORD dwIndex; VOID* TokenInformation = NULL; TOKEN_PRIVILEGES* pTokenPrivileges; BOOL fRet = FALSE; hToken = NULL; if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) { goto LEnd; } if (!GetTokenInformation( hToken, TokenPrivileges, NULL, 0, &dwSize)) { dwError = GetLastError(); if (dwError != ERROR_INSUFFICIENT_BUFFER) { goto LEnd; } } TokenInformation = LocalAlloc(LPTR, dwSize); if (NULL == TokenInformation) { goto LEnd; } if (!GetTokenInformation( hToken, TokenPrivileges, TokenInformation, dwSize, &dwSize)) { goto LEnd; } pTokenPrivileges = (TOKEN_PRIVILEGES*) TokenInformation; for (dwIndex = 0; dwIndex < pTokenPrivileges->PrivilegeCount; dwIndex++) { pTokenPrivileges->Privileges[dwIndex].Attributes = 4; //SE_PRIVILEGE_REMOVED; } if (!AdjustTokenPrivileges( hToken, FALSE, pTokenPrivileges, dwSize, NULL, NULL)) { dwError = GetLastError(); goto LEnd; } fRet = TRUE; LEnd: LocalFree(TokenInformation); return fRet; } extern "C" int WINAPI wWinMain( HINSTANCE hInstance , HINSTANCE hPrevInstance, LPWSTR lpCmdLine , int nShowCmd ) { HRESULT hr; int argc; LPCWSTR* argv; if (!JettisonPrivileges()) { return 10; } if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_MULTITHREADED ))) // We need to be a multi-threaded application. { if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL , -1 , // We don't care which authentication service we use. NULL , NULL , RPC_C_AUTHN_LEVEL_CONNECT , // We want to identify the callers. RPC_C_IMP_LEVEL_IDENTIFY , NULL , EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls. NULL ))) { __MPC_TRACE_INIT(); g_NTEvents.Init( L"UPLOADM" ); // // Parse the command line. // if(SUCCEEDED(hr = MPC::CommandLine_Parse( argc, argv ))) { // // Initialize ATL modules. // _Module.Init( ObjectMap, hInstance, L"uploadmgr", IDS_UPLOADM_DISPLAYNAME, IDS_UPLOADM_DESCRIPTION ); // // Initialize MPC module. // if(SUCCEEDED(hr = MPC::_MPC_Module.Init())) { // // Process arguments. // hr = ProcessArguments( argc, argv ); MPC::_MPC_Module.Term(); } _Module.Term(); MPC::CommandLine_Free( argc, argv ); } __MPC_TRACE_TERM(); } ::CoUninitialize(); } return FAILED(hr) ? 10 : 0; }