//======================================================================== //TITLE: // WinCE虛擬串口驅(qū)動(dòng)(二) //AUTHOR: // norains //DATE: // Saturday 28-March-2009 //Environment: // WINDOWS CE 5.0 //======================================================================== 虛擬串口驅(qū)動(dòng)的完整代碼如下:
- // VirtualSerial.cpp : Defines the entry point for the DLL application.
- //
-
- #include "windows.h"
- #include "reg.h"
- #include <vector>
- #include <Pegdser.h>
- #include "algorithm"
-
- //--------------------------------------------------------------------------
- //Macro
- #define REG_ROOT_KEY HKEY_LOCAL_MACHINE
- #define REG_DEVICE_SUB_KEY TEXT("Drivers//Builtin//VirtualSerial")
- #define REG_MAP_PORT_NAME TEXT("Map_Port")
-
- //The buffer length for storing the read data.
- #define READ_BUFFER_LENGTH MAX_PATH
- //--------------------------------------------------------------------------
- //Gloabal variable
- HANDLE g_hCom = INVALID_HANDLE_VALUE;
- unsigned int g_uiOpenCount = 0;
- CRITICAL_SECTION g_csOpen;
- CRITICAL_SECTION g_csRead;
- CRITICAL_SECTION g_csWrite;
- std::vector<BYTE> g_vtBufRead(READ_BUFFER_LENGTH,0);
- DWORD g_dwLenReadBuf = 0;
- DWORD g_dwEvtMask = 0;
- DWORD g_dwWaitMask = 0;
- HANDLE g_hEventComm = NULL;
- BOOL g_bMonitorProcRunning = FALSE;
- BOOL g_bExitMonitorProc = FALSE;
- BOOL g_bReaded = FALSE;
- //--------------------------------------------------------------------------
-
- BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
- {
- switch ( dwReason )
- {
- case DLL_PROCESS_ATTACH:
- break;
- }
- return TRUE;
- }
-
- DWORD MonitorCommEventProc(LPVOID pParam)
- {
- InterlockedExchange(reinterpret_cast<LONG *>(&g_bMonitorProcRunning),TRUE);
-
- RETAILMSG(TRUE,(TEXT("[VSP]:MonitorCommEventProc Running!/r/n")));
-
- std::vector<BYTE> vtBufRead(g_vtBufRead.size(),0);
- while(TRUE)
- {
- DWORD dwEvtMask = 0;
- BOOL bWaitRes = WaitCommEvent(g_hCom,&dwEvtMask,NULL);
-
- if(g_bExitMonitorProc != FALSE)
- {
- break;
- }
-
- if(bWaitRes == FALSE)
- {
- continue;
- }
-
- DWORD dwRead = 0;
- if(dwEvtMask & EV_RXCHAR)
- {
- EnterCriticalSection(&g_csRead);
-
- ReadFile(g_hCom,&g_vtBufRead[0],vtBufRead.size(),&dwRead,NULL);
- if(dwRead == vtBufRead.size() || g_bReaded != FALSE)
- {
- g_dwLenReadBuf = dwRead;
- g_vtBufRead.swap(vtBufRead);
- }
- else if(dwRead != 0)
- {
- if(g_dwLenReadBuf + dwRead <= g_vtBufRead.size())
- {
- g_dwLenReadBuf += dwRead;
- g_vtBufRead.insert(g_vtBufRead.end(),vtBufRead.begin(),vtBufRead.begin() + dwRead);
- }
- else
- {
- DWORD dwCover = g_dwLenReadBuf + dwRead - g_vtBufRead.size();
- std::copy(g_vtBufRead.begin() + dwCover,g_vtBufRead.begin() + g_dwLenReadBuf,g_vtBufRead.begin());
- std::copy(vtBufRead.begin(),vtBufRead.begin() + dwRead,g_vtBufRead.begin() + (g_dwLenReadBuf - dwCover));
- g_dwLenReadBuf = g_vtBufRead.size();
- }
- }
-
- g_bReaded = FALSE;
-
- DEBUGMSG(TRUE,(TEXT("[VSP]:Read data : %d/r/n"),dwRead));
-
- LeaveCriticalSection(&g_csRead);
- }
-
- if(dwEvtMask == EV_RXCHAR && ((g_dwWaitMask & EV_RXCHAR) == 0 || dwRead == 0))
- {
- //The return event mask is only EV_RXCHAR and there is not EV_RXCHAR in the wait mask.
- continue;
- }
-
- InterlockedExchange(reinterpret_cast<LONG *>(&g_dwEvtMask),dwEvtMask);
- PulseEvent(g_hEventComm);
-
- //Sleep for other thread to respond to the event
- Sleep(100);
-
- DEBUGMSG(TRUE,(TEXT("[VSP]:PulseEvent! The event-mask is 0x%x/r/n"),dwEvtMask));
-
- }
-
- RETAILMSG(TRUE,(TEXT("[VSP]:Exit the MonitorCommEventProc/r/n")));
- InterlockedExchange(reinterpret_cast<LONG *>(&g_bMonitorProcRunning),FALSE);
-
- return 0;
- }
-
- BOOL VSP_Close(DWORD dwHandle)
- {
- EnterCriticalSection(&g_csOpen);
-
- g_uiOpenCount --;
- if(g_uiOpenCount == 0)
- {
- //Notify the monitor thread to exit.
- InterlockedExchange(reinterpret_cast<LONG *>(&g_bExitMonitorProc),TRUE);
- DWORD dwMask = 0;
- GetCommMask(g_hCom,&dwMask);
- SetCommMask(g_hCom,dwMask);
-
- while(InterlockedExchange(reinterpret_cast<LONG *>(&g_bMonitorProcRunning),TRUE) == TRUE)
- {
- Sleep(20);
- }
- InterlockedExchange(reinterpret_cast<LONG *>(&g_bMonitorProcRunning),FALSE);
-
- CloseHandle(g_hCom);
- g_hCom = NULL;
- }
-
- LeaveCriticalSection(&g_csOpen);
-
- return TRUE;
- }
-
- DWORD VSP_Init(DWORD dwContext)
- {
- RETAILMSG(TRUE,(TEXT("[+VSP_Init]/r/n")));
-
- InitializeCriticalSection(&g_csOpen);
- InitializeCriticalSection(&g_csRead);
- InitializeCriticalSection(&g_csWrite);
-
- g_hEventComm = CreateEvent(NULL,TRUE,FALSE,NULL);
-
- RETAILMSG(TRUE,(TEXT("[-VSP_Init]/r/n")));
-
- return TRUE;
- }
-
- BOOL VSP_Deinit(
- DWORD dwContext // future: pointer to the per disk structure
- )
- {
- RETAILMSG(TRUE,(TEXT("[+VSP_Deinit]/r/n")));
-
- CloseHandle(g_hEventComm);
- g_hEventComm = NULL;
-
- DeleteCriticalSection(&g_csOpen);
- DeleteCriticalSection(&g_csRead);
- DeleteCriticalSection(&g_csWrite);
-
- RETAILMSG(TRUE,(TEXT("[-VSP_Deinit]/r/n")));
- return TRUE;
- }
-
- DWORD VSP_Open(
- DWORD dwData,
- DWORD dwAccess,
- DWORD dwShareMode
- )
- {
- BOOL bResult = FALSE;
-
- EnterCriticalSection(&g_csOpen);
-
- //The variable
- CReg reg;
- std::vector<TCHAR> vtBuf(MAX_PATH,0);
- COMMPROP commProp = {0};
-
- if(g_uiOpenCount != 0)
- {
- goto SET_SUCCEED_FLAG;
- }
-
- if(reg.Open(REG_ROOT_KEY,REG_DEVICE_SUB_KEY) == FALSE)
- {
- RETAILMSG(TRUE,(TEXT("[VSP]:Failed to open the registry/r/n")));
- goto LEAVE_CRITICAL_SECTION;
- }
-
- //Get the MAP_PORT name
- reg.GetValueSZ(REG_MAP_PORT_NAME,&vtBuf[0],vtBuf.size());
-
- g_hCom = CreateFile(&vtBuf[0],GENERIC_READ | GENERIC_WRITE ,0,NULL,OPEN_EXISTING,0,NULL);
- if(g_hCom == INVALID_HANDLE_VALUE )
- {
- RETAILMSG(TRUE,(TEXT("[VSP]Failed to map to %s/r/n"),&vtBuf[0]));
- goto LEAVE_CRITICAL_SECTION;
- }
- else
- {
- RETAILMSG(TRUE,(TEXT("[VSP]Succeed to map to %s/r/n"),&vtBuf[0]));
- }
-
- InterlockedExchange(reinterpret_cast<LONG *>(&g_bExitMonitorProc),FALSE);
- CloseHandle(CreateThread(NULL,NULL,MonitorCommEventProc,NULL,NULL,NULL));
-
- SET_SUCCEED_FLAG:
-
- g_uiOpenCount ++;
- bResult = TRUE;
-
- LEAVE_CRITICAL_SECTION:
-
- LeaveCriticalSection(&g_csOpen);
-
- return bResult;
- }
-
-
- BOOL VSP_IOControl(
- DWORD dwHandle,
- DWORD dwIoControlCode,
- PBYTE pBufIn,
- DWORD dwBufInSize,
- PBYTE pBufOut,
- DWORD dwBufOutSize,
- PDWORD pBytesReturned
- )
- {
- switch(dwIoControlCode)
- {
- case IOCTL_SERIAL_SET_DCB:
- {
- return SetCommState(g_hCom,reinterpret_cast<DCB *>(pBufIn));
- }
- case IOCTL_SERIAL_GET_DCB:
- {
- return GetCommState(g_hCom,reinterpret_cast<DCB *>(pBufOut));
- }
- case IOCTL_SERIAL_WAIT_ON_MASK:
- {
- if(dwBufOutSize < sizeof(DWORD) || WaitForSingleObject(g_hEventComm,INFINITE) == WAIT_TIMEOUT)
- {
- *pBytesReturned = 0;
- return FALSE;
- }
- else
- {
- InterlockedExchange(reinterpret_cast<LONG *>(pBufOut),g_dwEvtMask);
- *pBytesReturned = sizeof(DWORD);
- return TRUE;
- }
- }
- case IOCTL_SERIAL_SET_WAIT_MASK:
- {
- g_dwWaitMask = *reinterpret_cast<DWORD *>(pBufIn);
- return SetCommMask(g_hCom,g_dwWaitMask | EV_RXCHAR); //The driver need the EV_RXCHAR notify event.
- }
- case IOCTL_SERIAL_GET_WAIT_MASK:
- {
- if(dwBufOutSize < sizeof(DWORD) || GetCommMask(g_hCom,reinterpret_cast<DWORD *>(pBufOut)) == FALSE)
- {
- *pBytesReturned = 0;
- return FALSE;
- }
- else
- {
- *pBytesReturned = sizeof(DWORD);
- return TRUE;
- }
- }
- }
-
- return FALSE;
- }
-
- DWORD VSP_Read(DWORD dwHandle, LPVOID pBuffer, DWORD dwNumBytes)
- {
- EnterCriticalSection(&g_csRead);
-
- //The g_dwLenReadBuf must be less than or equal to g_vtBufRead.size(), so needn't compare with each other.
- DWORD dwCopy = g_dwLenReadBuf > dwNumBytes ? dwNumBytes : g_dwLenReadBuf;
- if(dwCopy != 0)
- {
- memcpy(pBuffer,&g_vtBufRead[0],dwCopy);
- }
- DEBUGMSG(TRUE,(TEXT("[VSP]:Copy cout:%d/r/n"),dwCopy));
-
- g_bReaded = TRUE;
-
- LeaveCriticalSection(&g_csRead);
-
- //Sleep for other thread to entry the function.
- Sleep(10);
-
-
- return dwCopy;
- }
-
- DWORD VSP_Write(DWORD dwHandle, LPCVOID pBuffer, DWORD dwNumBytes)
- {
- EnterCriticalSection(&g_csWrite);
- DWORD dwWrite = 0;
- WriteFile(g_hCom,pBuffer,dwNumBytes,&dwWrite,NULL);
- LeaveCriticalSection(&g_csWrite);
- return dwWrite;
- }
-
-
- DWORD VSP_Seek(DWORD dwHandle, long lDistance, DWORD dwMoveMethod)
- {
- return FALSE;
- }
-
- void VSP_PowerUp(void)
- {
- return;
- }
-
- void VSP_PowerDown(void)
- {
- return;
- }
|