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.
234 lines
5.0 KiB
234 lines
5.0 KiB
//=================================================================
|
|
|
|
//
|
|
|
|
// PowerManagement.cpp --
|
|
|
|
//
|
|
|
|
// Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
//=================================================================
|
|
|
|
#include "precomp.h"
|
|
#include "ShutdownEvent.h"
|
|
#include <cnvmacros.h>
|
|
|
|
#include <computerAPI.h>
|
|
|
|
DWORD g_dwLogoffMarker = 0 ;
|
|
DWORD g_dwShutdownMarker = 0 ;
|
|
|
|
//=================================================================
|
|
//
|
|
// CFactoryRouter
|
|
//
|
|
// provides for registration and instance creation
|
|
//
|
|
//
|
|
//=================================================================
|
|
// Implements a PowerEventProvider
|
|
IUnknown * CShutdownEventFactory::CreateInstance (
|
|
|
|
REFIID a_riid ,
|
|
LPVOID FAR *a_ppvObject
|
|
)
|
|
{
|
|
return static_cast<IWbemProviderInit *>(new CShutdownEvent) ;
|
|
}
|
|
|
|
|
|
|
|
//=================================================================
|
|
//
|
|
// CShutdownEvent
|
|
//
|
|
// provides for eventing of power management events
|
|
//
|
|
//
|
|
//=================================================================
|
|
//
|
|
|
|
// CWmiProviderInit needs the class name
|
|
BSTR CShutdownEvent::GetClassName()
|
|
{
|
|
return SysAllocString(SHUTDOWN_EVENT_CLASS);
|
|
}
|
|
|
|
|
|
// CWmiEventProvider signals us to begin providing for events
|
|
void CShutdownEvent::ProvideEvents()
|
|
{
|
|
if (!m_bRegistered)
|
|
{
|
|
m_bRegistered = TRUE;
|
|
CWinMsgEvent::RegisterForMessage( WM_ENDSESSION ) ;
|
|
}
|
|
}
|
|
|
|
|
|
// CWinMsgEvent signals that a message event has arrived
|
|
void CShutdownEvent::WinMsgEvent(
|
|
|
|
IN HWND a_hWnd,
|
|
IN UINT a_message,
|
|
IN WPARAM a_wParam,
|
|
IN LPARAM a_lParam,
|
|
OUT E_ReturnAction &a_eRetAction,
|
|
OUT LRESULT &a_lResult
|
|
)
|
|
{
|
|
switch ( a_message )
|
|
{
|
|
case WM_ENDSESSION:
|
|
{
|
|
BOOL t_HandleMessage = FALSE ;
|
|
DWORD t_dwTicks = GetTickCount() ;
|
|
|
|
// we will get a number of these...
|
|
// pace the events 30 sec apart.
|
|
|
|
if( ENDSESSION_LOGOFF & a_lParam ) // logoff
|
|
{
|
|
// don't resignal if the minimum time between events
|
|
// have not passed.
|
|
if( 30000 < t_dwTicks - g_dwLogoffMarker )
|
|
{
|
|
g_dwLogoffMarker = t_dwTicks ;
|
|
t_HandleMessage = TRUE ;
|
|
}
|
|
}
|
|
else // shutdown
|
|
{
|
|
// don't resignal if the minimum time between events
|
|
// have not passed.
|
|
if( 30000 < t_dwTicks - g_dwShutdownMarker )
|
|
{
|
|
g_dwShutdownMarker = t_dwTicks ;
|
|
t_HandleMessage = TRUE ;
|
|
}
|
|
}
|
|
|
|
if( t_HandleMessage )
|
|
{
|
|
HandleEvent( a_message, a_wParam, a_lParam ) ;
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
void CShutdownEvent::HandleEvent(
|
|
|
|
UINT a_message,
|
|
WPARAM a_wParam,
|
|
LPARAM a_lParam
|
|
)
|
|
{
|
|
BOOL t_Pause = FALSE ;
|
|
|
|
IWbemObjectSinkPtr t_pHandler(CEventProvider::GetHandler(), false);
|
|
IWbemClassObjectPtr t_pClass(CEventProvider::GetClass(), false);
|
|
|
|
if( t_pClass != NULL && t_pHandler != NULL )
|
|
{
|
|
IWbemClassObjectPtr t_pInst;
|
|
|
|
if( SUCCEEDED( t_pClass->SpawnInstance( 0L, &t_pInst ) ) )
|
|
{
|
|
VARIANT t_varEvent ;
|
|
VariantInit( &t_varEvent ) ;
|
|
|
|
t_varEvent.vt = VT_I4 ;
|
|
|
|
if( ENDSESSION_LOGOFF & a_lParam )
|
|
{
|
|
t_varEvent.lVal = 0 ; // logoff
|
|
}
|
|
else
|
|
{
|
|
t_varEvent.lVal = 1 ; // shutdown
|
|
}
|
|
|
|
if ( SUCCEEDED( t_pInst->Put( L"Type", 0, &t_varEvent, CIM_UINT32 ) ) )
|
|
{
|
|
// Get the current computer name
|
|
CHString t_sComputerName;
|
|
DWORD t_dwBufferLength = MAX_COMPUTERNAME_LENGTH + 1;
|
|
|
|
fGetComputerName( t_sComputerName.GetBuffer( t_dwBufferLength ), &t_dwBufferLength ) ;
|
|
t_sComputerName.ReleaseBuffer();
|
|
|
|
variant_t t_vName( t_sComputerName ) ;
|
|
|
|
if ( SUCCEEDED( t_pInst->Put( L"MachineName", 0, &t_vName, NULL ) ) )
|
|
{
|
|
IWbemClassObject *p2 = t_pInst;
|
|
t_pHandler->Indicate ( 1, &p2 ) ;
|
|
|
|
t_Pause = TRUE ;
|
|
}
|
|
}
|
|
|
|
VariantClear ( &t_varEvent ) ;
|
|
}
|
|
}
|
|
if( t_Pause )
|
|
{
|
|
// allow WMI some time to process this event
|
|
//Sleep( 3500 ) ;
|
|
}
|
|
}
|
|
|
|
//
|
|
BOOL CShutdownEvent::fGetComputerName(LPWSTR lpwcsBuffer, LPDWORD nSize)
|
|
{
|
|
if (CWbemProviderGlue::GetPlatform() == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
return ProviderGetComputerName ( lpwcsBuffer, nSize ) ;
|
|
}
|
|
else
|
|
{
|
|
char lpBuffer[_MAX_PATH];
|
|
|
|
BOOL bRet = GetComputerNameA(lpBuffer, nSize);
|
|
|
|
// If the call worked
|
|
if (bRet)
|
|
{
|
|
bool t_ConversionFailure = false ;
|
|
WCHAR *pName = NULL ;
|
|
ANSISTRINGTOWCS(lpBuffer, pName , t_ConversionFailure );
|
|
if ( ! t_ConversionFailure )
|
|
{
|
|
if ( pName )
|
|
{
|
|
wcscpy(lpwcsBuffer, pName);
|
|
}
|
|
else
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_NO_UNICODE_TRANSLATION);
|
|
return FALSE ;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
}
|
|
|
|
void CShutdownEvent::OnFinalRelease()
|
|
{
|
|
if (m_bRegistered)
|
|
{
|
|
CWinMsgEvent::UnRegisterMessage( WM_ENDSESSION ) ;
|
|
}
|
|
|
|
delete this;
|
|
}
|