Index: peripherals/nic/w5100_internals.h =================================================================== --- peripherals/nic/w5100_internals.h (revision 4494) +++ peripherals/nic/w5100_internals.h (working copy) @@ -29,6 +29,19 @@ #ifndef FUSE_W5100_INTERNALS_H #define FUSE_W5100_INTERNALS_H +#ifdef WIN32 +#include +#endif /* #ifdef WIN32 */ + +#ifdef WIN32 +#define close_socket( x ) closesocket( x ) +typedef SOCKET socket_t; +#else +#define INVALID_SOCKET -1 +#define close_socket( x ) close( x ) +typedef int socket_t; +#endif /* #ifdef WIN32 */ + typedef enum w5100_socket_mode { W5100_SOCKET_MODE_CLOSED = 0x00, W5100_SOCKET_MODE_TCP, @@ -105,7 +118,7 @@ /* Host properties */ - int fd; /* Socket file descriptor */ + socket_t fd; /* Socket file descriptor */ int write_pending; /* True if we're waiting to write data on this socket */ /* Flag used to indicate that a socket has been closed since we started @@ -126,6 +139,10 @@ nic_w5100_socket_t socket[4]; +#ifdef WIN32 + nic_w5100_socket_t dummy_socket; +#endif + pthread_t thread; /* Thread for doing I/O */ sig_atomic_t stop_io_thread; /* Flag to stop I/O thread */ int pipe_read; /* Pipe for waking I/O thread */ @@ -136,6 +153,9 @@ void nic_w5100_socket_init( nic_w5100_socket_t *socket, int which ); void nic_w5100_socket_free( nic_w5100_socket_t *socket ); +#ifdef WIN32 +void nic_w5100_open_control_socket( nic_w5100_socket_t *socket ); +#endif void nic_w5100_socket_reset( nic_w5100_socket_t *socket ); Index: peripherals/nic/w5100_socket.c =================================================================== --- peripherals/nic/w5100_socket.c (revision 4494) +++ peripherals/nic/w5100_socket.c (working copy) @@ -29,12 +29,17 @@ #include "config.h" #include -#include #include -#include #include #include +#ifdef WIN32 +#include +#else +#include +#include +#endif /* #ifdef WIN32 */ + #include "fuse.h" #include "ui/ui.h" #include "w5100.h" @@ -51,7 +56,7 @@ nic_w5100_socket_init( nic_w5100_socket_t *socket, int which ) { socket->id = which; - socket->fd = -1; + socket->fd = INVALID_SOCKET; socket->ok_for_io = 0; pthread_mutex_init( &socket->lock, NULL ); } @@ -105,10 +110,11 @@ void nic_w5100_socket_free( nic_w5100_socket_t *socket ) { - if( socket->fd != -1 ) { + if( socket->fd != INVALID_SOCKET ) { + printf( "nic_w5100_socket_free %d\n", socket->id ); w5100_socket_acquire_lock( socket ); - close( socket->fd ); - socket->fd = -1; + close_socket( socket->fd ); + socket->fd = INVALID_SOCKET; socket->ok_for_io = 0; socket->write_pending = 0; w5100_socket_release_lock( socket ); @@ -162,7 +168,7 @@ w5100_socket_acquire_lock( socket_obj ); socket_obj->fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - if( socket_obj->fd == -1 ) { + if( socket_obj->fd == INVALID_SOCKET ) { printf("w5100: failed to open UDP socket for socket %d; errno = %d\n", socket_obj->id, errno); w5100_socket_release_lock( socket_obj ); return; @@ -178,7 +184,7 @@ w5100_socket_acquire_lock( socket_obj ); socket_obj->fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); - if( socket_obj->fd == -1 ) { + if( socket_obj->fd == INVALID_SOCKET ) { printf("w5100: failed to open TCP socket for socket %d; errno = %d\n", socket_obj->id, errno); w5100_socket_release_lock( socket_obj ); return; @@ -218,8 +224,8 @@ if( socket->mode == W5100_SOCKET_MODE_UDP && socket->state == W5100_SOCKET_STATE_UDP ) { w5100_socket_acquire_lock( socket ); - close( socket->fd ); - socket->fd = -1; + close_socket( socket->fd ); + socket->fd = INVALID_SOCKET; socket->ok_for_io = 0; socket->state = W5100_SOCKET_STATE_CLOSED; w5100_socket_release_lock( socket ); @@ -334,6 +340,7 @@ printf("w5100: reading 0x%02x from unsupported register 0x%03x\n", b, reg ); break; } + return b; } @@ -414,7 +421,7 @@ { w5100_socket_acquire_lock( socket ); - if( socket->fd != -1 ) { + if( socket->fd != INVALID_SOCKET ) { socket->ok_for_io = 1; /* We can process a UDP read if we're in a UDP state and there are at least @@ -455,7 +462,7 @@ sa.sin_family = AF_INET; memcpy( &sa.sin_port, socket->port, 2 ); sa.sin_addr.s_addr = htonl(INADDR_ANY); - bytes_read = recvfrom( socket->fd, buffer + 8, bytes_free - 8, 0, (struct sockaddr*)&sa, &sa_length ); + bytes_read = recvfrom( socket->fd, (char *)buffer + 8, bytes_free - 8, 0, (struct sockaddr*)&sa, &sa_length ); printf("w5100: read 0x%03x bytes from socket %d\n", (int)bytes_read, socket->id); if( bytes_read != -1 ) { @@ -506,7 +513,7 @@ memcpy( &sa.sin_port, socket->dport, 2 ); memcpy( &sa.sin_addr.s_addr, socket->dip, 4 ); - bytes_sent = sendto( socket->fd, data, length, 0, (struct sockaddr*)&sa, sizeof(sa) ); + bytes_sent = sendto( socket->fd, (const char *)data, length, 0, (struct sockaddr*)&sa, sizeof(sa) ); printf("w5100: sent 0x%03x bytes of %d to socket %d\n", (int)bytes_sent, length, socket->id); if( bytes_sent != -1 ) { @@ -528,7 +535,7 @@ /* Process only if we're an open socket, and we haven't been closed and re-opened since the select() started */ - if( socket->fd != -1 && socket->ok_for_io ) { + if( socket->fd != INVALID_SOCKET && socket->ok_for_io ) { if( FD_ISSET( socket->fd, &readfds ) ) w5100_socket_process_read( socket ); @@ -538,3 +545,12 @@ w5100_socket_release_lock( socket ); } + +#ifdef WIN32 +void +nic_w5100_open_control_socket( nic_w5100_socket_t *socket ) +{ + socket->mode = W5100_SOCKET_MODE_UDP; + w5100_socket_open( socket ); +} +#endif \ No newline at end of file Index: peripherals/nic/w5100.c =================================================================== --- peripherals/nic/w5100.c (revision 4494) +++ peripherals/nic/w5100.c (working copy) @@ -29,12 +29,17 @@ #include "config.h" #include -#include #include -#include #include #include +#ifdef WIN32 +#include +#else +#include +#include +#endif /* #ifdef WIN32 */ + #include "fuse.h" #include "ui/ui.h" #include "w5100.h" @@ -91,32 +96,57 @@ w5100_io_thread( void *arg ) { nic_w5100_t *self = arg; - int i; + int i, retval; + struct timeval *tvp = NULL; +#ifdef WIN32 + struct timeval tv; + tvp = &tv; +#endif + while( !self->stop_io_thread ) { fd_set readfds, writefds; - int max_fd = self->pipe_read; + int max_fd = -1; FD_ZERO( &readfds ); + FD_ZERO( &writefds ); + +#ifndef WIN32 + max_fd = self->pipe_read; FD_SET( self->pipe_read, &readfds ); +#else + nic_w5100_socket_add_to_sets( &self->dummy_socket, &readfds, &writefds, + &max_fd ); - FD_ZERO( &writefds ); + tv.tv_sec = 1; /* wait 1 second max */ + tv.tv_usec = 0; +#endif for( i = 0; i < 4; i++ ) nic_w5100_socket_add_to_sets( &self->socket[i], &readfds, &writefds, &max_fd ); printf("w5100: io thread select\n"); + retval = select( max_fd + 1, &readfds, &writefds, NULL, tvp ); + if( retval < 0 ) { +#ifdef WIN32 + printf( "w5100: io thread wake from select with error %d\n", + WSAGetLastError() ); +#else + printf( "w5100: io thread wake from select with error %d\n", + retval ); +#endif + } - select( max_fd + 1, &readfds, &writefds, NULL, NULL ); + printf("w5100: io thread wake from select %d\n", retval); - printf("w5100: io thread wake\n"); - +#ifndef WIN32 if( FD_ISSET( self->pipe_read, &readfds ) ) { char bitbucket; printf("w5100: discarding pipe data\n"); read( self->pipe_read, &bitbucket, 1 ); } +#endif for( i = 0; i < 4; i++ ) nic_w5100_socket_process_io( &self->socket[i], readfds, writefds ); @@ -128,28 +158,54 @@ void nic_w5100_wake_io_thread( nic_w5100_t *self ) { +#ifndef WIN32 const char dummy = 0; write( self->pipe_write, &dummy, 1 ); +#endif } nic_w5100_t* nic_w5100_alloc( void ) { int error; - int pipefd[2]; int i; +#ifndef WIN32 + int pipefd[2]; +#else + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD( 2, 2 ); + error = WSAStartup( wVersionRequested, &wsaData ); + if( error ) { + ui_error( UI_ERROR_ERROR, "WSAStartup failed with error: %d", error ); + fuse_abort(); + } + + if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { + WSACleanup(); + ui_error( UI_ERROR_ERROR, "FUSE could not find a usable Winsock DLL" ); + fuse_abort(); + } +#endif /* ifndef WIN32 */ + nic_w5100_t *self = malloc( sizeof( *self ) ); if( !self ) { ui_error( UI_ERROR_ERROR, "%s:%d out of memory", __FILE__, __LINE__ ); fuse_abort(); } +#ifdef WIN32 + nic_w5100_socket_init( &self->dummy_socket, -1 ); +#endif /* ifdef WIN32 */ + for( i = 0; i < 4; i++ ) nic_w5100_socket_init( &self->socket[i], i ); w5100_reset( self ); +#ifndef WIN32 error = pipe( pipefd ); if( error ) { ui_error( UI_ERROR_ERROR, "w5100: error %d creating pipe", error ); @@ -158,6 +214,10 @@ self->pipe_read = pipefd[0]; self->pipe_write = pipefd[1]; +#else + /* open dummy socket to allow SELECT model */ + nic_w5100_open_control_socket( &self->dummy_socket ); +#endif self->stop_io_thread = 0; @@ -182,7 +242,12 @@ for( i = 0; i < 4; i++ ) nic_w5100_socket_free( &self->socket[i] ); - + +#ifdef WIN32 + nic_w5100_socket_free( &self->dummy_socket ); + WSACleanup(); +#endif + free( self ); } Index: configure.in =================================================================== --- configure.in (revision 4494) +++ configure.in (working copy) @@ -110,7 +110,7 @@ AC_MSG_RESULT($win32) if test "$win32" = yes; then AC_CHECK_HEADER(windows.h, - LIBS="$LIBS -mwindows -lcomctl32 -lwinmm"; + LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread"; AC_DEFINE([UI_WIN32], 1, [Defined if Win32 UI in use]) AC_DEFINE([WINVER], 0x0400, [Minimal supported version of Windows is 95 or NT4]) AC_DEFINE([_WIN32_IE], 0x400, [Internet Explorer is 4.0 or higher is required]) Index: ui/win32/win32ui.c =================================================================== --- ui/win32/win32ui.c (revision 4494) +++ ui/win32/win32ui.c (working copy) @@ -24,6 +24,7 @@ */ #include +#include #include #include "debugger/debugger.h" @@ -277,6 +278,46 @@ return( DefWindowProc( hWnd, msg, wParam, lParam ) ); } +void redirect_IO_to_console( void ) +{ + int hConHandle; + HANDLE std_handle; + CONSOLE_SCREEN_BUFFER_INFO coninfo; + FILE *fp; + + /* allocate a console for this app */ + AllocConsole(); + + /* set the screen buffer to be big enough to let us scroll text */ + std_handle = GetStdHandle( STD_OUTPUT_HANDLE ); + if( !std_handle || std_handle == INVALID_HANDLE_VALUE ) return; + GetConsoleScreenBufferInfo( std_handle, &coninfo ); + coninfo.dwSize.Y = 500; + SetConsoleScreenBufferSize( std_handle, coninfo.dwSize ); + + /* redirect unbuffered STDOUT to the console */ + hConHandle = _open_osfhandle( (intptr_t)std_handle, _O_TEXT ); + fp = _fdopen( hConHandle, "w" ); + *stdout = *fp; + setvbuf( stdout, NULL, _IONBF, 0 ); + + /* redirect unbuffered STDIN to the console */ + std_handle = GetStdHandle( STD_INPUT_HANDLE ); + if( !std_handle || std_handle == INVALID_HANDLE_VALUE ) return; + hConHandle = _open_osfhandle( (intptr_t)std_handle, _O_TEXT ); + fp = _fdopen( hConHandle, "r" ); + *stdin = *fp; + setvbuf( stdin, NULL, _IONBF, 0 ); + + /* redirect unbuffered STDERR to the console */ + std_handle = GetStdHandle( STD_ERROR_HANDLE ); + if( !std_handle || std_handle == INVALID_HANDLE_VALUE ) return; + hConHandle = _open_osfhandle( (intptr_t)std_handle, _O_TEXT ); + fp = _fdopen( hConHandle, "w" ); + *stderr = *fp; + setvbuf( stderr, NULL, _IONBF, 0 ); +} + /* this is where windows program begins */ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, @@ -287,6 +328,10 @@ fuse_nCmdShow = nCmdShow; fuse_hPrevInstance = hPrevInstance; +#ifdef _DEBUG + redirect_IO_to_console(); +#endif + return fuse_main(__argc, __argv); /* FIXME: how do deal with returning wParam */ }