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.

234 lines
5.0 KiB

  1. //=================================================================
  2. //
  3. // PowerManagement.cpp --
  4. //
  5. // Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  6. //
  7. //=================================================================
  8. #include "precomp.h"
  9. #include "ShutdownEvent.h"
  10. #include <cnvmacros.h>
  11. #include <computerAPI.h>
  12. DWORD g_dwLogoffMarker = 0 ;
  13. DWORD g_dwShutdownMarker = 0 ;
  14. //=================================================================
  15. //
  16. // CFactoryRouter
  17. //
  18. // provides for registration and instance creation
  19. //
  20. //
  21. //=================================================================
  22. // Implements a PowerEventProvider
  23. IUnknown * CShutdownEventFactory::CreateInstance (
  24. REFIID a_riid ,
  25. LPVOID FAR *a_ppvObject
  26. )
  27. {
  28. return static_cast<IWbemProviderInit *>(new CShutdownEvent) ;
  29. }
  30. //=================================================================
  31. //
  32. // CShutdownEvent
  33. //
  34. // provides for eventing of power management events
  35. //
  36. //
  37. //=================================================================
  38. //
  39. // CWmiProviderInit needs the class name
  40. BSTR CShutdownEvent::GetClassName()
  41. {
  42. return SysAllocString(SHUTDOWN_EVENT_CLASS);
  43. }
  44. // CWmiEventProvider signals us to begin providing for events
  45. void CShutdownEvent::ProvideEvents()
  46. {
  47. if (!m_bRegistered)
  48. {
  49. m_bRegistered = TRUE;
  50. CWinMsgEvent::RegisterForMessage( WM_ENDSESSION ) ;
  51. }
  52. }
  53. // CWinMsgEvent signals that a message event has arrived
  54. void CShutdownEvent::WinMsgEvent(
  55. IN HWND a_hWnd,
  56. IN UINT a_message,
  57. IN WPARAM a_wParam,
  58. IN LPARAM a_lParam,
  59. OUT E_ReturnAction &a_eRetAction,
  60. OUT LRESULT &a_lResult
  61. )
  62. {
  63. switch ( a_message )
  64. {
  65. case WM_ENDSESSION:
  66. {
  67. BOOL t_HandleMessage = FALSE ;
  68. DWORD t_dwTicks = GetTickCount() ;
  69. // we will get a number of these...
  70. // pace the events 30 sec apart.
  71. if( ENDSESSION_LOGOFF & a_lParam ) // logoff
  72. {
  73. // don't resignal if the minimum time between events
  74. // have not passed.
  75. if( 30000 < t_dwTicks - g_dwLogoffMarker )
  76. {
  77. g_dwLogoffMarker = t_dwTicks ;
  78. t_HandleMessage = TRUE ;
  79. }
  80. }
  81. else // shutdown
  82. {
  83. // don't resignal if the minimum time between events
  84. // have not passed.
  85. if( 30000 < t_dwTicks - g_dwShutdownMarker )
  86. {
  87. g_dwShutdownMarker = t_dwTicks ;
  88. t_HandleMessage = TRUE ;
  89. }
  90. }
  91. if( t_HandleMessage )
  92. {
  93. HandleEvent( a_message, a_wParam, a_lParam ) ;
  94. }
  95. break ;
  96. }
  97. }
  98. }
  99. //
  100. void CShutdownEvent::HandleEvent(
  101. UINT a_message,
  102. WPARAM a_wParam,
  103. LPARAM a_lParam
  104. )
  105. {
  106. BOOL t_Pause = FALSE ;
  107. IWbemObjectSinkPtr t_pHandler(CEventProvider::GetHandler(), false);
  108. IWbemClassObjectPtr t_pClass(CEventProvider::GetClass(), false);
  109. if( t_pClass != NULL && t_pHandler != NULL )
  110. {
  111. IWbemClassObjectPtr t_pInst;
  112. if( SUCCEEDED( t_pClass->SpawnInstance( 0L, &t_pInst ) ) )
  113. {
  114. VARIANT t_varEvent ;
  115. VariantInit( &t_varEvent ) ;
  116. t_varEvent.vt = VT_I4 ;
  117. if( ENDSESSION_LOGOFF & a_lParam )
  118. {
  119. t_varEvent.lVal = 0 ; // logoff
  120. }
  121. else
  122. {
  123. t_varEvent.lVal = 1 ; // shutdown
  124. }
  125. if ( SUCCEEDED( t_pInst->Put( L"Type", 0, &t_varEvent, CIM_UINT32 ) ) )
  126. {
  127. // Get the current computer name
  128. CHString t_sComputerName;
  129. DWORD t_dwBufferLength = MAX_COMPUTERNAME_LENGTH + 1;
  130. fGetComputerName( t_sComputerName.GetBuffer( t_dwBufferLength ), &t_dwBufferLength ) ;
  131. t_sComputerName.ReleaseBuffer();
  132. variant_t t_vName( t_sComputerName ) ;
  133. if ( SUCCEEDED( t_pInst->Put( L"MachineName", 0, &t_vName, NULL ) ) )
  134. {
  135. IWbemClassObject *p2 = t_pInst;
  136. t_pHandler->Indicate ( 1, &p2 ) ;
  137. t_Pause = TRUE ;
  138. }
  139. }
  140. VariantClear ( &t_varEvent ) ;
  141. }
  142. }
  143. if( t_Pause )
  144. {
  145. // allow WMI some time to process this event
  146. //Sleep( 3500 ) ;
  147. }
  148. }
  149. //
  150. BOOL CShutdownEvent::fGetComputerName(LPWSTR lpwcsBuffer, LPDWORD nSize)
  151. {
  152. if (CWbemProviderGlue::GetPlatform() == VER_PLATFORM_WIN32_NT)
  153. {
  154. return ProviderGetComputerName ( lpwcsBuffer, nSize ) ;
  155. }
  156. else
  157. {
  158. char lpBuffer[_MAX_PATH];
  159. BOOL bRet = GetComputerNameA(lpBuffer, nSize);
  160. // If the call worked
  161. if (bRet)
  162. {
  163. bool t_ConversionFailure = false ;
  164. WCHAR *pName = NULL ;
  165. ANSISTRINGTOWCS(lpBuffer, pName , t_ConversionFailure );
  166. if ( ! t_ConversionFailure )
  167. {
  168. if ( pName )
  169. {
  170. wcscpy(lpwcsBuffer, pName);
  171. }
  172. else
  173. {
  174. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  175. }
  176. }
  177. else
  178. {
  179. SetLastError(ERROR_NO_UNICODE_TRANSLATION);
  180. return FALSE ;
  181. }
  182. }
  183. return bRet;
  184. }
  185. }
  186. void CShutdownEvent::OnFinalRelease()
  187. {
  188. if (m_bRegistered)
  189. {
  190. CWinMsgEvent::UnRegisterMessage( WM_ENDSESSION ) ;
  191. }
  192. delete this;
  193. }