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

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

Changes:

  • Update of the copyright notices to include the year 2013.
File size: 4.8 KB
Line 
1//======================================================================
2//
3// Project: XTIDE Universal BIOS, Serial Port Server
4//
5// File: Win32Serial.h - Microsoft Windows serial code
6//
7
8//
9// XTIDE Universal BIOS and Associated Tools
10// Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
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.
16//
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
20// GNU General Public License for more details.
21// Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22//
23
24#include <stdio.h>
25#include "windows.h"
26#include "../library/library.h"
27
28#define PIPENAME "\\\\.\\pipe\\xtide"
29
30class SerialAccess
31{
32public:
33 void Connect( char *name, struct baudRate *p_baudRate )
34 {
35 char buff1[20], buff2[1024];
36
37 baudRate = p_baudRate;
38
39 pipe = NULL;
40
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
53 if( name[0] == '\\' && name[1] == '\\' )
54 {
55 log( 0, "Opening named pipe %s (simulating %s baud)", name, baudRate->display );
56
57 pipe = CreateNamedPipeA( name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_REJECT_REMOTE_CLIENTS, 2, 1024, 1024, 0, NULL );
58 if( pipe == INVALID_HANDLE_VALUE )
59 log( -1, "Could not CreateNamedPipe " PIPENAME );
60
61 if( !ConnectNamedPipe( pipe, NULL ) )
62 log( -1, "Could not ConnectNamedPipe" );
63
64 if( baudRate->divisor > 0x80 )
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
77 log( 0, "Opening %s (%s baud)", name, baudRate->display );
78
79 pipe = CreateFileA( name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
80 if( pipe == INVALID_HANDLE_VALUE )
81 log( -1, "Could not Open \"%s\"", name );
82
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 ) )
92 {
93 char *msg = "";
94 COMMPROP comProp;
95
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 }
101 log( -1, "Could not SetCommState: baud rate selected may not be available%s", msg );
102 }
103
104 if( !SetCommTimeouts( pipe, &timeouts ) )
105 log( -1, "Could not SetCommTimeouts" );
106 }
107 else
108 {
109 char logbuff[ 1024 ];
110
111 EnumerateCOMPorts( logbuff, 1024 );
112
113 log( -1, "Serial port '%s' not found, detected COM ports: %s", name, logbuff );
114 }
115 }
116 }
117
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
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
204private:
205 HANDLE pipe;
206};
207
Note: See TracBrowser for help on using the repository browser.