📄 commain.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
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:
commain.cpp
Abstract:
Notes:
--*/
#include "precomp.h"
#ifdef UNDER_CE
#include <pegdser.h>
#endif // UNDER_CE
//
// Global init data used by COM_OpenInternal()
//
static DWORD g_dwComInitData = 0;
//
// COM driver initialization
//
#ifdef __cplusplus
extern "C" DWORD COM_Init(DWORD dwInfo)
#else
DWORD COM_Init(DWORD dwInfo)
#endif
{
FUNCTION_TRACE(COM_Init(virt));
DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : COM_Init : params: dwInfo = %d\r\n"), dwInfo));
CComHandle* pDevice = NULL;
DWORD dwRet = NULL;
// Allocate a device handle
pDevice = new CComHandle;
if (!pDevice || !pDevice->Init()) {
goto Error;
}
dwRet = (DWORD)pDevice;
g_dwComInitData = dwRet;
DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : COM_Init : Started successfully\r\n")));
Error:
if (!dwRet) {
delete pDevice;
}
return dwRet;
}
//
// COM driver de-initialization
//
#ifdef __cplusplus
extern "C" BOOL COM_Deinit(DWORD dwData)
#else
BOOL COM_Deinit(DWORD dwData)
#endif
{
FUNCTION_TRACE(COM_Deinit(virt));
DEBUGCHK(dwData != 0);
CComHandle* pDevice = (CComHandle*)dwData;
BOOL fRet = FALSE;
if (!pDevice) {
goto Error;
}
delete pDevice;
fRet = TRUE;
Error:
return fRet;
}
//
// Open a COM driver instance
//
#ifdef __cplusplus
extern "C" DWORD COM_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
#else
DWORD COM_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
#endif
{
FUNCTION_TRACE(COM_Open(virt));
DEBUGCHK(dwData != 0);
CComInstanceHandle* pHandle = NULL;
CComHandle* pDevice = (CComHandle*)dwData;
DWORD dwRet = 0;
if (!pDevice) {
goto Error;
}
pHandle = new CComInstanceHandle;
if (!pHandle || !pHandle->Init(pDevice, dwAccess)) {
goto Error;
}
dwRet = (DWORD)pHandle;
Error:
if (!dwRet) {
delete pHandle;
}
return dwRet;
}
//
// Close a COM driver instance
//
#ifdef __cplusplus
extern "C" BOOL COM_Close(DWORD dwOpenData)
#else
BOOL COM_Close(DWORD dwOpenData)
#endif
{
FUNCTION_TRACE(COM_Close(virt));
DEBUGCHK(0 != dwOpenData);
CComInstanceHandle* pHandle = NULL;
BOOL fRet = FALSE;
pHandle = (CComInstanceHandle*)dwOpenData;
if (!pHandle) {
goto Error;
}
delete pHandle;
fRet = TRUE;
Error:
return fRet;
}
//
// COM read
//
#ifdef __cplusplus
extern "C" DWORD COM_Read(DWORD dwOpenData, LPVOID pBuf, DWORD len)
#else
DWORD COM_Read(DWORD dwOpenData, LPVOID pBuf, DWORD len)
#endif
{
// FUNCTION_TRACE(COM_Read(virt));
DEBUGCHK(0 != dwOpenData);
CComHandle* pDevice = NULL;
UINT cbCopied;
DWORD dwDownstreamRead = 0;
DWORD dwRet = 0;
if (!ValidateOpenData(dwOpenData, pDevice)) {
goto Error;
}
if (len > 0) {
if (pDevice->EnterSharedUse())
{
cbCopied = pDevice->ReadFromBackupBuffer(pBuf, len);
if (len > cbCopied && !pDevice->Read((BYTE*)pBuf + cbCopied, len - cbCopied, dwDownstreamRead)) {
dwRet = (DWORD)-1;
}
else {
dwRet = cbCopied + dwDownstreamRead;
pDevice->UpdateComStatData(TRUE, dwRet);
}
(void)pDevice->ExitSharedUse();
}
else
{
dwRet = (DWORD)-1;
}
}
Error:
return dwRet;
}
//
// COM write
//
#ifdef __cplusplus
extern "C" DWORD COM_Write(DWORD dwOpenData, LPCVOID pBuf, DWORD len)
#else
DWORD COM_Write(DWORD dwOpenData, LPCVOID pBuf, DWORD len)
#endif
{
// FUNCTION_TRACE(COM_Write(virt));
DEBUGCHK(dwOpenData != 0);
CComHandle* pDevice = NULL;
DWORD dwRet = 0;
if (!ValidateOpenData(dwOpenData, pDevice)) {
goto Error;
}
if (pDevice->EnterSharedUse())
{
if (pDevice->Write(pBuf, len, dwRet)) {
pDevice->UpdateComStatData(FALSE, dwRet);
} else {
dwRet = (DWORD)-1;
}
(void)pDevice->ExitSharedUse();
}
else
{
dwRet = (DWORD)-1;
}
Error:
return dwRet;
}
//
// COM seek
//
#ifdef __cplusplus
extern "C" DWORD COM_Seek(DWORD dwOpenData, long pos, DWORD type)
#else
DWORD COM_Seek(DWORD dwOpenData, long pos, DWORD type)
#endif
{
return (DWORD)-1;
}
//
// COM IO-control
//
#ifdef __cplusplus
extern "C" BOOL COM_IOControl(DWORD dwOpenData, DWORD dwCode, const BYTE *pBufIn, DWORD dwLenIn, __out_bcount( dwLenOut ) PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
#else
BOOL COM_IOControl(DWORD dwOpenData, DWORD dwCode, const BYTE *pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
#endif
{
// FUNCTION_TRACE(COM_IOControl(virt));
DEBUGCHK(0 != dwOpenData);
CComHandle* pDevice = NULL;
DWORD dwOutUsed;
BOOL fRet = FALSE;
bool fKeepWaiting = false;
if (!ValidateOpenData(dwOpenData, pDevice)) {
goto Error;
}
do
{
#ifndef DEDICATED_DATA_PORT
if (dwCode == IOCTL_SERIAL_WAIT_ON_MASK)
{
pDevice->ResetDataModeInterrupted();
fKeepWaiting = true;
}
#endif
if (pDevice->EnterSharedUse())
{
#ifdef UNDER_CE
// Don't let the outside users change DTR
if (IOCTL_SERIAL_SET_DTR == dwCode || IOCTL_SERIAL_CLR_DTR == dwCode) {
fRet = TRUE;
(void)pDevice->ExitSharedUse();
goto Error;
}
#endif // UNDER_CE
BOOL fOk = FALSE;
__try
{
fOk = pDevice->IOControl(dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, dwOutUsed);
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
fOk = FALSE;
}
if ( !fOk )
{
(void)pDevice->ExitSharedUse();
goto Error;
}
#ifndef DEDICATED_DATA_PORT
if (dwCode == IOCTL_SERIAL_WAIT_ON_MASK)
{
// Check if a command was sent while we were asleep.
// If not, then we weren't woken up erroneously, and we can return.
// otherwise we should wait for the next comm event.
if (!pDevice->FDataModeInterrupted())
{
fKeepWaiting = false;
}
}
#endif
(void)pDevice->ExitSharedUse();
}
else
{
goto Error;
}
}while (fKeepWaiting);
if (pdwActualOut)
{
fRet = CeSafeCopyMemory( pdwActualOut, &dwOutUsed, sizeof(DWORD) );
}
else
{
fRet = TRUE;
}
Error:
return fRet;
}
//
// Used by RIL to open virtual serial port
//
CComHandle* COM_OpenInternal()
{
FUNCTION_TRACE(COM_OpenInternal);
CComHandle* pRet = NULL;
CComHandle* pDevice;
#ifdef DEDICATED_DATA_PORT
// Allocate a device handle
pDevice = new CComHandle;
if (!pDevice || !pDevice->Init()) {
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : COM_Init failed when called from COM_OpenInternal\r\n")));
goto Error;
}
g_dwComInitData = (DWORD)pDevice;
#endif
DEBUGCHK(g_dwComInitData != 0);
pDevice = (CComHandle*)g_dwComInitData;
if (!pDevice) {
goto Error;
}
if (!pDevice->OpenDownstreamPort()) {
goto Error;
}
pRet = pDevice;
Error:
return pRet;
}
//
// Ued by RIL to close virtual serial port
//
void COM_CloseInternal(CComHandle* const pDevice)
{
FUNCTION_TRACE(COM_CloseInternal);
DEBUGCHK(pDevice != NULL);
(void)pDevice->CloseDownstreamPort();
}
//
//
//
BOOL ValidateOpenData(const DWORD dwOpenData, CComHandle*& rpDevice)
{
DEBUGCHK(dwOpenData != 0);
CComInstanceHandle* pHandle = NULL;
BOOL fRet = FALSE;
pHandle = (CComInstanceHandle*)dwOpenData;
if (!pHandle) {
goto Error;
}
rpDevice = pHandle->GetDevice();
DEBUGCHK(rpDevice != NULL);
if (!rpDevice->FHandleIsOwner(pHandle)) {
goto Error;
}
fRet = TRUE;
Error:
return fRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -