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.
 
 
 
 
 
 

728 lines
19 KiB

//#--------------------------------------------------------------
//
// File: worker.cpp
//
// Synopsis: Implementation of CWorker class methods
//
//
// History:
//
// Copyright (C) 1999-2000 Microsoft Corporation
// All rights reserved.
//
//----------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#include "windows.h"
#include "ntpoapi.h"
#ifdef __cplusplus
}
#endif
#include "shutdowntask.h"
#include "stdafx.h"
#include "worker.h"
#include "appmgrobjs.h"
//
// string constants here
//
const WCHAR METHOD_NAME_STRING [] = L"MethodName";
const WCHAR POWER_OFF_STRING [] = L"PowerOff";
const WCHAR SLEEP_DURATION_STRING [] = L"SleepDuration";
const WCHAR SHUTDOWN_TASK_STRING [] = L"ApplianceShutdownTask";
//++--------------------------------------------------------------
//
// Function: OnTaskComplete
//
// Synopsis: This is the IApplianceTask interface method
//
// Arguments: [in]
//
// Returns: HRESULT - success/failure
//
// History: MKarki Created 06/06/2000
//
// Called By:
//
//----------------------------------------------------------------
STDMETHODIMP
CWorker::OnTaskComplete(
/*[in]*/ IUnknown *pTaskContext,
/*[in]*/ LONG lTaskResult
)
{
CSATraceFunc objTrace ("CWorker::OnTaskComplete");
_ASSERT(pTaskContext);
HRESULT hr = S_OK;
try
{
do
{
if (NULL == pTaskContext)
{
SATraceString (
"ShutdownTask-OnTaskComplete passed invalid parameter"
);
hr = E_POINTER;
break;
}
//
//
// Do nothing on Commit
//
if (lTaskResult == SA_TASK_RESULT_COMMIT)
{
SATraceString (
"ShutdownTask-OnTaskComplete-No rollback in OnTaskComplete"
);
break;
}
CComPtr <ITaskContext> pTaskParameters;
//
// get the task parameters from the context
//
hr = pTaskContext->QueryInterface(
IID_ITaskContext,
(PVOID*)&pTaskParameters
);
if (FAILED (hr))
{
SATracePrintf (
"ShutdownTask-OnTaskComplete failed to query "
" TaskContext:%x",
hr
);
break;
}
SA_TASK eTask = NO_TASK;
//
// Check which Task is being executed and call that method
//
hr = GetMethodName(pTaskParameters, &eTask);
if (FAILED (hr)) {break;}
//
// initiate the appropriate task now
//
switch (eTask)
{
case SHUTDOWN:
hr = InitTask (pTaskParameters);
break;
default:
SATracePrintf (
"ShutdownTask-OnTaskComplete passed unknown task type:%d",
eTask
);
hr = E_INVALIDARG;
break;
}
}
while (false);
}
catch (...)
{
SATraceString (
"ShutdownTask-OnTaskComplete caught unknown exception"
);
hr = E_FAIL;
}
return (hr);
} // end of CWorker::OnTaskComplete method
//++--------------------------------------------------------------
//
// Function: OnTaskExecute
//
// Synopsis: This is the IApplianceTask interface method
//
// Arguments: [in]
//
// Returns: HRESULT - success/failure
//
// History: MKarki Created 06/06/2000
//
// Called By:
//
//----------------------------------------------------------------
STDMETHODIMP
CWorker::OnTaskExecute (
/*[in]*/ IUnknown *pTaskContext
)
{
CSATraceFunc objTrace ("ShutdownTask::OnTaskExecute");
_ASSERT (pTaskContext);
HRESULT hr = S_OK;
try
{
do
{
if (NULL == pTaskContext)
{
SATraceString (
"ShutdownTask-OnTaskExecute passed invalid parameter"
);
hr = E_POINTER;
break;
}
CComPtr <ITaskContext> pTaskParameters;
//
// get the task parameters from the context
//
hr = pTaskContext->QueryInterface(
IID_ITaskContext,
(PVOID*)&pTaskParameters
);
if (FAILED (hr))
{
SATracePrintf (
"ShutdownTask-OnTaskExecute failed to query "
" TaskContext:%x",
hr
);
break;
}
SA_TASK eTask = NO_TASK;
//
// Check which Task is being executed and call that method
//
hr = GetMethodName(pTaskParameters, &eTask);
if (FAILED (hr)) {break;}
//
// initiate the appropriate task now
//
switch (eTask)
{
case SHUTDOWN:
hr = InitTask (pTaskParameters);
break;
default:
SATracePrintf (
"ShutdownTask-OnTaskExecute passed unknown task type:%d",
eTask
);
hr = E_INVALIDARG;
break;
}
}
while (false);
}
catch (...)
{
SATraceString (
"ShutdownTask-OnTaskExecute caught unknown exception"
);
hr = E_FAIL;
}
return (hr);
} // end of CWorker::OnTaskExecute method
//++--------------------------------------------------------------
//
// Function: GetMethodName
//
// Synopsis: This is the CUpdateTask private method to obtain
// the method that the user wants to execute
//
// Arguments: [in] ITaskContext* - task context
// [out] PSA_TASK - task to execute
//
// Returns: HRESULT
//
// History:
//
// Called By:
//
//----------------------------------------------------------------
HRESULT
CWorker::GetMethodName (
/*[in]*/ ITaskContext *pTaskParameter,
/*[out]*/ PSA_TASK peTask
)
{
CSATraceFunc objTraceFunc ("CWorker:GetMethodName");
_ASSERT(pTaskParameter && peTask);
HRESULT hr = S_OK;
try
{
do
{
CComVariant vtValue;
CComBSTR bstrParamName (METHOD_NAME_STRING);
//
// get the methodname parameter out of the Context
//
hr = pTaskParameter->GetParameter(
bstrParamName,
&vtValue
);
if (FAILED(hr))
{
SATracePrintf (
"Shutdown Task failed on ITaskParameter::GetParameter "
"with error:%x",
hr
);
break;
}
if (V_VT(&vtValue) != VT_BSTR)
{
SATracePrintf (
"Shutdown Task did not receive a string parameter "
" for method name:%d",
V_VT(&vtValue)
);
hr = E_INVALIDARG;
break;
}
//
// check the task now
//
if (0 == ::_wcsicmp (V_BSTR (&vtValue), SHUTDOWN_TASK_STRING))
{
*peTask = SHUTDOWN;
}
else
{
SATracePrintf (
"Shutdown Task was requested an unknown task:%ws",
V_BSTR (&vtValue)
);
hr = E_INVALIDARG;
break;
}
//
// succeeded
//
}
while (false);
}
catch (...)
{
SATraceString (
"Shutdown Task caught unknown exception in GetMethodName"
);
hr = E_FAIL;
}
if (FAILED(hr)) {*peTask = NO_TASK;}
return (hr);
} // end of CWorker::GetMethodName method
//++--------------------------------------------------------------
//
// Function: IsRebootRequested
//
// Synopsis: This is the CUpdateTask private method to check
// if a reboot is requested
//
// Arguments: [in] ITaskContext* - task context
//
// Returns: BOOL - true (reboot)/false (shutdown)
//
// History:
//
// Called By:
//
//----------------------------------------------------------------
BOOL
CWorker::IsRebootRequested (
/*[in]*/ ITaskContext *pTaskParameter
)
{
CSATraceFunc objTraceFunc ("CWorker::IsRebootRequested");
_ASSERT (pTaskParameter);
HRESULT hr = S_OK;
BOOL bReboot = TRUE;
try
{
do
{
CComVariant vtValue;
CComBSTR bstrParamName (POWER_OFF_STRING);
//
// get the parameter out of the Context
//
hr = pTaskParameter->GetParameter(
bstrParamName,
&vtValue
);
if (FAILED(hr))
{
SATracePrintf (
"Shutdown Task failed on ITaskParameter::IsRebootRequested "
"with error:%x",
hr
);
break;
}
if (V_VT(&vtValue) != VT_BSTR)
{
SATracePrintf (
"Shutdown Task did not receive a string parameter "
" for method name:%d",
V_VT(&vtValue)
);
hr = E_INVALIDARG;
break;
}
//
// check the task now
//
if (0 == ::_wcsicmp (V_BSTR (&vtValue), L"0"))
{
bReboot = TRUE;
SATraceString ("Shutdown Task requestd a REBOOT");
}
else
{
bReboot = FALSE;
SATraceString ("Shutdown Task requested a SHUTDOWN");
}
//
// succeeded
//
}
while (false);
}
catch (...)
{
SATraceString (
"Shutdown Task caught unknown exception in IsRebootRequested"
);
}
return (bReboot);
} // end of CWorker::IsRbootRequested method
//++--------------------------------------------------------------
//
// Function: GetSleepDuration
//
// Synopsis: This is the CUpdateTask private method to
// obtain the Sleep duration requested by the caller
//
// Arguments: [in] ITaskContext* - task context
//
// Returns: DWORD - Sleep Duration in milliseconds
//
// History:
//
// Called By:
//
//----------------------------------------------------------------
DWORD
CWorker::GetSleepDuration (
/*[in]*/ ITaskContext *pTaskParameter
)
{
CSATraceFunc objTraceFunc ("CWorker::GetSleepDuration");
_ASSERT (pTaskParameter);
HRESULT hr = S_OK;
DWORD dwSleepDuration = 0;
try
{
do
{
CComVariant vtValue;
CComBSTR bstrParamName (SLEEP_DURATION_STRING);
//
// get the parameter out of the Context
//
hr = pTaskParameter->GetParameter(
bstrParamName,
&vtValue
);
if (FAILED(hr))
{
SATracePrintf (
"Shutdown Task failed on ITaskParameter::GetSleepDuration "
"with error:%x",
hr
);
break;
}
if (V_VT(&vtValue) == VT_I4)
{
dwSleepDuration = V_I4 (&vtValue);
}
else if (V_VT (&vtValue) == VT_I2)
{
dwSleepDuration = V_I2 (&vtValue);
}
else if (V_VT (&vtValue) == VT_UI4)
{
dwSleepDuration = V_UI4 (&vtValue);
}
else if (V_VT (&vtValue) == VT_UI2)
{
dwSleepDuration = V_UI2 (&vtValue);
}
else if (V_VT (&vtValue) == VT_R8)
{
dwSleepDuration = (DWORD) V_R8 (&vtValue);
}
else
{
SATracePrintf (
"Shutdown Task did not receive a integer parameter "
" for power off:%d",
V_VT(&vtValue)
);
hr = E_INVALIDARG;
break;
}
SATracePrintf (
"Shutdown task found sleep duration requested:%d millisecs",
dwSleepDuration
);
}
while (false);
}
catch (...)
{
SATraceString (
"Shutdown Task caught unknown exception in GetSleepDuration"
);
}
return (dwSleepDuration);
} // end of CWorker::IsPowerOffRequired method
//++--------------------------------------------------------------
//
// Function: InitTask
//
// Synopsis: This is the CWorker private method which
// is responsible for carrying out the shutdown
//
// Arguments: [in] ITaskContext*
//
// Returns: HRESULT
//
// History: MKarki 06/06/2000 Created
//
// Called By: OnTaskComplete/OnTaskExecute methods of IApplianceTask
// interface
//
//----------------------------------------------------------------
HRESULT
CWorker::InitTask (
/*[in]*/ ITaskContext *pTaskParameter
)
{
CSATraceFunc objTrace ("CWorker::InitTask");
_ASSERT (pTaskParameter);
HRESULT hr = S_OK;
try
{
do
{
//
// Sleep for the time requested
//
Sleep (GetSleepDuration (pTaskParameter));
//
// set the shutdown privilege now
//
SetShutdownPrivilege ();
//
// now do the required operation - shutdown or reboot
//
BOOL bSuccess = InitiateSystemShutdown(
NULL, // this machine
NULL, // no message
0, // no wait
TRUE, // force app close option
IsRebootRequested (pTaskParameter) // reboot option
);
if (!bSuccess)
{
SATraceFailure ("CWorker::InitTask::InitiateSystemShutdown", GetLastError());
break;
}
//
// suceess
//
}
while (false);
}
catch (...)
{
SATraceString (
"Shutdown Task failed while doing shutdown "
"with unknown exception"
);
}
return (hr);
} // end of CWorker::InitTask method
//++--------------------------------------------------------------
//
// Function: SetShutdownPrivilege
//
// Synopsis: This is the CWorker private method which
// is responsible for giving process SE_SHUTDOWN_NAME
// priviledge
//
//
// Arguments: none
//
// Returns: bool - yes/now
//
// History: MKarki 06/06/2000 Created
//
// Called By: OnTaskComplete/OnTaskExecute methods of IApplianceTask
// interface
//
//----------------------------------------------------------------
bool
CWorker::SetShutdownPrivilege(void)
{
CSATraceFunc objTrace ("CWorker::SetShutdownPrivilege");
bool bReturn = false;
HANDLE hProcessToken = NULL;
do
{
//
// Open the process token
//
BOOL bRetVal = OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hProcessToken
);
if (!bRetVal)
{
SATraceFailure (
"CWorker::SetShutdownPrivilege::OpenProcessToken", GetLastError ()
);
break;
}
//
// build the privileges structure
//
TOKEN_PRIVILEGES tokPriv;
tokPriv.PrivilegeCount = 1;
tokPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//
// get the LUID of the shutdown privilege
//
bRetVal = LookupPrivilegeValue(
NULL,
SE_SHUTDOWN_NAME ,
&tokPriv.Privileges[0].Luid
);
if (!bRetVal)
{
SATraceFailure (
"CWorker::SetShutdownPriviledge::LookupPrivilegeValue", GetLastError ()
);
break;
}
//
// adjust the process token privileges
//
bRetVal = AdjustTokenPrivileges(
hProcessToken,
FALSE,
&tokPriv,
0,
NULL,
NULL
);
if (!bRetVal)
{
SATraceFailure (
"CWorker::SetShutdownPriviledge::AdjustTokenPrivileges", GetLastError ()
);
break;
}
//
// success
//
bRetVal = true;
}
while (false);
//
// resource cleanup
//
if (hProcessToken)
{
CloseHandle (hProcessToken);
}
return bReturn;
} // end of CWorker::SetShutdownPrivilege method