Index: /trunk/Serial_Server/library/File.h
===================================================================
--- /trunk/Serial_Server/library/File.h	(revision 219)
+++ /trunk/Serial_Server/library/File.h	(revision 219)
@@ -0,0 +1,95 @@
+//======================================================================
+//
+// Project:     XTIDE Universal BIOS, Serial Port Server
+//
+// File:        file.h - File access via standard "stdio.h" routines
+//
+// Routines for accessing the file system using generic routines, which
+// should work on all systems.  The issue with using these is that 
+// ftell() and fseek() are limited to 2 GB files (signed 32-bit quantities)
+// and there is no standard for 64-bit quantities.  So, look for a 
+// OS specific version of this file in the distribution, such as 
+// win32/win32file.h which may be in use instead.
+// 
+
+#include <stdio.h>
+
+class FileAccess
+{
+public:
+	void Create( char *p_name )
+	{
+		fp = fopen( p_name, "r" );
+
+		if( fp )
+			log( -1, "Create Failure: '%s' already exists", p_name );
+		
+		if( !(fp = fopen( p_name, "w" )) )
+			log( -1, "Could not create file '%s'", p_name );
+
+		name = p_name;
+	}
+
+	void Open( char *p_name )
+	{
+		fp = fopen( p_name, "r+" );
+		if( !fp )
+			log( -1, "Could not Open '%s'", p_name );
+		name = p_name;
+	}
+
+	void Close()
+	{
+		if( fp )
+			fclose( fp );
+		fp = NULL;
+	}
+
+	unsigned long SizeSectors(void)
+	{
+		long filesize;
+
+		fseek( fp, 0, SEEK_END );
+		filesize = ftell( fp );
+
+		if( filesize == 0 || filesize == -1L )
+			log( -1, "Could not get file size for '%s', file possibly larger than 2 GB", name );
+
+		if( filesize & 0x1ff )
+			log( -1, "'%s' not made up of 512 byte sectors", name );
+
+		return( filesize >> 9 );     // 512 bytes per sector
+	}
+
+	void SeekSectors( unsigned long lba )
+	{
+		if( fseek( fp, lba * 512, SEEK_SET ) )
+			log( -1, "'%s', Failed to seek to lba=%lu", name, lba );
+	}
+
+	void Read( void *buff, unsigned long len )
+	{
+		if( fread( buff, 1, 512, fp ) != 512 )
+			log( -1, "'%s', Failed to read sector", name );
+	}
+
+	void Write( void *buff, unsigned long len )
+	{
+		if( fwrite( buff, 1, 512, fp ) != 512 )
+			log( -1, "'%s', Failed to write sector", name );
+	}
+
+	FileAccess()
+	{
+		fp = NULL;
+		name = NULL;
+	}
+
+	const static unsigned long MaxSectors = 4194303;  // limited by signed 32-bit file sizes 
+#define USAGE_MAXSECTORS "2048 MB (signed 32-bit file size limit)"
+
+private:
+	FILE *fp;
+	char *name;
+};
+
Index: unk/Serial_Server/library/FlatImage.cpp
===================================================================
--- /trunk/Serial_Server/library/FlatImage.cpp	(revision 218)
+++ 	(revision )
@@ -1,98 +1,0 @@
-//======================================================================
-//
-// Project:     XTIDE Universal BIOS, Serial Port Server
-//
-// File:        FlatImage.cpp - Basic flat disk image file support
-//
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <memory.h>
-
-#include "FlatImage.h"
-
-FlatImage::FlatImage( char *name, int p_readOnly, int p_drive, int p_create, unsigned long p_cyl, unsigned long p_head, unsigned long p_sect, int p_useCHS )   :   Image( name, p_readOnly, p_drive, p_create, p_cyl, p_head, p_sect, p_useCHS )
-{
-	long filesize;
-
-	if( p_create )
-	{
-		char buff[512];
-		unsigned long size;
-		unsigned long size2;
-		double sizef;
-
-		fp = fopen( name, "r" );
-		if( fp )
-			log( -1, "Create Failure: '%s' already exists", name );
-		
-		if( !(fp = fopen( name, "w" )) )
-			log( -1, "Could not create file '%s'", name );
-
-		memset( &buff[0], 0, 512 );
-		size2 = size = (unsigned long) p_cyl * (unsigned long) p_sect * (unsigned long) p_head;
-		while( size-- )
-		{
-			if( fwrite( &buff[0], 1, 512, fp ) != 512 )
-				log( -1, "Create write black sector error" );
-		}
-		fclose( fp );
-		
-		sizef = size2/2048.0;
-		if( p_cyl > 1024 )
-			log( 0, "Created file '%s', size %.1lf MB", name, sizef );
-		else
-			log( 0, "Created file '%s', geometry %u:%u:%u, size %.1lf MB", name, p_cyl, p_sect, p_head, sizef );
-	}
-
-	fp = fopen( name, "r+" );
-	if( !fp )
-		log( -1, "Could not Open '%s'", name );
-
-	fseek( fp, 0, SEEK_END );
-	filesize = ftell( fp );
-
-	if( filesize == 0 || filesize == -1L )
-		log( -1, "Could not get file size for '%s', file possibly larger than 2 GB", name );
-
-	if( filesize & 0x1ff )
-		log( -1, "'%s' not made up of 512 byte sectors", name );
-
-	totallba = filesize >> 9;     // 512 bytes per sector
-
-	init( name, p_readOnly, p_drive, p_cyl, p_head, p_sect, p_useCHS );
-}
-
-int FlatImage::seekSector( unsigned long cyl, unsigned long sect, unsigned long head )
-{
-	return( 0 );
-}
-
-int FlatImage::seekSector( unsigned long lba )
-{
-	return( fseek( fp, lba * 512, SEEK_SET ) );
-}
-
-int FlatImage::writeSector( void *buff )
-{
-	int r;
-
-	r = fwrite( buff, 1, 512, fp );
-	fflush( fp );
-	
-	return( r == 512 ? 0 : 1 );
-}
-
-int FlatImage::readSector( void *buff )
-{
-	return( fread( buff, 1, 512, fp ) == 512 ? 0 : 1 );
-}
-
-FlatImage::~FlatImage()
-{
-	if( fp )
-		fclose( fp );
-	fp = NULL;
-}
-
-
Index: /trunk/Serial_Server/library/FlatImage.h
===================================================================
--- /trunk/Serial_Server/library/FlatImage.h	(revision 218)
+++ /trunk/Serial_Server/library/FlatImage.h	(revision 219)
@@ -6,5 +6,4 @@
 //
 
-#include <stdio.h>
 #include "library.h"
 
@@ -12,14 +11,63 @@
 {
 private:
-	FILE *fp;
+	class FileAccess fp;
 
 public:
-	FlatImage( char *name, int p_readOnly, int p_drive, int create, unsigned long cyl, unsigned long head, unsigned long sect, int useCHS );
-	~FlatImage();
+	FlatImage( char *name, int p_readOnly, int p_drive, int p_create, unsigned long p_cyl, unsigned long p_head, unsigned long p_sect, int p_useCHS )   :   Image( name, p_readOnly, p_drive, p_create, p_cyl, p_head, p_sect, p_useCHS )
+	{
+		long filesize;
 
-	int seekSector( unsigned long cyl, unsigned long sect, unsigned long head );
-	int seekSector( unsigned long lba );
-	int writeSector( void *buff );
-	int readSector( void *buff );
+		if( p_create )
+		{
+			char buff[512];
+			unsigned long size;
+			double sizef;
+			FileAccess cf;
+
+			size = (unsigned long) p_cyl * (unsigned long) p_sect * (unsigned long) p_head;
+			if( size > cf.MaxSectors )
+				log( -1, "'%s', can't create flat file with size greater than %lu 512-byte sectors", name, cf.MaxSectors );
+			sizef = size / 2048.0;   // 512 byte sectors -> MB
+
+			cf.Create( name );
+
+			memset( &buff[0], 0, 512 );
+			while( size-- )
+				cf.Write( &buff[0], 512 );
+		
+			if( p_cyl > 1024 )
+				log( 0, "Created file '%s', size %.1lf MB", name, sizef );
+			else
+				log( 0, "Created file '%s', geometry %u:%u:%u, size %.1lf MB", name, p_cyl, p_sect, p_head, sizef );
+
+			cf.Close();
+		}
+
+		fp.Open( name );
+
+		totallba = fp.SizeSectors();
+
+		init( name, p_readOnly, p_drive, p_cyl, p_head, p_sect, p_useCHS );
+	}
+
+	FlatImage::~FlatImage()
+	{
+		fp.Close();
+	}
+
+	void seekSector( unsigned long lba )
+	{
+		fp.SeekSectors( lba );
+	}
+
+	void writeSector( void *buff )
+	{
+		fp.Write( buff, 512 );
+	}
+
+	void readSector( void *buff )
+	{
+		fp.Read( buff, 512 );
+	}
 };
 
Index: /trunk/Serial_Server/library/Image.cpp
===================================================================
--- /trunk/Serial_Server/library/Image.cpp	(revision 218)
+++ /trunk/Serial_Server/library/Image.cpp	(revision 219)
@@ -10,4 +10,5 @@
 #include <stdlib.h>
 #include <string.h>
+#include <stdio.h>
 
 Image::Image( char *name, int p_readOnly, int p_drive )
@@ -82,7 +83,7 @@
 	sizef = totallba/2048.0;
 	if( useCHS )
-		log( 0, "Opening '%s', CHS geometry %u:%u:%u, total size %.1lf MB", name, cyl, sect, head, sizef );
-	else
-		log( 0, "Opening '%s', total lba %lu, total size %.1lf MB", name, totallba, sizef );
+		log( 0, "Opening '%s', CHS geometry %u:%u:%u, total LBA %lu, total size %.1lf MB", name, cyl, sect, head, totallba, sizef );
+	else
+		log( 0, "Opening '%s', total LBA %lu, total size %.1lf MB", name, totallba, sizef );
 }
 
Index: /trunk/Serial_Server/library/Library.h
===================================================================
--- /trunk/Serial_Server/library/Library.h	(revision 218)
+++ /trunk/Serial_Server/library/Library.h	(revision 219)
@@ -9,7 +9,6 @@
 #define LIBRARY_H_INCLUDED
 
-#include "stdio.h"
+void log( int level, char *message, ... );
 
-void log( int level, char *message, ... );
 unsigned long GetTime(void);
 unsigned long GetTime_Timeout(void);
@@ -20,10 +19,9 @@
 {
 public:
-	virtual int seekSector( unsigned long cyl, unsigned long sect, unsigned long head ) = 0;
-	virtual int seekSector( unsigned long lba ) = 0;
+	virtual void seekSector( unsigned long lba ) = 0;
 
-	virtual int writeSector( void *buff ) = 0;
+	virtual void writeSector( void *buff ) = 0;
 	
-	virtual int readSector( void *buff ) = 0;
+	virtual void readSector( void *buff ) = 0;
 
 	Image( char *name, int p_readOnly, int p_drive );
@@ -57,32 +55,17 @@
 struct baudRate *baudRateMatchDivisor( unsigned char divisor );
 
-class Serial
-{
-public:
-	virtual unsigned long readCharacters( void *buff, unsigned long len ) = 0;
+#ifdef WIN32
+#include "../win32/win32serial.h"
+#else
+// there is no standard way to read/write and configure the serial port, OS specifc only
+#endif
 
-	virtual unsigned long writeCharacters( void *buff, unsigned long len ) = 0;
+#ifdef WIN32
+#include "../win32/win32file.h"
+#else
+#include "file.h"
+#endif
 
-	Serial( char *name, struct baudRate *p_baudRate ) 
-	{
-		speedEmulation = 0;
-		resetConnection = 0;
-		baudRate = p_baudRate;
-	};
-
-	virtual ~Serial() {};
-
-	int speedEmulation;
-	int resetConnection;
-
-	struct baudRate *baudRate;
-};
-
-void processRequests( Serial *serial, Image *image0, Image *image1, int timeoutEnabled, int verboseLevel );
-
-#define ATA_COMMAND_LBA 0x40
-#define ATA_COMMAND_HEADMASK 0xf
-
-#define ATA_DriveAndHead_Drive 0x10
+void processRequests( SerialAccess *serial, Image *image0, Image *image1, int timeoutEnabled, int verboseLevel );
 
 #endif
Index: /trunk/Serial_Server/library/Process.cpp
===================================================================
--- /trunk/Serial_Server/library/Process.cpp	(revision 218)
+++ /trunk/Serial_Server/library/Process.cpp	(revision 219)
@@ -9,4 +9,5 @@
 #include <memory.h>
 #include <string.h>
+#include <stdio.h>
 
 union _buff {
@@ -54,4 +55,9 @@
 #define SERIAL_INQUIRE_PORTANDBAUD_PORTTRANSLATE( a ) ( ((a) & SERIAL_INQUIRE_PORTANDBAUD_PORT) << 1 | SERIAL_INQUIRE_PORTANDBAUD_STARTINGPORT )
 
+#define ATA_COMMAND_LBA 0x40
+#define ATA_COMMAND_HEADMASK 0xf
+
+#define ATA_DriveAndHead_Drive 0x10
+
 void logBuff( char *message, unsigned long buffoffset, unsigned long readto, int verboseLevel )
 {
@@ -75,5 +81,5 @@
 }
 
-void processRequests( Serial *serial, Image *image0, Image *image1, int timeoutEnabled, int verboseLevel )
+void processRequests( SerialAccess *serial, Image *image0, Image *image1, int timeoutEnabled, int verboseLevel )
 {
 	unsigned char workCommand;
@@ -204,6 +210,6 @@
 			// Echo back the CRC
 			//
-			if( serial->writeCharacters( &buff.w[256], 2 ) != 2 )
-				log( 0, "Serial Port Write Error" );
+			if( !serial->writeCharacters( &buff.w[256], 2 ) )
+				break;
 
 			workOffset++;
@@ -340,6 +346,6 @@
 				buff.w[256] = checksum( &buff.w[0], 256 );
 
-				if( serial->writeCharacters( &buff.w[0], 514 ) != 514 )
-					log( 0, "Serial Port Write Error" );
+				if( !serial->writeCharacters( &buff.w[0], 514 ) )
+					break;
 
 				if( verboseLevel >= 3 )
Index: /trunk/Serial_Server/makefile
===================================================================
--- /trunk/Serial_Server/makefile	(revision 218)
+++ /trunk/Serial_Server/makefile	(revision 219)
@@ -9,7 +9,7 @@
 
 CL = cl
-CLFLAGS = /Ox
+CLFLAGS = /Ox /DWIN32
 
-WIN32OBJS = build/win32.obj build/win32serial.obj build/checksum.obj build/serial.obj build/flatimage.obj build/process.obj build/image.obj
+WIN32OBJS = build/win32.obj build/checksum.obj build/serial.obj build/process.obj build/image.obj
 
 build/serdrive.exe:	$(WIN32OBJS)
@@ -22,5 +22,5 @@
 	$(CL) /c $(CLFLAGS) $< /Fo$@
 
-$(WIN32OBJS):	library/library.h
+$(WIN32OBJS):	library/library.h win32/win32file.h win32/win32serial.h library/file.h library/flatimage.h
 
 build/checksum_test.exe:	library/checksum.cpp
Index: /trunk/Serial_Server/win32/Win32.cpp
===================================================================
--- /trunk/Serial_Server/win32/Win32.cpp	(revision 218)
+++ /trunk/Serial_Server/win32/Win32.cpp	(revision 219)
@@ -16,5 +16,4 @@
 #include "../library/library.h"
 #include "../library/flatimage.h"
-#include "Win32Serial.h"
 
 void usage(void)
@@ -30,5 +29,5 @@
 		"",
 		"  -n [megabytes]      Create new disk with given size or use -g geometry",
-		"                      Maximum size is 137.4 GB (LBA28 limit)",
+		"                      Maximum size is " USAGE_MAXSECTORS, 
 		"                      (default is a 32 MB disk, with CHS geometry 65:63:16)",
 		"",
@@ -74,5 +73,5 @@
 	unsigned short wbuff[256];
 
-	Serial *serial;
+	SerialAccess serial;
 	Image *img;
 	struct baudRate *baudRate = NULL;
@@ -178,14 +177,14 @@
 	do
 	{
-		serial = new Win32Serial( ComPort, baudRate );
-
-		processRequests( serial, images[0], images[1], timeoutEnabled, verbose );
-
-		delete serial;
-
-		if( serial->resetConnection )
-			log( 0, "Connection closed, reset..." );
-	}
-	while( serial->resetConnection );
+		serial.Connect( ComPort, baudRate );
+
+		processRequests( &serial, images[0], images[1], timeoutEnabled, verbose );
+
+		serial.Disconnect();
+
+		if( serial.resetConnection )
+			log( 0, "Serial Connection closed, reset..." );
+	}
+	while( serial.resetConnection );
 }
 
Index: /trunk/Serial_Server/win32/Win32File.h
===================================================================
--- /trunk/Serial_Server/win32/Win32File.h	(revision 219)
+++ /trunk/Serial_Server/win32/Win32File.h	(revision 219)
@@ -0,0 +1,105 @@
+//======================================================================
+//
+// Project:     XTIDE Universal BIOS, Serial Port Server
+//
+// File:        Win32File.h - Microsoft Windows file system access.
+//
+// Routines for accessing the file system under Win32.  It's important
+// to use these direct Win32 calls for large files, since FILE * routines,
+// in particular ftell() and fseek(), are limites to signed 32-bits (2 GB).
+// These are also likely faster since they are more direct.
+// 
+
+#include <windows.h>
+#include <stdio.h>
+#include "../library/library.h"
+
+class FileAccess
+{
+public:
+	void Create( char *p_name )
+	{
+		fp = CreateFileA( p_name, GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
+		if( !fp )
+			log( -1, "'%s', could not create file", p_name );
+		name = p_name;
+	}
+
+	void Open( char *p_name )
+	{
+		fp = CreateFileA( p_name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
+		if( !fp )
+			log( -1, "'%s', could not open file", p_name );
+		name = p_name;
+	}
+
+	void Close()
+	{
+		if( fp )
+		{
+			if( !CloseHandle( fp ) )
+				log( 0, "'%s', could not close file handle", name ? name : "unknown" );			
+		}
+	}
+
+	unsigned long SizeSectors(void)
+	{
+		LARGE_INTEGER li;
+		unsigned long i;
+
+		if( !GetFileSizeEx( fp, &li ) )
+			log( -1, "'%s', could not retrieve file size (error %ul)", name, GetLastError() );
+
+		if( li.LowPart & 0x1ff )
+			log( -1, "'%s', file size is not a multiple of 512 byte sectors", name );
+
+		if( li.HighPart > 0x1f )
+			log( -1, "'%s', file size greater than LBA28 limit of 137,438,952,960 bytes", name );
+
+		i = ((li.HighPart << 23 ) & 0xff800000) | ((li.LowPart >> 9) & 0x7fffff);
+
+		return( (unsigned long) i );
+	}
+
+	void SeekSectors( unsigned long lba )
+	{
+		LARGE_INTEGER dist;
+
+		dist.HighPart = lba >> 23;
+		dist.LowPart = lba << 9;
+
+		if( !SetFilePointerEx( fp, dist, NULL, FILE_BEGIN ) )
+			log( -1, "'%s', Failed to seek to lba=%lu", name, lba );
+	}
+
+	void Read( void *buff, unsigned long len )
+	{
+		unsigned long out_len;
+
+		if( !ReadFile( fp, buff, len, &out_len, NULL ) || len != out_len )
+			log( -1, "'%s', ReadFile failed" );
+	}
+
+	void Write( void *buff, unsigned long len )
+	{
+		unsigned long out_len;
+
+		if( !WriteFile( fp, buff, len, &out_len, NULL ) || len != out_len )
+			log( -1, "'%s', WriteFile failed" );
+	}
+
+	FileAccess()
+	{
+		fp = NULL;
+		name = NULL;
+	}
+
+    // LBA 28 limit - 28-bits (could be 1 more, but not worth pushing it)
+	const static unsigned long MaxSectors = 0xfffffff; 
+#define USAGE_MAXSECTORS "137438 MB (LBA28 limit)"
+
+private:
+	HANDLE fp;
+	char *name;
+};
+
Index: unk/Serial_Server/win32/Win32Serial.cpp
===================================================================
--- /trunk/Serial_Server/win32/Win32Serial.cpp	(revision 218)
+++ 	(revision )
@@ -1,130 +1,0 @@
-//======================================================================
-//
-// Project:     XTIDE Universal BIOS, Serial Port Server
-//
-// File:        Win32Serial.cpp - Microsoft Windows serial code
-//
-// Support for the serial port under Win32.
-// 
-
-#include <stdio.h>
-
-#include "..\library\library.h"
-#include "Win32Serial.h"
-
-COMMTIMEOUTS timeouts;
-
-DCB dcb;
-
-Win32Serial::~Win32Serial()
-{
-	if( pipe )
-		CloseHandle( pipe );
-
-	pipe = NULL;
-}
-
-Win32Serial::Win32Serial( char *name, struct baudRate *baudRate ) : Serial( name, baudRate )
-{
-	char buff1[20], buff2[1024];
-
-	pipe = NULL;
-	
-	if( !name )
-	{
-		for( int t = 1; t <= 30 && !name; t++ )
-		{
-			sprintf( buff1, "COM%d", t );
-			if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
-				name = buff1;
-		}
-		if( !name )
-			log( -1, "No physical COM ports found" );
-	}
-
-	if( !strcmp( name, "PIPE" ) )
-	{
-		log( 0, "Opening named pipe %s (simulating %lu baud)", PIPENAME, baudRate->rate );
-		
-		pipe = CreateNamedPipeA( PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_REJECT_REMOTE_CLIENTS, 2, 1024, 1024, 0, NULL );
-		if( !pipe )
-			log( -1, "Could not CreateNamedPipe " PIPENAME );
-		
-		if( !ConnectNamedPipe( pipe, NULL ) )
-			log( -1, "Could not ConnectNamedPipe" );
-
-		if( baudRate->divisor > 3 )
-			log( -1, "Cannot simulate baud rates with hardware multipliers" );
-
-		speedEmulation = 1;
-		resetConnection = 1;
-	}
-	else
-	{
-		if( QueryDosDeviceA( name, buff2, sizeof(buff2) ) )
-		{
-			log( 0, "Opening %s (%lu baud)", name, baudRate->rate );
-			
-			pipe = CreateFileA( name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
-			if( !pipe )
-				log( -1, "Could not Open \"%s\"", name );
-			
-			FillMemory(&dcb, sizeof(dcb), 0);
-			dcb.DCBlength = sizeof(dcb);
-			dcb.BaudRate = baudRate->rate;
-			dcb.ByteSize = 8;
-			dcb.StopBits = ONESTOPBIT;
-			dcb.Parity = NOPARITY;
-			if( !SetCommState( pipe, &dcb ) )
-				log( -1, "Could not SetCommState" );
-
-			if( !SetCommTimeouts( pipe, &timeouts ) )
-				log( -1, "Could not SetCommTimeouts" );
-		}
-		else
-		{
-			char logbuff[ 1024 ];
-			int found = 0;
-
-			sprintf( logbuff, "serial port '%s' not found, detected COM ports:", name );
-
-			for( int t = 1; t <= 40; t++ )
-			{
-				sprintf( buff1, "COM%d", t );
-				if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
-				{
-					strcat( logbuff, "\n    " );
-					strcat( logbuff, buff1 );
-					found = 1;
-				}
-			}
-			if( !found )
-				strcat( logbuff, "\n    (none)" );
-
-			log( -1, logbuff );
-		}
-	}
-}
-
-unsigned long Win32Serial::readCharacters( void *buff, unsigned long len )
-{
-	unsigned long readLen;
-	int ret;
-	ret = ReadFile( pipe, buff, len, &readLen, NULL );
-	return( ret ? readLen : 0 );
-}
-
-unsigned long Win32Serial::writeCharacters( void *buff, unsigned long len )
-{
-	unsigned long writeLen;
-	int ret;
-	ret = WriteFile( pipe, buff, len, &writeLen, NULL );
-	return( ret ? writeLen : 0 );
-}
-
-
-
-
-
-
-
Index: /trunk/Serial_Server/win32/Win32Serial.h
===================================================================
--- /trunk/Serial_Server/win32/Win32Serial.h	(revision 218)
+++ /trunk/Serial_Server/win32/Win32Serial.h	(revision 219)
@@ -6,4 +6,5 @@
 //
 
+#include <stdio.h>
 #include "windows.h"
 #include "../library/library.h"
@@ -11,12 +12,158 @@
 #define PIPENAME "\\\\.\\pipe\\xtide"
 
-class Win32Serial : public Serial
+class SerialAccess 
 {
 public:
-	Win32Serial( char *name, struct baudRate *baudRate );
-	~Win32Serial();
+	void Connect( char *name, struct baudRate *p_baudRate )
+	{
+		char buff1[20], buff2[1024];
 
-	unsigned long readCharacters( void *buff, unsigned long len );
-	unsigned long writeCharacters( void *buff, unsigned long len );
+		baudRate = p_baudRate;
+
+		pipe = NULL;
+	
+		if( !name )
+		{
+			for( int t = 1; t <= 30 && !name; t++ )
+			{
+				sprintf( buff1, "COM%d", t );
+				if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
+					name = buff1;
+			}
+			if( !name )
+				log( -1, "No physical COM ports found" );
+		}
+
+		if( !strcmp( name, "PIPE" ) )
+		{
+			log( 0, "Opening named pipe %s (simulating %lu baud)", PIPENAME, baudRate->rate );
+		
+			pipe = CreateNamedPipeA( PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_REJECT_REMOTE_CLIENTS, 2, 1024, 1024, 0, NULL );
+			if( !pipe )
+				log( -1, "Could not CreateNamedPipe " PIPENAME );
+		
+			if( !ConnectNamedPipe( pipe, NULL ) )
+				log( -1, "Could not ConnectNamedPipe" );
+
+			if( baudRate->divisor > 3 )
+				log( -1, "Cannot simulate baud rates with hardware multipliers" );
+
+			speedEmulation = 1;
+			resetConnection = 1;
+		}
+		else
+		{
+			if( QueryDosDeviceA( name, buff2, sizeof(buff2) ) )
+			{
+				COMMTIMEOUTS timeouts;
+				DCB dcb;
+
+				log( 0, "Opening %s (%lu baud)", name, baudRate->rate );
+			
+				pipe = CreateFileA( name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
+				if( !pipe )
+					log( -1, "Could not Open \"%s\"", name );
+			
+				FillMemory(&dcb, sizeof(dcb), 0);
+				FillMemory(&timeouts, sizeof(timeouts), 0);
+
+				dcb.DCBlength = sizeof(dcb);
+				dcb.BaudRate = baudRate->rate;
+				dcb.ByteSize = 8;
+				dcb.StopBits = ONESTOPBIT;
+				dcb.Parity = NOPARITY;
+				if( !SetCommState( pipe, &dcb ) )
+					log( -1, "Could not SetCommState" );
+
+				if( !SetCommTimeouts( pipe, &timeouts ) )
+					log( -1, "Could not SetCommTimeouts" );
+			}
+			else
+			{
+				char logbuff[ 1024 ];
+				int found = 0;
+
+				sprintf( logbuff, "serial port '%s' not found, detected COM ports:", name );
+
+				for( int t = 1; t <= 40; t++ )
+				{
+					sprintf( buff1, "COM%d", t );
+					if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
+					{
+						strcat( logbuff, "\n    " );
+						strcat( logbuff, buff1 );
+						found = 1;
+					}
+				}
+				if( !found )
+					strcat( logbuff, "\n    (none)" );
+				
+				log( -1, logbuff );
+			}
+		}
+	}
+
+	void Disconnect()
+	{
+		if( pipe )
+		{
+			CloseHandle( pipe );
+			pipe = NULL;
+		}
+	}
+
+	unsigned long readCharacters( void *buff, unsigned long len )
+	{
+		unsigned long readLen;
+		int ret;
+
+		ret = ReadFile( pipe, buff, len, &readLen, NULL );
+
+		if( !ret || readLen == 0 )
+		{
+			if( GetLastError() == ERROR_BROKEN_PIPE )
+				return( 0 );
+		    else
+				log( -1, "read serial failed (error code %d)", GetLastError() );
+		}
+
+		return( readLen );
+	}
+
+	int writeCharacters( void *buff, unsigned long len )
+	{
+		unsigned long writeLen;
+		int ret;
+
+		ret = WriteFile( pipe, buff, len, &writeLen, NULL );
+
+		if( !ret || len != writeLen )
+		{
+			if( GetLastError() == ERROR_BROKEN_PIPE )
+				return( 0 );
+			else
+				log( -1, "write serial failed (error code %d)", GetLastError() );
+		}
+
+		return( 1 );
+	}
+
+	SerialAccess()
+	{
+		pipe = NULL;
+		speedEmulation = 0;
+		resetConnection = 0;
+		baudRate = NULL;
+	}
+
+	~SerialAccess()
+	{
+		Disconnect();
+	}
+
+	int speedEmulation;
+	int resetConnection;
+
+	struct baudRate *baudRate;
 
 private:
