// ------------------------------- // // -------- Start of File -------- // // ------------------------------- // // ----------------------------------------------------------- // // C++ Source Code File Name: r_win32.cpp // C++ Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC // Produced By: DataReel Software Development Team // File Creation Date: 09/20/1999 // Date Last Modified: 06/17/2016 // Copyright (c) 2001-2024 DataReel Software Development // ----------------------------------------------------------- // // ------------- Program Description and Details ------------- // // ----------------------------------------------------------- // /* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Code used by Win32 applications to read and write data to and from a serial port using overlapped I/O. */ // ----------------------------------------------------------- // #include "gxdlcode.h" void PrintError(LPCSTR str) { LPVOID lpMessageBuffer; int error = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMessageBuffer, 0, NULL); cout << str << ": " << error << " " << lpMessageBuffer << "\n"; LocalFree(lpMessageBuffer); } DWORD CALLBACK ConsoleThread(HANDLE h) // Starts a user input thread using the console. // Takes console characters and sends them to the com port. { OVERLAPPED ov; HANDLE hconn = GetStdHandle(STD_INPUT_HANDLE); BOOL quit = FALSE; ZeroMemory(&ov, sizeof(ov)); ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(ov.hEvent == INVALID_HANDLE_VALUE) { PrintError("CreateEvent failed"); SetCommMask(h, 0); return 0; } SetConsoleMode(hconn, 0); cout << "Waiting to receive..." << "\n"; cout << "Press Esc to terminate." << "\n"; do { char buf[10]; DWORD bytes_read = 0; // Wait for user data WaitForSingleObject(hconn, INFINITE); // Read the console buffer if(!ReadConsole(hconn, buf, sizeof(buf), &bytes_read, NULL)) { PrintError("ReadConsole failed"); quit = TRUE; } if(bytes_read) { DWORD write; // Check for Esc key for(write=0; write < bytes_read; write++) { // Terminate when Esc key is pressed if(buf[write] == 0x1b) { quit = TRUE; break; } } // Send data to the serial device if(write) { if(!WriteFile(h, buf, write, &write, &ov)) { if(GetLastError() == ERROR_IO_PENDING) { if(!GetOverlappedResult(h, &ov, &write, TRUE)) { PrintError("GetOverlappedResult failed"); quit = TRUE; } } } else { PrintError("WriteFile failed"); quit = TRUE; } } } } while(!quit); // Signal the terminal thread to quit SetCommMask(h, 0); return 0; } void SerialRead(gxSerialComm *dev, char *dumpfile = 0) { DiskFileB outfile; if(dumpfile) { cout << "Writing output to the " << dumpfile << " file" << "\n"; outfile.df_Open(dumpfile); if(!outfile) { cout << "\n"; cout << "Cannot open the: " << dumpfile << " capture file" << "\n"; cout << "Exiting..." << "\n"; cout << "\n"; return; } } HANDLE hconn = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE h = dev->DeviceHandle(); DWORD mask; DWORD id; OVERLAPPED ov; HANDLE hConsole = CreateThread(NULL, 0, ConsoleThread, h, 0, &id); if(hConsole == INVALID_HANDLE_VALUE) { PrintError("CreateThread failed"); return; } CloseHandle(hConsole); ZeroMemory(&ov, sizeof(ov)); // Create event for overlapped I/O ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(ov.hEvent == INVALID_HANDLE_VALUE) PrintError("CreateEvent failed"); // Wait for received characters if(!SetCommMask(h, EV_RXCHAR)) PrintError("SetCommMask failed"); while(1) { // Get the event mask if(!WaitCommEvent(h, &mask, &ov)) { DWORD e = GetLastError(); if(e == ERROR_IO_PENDING) { DWORD r; if(!GetOverlappedResult(h, &ov, &r, TRUE)) { PrintError("GetOverlappedResult failed"); break; } } else { PrintError("WaitCommEvent failed"); break; } } // If no event, then UI thread terminated with SetCommMask(h, 0) if(mask == 0) { break; } if(mask & EV_RXCHAR) { char buf[10]; DWORD bytes_read; do { bytes_read = 0; if(!ReadFile(h, buf, sizeof(buf), &bytes_read, &ov)) { if(GetLastError() == ERROR_IO_PENDING) { if(!GetOverlappedResult(h, &ov, &bytes_read, TRUE)) { PrintError("GetOverlappedResult failed"); break; } } else { PrintError("ReadFile failed"); break; } } if(bytes_read) { if(dumpfile) { // Capture the data to a file outfile.df_Write((char *)buf, bytes_read); outfile.df_Flush(); } else // Write the data to the console WriteFile(hconn, buf, bytes_read, &bytes_read, NULL); } } while(bytes_read); } mask = 0; } outfile.df_Close(); CloseHandle(ov.hEvent); // Close the event } // ----------------------------------------------------------- // // ------------------------------- // // --------- End of File --------- // // ------------------------------- //