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

Last change on this file since 284 was 284, checked in by gregli@…, 12 years ago

Increased the width of the drive Model name that the boot menu display, better accomodating serial drives on auto detect which include the COM port and baud rate information.

File size: 4.2 KB
Line 
1//======================================================================
2//
3// Project:     XTIDE Universal BIOS, Serial Port Server
4//
5// File:        Win32Serial.h - Microsoft Windows serial code
6//
7
8#include <stdio.h>
9#include "windows.h"
10#include "../library/library.h"
11
12#define PIPENAME "\\\\.\\pipe\\xtide"
13
14class SerialAccess
15{
16public:
17    void Connect( char *name, struct baudRate *p_baudRate )
18    {
19        char buff1[20], buff2[1024];
20
21        baudRate = p_baudRate;
22
23        pipe = NULL;
24   
25        if( !name )
26        {
27            for( int t = 1; t <= 30 && !name; t++ )
28            {
29                sprintf( buff1, "COM%d", t );
30                if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
31                    name = buff1;
32            }
33            if( !name )
34                log( -1, "No physical COM ports found" );
35        }
36
37        if( name[0] == '\\' && name[1] == '\\' )
38        {
39            log( 0, "Opening named pipe %s (simulating %s baud)", name, baudRate->display );
40       
41            pipe = CreateNamedPipeA( name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_REJECT_REMOTE_CLIENTS, 2, 1024, 1024, 0, NULL );
42            if( pipe == INVALID_HANDLE_VALUE )
43                log( -1, "Could not CreateNamedPipe " PIPENAME );
44       
45            if( !ConnectNamedPipe( pipe, NULL ) )
46                log( -1, "Could not ConnectNamedPipe" );
47
48            if( baudRate->divisor > 0x80 )
49                log( -1, "Cannot simulate baud rates with hardware multipliers" );
50
51            speedEmulation = 1;
52            resetConnection = 1;
53        }
54        else
55        {
56            if( QueryDosDeviceA( name, buff2, sizeof(buff2) ) )
57            {
58                COMMTIMEOUTS timeouts;
59                DCB dcb;
60
61                log( 0, "Opening %s (%s baud)", name, baudRate->display );
62           
63                pipe = CreateFileA( name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
64                if( pipe == INVALID_HANDLE_VALUE )
65                    log( -1, "Could not Open \"%s\"", name );
66           
67                FillMemory(&dcb, sizeof(dcb), 0);
68                FillMemory(&timeouts, sizeof(timeouts), 0);
69
70                dcb.DCBlength = sizeof(dcb);
71                dcb.BaudRate = baudRate->rate;
72                dcb.ByteSize = 8;
73                dcb.StopBits = ONESTOPBIT;
74                dcb.Parity = NOPARITY;
75                if( !SetCommState( pipe, &dcb ) )
76                {
77                    char *msg = "";
78                    COMMPROP comProp;
79
80                    if( GetCommProperties( pipe, &comProp ) )
81                    {
82                        if( comProp.dwMaxBaud != BAUD_USER )
83                            msg = "\n    On this COM port, baud rate is limited to 115.2K";
84                    }
85                    log( -1, "Could not SetCommState: baud rate selected may not be availabele%s", msg );
86                }
87
88                if( !SetCommTimeouts( pipe, &timeouts ) )
89                    log( -1, "Could not SetCommTimeouts" );
90            }
91            else
92            {
93                char logbuff[ 1024 ];
94
95                EnumerateCOMPorts( logbuff, 1024 );
96               
97                log( -1, "Serial port '%s' not found, detected COM ports: %s", name, logbuff );
98            }
99        }
100    }
101
102    static void EnumerateCOMPorts( char *logbuff, int logbuffLen )
103    {
104        int found = 0;
105        char buff1[20], buff2[1024];
106
107        logbuff[0] = 0;
108
109        for( int t = 1; t <= 40 && strlen(logbuff) < (logbuffLen - 40); t++ )
110        {
111            sprintf( buff1, "COM%d", t );
112            if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
113            {
114                if( found )
115                    strcat( logbuff, ", " );
116                strcat( logbuff, buff1 );
117                found = 1;
118            }
119        }
120
121        if( !found )
122            strcat( logbuff, "(none)" );
123    }
124
125    void Disconnect()
126    {
127        if( pipe )
128        {
129            CloseHandle( pipe );
130            pipe = NULL;
131        }
132    }
133
134    unsigned long readCharacters( void *buff, unsigned long len )
135    {
136        unsigned long readLen;
137        int ret;
138
139        ret = ReadFile( pipe, buff, len, &readLen, NULL );
140
141        if( !ret || readLen == 0 )
142        {
143            if( GetLastError() == ERROR_BROKEN_PIPE )
144                return( 0 );
145            else
146                log( -1, "read serial failed (error code %d)", GetLastError() );
147        }
148
149        return( readLen );
150    }
151
152    int writeCharacters( void *buff, unsigned long len )
153    {
154        unsigned long writeLen;
155        int ret;
156
157        ret = WriteFile( pipe, buff, len, &writeLen, NULL );
158
159        if( !ret || len != writeLen )
160        {
161            if( GetLastError() == ERROR_BROKEN_PIPE )
162                return( 0 );
163            else
164                log( -1, "write serial failed (error code %d)", GetLastError() );
165        }
166
167        return( 1 );
168    }
169
170    SerialAccess()
171    {
172        pipe = NULL;
173        speedEmulation = 0;
174        resetConnection = 0;
175        baudRate = NULL;
176    }
177
178    ~SerialAccess()
179    {
180        Disconnect();
181    }
182
183    int speedEmulation;
184    int resetConnection;
185
186    struct baudRate *baudRate;
187
188private:
189    HANDLE pipe;
190};
191
Note: See TracBrowser for help on using the repository browser.