diff --git a/winpr/include/winpr/comm.h b/winpr/include/winpr/comm.h new file mode 100644 index 000000000..7179080c6 --- /dev/null +++ b/winpr/include/winpr/comm.h @@ -0,0 +1,344 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_COMM_H +#define WINPR_COMM_H + +#include +#include + +#include + +#ifndef _WIN32 + +#define NOPARITY 0 +#define ODDPARITY 1 +#define EVENPARITY 2 +#define MARKPARITY 3 +#define SPACEPARITY 4 + +#define ONESTOPBIT 0 +#define ONE5STOPBITS 1 +#define TWOSTOPBITS 2 + +#ifndef IGNORE +#define IGNORE 0 +#endif + +#define CBR_110 110 +#define CBR_300 300 +#define CBR_600 600 +#define CBR_1200 1200 +#define CBR_2400 2400 +#define CBR_4800 4800 +#define CBR_9600 9600 +#define CBR_14400 14400 +#define CBR_19200 19200 +#define CBR_38400 38400 +#define CBR_56000 56000 +#define CBR_57600 57600 +#define CBR_115200 115200 +#define CBR_128000 128000 +#define CBR_256000 256000 + +#define CE_RXOVER 0x0001 +#define CE_OVERRUN 0x0002 +#define CE_RXPARITY 0x0004 +#define CE_FRAME 0x0008 +#define CE_BREAK 0x0010 +#define CE_TXFULL 0x0100 +#define CE_PTO 0x0200 +#define CE_IOE 0x0400 +#define CE_DNS 0x0800 +#define CE_OOP 0x1000 +#define CE_MODE 0x8000 + +#define IE_BADID (-1) +#define IE_OPEN (-2) +#define IE_NOPEN (-3) +#define IE_MEMORY (-4) +#define IE_DEFAULT (-5) +#define IE_HARDWARE (-10) +#define IE_BYTESIZE (-11) +#define IE_BAUDRATE (-12) + +#define EV_RXCHAR 0x0001 +#define EV_RXFLAG 0x0002 +#define EV_TXEMPTY 0x0004 +#define EV_CTS 0x0008 +#define EV_DSR 0x0010 +#define EV_RLSD 0x0020 +#define EV_BREAK 0x0040 +#define EV_ERR 0x0080 +#define EV_RING 0x0100 +#define EV_PERR 0x0200 +#define EV_RX80FULL 0x0400 +#define EV_EVENT1 0x0800 +#define EV_EVENT2 0x1000 + +#define SETXOFF 1 +#define SETXON 2 +#define SETRTS 3 +#define CLRRTS 4 +#define SETDTR 5 +#define CLRDTR 6 +#define RESETDEV 7 +#define SETBREAK 8 +#define CLRBREAK 9 + +#define PURGE_TXABORT 0x0001 +#define PURGE_RXABORT 0x0002 +#define PURGE_TXCLEAR 0x0004 +#define PURGE_RXCLEAR 0x0008 + +#define LPTx 0x80 + +#define MS_CTS_ON ((DWORD)0x0010) +#define MS_DSR_ON ((DWORD)0x0020) +#define MS_RING_ON ((DWORD)0x0040) +#define MS_RLSD_ON ((DWORD)0x0080) + +#define SP_SERIALCOMM ((DWORD)0x00000001) + +#define PST_UNSPECIFIED ((DWORD)0x00000000) +#define PST_RS232 ((DWORD)0x00000001) +#define PST_PARALLELPORT ((DWORD)0x00000002) +#define PST_RS422 ((DWORD)0x00000003) +#define PST_RS423 ((DWORD)0x00000004) +#define PST_RS449 ((DWORD)0x00000005) +#define PST_MODEM ((DWORD)0x00000006) +#define PST_FAX ((DWORD)0x00000021) +#define PST_SCANNER ((DWORD)0x00000022) +#define PST_NETWORK_BRIDGE ((DWORD)0x00000100) +#define PST_LAT ((DWORD)0x00000101) +#define PST_TCPIP_TELNET ((DWORD)0x00000102) +#define PST_X25 ((DWORD)0x00000103) + +#define PCF_DTRDSR ((DWORD)0x0001) +#define PCF_RTSCTS ((DWORD)0x0002) +#define PCF_RLSD ((DWORD)0x0004) +#define PCF_PARITY_CHECK ((DWORD)0x0008) +#define PCF_XONXOFF ((DWORD)0x0010) +#define PCF_SETXCHAR ((DWORD)0x0020) +#define PCF_TOTALTIMEOUTS ((DWORD)0x0040) +#define PCF_INTTIMEOUTS ((DWORD)0x0080) +#define PCF_SPECIALCHARS ((DWORD)0x0100) +#define PCF_16BITMODE ((DWORD)0x0200) + +#define SP_PARITY ((DWORD)0x0001) +#define SP_BAUD ((DWORD)0x0002) +#define SP_DATABITS ((DWORD)0x0004) +#define SP_STOPBITS ((DWORD)0x0008) +#define SP_HANDSHAKING ((DWORD)0x0010) +#define SP_PARITY_CHECK ((DWORD)0x0020) +#define SP_RLSD ((DWORD)0x0040) + +#define BAUD_075 ((DWORD)0x00000001) +#define BAUD_110 ((DWORD)0x00000002) +#define BAUD_134_5 ((DWORD)0x00000004) +#define BAUD_150 ((DWORD)0x00000008) +#define BAUD_300 ((DWORD)0x00000010) +#define BAUD_600 ((DWORD)0x00000020) +#define BAUD_1200 ((DWORD)0x00000040) +#define BAUD_1800 ((DWORD)0x00000080) +#define BAUD_2400 ((DWORD)0x00000100) +#define BAUD_4800 ((DWORD)0x00000200) +#define BAUD_7200 ((DWORD)0x00000400) +#define BAUD_9600 ((DWORD)0x00000800) +#define BAUD_14400 ((DWORD)0x00001000) +#define BAUD_19200 ((DWORD)0x00002000) +#define BAUD_38400 ((DWORD)0x00004000) +#define BAUD_56K ((DWORD)0x00008000) +#define BAUD_128K ((DWORD)0x00010000) +#define BAUD_115200 ((DWORD)0x00020000) +#define BAUD_57600 ((DWORD)0x00040000) +#define BAUD_USER ((DWORD)0x10000000) + +#define DATABITS_5 ((WORD)0x0001) +#define DATABITS_6 ((WORD)0x0002) +#define DATABITS_7 ((WORD)0x0004) +#define DATABITS_8 ((WORD)0x0008) +#define DATABITS_16 ((WORD)0x0010) +#define DATABITS_16X ((WORD)0x0020) + +#define STOPBITS_10 ((WORD)0x0001) +#define STOPBITS_15 ((WORD)0x0002) +#define STOPBITS_20 ((WORD)0x0004) + +#define PARITY_NONE ((WORD)0x0100) +#define PARITY_ODD ((WORD)0x0200) +#define PARITY_EVEN ((WORD)0x0400) +#define PARITY_MARK ((WORD)0x0800) +#define PARITY_SPACE ((WORD)0x1000) + +#define COMMPROP_INITIALIZED ((DWORD)0xE73CF52E) + +#define DTR_CONTROL_DISABLE 0x00 +#define DTR_CONTROL_ENABLE 0x01 +#define DTR_CONTROL_HANDSHAKE 0x02 + +#define RTS_CONTROL_DISABLE 0x00 +#define RTS_CONTROL_ENABLE 0x01 +#define RTS_CONTROL_HANDSHAKE 0x02 +#define RTS_CONTROL_TOGGLE 0x03 + +typedef struct _DCB +{ + DWORD DCBlength; + DWORD BaudRate; + DWORD fBinary:1; + DWORD fParity:1; + DWORD fOutxCtsFlow:1; + DWORD fOutxDsrFlow:1; + DWORD fDtrControl:2; + DWORD fDsrSensitivity:1; + DWORD fTXContinueOnXoff:1; + DWORD fOutX:1; + DWORD fInX:1; + DWORD fErrorChar:1; + DWORD fNull:1; + DWORD fRtsControl:2; + DWORD fAbortOnError:1; + DWORD fDummy2:17; + WORD wReserved; + WORD XonLim; + WORD XoffLim; + BYTE ByteSize; + BYTE Parity; + BYTE StopBits; + char XonChar; + char XoffChar; + char ErrorChar; + char EofChar; + char EvtChar; + WORD wReserved1; +} DCB, *LPDCB; + +typedef struct _COMM_CONFIG +{ + DWORD dwSize; + WORD wVersion; + WORD wReserved; + DCB dcb; + DWORD dwProviderSubType; + DWORD dwProviderOffset; + DWORD dwProviderSize; + WCHAR wcProviderData[1]; +} COMMCONFIG, *LPCOMMCONFIG; + +typedef struct _COMMPROP +{ + WORD wPacketLength; + WORD wPacketVersion; + DWORD dwServiceMask; + DWORD dwReserved1; + DWORD dwMaxTxQueue; + DWORD dwMaxRxQueue; + DWORD dwMaxBaud; + DWORD dwProvSubType; + DWORD dwProvCapabilities; + DWORD dwSettableParams; + DWORD dwSettableBaud; + WORD wSettableData; + WORD wSettableStopParity; + DWORD dwCurrentTxQueue; + DWORD dwCurrentRxQueue; + DWORD dwProvSpec1; + DWORD dwProvSpec2; + WCHAR wcProvChar[1]; +} COMMPROP, *LPCOMMPROP; + +typedef struct _COMMTIMEOUTS +{ + DWORD ReadIntervalTimeout; + DWORD ReadTotalTimeoutMultiplier; + DWORD ReadTotalTimeoutConstant; + DWORD WriteTotalTimeoutMultiplier; + DWORD WriteTotalTimeoutConstant; +} COMMTIMEOUTS, *LPCOMMTIMEOUTS; + +typedef struct _COMSTAT +{ + DWORD fCtsHold:1; + DWORD fDsrHold:1; + DWORD fRlsdHold:1; + DWORD fXoffHold:1; + DWORD fXoffSent:1; + DWORD fEof:1; + DWORD fTxim:1; + DWORD fReserved:25; + DWORD cbInQue; + DWORD cbOutQue; +} COMSTAT, *LPCOMSTAT; + +#ifdef __cplusplus +extern "C" { +#endif + +WINPR_API BOOL BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB); +WINPR_API BOOL BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB); + +WINPR_API BOOL BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts); +WINPR_API BOOL BuildCommDCBAndTimeoutsW(LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts); + +WINPR_API BOOL CommConfigDialogA(LPCSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC); +WINPR_API BOOL CommConfigDialogW(LPCWSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC); + +WINPR_API BOOL GetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize); +WINPR_API BOOL SetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, DWORD dwSize); + +WINPR_API BOOL GetCommMask(HANDLE hFile, PDWORD lpEvtMask); +WINPR_API BOOL SetCommMask(HANDLE hFile, DWORD dwEvtMask); + +WINPR_API BOOL GetCommModemStatus(HANDLE hFile, PDWORD lpModemStat); +WINPR_API BOOL GetCommProperties(HANDLE hFile, LPCOMMPROP lpCommProp); + +WINPR_API BOOL GetCommState(HANDLE hFile, LPDCB lpDCB); +WINPR_API BOOL SetCommState(HANDLE hFile, LPDCB lpDCB); + +WINPR_API BOOL GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts); +WINPR_API BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts); + +WINPR_API BOOL GetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize); +WINPR_API BOOL GetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize); + +WINPR_API BOOL SetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize); +WINPR_API BOOL SetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize); + +WINPR_API BOOL SetCommBreak(HANDLE hFile); +WINPR_API BOOL ClearCommBreak(HANDLE hFile); +WINPR_API BOOL ClearCommError(HANDLE hFile, PDWORD lpErrors, LPCOMSTAT lpStat); + +WINPR_API BOOL PurgeComm(HANDLE hFile, DWORD dwFlags); +WINPR_API BOOL SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue); + +WINPR_API BOOL EscapeCommFunction(HANDLE hFile, DWORD dwFunc); + +WINPR_API BOOL TransmitCommChar(HANDLE hFile, char cChar); + +WINPR_API BOOL WaitCommEvent(HANDLE hFile, PDWORD lpEvtMask, LPOVERLAPPED lpOverlapped); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* WINPR_COMM_H */ + diff --git a/winpr/include/winpr/pipe.h b/winpr/include/winpr/pipe.h index 5c5b12f0f..c06f299ca 100644 --- a/winpr/include/winpr/pipe.h +++ b/winpr/include/winpr/pipe.h @@ -110,6 +110,7 @@ WINPR_API BOOL GetNamedPipeClientComputerNameW(HANDLE Pipe, LPCWSTR ClientComput * Extended API */ +WINPR_API BOOL IsNamedPipeFileNameA(LPCSTR lpName); WINPR_API char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName); WINPR_API char* GetNamedPipeUnixDomainSocketBaseFilePathA(); WINPR_API char* GetNamedPipeUnixDomainSocketFilePathA(LPCSTR lpName); diff --git a/winpr/libwinpr/comm/CMakeLists.txt b/winpr/libwinpr/comm/CMakeLists.txt new file mode 100644 index 000000000..f13d67cff --- /dev/null +++ b/winpr/libwinpr/comm/CMakeLists.txt @@ -0,0 +1,52 @@ +# WinPR: Windows Portable Runtime +# libwinpr-comm cmake build script +# +# Copyright 2014 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "winpr-comm") +set(MODULE_PREFIX "WINPR_COMM") + +set(${MODULE_PREFIX}_SRCS + comm.c + comm.h) + +if(MSVC AND (NOT MONOLITHIC_BUILD)) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) +endif() + +add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" + MONOLITHIC ${MONOLITHIC_BUILD} + SOURCES ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL + MODULE winpr + MODULES winpr-crt winpr-thread winpr-synch winpr-utils) + +if(MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) +else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT WinPRTargets) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() + diff --git a/winpr/libwinpr/comm/ModuleOptions.cmake b/winpr/libwinpr/comm/ModuleOptions.cmake new file mode 100644 index 000000000..40955892a --- /dev/null +++ b/winpr/libwinpr/comm/ModuleOptions.cmake @@ -0,0 +1,9 @@ + +set(MINWIN_LAYER "1") +set(MINWIN_GROUP "core") +set(MINWIN_MAJOR_VERSION "1") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "comm") +set(MINWIN_LONG_NAME "Serial Communication API") +set(MODULE_LIBRARY_NAME "api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}") + diff --git a/winpr/libwinpr/comm/comm.c b/winpr/libwinpr/comm/comm.c new file mode 100644 index 000000000..f91055b69 --- /dev/null +++ b/winpr/libwinpr/comm/comm.c @@ -0,0 +1,266 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +/** + * Communication Resources: + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa363196/ + */ + +#ifndef _WIN32 + +#include "comm.h" + +BOOL BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB) +{ + return TRUE; +} + +BOOL BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB) +{ + return TRUE; +} + +BOOL BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts) +{ + return TRUE; +} + +BOOL BuildCommDCBAndTimeoutsW(LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts) +{ + return TRUE; +} + +BOOL CommConfigDialogA(LPCSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC) +{ + return TRUE; +} + +BOOL CommConfigDialogW(LPCWSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC) +{ + return TRUE; +} + +BOOL GetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hCommDev; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL SetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, DWORD dwSize) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hCommDev; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL GetCommMask(HANDLE hFile, PDWORD lpEvtMask) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL SetCommMask(HANDLE hFile, DWORD dwEvtMask) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL GetCommModemStatus(HANDLE hFile, PDWORD lpModemStat) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL GetCommProperties(HANDLE hFile, LPCOMMPROP lpCommProp) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL GetCommState(HANDLE hFile, LPDCB lpDCB) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL SetCommState(HANDLE hFile, LPDCB lpDCB) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL GetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize) +{ + return TRUE; +} + +BOOL GetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize) +{ + return TRUE; +} + +BOOL SetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize) +{ + return TRUE; +} + +BOOL SetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize) +{ + return TRUE; +} + +BOOL SetCommBreak(HANDLE hFile) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL ClearCommBreak(HANDLE hFile) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL ClearCommError(HANDLE hFile, PDWORD lpErrors, LPCOMSTAT lpStat) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL PurgeComm(HANDLE hFile, DWORD dwFlags) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL EscapeCommFunction(HANDLE hFile, DWORD dwFunc) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL TransmitCommChar(HANDLE hFile, char cChar) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +BOOL WaitCommEvent(HANDLE hFile, PDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) +{ + WINPR_COMM* pComm = (WINPR_COMM*) hFile; + + if (!pComm) + return FALSE; + + return TRUE; +} + +#endif diff --git a/winpr/libwinpr/comm/comm.h b/winpr/libwinpr/comm/comm.h new file mode 100644 index 000000000..a912b21cd --- /dev/null +++ b/winpr/libwinpr/comm/comm.h @@ -0,0 +1,39 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_COMM_PRIVATE_H +#define WINPR_COMM_PRIVATE_H + +#ifndef _WIN32 + +#include + +#include "../handle/handle.h" + +struct winpr_comm +{ + WINPR_HANDLE_DEF(); + + int fd; +}; +typedef struct winpr_comm WINPR_COMM; + +#endif + +#endif /* WINPR_COMM_PRIVATE_H */ diff --git a/winpr/libwinpr/comm/module.def b/winpr/libwinpr/comm/module.def new file mode 100644 index 000000000..fc26e7287 --- /dev/null +++ b/winpr/libwinpr/comm/module.def @@ -0,0 +1,3 @@ +LIBRARY "libwinpr-comm" +EXPORTS + diff --git a/winpr/libwinpr/comm/test/.gitignore b/winpr/libwinpr/comm/test/.gitignore new file mode 100644 index 000000000..78bb24b78 --- /dev/null +++ b/winpr/libwinpr/comm/test/.gitignore @@ -0,0 +1,2 @@ +TestComm +TestComm.c diff --git a/winpr/libwinpr/comm/test/CMakeLists.txt b/winpr/libwinpr/comm/test/CMakeLists.txt new file mode 100644 index 000000000..0291bcdc4 --- /dev/null +++ b/winpr/libwinpr/comm/test/CMakeLists.txt @@ -0,0 +1,32 @@ + +set(MODULE_NAME "TestComm") +set(MODULE_PREFIX "TEST_COMM") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestCommConfig.c + TestCommMonitor.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-comm winpr-crt) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/comm/test/TestCommConfig.c b/winpr/libwinpr/comm/test/TestCommConfig.c new file mode 100644 index 000000000..ce128bfc2 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestCommConfig.c @@ -0,0 +1,66 @@ + +#include +#include +#include +#include +#include + +int TestCommConfig(int argc, char* argv[]) +{ + DCB dcb; + HANDLE hComm; + BOOL fSuccess; + LPCSTR lpFileName = "\\\\.\\COM1"; + + hComm = CreateFileA(lpFileName, + GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (!hComm || (hComm == INVALID_HANDLE_VALUE)) + { + printf("CreateFileA failure: %s\n", lpFileName); + return 0; + } + + ZeroMemory(&dcb, sizeof(DCB)); + + fSuccess = GetCommState(hComm, &dcb); + + if (!fSuccess) + { + printf("GetCommState failure: GetLastError() = %d\n", (int) GetLastError()); + return 0; + } + + printf("BaudRate: %d ByteSize: %d Parity: %d StopBits: %d\n", + (int) dcb.BaudRate, (int) dcb.ByteSize, (int) dcb.Parity, (int) dcb.StopBits); + + dcb.BaudRate = CBR_57600; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + + fSuccess = SetCommState(hComm, &dcb); + + if (!fSuccess) + { + printf("SetCommState failure: GetLastError() = %d\n", (int) GetLastError()); + return 0; + } + + fSuccess = GetCommState(hComm, &dcb); + + if (!fSuccess) + { + printf("GetCommState failure: GetLastError() = %d\n", (int) GetLastError()); + return 0; + } + + printf("BaudRate: %d ByteSize: %d Parity: %d StopBits: %d\n", + (int) dcb.BaudRate, (int) dcb.ByteSize, (int) dcb.Parity, (int) dcb.StopBits); + + CloseHandle(hComm); + + return 0; +} + diff --git a/winpr/libwinpr/comm/test/TestCommMonitor.c b/winpr/libwinpr/comm/test/TestCommMonitor.c new file mode 100644 index 000000000..1154b2789 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestCommMonitor.c @@ -0,0 +1,69 @@ + +#include +#include +#include +#include +#include + +int TestCommMonitor(int argc, char* argv[]) +{ + HANDLE hComm; + DWORD dwError; + BOOL fSuccess; + DWORD dwEvtMask; + OVERLAPPED overlapped; + LPCSTR lpFileName = "\\\\.\\COM1"; + + hComm = CreateFileA(lpFileName, + GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + + if (!hComm || (hComm == INVALID_HANDLE_VALUE)) + { + printf("CreateFileA failure: %s\n", lpFileName); + return 0; + } + + fSuccess = SetCommMask(hComm, EV_CTS | EV_DSR); + + if (!fSuccess) + { + printf("SetCommMask failure: GetLastError() = %d\n", (int) GetLastError()); + return 0; + } + + ZeroMemory(&overlapped, sizeof(OVERLAPPED)); + overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (WaitCommEvent(hComm, &dwEvtMask, &overlapped)) + { + if (dwEvtMask & EV_DSR) + { + printf("EV_DSR\n"); + } + + if (dwEvtMask & EV_CTS) + { + printf("EV_CTS\n"); + } + } + else + { + dwError = GetLastError(); + + if (dwError == ERROR_IO_PENDING) + { + printf("ERROR_IO_PENDING\n"); + } + else + { + printf("WaitCommEvent failure: GetLastError() = %d\n", (int) dwError); + return 0; + } + } + + CloseHandle(hComm); + + return 0; +} + diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 95a71887f..9e824bd57 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -183,6 +183,7 @@ #include "../handle/handle.h" #include "../pipe/pipe.h" +#include "../comm/comm.h" #ifdef HAVE_AIO_H @@ -227,6 +228,19 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, if (!lpFileName) return INVALID_HANDLE_VALUE; + if (!IsNamedPipeFileNameA(lpFileName)) + { + HANDLE hComm; + WINPR_COMM* pComm; + + pComm = (WINPR_COMM*) calloc(1, sizeof(WINPR_COMM)); + hComm = (HANDLE) pComm; + + WINPR_HANDLE_SET_TYPE(pComm, HANDLE_TYPE_COMM); + + return hComm; + } + name = GetNamedPipeNameWithoutPrefixA(lpFileName); if (!name) @@ -809,6 +823,14 @@ BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttrib #define NAMED_PIPE_PREFIX_PATH "\\\\.\\pipe\\" +BOOL IsNamedPipeFileNameA(LPCSTR lpName) +{ + if (strncmp(lpName, NAMED_PIPE_PREFIX_PATH, sizeof(NAMED_PIPE_PREFIX_PATH) - 1) != 0) + return FALSE; + + return TRUE; +} + char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName) { char* lpFileName; @@ -816,7 +838,7 @@ char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName) if (!lpName) return NULL; - if (strncmp(lpName, NAMED_PIPE_PREFIX_PATH, sizeof(NAMED_PIPE_PREFIX_PATH) - 1) != 0) + if (!IsNamedPipeFileNameA(lpName)) return NULL; lpFileName = _strdup(&lpName[strlen(NAMED_PIPE_PREFIX_PATH)]); diff --git a/winpr/libwinpr/handle/handle.c b/winpr/libwinpr/handle/handle.c index 929ee0399..7d56d9717 100644 --- a/winpr/libwinpr/handle/handle.c +++ b/winpr/libwinpr/handle/handle.c @@ -28,6 +28,7 @@ #include "../synch/synch.h" #include "../thread/thread.h" #include "../pipe/pipe.h" +#include "../comm/comm.h" #include "../security/security.h" #ifdef HAVE_UNISTD_H @@ -194,6 +195,14 @@ BOOL CloseHandle(HANDLE hObject) free(token); } + else if (Type == HANDLE_TYPE_COMM) + { + WINPR_COMM* comm; + + comm = (WINPR_COMM*) Object; + + free(comm); + } return FALSE; } diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h index f9075e114..e5b6bae72 100644 --- a/winpr/libwinpr/handle/handle.h +++ b/winpr/libwinpr/handle/handle.h @@ -35,6 +35,7 @@ #define HANDLE_TYPE_FILE 10 #define HANDLE_TYPE_TIMER_QUEUE 11 #define HANDLE_TYPE_TIMER_QUEUE_TIMER 12 +#define HANDLE_TYPE_COMM 13 #define WINPR_HANDLE_DEF() \ ULONG Type