📄 cserpdd.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name: CSerpdd.cpp
Abstract:
Serial PDD Common Code.
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <ceddk.h>
#include <notify.h>
#include <ddkreg.h>
#include <serhw.h>
#include <ser16550.h>
#include <hw16550.h>
#include <ddkreg.h>
#include <pm.h>
#include <Serdbg.h>
#include "CSerPdd.h"
CSerialPDDPowerUpCallback::CSerialPDDPowerUpCallback(CSerialPDD * pSerialObj)
: m_pSerialObj(pSerialObj)
, CMiniThread (0, TRUE)
{
DEBUGCHK(m_pSerialObj!=NULL);
m_hEvent =CreateEvent(NULL,FALSE,FALSE,NULL);
ThreadStart();
}
CSerialPDDPowerUpCallback::~CSerialPDDPowerUpCallback()
{
m_bTerminated = TRUE;
SignalCallback();
ThreadTerminated(1000);
}
DWORD CSerialPDDPowerUpCallback::ThreadRun()
{
while (!IsTerminated() && m_hEvent!=NULL && m_pSerialObj!=NULL) {
if (WaitForSingleObject(m_hEvent,INFINITE)==WAIT_OBJECT_0) {
if (!IsTerminated()) {
m_pSerialObj->NotifyPDDInterrupt(INTR_NONE);
}
}
else
ASSERT(FALSE);
}
return 0;
}
CSerialPDD::CSerialPDD(LPTSTR lpActivePath, PVOID pMdd, PHWOBJ pHwObj )
: CRegistryEdit(lpActivePath)
, m_pMdd(pMdd)
, m_pHwObj(pHwObj)
{
m_hParent = CreateBusAccessHandle(lpActivePath);
m_PowerHelperHandle = INVALID_HANDLE_VALUE;
m_hPowerLock = NULL;
// Initial Open Count.
m_lOpenCount = 0;
m_ulCommErrors = 0;
m_PowerCallbackThread = NULL;
if (!GetRegValue(PC_REG_SERIALPRIORITY_VAL_NAME,(LPBYTE)&m_dwPriority256,sizeof(DWORD))) {
m_dwPriority256 = DEFAULT_CE_THREAD_PRIORITY+55;
}
}
CSerialPDD::~CSerialPDD()
{
InitialEnableInterrupt(FALSE);
if (m_hParent)
CloseBusAccessHandle(m_hParent);
if (m_PowerHelperHandle != INVALID_HANDLE_VALUE )
DDKPwr_Deinitialize(m_PowerHelperHandle);
if (m_PowerCallbackThread)
delete m_PowerCallbackThread;
InitialPower(FALSE);
}
BOOL CSerialPDD::Init()
{
InitialPower(TRUE);
if (m_PowerCallbackThread == NULL) {
m_PowerCallbackThread = new CSerialPDDPowerUpCallback(this);
if ( m_PowerCallbackThread && !m_PowerCallbackThread->Init()){
delete m_PowerCallbackThread;
m_PowerCallbackThread = NULL;
}
}
m_PowerHelperHandle = DDKPwr_Initialize(SetPowerStateStatic, (DWORD)this , TRUE, 1000 );
return (m_PowerCallbackThread!=NULL && m_PowerHelperHandle!=INVALID_HANDLE_VALUE );
}
void CSerialPDD::PostInit()
{
InitialEnableInterrupt(TRUE);
InitModem(TRUE);
}
BOOL CSerialPDD::Open()
{
if (InterlockedExchange(&m_lOpenCount,1) !=0)
return FALSE;
PREFAST_ASSERT(m_PowerHelperHandle!=INVALID_HANDLE_VALUE);
ASSERT(m_hPowerLock==NULL);
m_hPowerLock= DDKPwr_RequestLevel( m_PowerHelperHandle, D0 );
ASSERT(m_hPowerLock!=NULL);
SetDefaultConfiguration();
InitLine(TRUE);
InitReceive(TRUE);
InitXmit(TRUE);
return TRUE;
}
BOOL CSerialPDD::Close()
{
if (InterlockedExchange(&m_lOpenCount,0) !=1)
return FALSE;
InitXmit(FALSE);
InitReceive(FALSE);
InitLine(FALSE);
PREFAST_ASSERT(m_PowerHelperHandle!=INVALID_HANDLE_VALUE);
ASSERT(m_hPowerLock!=NULL);
DDKPwr_ReleaseLevel(m_PowerHelperHandle, m_hPowerLock);
m_hPowerLock=NULL;
return TRUE;
}
void CSerialPDD::Reset()
{
InitialPower(TRUE);
InitModem(TRUE);
InitLine(TRUE);
InitReceive(TRUE);
InitXmit(TRUE);
InitialEnableInterrupt(TRUE);
}
BOOL CSerialPDD::Ioctl(DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
BOOL RetVal=FALSE;
switch ( dwCode ) {
case IOCTL_POWER_CAPABILITIES:
if (!pBufOut || dwLenOut < sizeof(POWER_CAPABILITIES) || !pdwActualOut) {
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
} else {
m_IsThisPowerManaged= TRUE;
PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES)pBufOut;
*ppc= GetPowerCapabilities();
if (pdwActualOut)
*pdwActualOut = sizeof(POWER_CAPABILITIES);
RetVal = TRUE;
}
break;
case IOCTL_POWER_SET:
if (!pBufOut || dwLenOut < sizeof(CEDEVICE_POWER_STATE) || !pdwActualOut || m_PowerHelperHandle == INVALID_HANDLE_VALUE ) {
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
} else {
m_IsThisPowerManaged= TRUE;
CEDEVICE_POWER_STATE newDx = *(PCEDEVICE_POWER_STATE) pBufOut;
DEBUGMSG(1, (TEXT("COM: IOCTL_POWER_SET: D%d\r\n"), newDx));
RetVal = DDKPwr_SetDeviceLevel( m_PowerHelperHandle, newDx, NULL );
// did we set the device power?
if(RetVal == TRUE) {
*(PCEDEVICE_POWER_STATE)pBufOut = DDKPwr_GetDeviceLevel(m_PowerHelperHandle );
if (pdwActualOut) {
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
}
}
else
SetLastError(ERROR_INVALID_PARAMETER);
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
RetVal = FALSE;
break;
}
return RetVal;
}
//
//Power Managment Operation
BOOL CSerialPDD::InitialPower(BOOL bInit)
{
m_PowerState=D0;
m_IsThisPowerManaged=FALSE;
m_PowerCapabilities.DeviceDx=DX_MASK(D0)|DX_MASK(D3)|DX_MASK(D4);
return TRUE;
}
CEDEVICE_POWER_STATE CSerialPDD::SetPowerStateStatic(DWORD dwContext, CEDEVICE_POWER_STATE powerState)
{
CEDEVICE_POWER_STATE rState = powerState;
if (dwContext) {
((CSerialPDD *)dwContext)->SetDevicePowerState(powerState);
rState = ((CSerialPDD *)dwContext)->GetDevicePowerState();
}
else
ASSERT(FALSE);
return rState;
}
BOOL CSerialPDD::PowerOff()
{
if (!m_IsThisPowerManaged ) {
SerialRegisterBackup();
if (m_hParent ) {
::SetDevicePowerState( m_hParent, D4, NULL);
}
}
return TRUE;
}
BOOL CSerialPDD::PowerOn()
{
if (!m_IsThisPowerManaged ) {
if ( m_hParent ) {
::SetDevicePowerState( m_hParent, D0, NULL);
}
SerialRegisterRestore();
}
m_IsResumed = 1;
if (m_PowerCallbackThread)
m_PowerCallbackThread->SignalCallback();
return TRUE;
}
BOOL CSerialPDD::SetDevicePowerState(CEDEVICE_POWER_STATE pwrState)
{
if (m_PowerState!=pwrState) {
BOOL bReturn = TRUE;
if ((m_PowerState != D3 && m_PowerState !=D4) && (pwrState== D3 || pwrState==D4)) { // Power Off.
SerialRegisterBackup();
}
if (m_hParent && ::SetDevicePowerState( m_hParent, pwrState, NULL)) {
m_PowerState = pwrState;
bReturn = TRUE;
}
else
bReturn = FALSE;
if ((m_PowerState == D3 || m_PowerState ==D4) && (pwrState!= D3 && pwrState!=D4)) { // Power On.
SerialRegisterRestore();
m_IsResumed = 1;
}
return bReturn;
}
return TRUE;
}
//
// Interrupt Handle
BOOL CSerialPDD::InitialEnableInterrupt(BOOL /*bEnable*/ )
{
m_InterruptLock.Lock();
m_dwInterruptFlag = INTR_NONE;
m_InterruptLock.Unlock();
return TRUE;
}
extern "C" VOID SerialEventHandler(PVOID pMddHead);
BOOL CSerialPDD::NotifyPDDInterrupt(INTERRUPT_TYPE interruptType)
{
m_InterruptLock.Lock();
// The interrupt is define as Bit event.
m_dwInterruptFlag |= (DWORD)interruptType;
m_InterruptLock.Unlock();
if (IsPowerResumed ( )) {
if (m_lOpenCount) { // If application is opened.
EventCallback( EV_POWER );
}
else {
if (GetModemStatus() & MS_RLSD_ON)
CeEventHasOccurred (NOTIFICATION_EVENT_RS232_DETECTED, NULL);
}
}
SerialEventHandler(m_pMdd);
return TRUE;
}
INTERRUPT_TYPE CSerialPDD::GetInterruptType()
{
m_InterruptLock.Lock();
// The interrupt is define as Bit event.
INTERRUPT_TYPE lIntrFlagRet= (INTERRUPT_TYPE )m_dwInterruptFlag;
m_dwInterruptFlag = INTR_NONE;
m_InterruptLock.Unlock();
return lIntrFlagRet;
}
BOOL CSerialPDD::DataReplaced(PBYTE puData,BOOL isBadData)
{
BOOL bReturn = FALSE;
if (puData) {
UCHAR inputData= *puData;
if (m_DCB.fDsrSensitivity && IsDSROff() ) {
}
else
if (inputData==NULL && m_DCB.fNull) {
}
else {
bReturn = TRUE;
if (m_DCB.fErrorChar && isBadData) {
inputData = m_DCB.ErrorChar;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -