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
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;
|
|
}
|
|
|