source: xtideuniversalbios/trunk/Serial_Server/win32/Win32Serial.h@ 538

Last change on this file since 538 was 526, checked in by krille_n_@…, 11 years ago

Changes:

  • Update of the copyright notices to include the year 2013.
File size: 4.8 KB
RevLine 
[209]1//======================================================================
2//
3// Project: XTIDE Universal BIOS, Serial Port Server
4//
5// File: Win32Serial.h - Microsoft Windows serial code
6//
7
[376]8//
[526]9// XTIDE Universal BIOS and Associated Tools
10// Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]11//
12// This program is free software; you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation; either version 2 of the License, or
15// (at your option) any later version.
[526]16//
[376]17// This program is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
[526]20// GNU General Public License for more details.
[376]21// Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22//
23
[219]24#include <stdio.h>
[209]25#include "windows.h"
26#include "../library/library.h"
27
28#define PIPENAME "\\\\.\\pipe\\xtide"
29
[293]30class SerialAccess
[209]31{
32public:
[219]33 void Connect( char *name, struct baudRate *p_baudRate )
34 {
35 char buff1[20], buff2[1024];
[209]36
[219]37 baudRate = p_baudRate;
[209]38
[219]39 pipe = NULL;
[293]40
[219]41 if( !name )
42 {
43 for( int t = 1; t <= 30 && !name; t++ )
44 {
45 sprintf( buff1, "COM%d", t );
46 if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
47 name = buff1;
48 }
49 if( !name )
50 log( -1, "No physical COM ports found" );
51 }
52
[258]53 if( name[0] == '\\' && name[1] == '\\' )
[219]54 {
[258]55 log( 0, "Opening named pipe %s (simulating %s baud)", name, baudRate->display );
[293]56
[258]57 pipe = CreateNamedPipeA( name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_REJECT_REMOTE_CLIENTS, 2, 1024, 1024, 0, NULL );
[225]58 if( pipe == INVALID_HANDLE_VALUE )
[219]59 log( -1, "Could not CreateNamedPipe " PIPENAME );
[293]60
[219]61 if( !ConnectNamedPipe( pipe, NULL ) )
62 log( -1, "Could not ConnectNamedPipe" );
63
[284]64 if( baudRate->divisor > 0x80 )
[219]65 log( -1, "Cannot simulate baud rates with hardware multipliers" );
66
67 speedEmulation = 1;
68 resetConnection = 1;
69 }
70 else
71 {
72 if( QueryDosDeviceA( name, buff2, sizeof(buff2) ) )
73 {
74 COMMTIMEOUTS timeouts;
75 DCB dcb;
76
[258]77 log( 0, "Opening %s (%s baud)", name, baudRate->display );
[293]78
[219]79 pipe = CreateFileA( name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
[225]80 if( pipe == INVALID_HANDLE_VALUE )
[219]81 log( -1, "Could not Open \"%s\"", name );
[293]82
[219]83 FillMemory(&dcb, sizeof(dcb), 0);
84 FillMemory(&timeouts, sizeof(timeouts), 0);
85
86 dcb.DCBlength = sizeof(dcb);
87 dcb.BaudRate = baudRate->rate;
88 dcb.ByteSize = 8;
89 dcb.StopBits = ONESTOPBIT;
90 dcb.Parity = NOPARITY;
91 if( !SetCommState( pipe, &dcb ) )
[258]92 {
93 char *msg = "";
94 COMMPROP comProp;
[219]95
[258]96 if( GetCommProperties( pipe, &comProp ) )
97 {
98 if( comProp.dwMaxBaud != BAUD_USER )
99 msg = "\n On this COM port, baud rate is limited to 115.2K";
100 }
[293]101 log( -1, "Could not SetCommState: baud rate selected may not be available%s", msg );
[258]102 }
103
[219]104 if( !SetCommTimeouts( pipe, &timeouts ) )
105 log( -1, "Could not SetCommTimeouts" );
106 }
107 else
108 {
109 char logbuff[ 1024 ];
110
[258]111 EnumerateCOMPorts( logbuff, 1024 );
[293]112
[258]113 log( -1, "Serial port '%s' not found, detected COM ports: %s", name, logbuff );
[219]114 }
115 }
116 }
117
[258]118 static void EnumerateCOMPorts( char *logbuff, int logbuffLen )
119 {
120 int found = 0;
121 char buff1[20], buff2[1024];
122
123 logbuff[0] = 0;
124
125 for( int t = 1; t <= 40 && strlen(logbuff) < (logbuffLen - 40); t++ )
126 {
127 sprintf( buff1, "COM%d", t );
128 if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
129 {
130 if( found )
131 strcat( logbuff, ", " );
132 strcat( logbuff, buff1 );
133 found = 1;
134 }
135 }
136
137 if( !found )
138 strcat( logbuff, "(none)" );
139 }
140
[219]141 void Disconnect()
142 {
143 if( pipe )
144 {
145 CloseHandle( pipe );
146 pipe = NULL;
147 }
148 }
149
150 unsigned long readCharacters( void *buff, unsigned long len )
151 {
152 unsigned long readLen;
153 int ret;
154
155 ret = ReadFile( pipe, buff, len, &readLen, NULL );
156
157 if( !ret || readLen == 0 )
158 {
159 if( GetLastError() == ERROR_BROKEN_PIPE )
160 return( 0 );
161 else
162 log( -1, "read serial failed (error code %d)", GetLastError() );
163 }
164
165 return( readLen );
166 }
167
168 int writeCharacters( void *buff, unsigned long len )
169 {
170 unsigned long writeLen;
171 int ret;
172
173 ret = WriteFile( pipe, buff, len, &writeLen, NULL );
174
175 if( !ret || len != writeLen )
176 {
177 if( GetLastError() == ERROR_BROKEN_PIPE )
178 return( 0 );
179 else
180 log( -1, "write serial failed (error code %d)", GetLastError() );
181 }
182
183 return( 1 );
184 }
185
186 SerialAccess()
187 {
188 pipe = NULL;
189 speedEmulation = 0;
190 resetConnection = 0;
191 baudRate = NULL;
192 }
193
194 ~SerialAccess()
195 {
196 Disconnect();
197 }
198
199 int speedEmulation;
200 int resetConnection;
201
202 struct baudRate *baudRate;
203
[209]204private:
205 HANDLE pipe;
206};
207
Note: See TracBrowser for help on using the repository browser.