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.
 
 
 
 
 
 

285 lines
9.5 KiB

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 2000
*
* TITLE: handler.cpp
*
* VERSION: 1.0
*
* AUTHOR: ByronC
*
* DATE: 15 Nov, 2000
*
* DESCRIPTION:
* Declarations and definitions for the WIA messsage handler class.
* This class gets called from the Service control function on PnP and Power
* event notifications, and informas the device manager to take the appropriate
* action.
*
*******************************************************************************/
#include "precomp.h"
#include "stiexe.h"
HRESULT CMsgHandler::HandlePnPEvent(
DWORD dwEventType,
PVOID pEventData)
{
HRESULT hr = S_OK;
PDEV_BROADCAST_HDR pDevHdr = (PDEV_BROADCAST_HDR)pEventData;
ACTIVE_DEVICE *pActiveDevice = NULL;
DEV_BROADCAST_HEADER *psDevBroadcast = NULL;
DEVICE_BROADCAST_INFO *pdbiDevice = NULL;
BOOL bFound = FALSE;
USES_CONVERSION;
DBG_TRC(("CMsgHandler::HandlePnPEvent, dwEventType = 0x%08X", dwEventType));
DBG_WRN(("==> CMsgHandler::HandlePnPEvent"));
//
// Trace that we are here. For all messages, not intended for StillImage devices , we should refresh
// device list if we are running on WIndows NT and registered for device interfaces other than StillImage
//
PDEV_BROADCAST_DEVNODE pDevNode = (PDEV_BROADCAST_DEVNODE)pDevHdr;
PDEV_BROADCAST_DEVICEINTERFACE pDevInterface = (PDEV_BROADCAST_DEVICEINTERFACE)pDevHdr;
switch (dwEventType) {
case DBT_DEVICEREMOVECOMPLETE:
case DBT_DEVICEQUERYREMOVE:
case DBT_DEVICEREMOVEPENDING:
DBG_TRC(("CMsgHandler::HandlePnPEvent, "
"DBT_DEVICEQUERYREMOVE | DBT_DEVICEREMOVEPENDING | DBT_DEVICEREMOVECOMPLETE, "
"dwEventType = %lu", dwEventType));
if (IsStillImagePnPMessage(pDevHdr)) {
//
// Get device name and store along with the broadacast structure
//
pdbiDevice = new DEVICE_BROADCAST_INFO;
if (!pdbiDevice) {
DBG_WRN(("CMsgHandler::HandlePnPEvent, out of memory"));
return E_OUTOFMEMORY;
}
//
// Fill in information we have
//
pdbiDevice->m_uiDeviceChangeMessage = dwEventType;
pdbiDevice->m_strBroadcastedName.CopyString(pDevInterface->dbcc_name) ;
pdbiDevice->m_dwDevNode = pDevNode->dbcd_devnode;
//
// Try to find our internal device name for this device if it exists in
// our internal set.
//
bFound = GetDeviceNameFromDevBroadcast((DEV_BROADCAST_HEADER *)pDevHdr,pdbiDevice);
DBG_WRN(("==> GetDeviceNameFromDevBroadcast returned DeviceID (%ws)", (WCHAR*)(LPCWSTR)pdbiDevice->m_strDeviceName));
if (bFound) {
//
// Mark that this device has been removed and throw disconnect event.
//
hr = g_pDevMan->ProcessDeviceRemoval((WCHAR*)(LPCWSTR)pdbiDevice->m_strDeviceName);
}
else {
DBG_TRC(("CMsgHandler::HandlePnPEvent, - failed to get device name from broadcast"));
}
} else {
//
// Not exactly one of ours, but we are registered for it, so re-enumerate
//
g_pDevMan->ReEnumerateDevices(DEV_MAN_GEN_EVENTS);
}
break;
case DBT_DEVICEARRIVAL:
DBG_TRC(("CMsgHandler::HandlePnPEvent - DBT_DEVICEARRIVAL"));
//
// Device has arrived (not installed). We simply find out which of
// our devices has changed state.
//
hr = g_pDevMan->ProcessDeviceArrival();
if (FAILED(hr)) {
DBG_WRN(("::CMsgHandler::HandlePnPEvent, unable to enumerate devices"));
}
break;
default:
DBG_TRC(("::CMsgHandler::HandlePnPEvent, Default case"));
break;
}
//
// Cleanup
//
if (pdbiDevice) {
delete pdbiDevice;
}
return hr;
}
DWORD CMsgHandler::HandlePowerEvent(
DWORD dwEventType,
PVOID pEventData)
{
DWORD dwRet = NO_ERROR;
UINT uiTraceMessage = 0;
#ifdef DEBUG
static LPCTSTR pszPwrEventNames[] = {
TEXT("PBT_APMQUERYSUSPEND"), // 0x0000
TEXT("PBT_APMQUERYSTANDBY"), // 0x0001
TEXT("PBT_APMQUERYSUSPENDFAILED"), // 0x0002
TEXT("PBT_APMQUERYSTANDBYFAILED"), // 0x0003
TEXT("PBT_APMSUSPEND"), // 0x0004
TEXT("PBT_APMSTANDBY"), // 0x0005
TEXT("PBT_APMRESUMECRITICAL"), // 0x0006
TEXT("PBT_APMRESUMESUSPEND"), // 0x0007
TEXT("PBT_APMRESUMESTANDBY"), // 0x0008
// TEXT(" PBTF_APMRESUMEFROMFAILURE"), // 0x00000001
TEXT("PBT_APMBATTERYLOW"), // 0x0009
TEXT("PBT_APMPOWERSTATUSCHANGE"), // 0x000A
TEXT("PBT_APMOEMEVENT"), // 0x000B
TEXT("PBT_UNKNOWN"), // 0x000C
TEXT("PBT_UNKNOWN"), // 0x000D
TEXT("PBT_UNKNOWN"), // 0x000E
TEXT("PBT_UNKNOWN"), // 0x000F
TEXT("PBT_UNKNOWN"), // 0x0010
TEXT("PBT_UNKNOWN"), // 0x0011
TEXT("PBT_APMRESUMEAUTOMATIC"), // 0x0012
};
UINT uiMsgIndex;
uiMsgIndex = (dwEventType < (sizeof(pszPwrEventNames) / sizeof(TCHAR *) )) ?
(UINT) dwEventType : 0x0010;
DBG_TRC(("Still image APM Broadcast Message:%S Code:%x ",
pszPwrEventNames[uiMsgIndex],dwEventType));
#endif
switch(dwEventType)
{
case PBT_APMQUERYSUSPEND:
//
// Request for permission to suspend
//
if(g_NumberOfActiveTransfers > 0) {
//
// Veto suspend while any transfers are in progress
//
dwRet = BROADCAST_QUERY_DENY;
} else {
//
// Notify drivers that we're about to enter a power suspend state
//
g_pDevMan->NotifyRunningDriversOfEvent(&WIA_EVENT_POWER_SUSPEND);
SchedulerSetPauseState(TRUE);
}
break;
case PBT_APMQUERYSUSPENDFAILED:
//
// Suspension request denied - unpause the scheduler
//
SchedulerSetPauseState(FALSE);
//
// Notify drivers that we can resume
//
g_pDevMan->NotifyRunningDriversOfEvent(&WIA_EVENT_POWER_RESUME);
break;
case PBT_APMSUSPEND:
//
// Set the service state to paused
//
StiServicePause();
uiTraceMessage = MSG_TRACE_PWR_SUSPEND;
break;
case PBT_APMRESUMECRITICAL:
case PBT_APMRESUMEAUTOMATIC:
// Operation resuming after critical suspension
// Fall through
case PBT_APMRESUMESUSPEND:
//
// Operation resuming after suspension
// Restart all services which were active at the moment of suspend
//
//
// ReEnumerate devices. NOTE: we should generate notification only events
//
g_pDevMan->ReEnumerateDevices(DEV_MAN_FULL_REFRESH | DEV_MAN_GEN_EVENTS);
StiServiceResume();
//
// Notify drivers that we can resume
//
g_pDevMan->NotifyRunningDriversOfEvent(&WIA_EVENT_POWER_RESUME);
uiTraceMessage = MSG_TRACE_PWR_RESUME;
g_fFirstDevNodeChangeMsg = TRUE;
break;
default:
//
// This is a message we either don't know about, or have nothing to do.
// In either case, we must return NO_ERROR, else the PnP Manager
// will assume we're veto'ing the power request.
//
dwRet = NO_ERROR;
}
return dwRet;
}
HRESULT CMsgHandler::HandleCustomEvent(
DWORD dwEventType)
{
HRESULT hr = S_OK;
switch (dwEventType) {
case STI_SERVICE_CONTROL_EVENT_REREAD :
//
// For each AVTICE_DEVICE we have, re-read the device settings
//
hr = g_pDevMan->ForEachDeviceInList(DEV_MAN_OP_DEV_REREAD, 0);
if (FAILED(hr)) {
DBG_WRN(("::CMsgHandler::HandleCustomEvent, unable to re-read device settings"));
}
break;
default:
//
// Default case is to refresh our device list
//
hr = g_pDevMan->ReEnumerateDevices(DEV_MAN_FULL_REFRESH | DEV_MAN_GEN_EVENTS);
if (FAILED(hr)) {
DBG_WRN(("::CMsgHandler::HandleCustomEvent, unable to enumerate devices"));
}
}
return hr;
}
HRESULT CMsgHandler::Initialize()
{
//
// Nothing to do for now
//
return S_OK;
}