From 6fe6e1125e13d44bafdaca76700411bf3675abb5 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 11 Jan 2012 19:05:40 +0200 Subject: [PATCH] 2400b11 --- akiko.cpp | 6 +- bsdsocket.cpp | 280 ++++++++++++++++++++++++++------ drawing.cpp | 4 +- include/bsdsocket.h | 26 ++- od-win32/bsdsock.cpp | 305 ++++++++++++++++++++++++----------- od-win32/dinput.cpp | 187 +++++++++++---------- od-win32/posixemu.cpp | 39 +++-- od-win32/win32.h | 4 +- od-win32/winuaechangelog.txt | 15 ++ zfile_archive.cpp | 6 +- 10 files changed, 604 insertions(+), 268 deletions(-) diff --git a/akiko.cpp b/akiko.cpp index 619b5bb0..76e8db14 100644 --- a/akiko.cpp +++ b/akiko.cpp @@ -590,7 +590,7 @@ static int cd_play_audio (int startlsn, int endlsn, int scan) } qcode_valid = 0; last_play_end = endlsn; - cdrom_audiotimeout = 0; + cdrom_audiotimeout = 10; cdrom_paused = 0; write_comm_pipe_u32 (&requests, 0x0110, 0); write_comm_pipe_u32 (&requests, startlsn, 0); @@ -1137,7 +1137,10 @@ static void akiko_handler (void) get_cdrom_toc (); return; } + if (cdrom_audiotimeout > 1) + cdrom_audiotimeout--; if (cdrom_audiotimeout == 1) { // play start + cdrom_playing = 1; cdrom_start_return_data (cdrom_playend_notify (0)); cdrom_audiotimeout = 0; } @@ -1227,6 +1230,7 @@ void AKIKO_hsync_handler (void) if (subcodebufferoffset >= MAX_SUBCODEBUFFER) subcodebufferoffset -= MAX_SUBCODEBUFFER; set_status (CDINTERRUPT_SUBCODE); + write_log (L"*"); } uae_sem_post (&sub_sem); } diff --git a/bsdsocket.cpp b/bsdsocket.cpp index 1352ac7c..ec5de8c3 100644 --- a/bsdsocket.cpp +++ b/bsdsocket.cpp @@ -144,7 +144,20 @@ void bsdsocklib_setherrno (SB, int sb_herrno) } } -BOOL checksd(SB, int sd) +uae_u32 callfdcallback (TrapContext *context, SB, uae_u32 fd, uae_u32 action) +{ + uae_u32 v; + if (!sb->fdcallback) + return 0; + BSDTRACE((L"FD_CALLBACK(%d,%d) ", fd, action)); + m68k_dreg (regs, 0) = fd; + m68k_dreg (regs, 1) = action; + v = CallFunc (context, sb->fdcallback); + BSDTRACE((L"-> %d\n", v)); + return v; +} + +BOOL checksd(TrapContext *context, SB, int sd) { int iCounter; SOCKET s; @@ -154,7 +167,7 @@ BOOL checksd(SB, int sd) for (iCounter = 1; iCounter <= sb->dtablesize; iCounter++) { if (iCounter != sd) { if (getsock(sb,iCounter) == s) { - releasesock(sb,sd); + releasesock(context, sb, sd); return TRUE; } } @@ -168,33 +181,57 @@ BOOL checksd(SB, int sd) return FALSE; } -void setsd(SB, int sd, SOCKET_TYPE s) +void setsd(TrapContext *context, SB, int sd, SOCKET_TYPE s) { + callfdcallback (context, sb, sd - 1, FDCB_ALLOC); sb->dtable[sd - 1] = s; } /* Socket descriptor/opaque socket handle management */ -int getsd (SB, SOCKET_TYPE s) +int getsd (TrapContext *context, SB, SOCKET_TYPE s) { - int i; + int i, fdcb; SOCKET_TYPE *dt = sb->dtable; /* return socket descriptor if already exists */ - for (i = sb->dtablesize; i--;) + for (i = sb->dtablesize; i--;) { if (dt[i] == s) return i + 1; + } /* create new table entry */ - for (i = 0; i < sb->dtablesize; i++) + fdcb = 0; + for (i = 0; i < sb->dtablesize; i++) { if (dt[i] == -1) { + if (callfdcallback (context, sb, i, FDCB_CHECK)) { + /* fd was allocated by link lib */ + dt[i] = -2; + continue; + } dt[i] = s; sb->ftable[i] = SF_BLOCKING; return i + 1; + } else if (dt[i] == -2) { + fdcb = 1; } - /* descriptor table full. */ - bsdsocklib_seterrno (sb, 24); /* EMFILE */ + } + /* recheck callback allocated FDs */ + if (fdcb) { + for (i = 0; i < sb->dtablesize; i++) { + if (dt[i] == -2) { + if (!callfdcallback (context, sb, i, FDCB_CHECK)) { + dt[i] = s; + sb->ftable[i] = SF_BLOCKING; + return i + 1; + } + } + } + } - return -1; + /* descriptor table full. */ + bsdsocklib_seterrno (sb, 24); /* EMFILE */ + + return -1; } SOCKET_TYPE getsock (SB, int sd) @@ -231,10 +268,12 @@ SOCKET_TYPE getsock (SB, int sd) return sb->dtable[sd - 1]; } -void releasesock (SB, int sd) +void releasesock (TrapContext *context, SB, int sd) { - if ((unsigned int) (sd - 1) < (unsigned int) sb->dtablesize) + if ((unsigned int) (sd - 1) < (unsigned int) sb->dtablesize) { sb->dtable[sd - 1] = -1; + callfdcallback (context, sb, sd - 1, FDCB_FREE); + } } /* Signal queue */ @@ -544,7 +583,7 @@ static uae_u32 REGPARAM2 bsdsocklib_Close (TrapContext *context) static uae_u32 REGPARAM2 bsdsocklib_socket (TrapContext *context) { struct socketbase *sb = get_socketbase (context); - return host_socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), + return host_socket (context, sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2)); } @@ -552,7 +591,7 @@ static uae_u32 REGPARAM2 bsdsocklib_socket (TrapContext *context) static uae_u32 REGPARAM2 bsdsocklib_bind (TrapContext *context) { struct socketbase *sb = get_socketbase (context); - return host_bind (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), + return host_bind (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1)); } @@ -560,7 +599,7 @@ static uae_u32 REGPARAM2 bsdsocklib_bind (TrapContext *context) static uae_u32 REGPARAM2 bsdsocklib_listen (TrapContext *context) { struct socketbase *sb = get_socketbase (context); - return host_listen (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1)); + return host_listen (context, sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1)); } /* accept(s, addr, addrlen)(d0/a0/a1) */ @@ -765,12 +804,13 @@ static uae_u32 REGPARAM2 bsdsocklib_ObtainSocket (TrapContext *context) } s = sockdata->sockpoolsocks[i]; - sd = getsd (sb, s); + sd = getsd (context, sb, s); BSDTRACE ((L"%d\n", sd)); if (sd != -1) { sb->ftable[sd - 1] = sockdata->sockpoolflags[i]; + callfdcallback (context, sb, sd - 1, FDCB_ALLOC); sockdata->sockpoolids[i] = UNIQUE_ID; return sd - 1; } @@ -803,7 +843,7 @@ static uae_u32 REGPARAM2 bsdsocklib_ReleaseSocket (TrapContext *context) write_log (L"bsdsocket: ERROR: ReleaseSocket() is not supported for sockets with async event notification enabled!\n"); return -1; } - releasesock (sb, sd); + releasesock (context, sb, sd); if (id == UNIQUE_ID) { for (;;) { @@ -1047,7 +1087,7 @@ static uae_u32 REGPARAM2 bsdsocklib_vsyslog (TrapContext *context) static uae_u32 REGPARAM2 bsdsocklib_Dup2Socket (TrapContext *context) { struct socketbase *sb = get_socketbase (context); - return host_dup2socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1)); + return host_dup2socket (context, sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1)); } static uae_u32 REGPARAM2 bsdsocklib_sendmsg (TrapContext *context) @@ -1111,6 +1151,70 @@ L"No address associated with name"}; static uae_u32 herrnotextptrs[sizeof (herrortexts) / sizeof (*herrortexts)]; static const uae_u32 number_host_error = sizeof (herrortexts) / sizeof (*herrortexts); + +static const TCHAR *sana2io_errlist[] = +{ + L"No error", /* S2ERR_NO_ERROR */ + L"Resource allocation failure", /* S2ERR_NO_RESOURCES */ + L"Unknown error code (2)", + L"Invalid argument", /* S2ERR_BAD_ARGUMENT */ + L"Inappropriate state", /* S2ERR_BAD_STATE */ + L"Invalid address", /* S2ERR_BAD_ADDRESS */ + L"Requested packet too large", /* S2ERR_MTU_EXCEEDED */ + L"Unknown error (7)", + L"Command is not supporter", /* S2ERR_NOT_SUPPORTED */ + L"Driver software error detected", /* S2ERR_SOFTWARE */ + L"Device driver is offline", /* S2ERR_OUTOFSERVICE */ + L"Transmission attempt failed" /* S2ERR_TX_FAILURE */ +}; + +static uae_u32 sana2iotextptrs[sizeof (sana2io_errlist) / sizeof (*sana2io_errlist)]; +static const uae_u32 number_sana2io_error = sizeof (sana2io_errlist) / sizeof (*sana2io_errlist); + + +static const TCHAR *sana2wire_errlist[] = +{ + L"Generic error: 0", /* S2WERR_GENERIC_ERROR */ + L"Unit not configured", /* S2WERR_NOT_CONFIGURED */ + L"Unit is currently online", /* S2WERR_UNIT_ONLINE */ + L"Unit is currently offline", /* S2WERR_UNIT_OFFLINE */ + L"Protocol already tracked", /* S2WERR_ALREADY_TRACKED */ + L"Protocol not tracked", /* S2WERR_NOT_TRACKED */ + L"Buff management function error", /* S2WERR_BUFF_ERROR */ + L"Source address error", /* S2WERR_SRC_ADDRESS */ + L"Destination address error", /* S2WERR_DST_ADDRESS */ + L"Broadcast address error", /* S2WERR_BAD_BROADCAST */ + L"Multicast address error", /* S2WERR_BAD_MULTICAST */ + L"Multicast address list full", /* S2WERR_MULTICAST_FULL */ + L"Unsupported event class", /* S2WERR_BAD_EVENT */ + L"Statdata failed sanity check", /* S2WERR_BAD_STATDATA */ + L"Unknown wire error (14)", + L"Attempt to config twice", /* S2WERR_IS_CONFIGURED */ + L"Null pointer detected", /* S2WERR_NULL_POINTER */ + L"tx failed - too many retries", /* S2WERR_TOO_MANY_RETIRES */ + L"Driver fixable HW error" /* S2WERR_RCVREL_HDW_ERR */ +}; + +static uae_u32 sana2wiretextptrs[sizeof (sana2wire_errlist) / sizeof (*sana2wire_errlist)]; +static const uae_u32 number_sana2wire_error = sizeof (sana2wire_errlist) / sizeof (*sana2wire_errlist); + + +static const TCHAR *io_errlist[] = +{ + L"Unknown error", /* 0 */ + L"Device or unit failed to open", /* IOERR_OPENFAIL */ + L"Request aborted", /* IOERR_ABORTED */ + L"Command not supported by device", /* IOERR_NOCMD */ + L"Invalid length", /* IOERR_BADLENGTH */ + L"Invalid address", /* IOERR_BADADDRESS */ + L"Requested unit is busy", /* IOERR_UNITBUSY */ + L"Hardware self-test failed" /* IOERR_SELFTEST */ +}; + +static uae_u32 iotextptrs[sizeof (io_errlist) / sizeof (*io_errlist)]; +static const uae_u32 number_io_error = sizeof (io_errlist) / sizeof (*io_errlist); + + static const TCHAR * const strErr = L"Errlist lookup error"; static uae_u32 strErrptr; @@ -1158,24 +1262,26 @@ static uae_u32 strErrptr; #define SBTC_HERRNOLONGPTR 25 #define SBTC_RELEASESTRPTR 29 +#define LOG_FACMASK 0x03f8 + static void tagcopy (uae_u32 currtag, uae_u32 currval, uae_u32 tagptr, uae_u32 * ptr) { - switch (currtag & 0x8001) { - case 0x0000: /* SBTM_GETVAL */ - - put_long (tagptr + 4, *ptr); + switch (currtag & 0x8001) + { + case 0x0000: /* SBTM_GETVAL */ + put_long (tagptr + 4, ptr ? *ptr : 0); break; - case 0x8000: /* SBTM_GETREF */ - - put_long (currval, *ptr); + case 0x8000: /* SBTM_GETREF */ + put_long (currval, ptr ? *ptr : 0); break; - case 0x0001: /* SBTM_SETVAL */ - - *ptr = currval; + case 0x0001: /* SBTM_SETVAL */ + if (ptr) + *ptr = currval; + break; + default: /* SBTM_SETREF */ + if (ptr) + *ptr = get_long (currval); break; - default: /* SBTM_SETREF */ - - *ptr = get_long (currval); } } @@ -1228,27 +1334,26 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context) switch ((currtag >> 1) & SBTS_CODE) { case SBTC_BREAKMASK: - BSDTRACE ((L"SBTC_BREAKMASK),0x%lx", currval)); + BSDTRACE ((L"SBTC_BREAKMASK),0x%x,0x%x", currval, sb->eintrsigs)); tagcopy (currtag, currval, tagptr, &sb->eintrsigs); break; case SBTC_SIGIOMASK: - BSDTRACE ((L"SBTC_SIGEVENTMASK),0x%lx", currval)); + BSDTRACE ((L"SBTC_SIGIOMASK),0x%x,0x%x", currval, sb->eventsigs)); tagcopy (currtag, currval, tagptr, &sb->eventsigs); break; case SBTC_SIGURGMASK: - BSDTRACE ((L"SBTC_SIGURGMASK),0x%lx", currval)); - //tagcopy (currtag, currval, tagptr, &sb->eventsigs); + BSDTRACE ((L"SBTC_SIGURGMASK),0x%x", currval)); break; case SBTC_SIGEVENTMASK: - BSDTRACE ((L"SBTC_SIGEVENTMASK),0x%lx", currval)); + BSDTRACE ((L"SBTC_SIGEVENTMASK),0x%x,0x%x", currval, sb->eventsigs)); tagcopy (currtag, currval, tagptr, &sb->eventsigs); break; case SBTC_ERRNO: - BSDTRACE ((L"SBTC_ERRNO),%d", currval)); + BSDTRACE ((L"SBTC_ERRNO),%x,%d", currval, sb->sb_errno)); tagcopy (currtag, currval, tagptr, (uae_u32*)&sb->sb_errno); break; case SBTC_HERRNO: - BSDTRACE ((L"SBTC_HERRNO),%d", currval)); + BSDTRACE ((L"SBTC_HERRNO),%x,%d", currval, sb->sb_herrno)); tagcopy (currtag, currval, tagptr, (uae_u32*)&sb->sb_herrno); break; case SBTC_DTABLESIZE: @@ -1259,18 +1364,89 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context) put_long (tagptr + 4, sb->dtablesize); } break; -#if 0 + case SBTC_FDCALLBACK: + BSDTRACE ((L"SBTC_FDCALLBACK),%08x", currval)); + tagcopy (currtag, currval, tagptr, &sb->fdcallback); break; + case SBTC_LOGSTAT: + BSDTRACE ((L"SBTC_LOGSTAT),%08x", currval)); + tagcopy (currtag, currval, tagptr, &sb->logstat); + sb->logstat &= 0xff; break; case SBTC_LOGTAGPTR: + BSDTRACE ((L"SBTC_LOGTAGPTR),%08x", currval)); + tagcopy (currtag, currval, tagptr, &sb->logptr); break; case SBTC_LOGFACILITY: + BSDTRACE ((L"SBTC_LOGFACILITY),%08x", currval)); + if (((currtag & 1) && currval != 0 && (currval & ~LOG_FACMASK)) || !(currtag & 1)) + tagcopy (currtag, currval, tagptr, &sb->logfacility); break; case SBTC_LOGMASK: + BSDTRACE ((L"SBTC_LOGMASK),%08x", currval)); + tagcopy (currtag, currval, tagptr, &sb->logmask); + sb->logmask &= 0xff; + break; + + case SBTC_IOERRNOSTRPTR: + if (currtag & 1) { + BSDTRACE ((L"IOERRNOSTRPTR),invalid")); + goto done; + } else { + unsigned long ulTmp; + if (currtag & 0x8000) { /* SBTM_GETREF */ + ulTmp = get_long (currval); + } else { /* SBTM_GETVAL */ + ulTmp = currval; + } + BSDTRACE ((L"IOERRNOSTRPTR),%d", ulTmp)); + if (ulTmp < number_sys_error) { + tagcopy (currtag, currval, tagptr, &iotextptrs[ulTmp]); + } else { + tagcopy (currtag, currval, tagptr, &strErrptr); + } + } + break; + case SBTC_S2ERRNOSTRPTR: + if (currtag & 1) { + BSDTRACE ((L"S2ERRNOSTRPTR),invalid")); + goto done; + } else { + unsigned long ulTmp; + if (currtag & 0x8000) { /* SBTM_GETREF */ + ulTmp = get_long (currval); + } else { /* SBTM_GETVAL */ + ulTmp = currval; + } + BSDTRACE ((L"S2ERRNOSTRPTR),%d", ulTmp)); + if (ulTmp < number_sys_error) { + tagcopy (currtag, currval, tagptr, &sana2iotextptrs[ulTmp]); + } else { + tagcopy (currtag, currval, tagptr, &strErrptr); + } + } + break; + case SBTC_S2WERRNOSTRPTR: + if (currtag & 1) { + BSDTRACE ((L"S2WERRNOSTRPTR),invalid")); + goto done; + } else { + unsigned long ulTmp; + if (currtag & 0x8000) { /* SBTM_GETREF */ + ulTmp = get_long (currval); + } else { /* SBTM_GETVAL */ + ulTmp = currval; + } + BSDTRACE ((L"S2WERRNOSTRPTR),%d", ulTmp)); + if (ulTmp < number_sys_error) { + tagcopy (currtag, currval, tagptr, &sana2wiretextptrs[ulTmp]); + } else { + tagcopy (currtag, currval, tagptr, &strErrptr); + } + } break; -#endif case SBTC_ERRNOSTRPTR: if (currtag & 1) { BSDTRACE ((L"ERRNOSTRPTR),invalid")); @@ -1309,14 +1485,7 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context) } } break; -#if 0 - case SBTC_IOERRNOSTRPTR: - break; - case SBTC_S2ERRNOSTRPTR: - break; - case SBTC_S2WERRNOSTRPTR: - break; -#endif + case SBTC_ERRNOBYTEPTR: BSDTRACE ((L"SBTC_ERRNOBYTEPTR),0x%lx", currval)); tagcopy (currtag, currval, tagptr, &sb->errnoptr); @@ -1338,8 +1507,8 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context) sb->herrnosize = 4; break; default: - write_log (L"bsdsocket: WARNING: Unsupported tag type (%08x) in SocketBaseTagList(%x)\n", - currtag, m68k_areg (regs, 0)); + write_log (L"bsdsocket: WARNING: Unsupported tag type (%08x=%d) in SocketBaseTagList(%x)\n", + currtag, (currtag / 2) & SBTS_CODE, m68k_areg (regs, 0)); goto done; } } @@ -1421,10 +1590,12 @@ static uae_u32 REGPARAM2 bsdsocklib_init (TrapContext *context) tmp1 = 0; for (i = number_sys_error; i--;) tmp1 += _tcslen (errortexts[i]) + 1; - for (i = number_host_error; i--;) tmp1 += _tcslen (herrortexts[i]) + 1; - + for (i = number_sana2io_error; i--;) + tmp1 += _tcslen (sana2io_errlist[i]) + 1; + for (i = number_sana2wire_error; i--;) + tmp1 += _tcslen (sana2wire_errlist[i]) + 1; tmp1 += _tcslen (strErr) + 1; m68k_dreg (regs, 0) = tmp1; @@ -1435,10 +1606,15 @@ static uae_u32 REGPARAM2 bsdsocklib_init (TrapContext *context) write_log (L"bsdsocket: FATAL: Ran out of memory while creating bsdsocket.library!\n"); return 0; } + for (i = 0; i < (int) (number_sys_error); i++) errnotextptrs[i] = addstr (&tmp1, errortexts[i]); for (i = 0; i < (int) (number_host_error); i++) herrnotextptrs[i] = addstr (&tmp1, herrortexts[i]); + for (i = 0; i < (int) (number_sana2io_error); i++) + sana2iotextptrs[i] = addstr (&tmp1, sana2io_errlist[i]); + for (i = 0; i < (int) (number_sana2wire_error); i++) + sana2wiretextptrs[i] = addstr (&tmp1, sana2wire_errlist[i]); strErrptr = addstr (&tmp1, strErr); #if 0 diff --git a/drawing.cpp b/drawing.cpp index 27e387fd..6789ee13 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -1752,12 +1752,14 @@ static void init_aspect_maps (void) max_drawn_amiga_line = -1; for (i = 0; i < maxl; i++) { int v = i - min_ypos_for_screen; - if (v >= gfxvidinfo.drawbuffer.height && max_drawn_amiga_line == -1) + if (v >= gfxvidinfo.drawbuffer.height && max_drawn_amiga_line < 0) max_drawn_amiga_line = i - min_ypos_for_screen; if (i < min_ypos_for_screen || v >= gfxvidinfo.drawbuffer.height) v = -1; amiga2aspect_line_map[i] = v; } + if (max_drawn_amiga_line < 0) + max_drawn_amiga_line = maxl - min_ypos_for_screen; max_drawn_amiga_line >>= linedbl; if (currprefs.gfx_ycenter && !currprefs.gfx_filter_autoscale) { diff --git a/include/bsdsocket.h b/include/bsdsocket.h index 1393b480..f31d8ffd 100644 --- a/include/bsdsocket.h +++ b/include/bsdsocket.h @@ -59,6 +59,11 @@ struct socketbase { uae_u32 eintrsigs; /* EINTR sigmask */ int eintr; /* interrupted by eintrsigs? */ int eventindex; /* current socket looked at by GetSocketEvents() to prevent starvation */ + uae_u32 logstat; + uae_u32 logptr; + uae_u32 logmask; + uae_u32 logfacility; + uaecptr fdcallback; /* host-specific fields below */ #ifdef _WIN32 @@ -118,6 +123,10 @@ struct UAEBSDBase { /* socket properties */ #define SF_BLOCKING 0x80000000 #define SF_BLOCKINGINPROGRESS 0x40000000 +/* STBC_FDCALLBACK */ +#define FDCB_FREE 0 +#define FDCB_ALLOC 1 +#define FDCB_CHECK 2 uae_u32 addstr (uae_u32 * dst, const TCHAR *src); uae_u32 addstr_ansi (uae_u32 * dst, const uae_char *src); @@ -138,11 +147,11 @@ extern void sigsockettasks (void); extern void locksigqueue (void); extern void unlocksigqueue (void); -extern BOOL checksd(SB, int sd); -extern void setsd(SB, int , SOCKET_TYPE); -extern int getsd (SB, SOCKET_TYPE); +extern BOOL checksd(TrapContext*, SB, int sd); +extern void setsd(TrapContext*, SB, int , SOCKET_TYPE); +extern int getsd (TrapContext*, SB, SOCKET_TYPE); extern SOCKET_TYPE getsock (SB, int); -extern void releasesock (SB, int); +extern void releasesock (TrapContext*, SB, int); extern void waitsig (TrapContext *context, SB); extern void cancelsig (TrapContext *context, SB); @@ -152,10 +161,10 @@ extern void host_sbcleanup (SB); extern void host_sbreset (void); extern void host_closesocketquick (SOCKET_TYPE); -extern int host_dup2socket (SB, int, int); -extern int host_socket (SB, int, int, int); -extern uae_u32 host_bind (SB, uae_u32, uae_u32, uae_u32); -extern uae_u32 host_listen (SB, uae_u32, uae_u32); +extern int host_dup2socket (TrapContext *, SB, int, int); +extern int host_socket (TrapContext *, SB, int, int, int); +extern uae_u32 host_bind (TrapContext *, SB, uae_u32, uae_u32, uae_u32); +extern uae_u32 host_listen (TrapContext *, SB, uae_u32, uae_u32); extern void host_accept (TrapContext *, SB, uae_u32, uae_u32, uae_u32); extern void host_sendto (TrapContext *, SB, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32); extern void host_recvfrom (TrapContext *, SB, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32); @@ -189,6 +198,7 @@ extern void host_getprotobynumber (TrapContext *, SB, uae_u32); extern uae_u32 host_vsyslog (void); extern uae_u32 host_Dup2Socket (void); extern uae_u32 host_gethostname (uae_u32, uae_u32); +extern uae_u32 callfdcallback (TrapContext *context, SB, uae_u32 fd, uae_u32 action); extern uaecptr bsdlib_startup (uaecptr); extern void bsdlib_install (void); diff --git a/od-win32/bsdsock.cpp b/od-win32/bsdsock.cpp index 2c1a00b8..0b1f6e58 100644 --- a/od-win32/bsdsock.cpp +++ b/od-win32/bsdsock.cpp @@ -47,6 +47,7 @@ struct threadargs { int args3; long args4; uae_char buf[MAXGETHOSTSTRUCT]; + int wscnt; }; struct threadargsw { @@ -56,6 +57,7 @@ struct threadargsw { uae_u32 writefds; uae_u32 exceptfds; uae_u32 timeout; + int wscnt; }; #define MAX_SELECT_THREADS 64 @@ -72,9 +74,10 @@ struct bsdsockdata { WSADATA wsbData; volatile HANDLE hGetThreads[MAX_GET_THREADS]; - struct threadargs threadGetargs[MAX_GET_THREADS]; + volatile struct threadargs *threadGetargs[MAX_GET_THREADS]; volatile int threadGetargs_inuse[MAX_GET_THREADS]; volatile HANDLE hGetEvents[MAX_GET_THREADS]; + volatile HANDLE hGetEvents2[MAX_GET_THREADS]; volatile HANDLE hThreads[MAX_SELECT_THREADS]; volatile struct threadargsw *threadargsw[MAX_SELECT_THREADS]; @@ -249,6 +252,10 @@ static void close_selectget_threads(void) CloseHandle (bsd->hGetEvents[i]); bsd->hGetEvents[i] = NULL; } + if (bsd->hGetEvents2[i]) { + CloseHandle (bsd->hGetEvents2[i]); + bsd->hGetEvents2[i] = NULL; + } bsd->threadGetargs_inuse[i] = 0; } @@ -395,6 +402,7 @@ static void sockmsg(unsigned int msg, WPARAM wParam, LPARAM lParam) { // cancel socket event WSAAsyncSelect((SOCKET)wParam, hWndSelector ? hAmigaWnd : bsd->hSockWnd, 0, 0); + BSDTRACE((L"unknown sockmsg %d\n", index)); return; } @@ -550,7 +558,7 @@ static void prepamigaaddr(struct sockaddr *realpt, int len) } -int host_dup2socket(SB, int fd1, int fd2) +int host_dup2socket(TrapContext *context, SB, int fd1, int fd2) { SOCKET s1,s2; @@ -570,12 +578,12 @@ int host_dup2socket(SB, int fd1, int fd2) shutdown(s2,1); closesocket(s2); } - setsd(sb,fd2,s1); + setsd(context, sb, fd2, s1); BSDTRACE((L"0\n")); return 0; } else { - fd2 = getsd(sb, 1); - setsd(sb,fd2,s1); + fd2 = getsd(context, sb, 1); + setsd(context, sb, fd2, s1); BSDTRACE((L"%d\n",fd2)); return (fd2 - 1); } @@ -584,7 +592,7 @@ int host_dup2socket(SB, int fd1, int fd2) return -1; } -int host_socket(SB, int af, int type, int protocol) +int host_socket(TrapContext *context, SB, int af, int type, int protocol) { int sd; SOCKET s; @@ -596,8 +604,9 @@ int host_socket(SB, int af, int type, int protocol) SETERRNO; BSDTRACE((L"failed (%d)\n",sb->sb_errno)); return -1; - } else - sd = getsd(sb,s); + } else { + sd = getsd(context, sb,s); + } sb->ftable[sd-1] = SF_BLOCKING; ioctlsocket(s,FIONBIO,&nonblocking); @@ -618,10 +627,11 @@ int host_socket(SB, int af, int type, int protocol) sb->ftable[sd-1] |= SF_RAW_RAW; } } + callfdcallback (context, sb, sd - 1, FDCB_ALLOC); return sd-1; } -uae_u32 host_bind(SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) +uae_u32 host_bind(TrapContext *context, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) { uae_char buf[MAXADDRLEN]; uae_u32 success = 0; @@ -652,7 +662,7 @@ uae_u32 host_bind(SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) return success; } -uae_u32 host_listen(SB, uae_u32 sd, uae_u32 backlog) +uae_u32 host_listen(TrapContext *context, SB, uae_u32 sd, uae_u32 backlog) { SOCKET s; uae_u32 success = -1; @@ -745,8 +755,9 @@ void host_accept(TrapContext *context, SB, uae_u32 sd, uae_u32 name, uae_u32 nam sb->resultval = -1; BSDTRACE((L"failed (%d)\n",sb->sb_errno)); } else { - sb->resultval = getsd(sb, s2); + sb->resultval = getsd(context, sb, s2); sb->ftable[sb->resultval - 1] = sb->ftable[sd - 1]; // new socket inherits the old socket's properties + callfdcallback(context, sb, sb->resultval - 1, FDCB_ALLOC); sb->resultval--; if (rp_name != 0) { // 1.11.2002 XXX if (hlen <= hlenuae) { // Fix for CNET BBS Part 2 @@ -816,6 +827,7 @@ struct threadsock_packet } params; SOCKET s; SB; + int wscnt; } sockreq; // sockreg.sb may be gone if thread dies at right time.. fixme.. */ @@ -830,6 +842,7 @@ static BOOL HandleStuff(void) // 100ms sleepiness might need some tuning... //if(WaitForSingleObject( hSockReq, 100 ) == WAIT_OBJECT_0 ) { + BSDTRACE((L"sockreq start %d:%d\n", sockreq.packet_type,sockreq.wscnt)); switch(sockreq.packet_type) { case connect_req: @@ -873,6 +886,7 @@ static BOOL HandleStuff(void) SETERRNO; } } + BSDTRACE((L"sockreq end %d,%d,%d:%d\n", sockreq.packet_type,sockreq.sb->resultval,sockreq.sb->sb_errno,sockreq.wscnt)); SetEvent(bsd->hSockReqHandled); } } else { @@ -884,8 +898,8 @@ static BOOL HandleStuff(void) static LRESULT CALLBACK SocketWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if(message >= 0xB000 && message < 0xB000 + MAXPENDINGASYNC * 2) { -#if DEBUG_SOCKETS - write_log ( "sockmsg(0x%x, 0x%x, 0x%x)\n", message, wParam, lParam ); +#ifdef TRACING_ENABLED + write_log (L"sockmsg(0x%x[%d], 0x%x, 0x%x)\n", message, (message - 0xb000) / 2, wParam, lParam ); #endif sockmsg(message, wParam, lParam); return 0; @@ -946,9 +960,13 @@ void host_connect(TrapContext *context, SB, uae_u32 sd, uae_u32 name, uae_u32 na int success = 0; unsigned int wMsg; uae_char buf[MAXADDRLEN]; + static int wscounter; + int wscnt; sd++; - BSDTRACE((L"connect(%d,0x%x,%d) -> ", sd, name, namelen)); + wscnt = ++wscounter; + + BSDTRACE((L"connect(%d,0x%x,%d):%d -> ", sd, name, namelen, wscnt)); if (!addr_valid (L"host_connect", name, namelen)) return; @@ -975,6 +993,7 @@ void host_connect(TrapContext *context, SB, uae_u32 sd, uae_u32 name, uae_u32 na sockreq.sb = sb; sockreq.params.connect_s.buf = buf; sockreq.params.connect_s.namelen = namelen; + sockreq.wscnt = wscnt; TRIGGER_THREAD; @@ -1007,10 +1026,11 @@ void host_connect(TrapContext *context, SB, uae_u32 sd, uae_u32 name, uae_u32 na setWSAAsyncSelect(sb,sd,s,0); } } - } else - write_log (L"BSDSOCK: WARNING - Excessive namelen (%d) in connect()!\n", namelen); + } else { + write_log (L"BSDSOCK: WARNING - Excessive namelen (%d) in connect():%d!\n", namelen, wscnt); + } } - BSDTRACE((L"%d\n",sb->sb_errno)); + BSDTRACE((L" -> connect %d:%d\n",sb->sb_errno, wscnt)); } void host_sendto (TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len, uae_u32 flags, uae_u32 to, uae_u32 tolen) @@ -1020,12 +1040,16 @@ void host_sendto (TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len unsigned int wMsg; uae_char buf[MAXADDRLEN]; int iCut; + static int wscounter; + int wscnt; + + wscnt = ++wscounter; #ifdef TRACING_ENABLED if (to) - BSDTRACE((L"sendto(%d,0x%x,%d,0x%x,0x%x,%d) -> ",sd,msg,len,flags,to,tolen)); + BSDTRACE((L"sendto(%d,0x%x,%d,0x%x,0x%x,%d):%d-> ",sd,msg,len,flags,to,tolen,wscnt)); else - BSDTRACE((L"send(%d,0x%x,%d,%d) -> ",sd,msg,len,flags)); + BSDTRACE((L"send(%d,0x%x,%d,%d):%d -> ",sd,msg,len,flags,wscnt)); #endif sd++; s = getsock(sb,sd); @@ -1037,7 +1061,7 @@ void host_sendto (TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len if (to) { if (tolen > sizeof buf) { - write_log (L"BSDSOCK: WARNING - Target address in sendto() too large (%d)!\n", tolen); + write_log (L"BSDSOCK: WARNING - Target address in sendto() too large (%d):%d!\n", tolen,wscnt); } else { if (!addr_valid (L"host_sendto2", to, tolen)) return; @@ -1096,6 +1120,7 @@ void host_sendto (TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len sockreq.params.sendto_s.flags = flags; sockreq.params.sendto_s.to = to; sockreq.params.sendto_s.tolen = tolen; + sockreq.wscnt = wscnt; if (sb->ftable[sd - 1] & SF_RAW_UDP) { *(buf+2) = *(realpt+2); @@ -1171,9 +1196,9 @@ void host_sendto (TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len #ifdef TRACING_ENABLED if (sb->resultval == -1) - BSDTRACE((L"failed (%d)\n",sb->sb_errno)); + BSDTRACE((L"sendto failed (%d):%d\n",sb->sb_errno,wscnt)); else - BSDTRACE((L"%d\n",sb->resultval)); + BSDTRACE((L"sendto %d:%d\n",sb->resultval,wscnt)); #endif } @@ -1186,12 +1211,16 @@ void host_recvfrom(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 le int hlen; unsigned int wMsg; int waitall, waitallgot; + static int wscounter; + int wscnt; + + wscnt = ++wscounter; #ifdef TRACING_ENABLED if (addr) - BSDTRACE((L"recvfrom(%d,0x%x,%d,0x%x,0x%x,%d) -> ",sd,msg,len,flags,addr,get_long (addrlen))); + BSDTRACE((L"recvfrom(%d,0x%x,%d,0x%x,0x%x,%d):%d -> ",sd,msg,len,flags,addr,get_long (addrlen),wscnt)); else - BSDTRACE((L"recv(%d,0x%x,%d,0x%x) -> ",sd,msg,len,flags)); + BSDTRACE((L"recv(%d,0x%x,%d,0x%x):%d -> ",sd,msg,len,flags,wscnt)); #endif sd++; s = getsock(sb,sd); @@ -1229,6 +1258,7 @@ void host_recvfrom(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 le sockreq.params.recvfrom_s.len = len; sockreq.params.recvfrom_s.realpt = realpt; sockreq.params.recvfrom_s.rp_addr = rp_addr; + sockreq.wscnt = wscnt; TRIGGER_THREAD; @@ -1292,9 +1322,9 @@ void host_recvfrom(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 le #ifdef TRACING_ENABLED if (sb->resultval == -1) - BSDTRACE((L"failed (%d)\n",sb->sb_errno)); + BSDTRACE((L"recv failed (%d):%d\n",sb->sb_errno,wscnt)); else - BSDTRACE((L"%d\n",sb->resultval)); + BSDTRACE((L"recv %d:%d\n",sb->resultval,wscnt)); #endif } @@ -1607,7 +1637,7 @@ int host_CloseSocket(TrapContext *context, SB, int sd) sb->mtable[sd-1] = 0; } - if (checksd(sb ,sd) == TRUE) + if (checksd(context, sb ,sd) == TRUE) return 0; BEGINBLOCKING; @@ -1616,7 +1646,7 @@ int host_CloseSocket(TrapContext *context, SB, int sd) shutdown(s,1); if (!closesocket(s)) { - releasesock(sb,sd); + releasesock(context, sb, sd); BSDTRACE((L"OK\n")); return 0; } @@ -1739,6 +1769,7 @@ static unsigned int thread_WaitSelect2(void *indexp) { int index = *((int*)indexp); unsigned int result = 0, resultval; + int wscnt; long nfds; uae_u32 readfds, writefds, exceptfds; uae_u32 timeout; @@ -1761,6 +1792,7 @@ static unsigned int thread_WaitSelect2(void *indexp) writefds = args->writefds; exceptfds = args->exceptfds; timeout = args->timeout; + wscnt = args->wscnt; // construct descriptor tables makesocktable(sb, readfds, &readsocks, nfds, sb->sockAbort); @@ -1772,15 +1804,18 @@ static unsigned int thread_WaitSelect2(void *indexp) if (timeout) { tv.tv_sec = get_long (timeout); tv.tv_usec = get_long (timeout+4); - BSDTRACE((L"(timeout: %d.%06d) ",tv.tv_sec,tv.tv_usec)); + BSDTRACE((L"(to: %d.%06d) ",tv.tv_sec,tv.tv_usec)); } - BSDTRACE((L"-> ")); + BSDTRACE((L"tWS2(%d) -> ", wscnt)); resultval = select(nfds+1, &readsocks, writefds ? &writesocks : NULL, exceptfds ? &exceptsocks : NULL, timeout ? &tv : 0); if (bsd->hEvents[index] == NULL) break; + + BSDTRACE((L"tWS2(%d,%d) -> ", resultval, wscnt)); + sb->resultval = resultval; if (sb->resultval == SOCKET_ERROR) { // select was stopped by sb->sockAbort @@ -1806,6 +1841,7 @@ static unsigned int thread_WaitSelect2(void *indexp) } } if (FD_ISSET(sb->sockAbort,&readsocks)) { + BSDTRACE((L"tWS2 abort %d:%d\n", sb->resultval, wscnt)); if (sb->resultval != SOCKET_ERROR) { sb->resultval--; } @@ -1814,7 +1850,7 @@ static unsigned int thread_WaitSelect2(void *indexp) } if (sb->resultval == SOCKET_ERROR) { SETERRNO; - BSDTRACE((L"failed (%d) - ",sb->sb_errno)); + BSDTRACE((L"tWS2 failed %d:%d - ",sb->sb_errno,wscnt)); if (readfds) fd_zero(readfds,nfds); if (writefds) @@ -1822,6 +1858,7 @@ static unsigned int thread_WaitSelect2(void *indexp) if (exceptfds) fd_zero(exceptfds,nfds); } else { + BSDTRACE((L"tWS2 ok %d\n", wscnt)); if (readfds) makesockbitfield(sb,readfds,&readsocks,nfds); if (writefds) @@ -1850,16 +1887,40 @@ static unsigned int __stdcall thread_WaitSelect(void *p) return 0; } +static void fddebug(const TCHAR *name, uae_u32 nfds, uae_u32 fd) +{ +#ifdef TRACING_ENABLED + if (!nfds) + return; + if (!fd) + return; + TCHAR out[40]; + uae_u32 v = get_long (fd); + for (int i = 0; i < nfds && i < 32; i++) { + out[i] = (v & (1 << i)) ? 'x' : '-'; + out[i + 1] = 0; + } + write_log (L"%s: %08x %s\n", name, v, out); +#endif +} + void host_WaitSelect(TrapContext *context, SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u32 exceptfds, uae_u32 timeout, uae_u32 sigmp) { + static int wscount; uae_u32 sigs, wssigs; int i; struct threadargsw taw; + int wscnt; + + wscnt = ++wscount; wssigs = sigmp ? get_long (sigmp) : 0; - BSDTRACE((L"WaitSelect(%d,0x%x,0x%x,0x%x,0x%x,0x%x) ", - nfds, readfds, writefds, exceptfds, timeout, wssigs)); + BSDTRACE((L"WaitSelect(%d,0x%x,0x%x,0x%x,0x%x,0x%x):%d ", + nfds, readfds, writefds, exceptfds, timeout, wssigs, wscnt)); + fddebug(L"read", nfds, readfds); + fddebug(L"write", nfds, writefds); + fddebug(L"except", nfds, exceptfds); if (!readfds && !writefds && !exceptfds && !timeout && !wssigs) { sb->resultval = 0; @@ -1939,7 +2000,7 @@ void host_WaitSelect(TrapContext *context, SB, uae_u32 nfds, uae_u32 readfds, ua unlocksigqueue (); if (i >= MAX_SELECT_THREADS) { - write_log (L"BSDSOCK: ERROR - Too many select()s\n"); + write_log (L"BSDSOCK: ERROR - Too many select()s, %d\n", wscnt); } else { SOCKET newsock = INVALID_SOCKET; @@ -1949,6 +2010,7 @@ void host_WaitSelect(TrapContext *context, SB, uae_u32 nfds, uae_u32 readfds, ua taw.writefds = writefds; taw.exceptfds = exceptfds; taw.timeout = timeout; + taw.wscnt = wscnt; bsd->threadargsw[i] = &taw; @@ -1964,7 +2026,7 @@ void host_WaitSelect(TrapContext *context, SB, uae_u32 nfds, uae_u32 readfds, ua */ if (sb->needAbort) { if ((newsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET) - write_log (L"BSDSOCK: ERROR - Cannot create socket: %d\n", WSAGetLastError()); + write_log (L"BSDSOCK: ERROR - Cannot create socket: %d, %d\n", WSAGetLastError(),wscnt); shutdown(sb->sockAbort,1); if (newsock != sb->sockAbort) { shutdown(sb->sockAbort, 1); @@ -1983,11 +2045,11 @@ void host_WaitSelect(TrapContext *context, SB, uae_u32 nfds, uae_u32 readfds, ua put_long (sigmp,sigs & wssigs); if (sigs & sb->eintrsigs) { - BSDTRACE((L"[interrupted]\n")); + BSDTRACE((L"[interrupted]:%d\n",wscnt)); sb->resultval = -1; bsdsocklib_seterrno(sb,4); // EINTR } else if (sigs & wssigs) { - BSDTRACE((L"[interrupted by signals 0x%08lx]\n",sigs & wssigs)); + BSDTRACE((L"[interrupted by signals 0x%08lx]:%d\n",sigs & wssigs,wscnt)); if (readfds) fd_zero(readfds,nfds); if (writefds) fd_zero(writefds,nfds); if (exceptfds) fd_zero(exceptfds,nfds); @@ -1995,12 +2057,13 @@ void host_WaitSelect(TrapContext *context, SB, uae_u32 nfds, uae_u32 readfds, ua sb->resultval = 0; } if (sb->resultval >= 0) { - BSDTRACE((L"%d\n",sb->resultval)); + BSDTRACE((L"WaitSelect, %d:%d\n",sb->resultval,wscnt)); } else { - BSDTRACE((L"%d errno %d\n",sb->resultval,sb->sb_errno)); + BSDTRACE((L"WaitSelect error, %d errno %d:%d\n",sb->resultval,sb->sb_errno,wscnt)); } - } else - BSDTRACE((L"%d\n",sb->resultval)); + } else { + BSDTRACE((L"WaitSelect done %d:%d\n",sb->resultval,wscnt)); + } } } @@ -2044,7 +2107,7 @@ uae_u32 host_inet_addr(uae_u32 cp) #ifdef TRACING_ENABLED TCHAR *s = au (cp_rp); - BSDTRACE((L"inet_addr(%s) -> 0x%08lx\n",cp_rp,addr)); + BSDTRACE((L"inet_addr(%s) -> 0x%08lx\n",s,addr)); xfree (s); #endif return addr; @@ -2075,12 +2138,15 @@ static BOOL CheckOnline(SB) #define GET_STATE_ACTIVE 1 #define GET_STATE_CANCEL 2 #define GET_STATE_FINISHED 3 +#define GET_STATE_DONE 4 +#define GET_STATE_REALLY_DONE 5 static unsigned int thread_get2 (void *indexp) { int index = *((int*)indexp); + int wscnt; unsigned int result = 0; - struct threadargs *args; + volatile struct threadargs *args; uae_u32 name; uae_u32 namelen; long addrtype; @@ -2094,8 +2160,12 @@ static unsigned int thread_get2 (void *indexp) if (bsd->hGetEvents[index] == NULL) break; + args = bsd->threadGetargs[index]; + + BSDTRACE((L"tg2 %p,%d,%d:%d -> ", args->sb, index, bsd->threadGetargs_inuse[index], args->wscnt)); + if (bsd->threadGetargs_inuse[index] == GET_STATE_ACTIVE) { - args = &bsd->threadGetargs[index]; + wscnt = args->wscnt; sb = args->sb; if (args->args1 == 0) { @@ -2112,20 +2182,22 @@ static unsigned int thread_get2 (void *indexp) if (strchr (name_rp, '.') == 0 || CheckOnline(sb) == TRUE) { // Local Address or Internet Online ? + BSDTRACE((L"tg2_0a %d:%d -> ",addrtype,wscnt)); if (addrtype == -1) { host = gethostbyname (name_rp); } else { host = gethostbyaddr (name_rp, namelen, addrtype); } + BSDTRACE((L"tg2_0b %d -> ", wscnt)); if (bsd->threadGetargs_inuse[index] != GET_STATE_CANCEL) { // No CTRL-C Signal if (host == 0) { // Error occured SETERRNO; - BSDTRACE((L"failed (%d) - ", sb->sb_errno)); + BSDTRACE((L"tg2_0 failed %d:%d -> ", sb->sb_errno,wscnt)); } else { bsdsocklib_seterrno(sb, 0); - memcpy(args->buf, host, sizeof(HOSTENT)); + memcpy((void*)args->buf, host, sizeof(HOSTENT)); } } } @@ -2145,10 +2217,10 @@ static unsigned int thread_get2 (void *indexp) if (proto == 0) { // Error occured SETERRNO; - BSDTRACE((L"failed (%d) - ", sb->sb_errno)); + BSDTRACE((L"tg2_1 failed %d:%d -> ", sb->sb_errno, wscnt)); } else { bsdsocklib_seterrno(sb, 0); - memcpy(args->buf, proto, sizeof(struct protoent)); + memcpy((void*)args->buf, proto, sizeof(struct protoent)); } } @@ -2182,23 +2254,27 @@ static unsigned int thread_get2 (void *indexp) if (serv == 0) { // Error occured SETERRNO; - BSDTRACE((L"failed (%d) - ", sb->sb_errno)); + BSDTRACE((L"tg2_2 failed %d:%d -> ", sb->sb_errno, wscnt)); } else { bsdsocklib_seterrno(sb, 0); - memcpy(args->buf, serv, sizeof (struct servent)); + memcpy((void*)args->buf, serv, sizeof (struct servent)); } } } - BSDTRACE((L"-> ")); + locksigqueue (); + bsd->threadGetargs_inuse[index] = GET_STATE_FINISHED; + unlocksigqueue (); - if (bsd->threadGetargs_inuse[index] == GET_STATE_ACTIVE) - SETSIGNAL; + SETSIGNAL; locksigqueue (); - bsd->threadGetargs_inuse[index] = GET_STATE_FINISHED; + bsd->threadGetargs_inuse[index] = GET_STATE_DONE; unlocksigqueue (); + SetEvent(bsd->hGetEvents2[index]); + + BSDTRACE((L"tg2 done %d:%d\n", index, wscnt)); } } write_log (L"BSDSOCK: thread_get2 terminated\n"); @@ -2215,14 +2291,16 @@ static unsigned int __stdcall thread_get(void *p) return 0; } -static volatile struct threadargs *run_get_thread(TrapContext *context, SB, struct threadargs *args) +static int run_get_thread(TrapContext *context, SB, struct threadargs *args) { int i; + sb->eintr = 0; + locksigqueue (); for (i = 0; i < MAX_GET_THREADS; i++) { - if (bsd->threadGetargs_inuse[i] == GET_STATE_FINISHED) { + if (bsd->threadGetargs_inuse[i] == GET_STATE_REALLY_DONE) { bsd->threadGetargs_inuse[i] = GET_STATE_FREE; } if (bsd->hGetThreads[i] && bsd->threadGetargs_inuse[i] == GET_STATE_FREE) { @@ -2235,18 +2313,22 @@ static volatile struct threadargs *run_get_thread(TrapContext *context, SB, stru if (bsd->hGetThreads[i] == NULL) { bsd->threadGetargs_inuse[i] = GET_STATE_FREE; bsd->hGetEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL); - if (bsd->hGetEvents[i]) + bsd->hGetEvents2[i] = CreateEvent(NULL,FALSE,FALSE,NULL); + if (bsd->hGetEvents[i] && bsd->hGetEvents2[i]) bsd->hGetThreads[i] = THREAD(thread_get, &threadindextable[i]); - if (bsd->hGetEvents[i] == NULL || bsd->hGetThreads[i] == NULL) { + if (bsd->hGetEvents[i] == NULL || bsd->hGetEvents2[i] == NULL || bsd->hGetThreads[i] == NULL) { if (bsd->hGetEvents[i]) CloseHandle (bsd->hGetEvents[i]); bsd->hGetEvents[i] = NULL; - write_log (L"BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n", - GetLastError()); + if (bsd->hGetEvents2[i]) + CloseHandle (bsd->hGetEvents2[i]); + bsd->hGetEvents2[i] = NULL; + write_log (L"BSDSOCK: ERROR - Thread/Event creation failed - error code: %d:%d\n", + GetLastError(), args->wscnt); bsdsocklib_seterrno(sb, 12); // ENOMEM sb->resultval = -1; unlocksigqueue (); - return 0; + return -1; } bsdsetpriority (bsd->hGetThreads[i]); break; @@ -2255,39 +2337,51 @@ static volatile struct threadargs *run_get_thread(TrapContext *context, SB, stru } if (i >= MAX_GET_THREADS) { - write_log (L"BSDSOCK: ERROR - Too many gethostbyname()s\n"); + write_log (L"BSDSOCK: ERROR - Too many gethostbyname()s:%d\n", args->wscnt); bsdsocklib_seterrno(sb, 12); // ENOMEM sb->resultval = -1; unlocksigqueue (); - return 0; + return -1; } else { - memcpy (&bsd->threadGetargs[i], args, sizeof (struct threadargs)); + bsd->threadGetargs[i] = args; bsd->threadGetargs_inuse[i] = GET_STATE_ACTIVE; + ResetEvent(bsd->hGetEvents2[i]); SetEvent(bsd->hGetEvents[i]); } unlocksigqueue (); - sb->eintr = 0; - while (bsd->threadGetargs_inuse[i] != GET_STATE_FINISHED && sb->eintr == 0) { + while (bsd->threadGetargs_inuse[i] != GET_STATE_FINISHED && bsd->threadGetargs_inuse[i] != GET_STATE_DONE) { WAITSIGNAL; locksigqueue (); - if (sb->eintr == 1 && bsd->threadGetargs_inuse[i] != GET_STATE_FINISHED) + int inuse = bsd->threadGetargs_inuse[i]; + if (sb->eintr == 1 && inuse != GET_STATE_FINISHED && inuse != GET_STATE_DONE) bsd->threadGetargs_inuse[i] = GET_STATE_CANCEL; unlocksigqueue (); } + + if (bsd->threadGetargs_inuse[i] >= GET_STATE_FINISHED) + WaitForSingleObject(bsd->hGetEvents2[i], INFINITE); + CANCELSIGNAL; - return &bsd->threadGetargs[i]; + return i; +} + + +static void release_get_thread(int index) +{ + bsd->threadGetargs_inuse[index] = GET_STATE_REALLY_DONE; } void host_gethostbynameaddr (TrapContext *context, SB, uae_u32 name, uae_u32 namelen, long addrtype) { + static int wscounter; HOSTENT *h; int size, numaliases = 0, numaddr = 0; uae_u32 aptr; char *name_rp; - int i; + int i, tindex; struct threadargs args; volatile struct threadargs *argsp; uae_u32 addr; @@ -2301,7 +2395,9 @@ void host_gethostbynameaddr (TrapContext *context, SB, uae_u32 name, uae_u32 nam memset(&args, 0, sizeof (args)); argsp = &args; + argsp->wscnt = ++wscounter; buf = argsp->buf; + name_rp = ""; if (addr_valid (L"host_gethostbynameaddr", name, 1)) @@ -2327,7 +2423,7 @@ void host_gethostbynameaddr (TrapContext *context, SB, uae_u32 name, uae_u32 nam goto kludge; } } else { - BSDTRACE((L"gethostbyaddr(0x%x,0x%x,%ld) -> ",name,namelen,addrtype)); + BSDTRACE((L"gethostbyaddr(0x%x,0x%x,%ld):%d -> ",name,namelen,addrtype,argsp->wscnt)); } argsp->sb = sb; @@ -2336,8 +2432,8 @@ void host_gethostbynameaddr (TrapContext *context, SB, uae_u32 name, uae_u32 nam argsp->args3 = namelen; argsp->args4 = addrtype; - argsp = run_get_thread(context, sb, &args); - if (!argsp) + tindex = run_get_thread(context, sb, &args); + if (tindex < 0) return; buf = argsp->buf; @@ -2367,9 +2463,10 @@ kludge: if (!sb->hostent) { write_log (L"BSDSOCK: WARNING - gethostby%s() ran out of Amiga memory " - L"(couldn't allocate %ld bytes) while returning result of lookup for '%s'\n", - addrtype == -1 ? L"name" : L"addr", size, name_rp); + L"(couldn't allocate %ld bytes) while returning result of lookup for '%s':%d\n", + addrtype == -1 ? L"name" : L"addr", size, name_rp, argsp->wscnt); bsdsocklib_seterrno(sb, 12); // ENOMEM + release_get_thread (tindex); return; } @@ -2394,46 +2491,51 @@ kludge: #ifdef TRACING_ENABLED TCHAR *s = au (h->h_name); - BSDTRACE((L"OK (%s)\n", s)); + BSDTRACE((L"OK (%s):%d\n", s, argsp->wscnt)); xfree (s); #endif bsdsocklib_seterrno(sb, 0); bsdsocklib_setherrno(sb, 0); } else { - BSDTRACE((L"failed (%d/%d)\n", sb->sb_errno, sb->sb_herrno)); + BSDTRACE((L"failed (%d/%d):%d\n", sb->sb_errno, sb->sb_herrno,argsp->wscnt)); } + release_get_thread (tindex); + } void host_getprotobyname(TrapContext *context, SB, uae_u32 name) { + static int wscounter; PROTOENT *p; int size, numaliases = 0; uae_u32 aptr; char *name_rp; - int i; + int i, tindex; struct threadargs args; volatile struct threadargs *argsp; + memset(&args, 0, sizeof (args)); + argsp = &args; + argsp->sb = sb; + argsp->wscnt = ++wscounter; + name_rp = ""; if (addr_valid (L"host_gethostbynameaddr", name, 1)) name_rp = (char*)get_real_address (name); #ifdef TRACING_ENABLED TCHAR *s = au (name_rp); - BSDTRACE((L"getprotobyname(%s) -> ",s)); + BSDTRACE((L"getprotobyname(%s):%d -> ",s, argsp->wscnt)); xfree (s); #endif - memset(&args, 0, sizeof (args)); - argsp = &args; - argsp->sb = sb; argsp->args1 = 1; argsp->args2 = name; - argsp = run_get_thread(context, sb, &args); - if (!argsp) + tindex = run_get_thread(context, sb, &args); + if (tindex < 0) return; if (!sb->sb_errno) { @@ -2457,11 +2559,12 @@ void host_getprotobyname(TrapContext *context, SB, uae_u32 name) #ifdef TRACING_ENABLED TCHAR *s = au (name_rp); write_log (L"BSDSOCK: WARNING - getprotobyname() ran out of Amiga memory " - L"(couldn't allocate %ld bytes) while returning result of lookup for '%s'\n", - size, s); + L"(couldn't allocate %ld bytes) while returning result of lookup for '%s':%d\n", + size, s, argsp->wscnt); xfree (s); #endif bsdsocklib_seterrno(sb,12); // ENOMEM + release_get_thread (tindex); return; } @@ -2480,15 +2583,16 @@ void host_getprotobyname(TrapContext *context, SB, uae_u32 name) addstr_ansi (&aptr, p->p_name); #ifdef TRACING_ENABLED TCHAR *s = au (p->p_name); - BSDTRACE((L"OK (%s, %d)\n", s, p->p_proto)); + BSDTRACE((L"OK (%s, %d):%d\n", s, p->p_proto, argsp->wscnt)); xfree (s); #endif bsdsocklib_seterrno (sb,0); } else { - BSDTRACE((L"failed (%d)\n", sb->sb_errno)); + BSDTRACE((L"failed (%d):%d\n", sb->sb_errno, argsp->wscnt)); } + release_get_thread (tindex); } void host_getprotobynumber(TrapContext *context, SB, uae_u32 name) @@ -2498,37 +2602,40 @@ void host_getprotobynumber(TrapContext *context, SB, uae_u32 name) void host_getservbynameport(TrapContext *context, SB, uae_u32 nameport, uae_u32 proto, uae_u32 type) { + static int wscounter; SERVENT *s; int size, numaliases = 0; uae_u32 aptr; TCHAR *name_rp = NULL, *proto_rp = NULL; - int i; + int i, tindex; struct threadargs args; volatile struct threadargs *argsp; + memset(&args, 0, sizeof (args)); + argsp = &args; + argsp->sb = sb; + argsp->wscnt = ++wscounter; + if (proto) { if (addr_valid (L"host_getservbynameport1", proto, 1)) proto_rp = au ((char*)get_real_address (proto)); } if (type) { - BSDTRACE((L"getservbyport(%d,%s) -> ",nameport, proto_rp ? proto_rp : L"NULL")); + BSDTRACE((L"getservbyport(%d,%s);%d -> ",nameport, proto_rp ? proto_rp : L"NULL", argsp->wscnt)); } else { if (addr_valid (L"host_getservbynameport2", nameport, 1)) name_rp = au ((char*)get_real_address (nameport)); - BSDTRACE((L"getservbyname(%s,%s) -> ",name_rp, proto_rp ? proto_rp : L"NULL")); + BSDTRACE((L"getservbyname(%s,%s):%d -> ",name_rp, proto_rp ? proto_rp : L"NULL", argsp->wscnt)); } - memset(&args, 0, sizeof (args)); - argsp = &args; - argsp->sb = sb; argsp->args1 = 2; argsp->args2 = nameport; argsp->args3 = proto; argsp->args4 = type; - argsp = run_get_thread (context, sb, &args); - if (!argsp) + tindex = run_get_thread (context, sb, &args); + if (tindex < 0) return; if (!sb->sb_errno) { @@ -2552,8 +2659,9 @@ void host_getservbynameport(TrapContext *context, SB, uae_u32 nameport, uae_u32 sb->servent = uae_AllocMem(context, size, 0); if (!sb->servent) { - write_log (L"BSDSOCK: WARNING - getservby%s() ran out of Amiga memory (couldn't allocate %ld bytes)\n", type ? L"port" : L"name", size); + write_log (L"BSDSOCK: WARNING - getservby%s() ran out of Amiga memory (couldn't allocate %ld bytes):%d\n", type ? L"port" : L"name", size, argsp->wscnt); bsdsocklib_seterrno(sb, 12); // ENOMEM + release_get_thread (tindex); return; } @@ -2575,15 +2683,16 @@ void host_getservbynameport(TrapContext *context, SB, uae_u32 nameport, uae_u32 #ifdef TRACING_ENABLED TCHAR *ss = au (s->s_name); - BSDTRACE((L"OK (%s, %d)\n", ss, (unsigned short)htons(s->s_port))); + BSDTRACE((L"OK (%s, %d):%d\n", ss, (unsigned short)htons(s->s_port), argsp->wscnt)); xfree (ss); #endif bsdsocklib_seterrno(sb, 0); } else { - BSDTRACE((L"failed (%d)\n",sb->sb_errno)); + BSDTRACE((L"failed (%d):%d\n",sb->sb_errno, argsp->wscnt)); } + release_get_thread (tindex); } uae_u32 host_gethostname(uae_u32 name, uae_u32 namelen) diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index ab2a2ece..1ad08ccb 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -10,8 +10,8 @@ int rawinput_enabled_hid = -1; #define _WIN32_WINNT 0x501 /* enable RAWINPUT support */ -#define DI_DEBUG -//#define DI_DEBUG2 +#define DI_DEBUG 1 +#define DI_DEBUG2 0 #define DI_DEBUG_RAWINPUT_KB 0 #define DI_DEBUG_RAWINPUT_MOUSE 0 #define DI_DEBUG_RAWINPUT_HID 0 @@ -365,7 +365,8 @@ static void fixthings_mouse (struct didata *did) } } -static int rawinput_available, rawinput_registered_mouse, rawinput_registered_kb, rawinput_registered_hid; +static int rawinput_available; +static bool rawinput_registered; static bool test_rawinput (int usage) { @@ -386,99 +387,96 @@ static bool test_rawinput (int usage) return true; } -static int doregister_rawinput (bool add) +static int doregister_rawinput (void) { - int num, rm, rkb, rhid; + int num; + bool add; RAWINPUTDEVICE rid[2 + MAX_INPUT_DEVICES]; + int activate; if (!rawinput_available) return 0; - rm = rawmouse ? 1 : 0; - rkb = rawkb ? 1 : 0; - rhid = rawhid ? 1 : 0; - if (rawinput_registered_mouse == rm && rawinput_registered_kb == rkb && rawinput_registered_hid == rhid) + activate = 0; + for (int i = 0; i < MAX_INPUT_DEVICES; i++) { + if (di_mouse[i].acquired) + activate++; + if (di_joystick[i].acquired) + activate++; + if (di_keyboard[i].acquired) + activate++; + } + + if (rawinput_registered && activate) + return 1; + if (!rawinput_registered && !activate) return 1; + add = activate != 0; + + rawinput_registered = add; memset (rid, 0, sizeof rid); num = 0; - if (rawinput_registered_mouse != rm) { - /* mouse */ - rid[num].usUsagePage = 1; - rid[num].usUsage = 2; - if (!rawmouse) { - rid[num].dwFlags = RIDEV_REMOVE; - } else if (hMainWnd) { + /* mouse */ + rid[num].usUsagePage = 1; + rid[num].usUsage = 2; + if (!add) { + rid[num].dwFlags = RIDEV_REMOVE; + } else if (hMainWnd) { + rid[num].dwFlags = RIDEV_INPUTSINK; + rid[num].hwndTarget = hMainWnd; + } + num++; + + /* keyboard */ + rid[num].usUsagePage = 1; + rid[num].usUsage = 6; + if (!add) { + rid[num].dwFlags = RIDEV_REMOVE; + } else { + if (hMainWnd) { rid[num].dwFlags = RIDEV_INPUTSINK; rid[num].hwndTarget = hMainWnd; } - num++; + rid[num].dwFlags |= RIDEV_NOHOTKEYS; } - if (rawinput_registered_kb != rkb) { - /* keyboard */ - rid[num].usUsagePage = 1; - rid[num].usUsage = 6; - if (!rawkb) { - rid[num].dwFlags = RIDEV_REMOVE; - } else { - if (hMainWnd) { - rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hMainWnd; - } - rid[num].dwFlags |= RIDEV_NOHOTKEYS; + num++; + + /* joystick */ + int off = num; + for (int i = 0; i < num_joystick; i++) { + struct didata *did = &di_joystick[i]; + if (did->connection != DIDC_RAW) + continue; + int j; + for (j = off; j < num; j++) { + if (rid[j].usUsage == did->hidcaps.Usage && rid[j].usUsagePage == did->hidcaps.UsagePage) + break; } - num++; - } - if (rawinput_registered_hid != rhid) { - /* joystick */ - int off = num; - for (int i = 0; i < num_joystick; i++) { - struct didata *did = &di_joystick[i]; - if (did->connection != DIDC_RAW) - continue; - int j; - for (j = off; j < num; j++) { - if (rid[j].usUsage == did->hidcaps.Usage && rid[j].usUsagePage == did->hidcaps.UsagePage) - break; - } - if (j == num) { - rid[num].usUsagePage = did->hidcaps.UsagePage; - rid[num].usUsage = did->hidcaps.Usage; - if (!rawhid) { - rid[num].dwFlags = RIDEV_REMOVE; - } else { - if (hMainWnd) { - rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hMainWnd; - } + if (j == num) { + rid[num].usUsagePage = did->hidcaps.UsagePage; + rid[num].usUsage = did->hidcaps.Usage; + if (!add) { + rid[num].dwFlags = RIDEV_REMOVE; + } else { + if (hMainWnd) { + rid[num].dwFlags = RIDEV_INPUTSINK; + rid[num].hwndTarget = hMainWnd; } - num++; } + num++; } } - if (num > 0) { - if (RegisterRawInputDevices (rid, num, sizeof (RAWINPUTDEVICE)) == FALSE) { - write_log (L"RAWINPUT %sregistration failed %d (%d,%d->%d,%d->%d,%d->%d)\n", - add ? L"" : L"un", GetLastError (), num, - rawinput_registered_mouse, rm, - rawinput_registered_kb, rkb, - rawinput_registered_hid, rhid); - return 0; - } + + write_log (L"RegisterRawInputDevices = %d (%d)\n", activate, num); + + if (RegisterRawInputDevices (rid, num, sizeof (RAWINPUTDEVICE)) == FALSE) { + write_log (L"RAWINPUT %sregistration failed %d\n", + add ? L"" : L"un", GetLastError ()); + return 0; } - rawinput_registered_mouse = rm; - rawinput_registered_kb = rkb; - rawinput_registered_hid = rhid; - return 1; -} -static int register_rawinput (int flags) -{ - return doregister_rawinput (true); -} -static int unregister_rawinput (int flags) -{ - return doregister_rawinput (false); + return 1; } static void cleardid (struct didata *did) @@ -933,7 +931,7 @@ static void sortobjects (struct didata *did) } } -#ifdef DI_DEBUG +#if DI_DEBUG if (did->axles + did->buttons > 0) { write_log (L"%s: (%x/%x)\n", did->name, did->vid, did->pid); if (did->connection == DIDC_DX) @@ -1286,7 +1284,6 @@ static bool initialize_rawinput (void) buf1 = bufp; buf2 = buf1 + 10000; - register_rawinput (0); if (GetRawInputDeviceList (NULL, &num, sizeof (RAWINPUTDEVICELIST)) != 0) { write_log (L"RAWINPUT error %08X\n", GetLastError()); goto error2; @@ -1677,8 +1674,10 @@ static void handle_rawinput_2 (RAWINPUT *raw) for (num = 0; num < num_mouse; num++) { did = &di_mouse[num]; - if (did->rawinput == h) - break; + if (did->acquired) { + if (did->rawinput == h) + break; + } } #if DI_DEBUG_RAWINPUT_MOUSE write_log (L"HANDLE=%08x %04x %04x %04x %08x %3d %3d %08x M=%d\n", @@ -2282,7 +2281,7 @@ static BOOL di_enumcallback2 (LPCDIDEVICEINSTANCE lpddi, int joy) typetxt = L"Unknown"; } -#ifdef DI_DEBUG +#if DI_DEBUG write_log (L"I=%s ", outGUID (&lpddi->guidInstance)); write_log (L"P=%s\n", outGUID (&lpddi->guidProduct)); write_log (L"'%s' '%s' %08X [%s]\n", lpddi->tszProductName, lpddi->tszInstanceName, lpddi->dwDevType, typetxt); @@ -2563,7 +2562,6 @@ static void close_mouse (void) for (i = 0; i < num_mouse; i++) di_dev_free (&di_mouse[i]); supermouse = normalmouse = rawmouse = winmouse = 0; - unregister_rawinput (0); di_free (); } @@ -2601,7 +2599,7 @@ static int acquire_mouse (int num, int flags) } else normalmouse++; } - register_rawinput (flags); + doregister_rawinput (); return di_mouse[num].acquired > 0 ? 1 : 0; } @@ -2619,7 +2617,7 @@ static void unacquire_mouse (int num) normalmouse--; di_mouse[num].acquired = 0; } - unregister_rawinput (0); + doregister_rawinput (); } static void read_mouse (void) @@ -2665,7 +2663,7 @@ static void read_mouse (void) int dimofs = didod[j].dwOfs; int data = didod[j].dwData; int state = (data & 0x80) ? 1 : 0; -#ifdef DI_DEBUG2 +#if DI_DEBUG2 write_log (L"MOUSE: %d OFF=%d DATA=%d STATE=%d\n", i, dimofs, data, state); #endif if (istest || isfocus () > 0) { @@ -2798,7 +2796,6 @@ static int init_kb (void) write_log (L"keyboard CreateDevice failed, %s\n", DXError (hr)); } } - register_rawinput (0); keyboard_german = 0; if ((LOWORD(GetKeyboardLayout (0)) & 0x3ff) == 7) keyboard_german = 1; @@ -2816,7 +2813,6 @@ static void close_kb (void) for (i = 0; i < num_keyboard; i++) di_dev_free (&di_keyboard[i]); superkb = normalkb = rawkb = 0; - unregister_rawinput (0); di_free (); } @@ -2891,7 +2887,7 @@ static int acquire_kb (int num, int flags) normalkb++; di_keyboard[num].acquired = 1; } - register_rawinput (flags); + doregister_rawinput (); return di_keyboard[num].acquired > 0 ? 1 : 0; } @@ -2923,7 +2919,7 @@ static void unacquire_kb (int num) } #endif } - unregister_rawinput (0); + doregister_rawinput (); //unlock_kb (); } @@ -3284,7 +3280,7 @@ static void read_joystick (void) if (bstate >= 0 && axisold[i][k] != bstate) { setjoybuttonstate (i, k, bstate); axisold[i][k] = bstate; -#ifdef DI_DEBUG2 +#if DI_DEBUG2 write_log (L"AB:NUM=%d OFF=%d AXIS=%d DIR=%d NAME=%s VAL=%d STATE=%d BS=%d\n", k, dimofs, axis, dir, did->buttonname[k], data, state, bstate); #endif @@ -3292,7 +3288,7 @@ static void read_joystick (void) } else if (did->buttonaxisparent[k] < 0 && did->buttonmappings[k] == dimofs) { -#ifdef DI_DEBUG2 +#if DI_DEBUG2 write_log (L"B:NUM=%d OFF=%d NAME=%s VAL=%d STATE=%d\n", k, dimofs, did->buttonname[k], data, state); #endif @@ -3306,11 +3302,11 @@ static void read_joystick (void) setjoystickstate (i, k, (data2 >= 20250 && data2 <= 33750) ? -1 : (data2 >= 2250 && data2 <= 15750) ? 1 : 0, 1); } else if (did->axistype[k] == 2) { setjoystickstate (i, k, ((data2 >= 29250 && data2 <= 33750) || (data2 >= 0 && data2 <= 6750)) ? -1 : (data2 >= 11250 && data2 <= 24750) ? 1 : 0, 1); -#ifdef DI_DEBUG2 +#if DI_DEBUG2 write_log (L"P:NUM=%d OFF=%d NAME=%s VAL=%d\n", k, dimofs, did->axisname[k], data2); #endif } else if (did->axistype[k] == 0) { -#ifdef DI_DEBUG2 +#if DI_DEBUG2 if (data < -20000 || data > 20000) write_log (L"A:NUM=%d OFF=%d NAME=%s VAL=%d\n", k, dimofs, did->axisname[k], data); #endif @@ -3370,7 +3366,6 @@ static int init_joystick (void) } } } - register_rawinput (0); return 1; } @@ -3384,7 +3379,6 @@ static void close_joystick (void) for (i = 0; i < num_joystick; i++) di_dev_free (&di_joystick[i]); rawhid = 0; - unregister_rawinput (0); di_free (); } @@ -3424,20 +3418,21 @@ static int acquire_joystick (int num, int flags) } else { di_joystick[num].acquired = 1; } - register_rawinput (flags); + doregister_rawinput (); return di_joystick[num].acquired > 0 ? 1 : 0; } static void unacquire_joystick (int num) { struct didata *did = &di_joystick[num]; + unacquire (did->lpdi, L"joystick"); if (did->connection == DIDC_RAW) { if (di_joystick[num].acquired) rawhid--; } di_joystick[num].acquired = 0; - unregister_rawinput (0); + doregister_rawinput (); } static int get_joystick_flags (int num) diff --git a/od-win32/posixemu.cpp b/od-win32/posixemu.cpp index 758ecac9..4b591291 100644 --- a/od-win32/posixemu.cpp +++ b/od-win32/posixemu.cpp @@ -77,6 +77,7 @@ static void get_time (time_t t, long *days, long *mins, long *ticks) *ticks = t * 50; } +#if 0 static DWORD getattr (const TCHAR *name, LPFILETIME lpft, uae_s64 *size) { HANDLE hFind; @@ -95,23 +96,43 @@ static DWORD getattr (const TCHAR *name, LPFILETIME lpft, uae_s64 *size) return fd.dwFileAttributes; } +#endif int posixemu_stat (const TCHAR *name, struct _stat64 *statbuf) { - DWORD attr; + DWORD attr, ok; FILETIME ft, lft; + HANDLE h; + BY_HANDLE_FILE_INFORMATION fi; - if ((attr = getattr (name, &ft, &statbuf->st_size)) == (DWORD)~0) { + // FILE_FLAG_BACKUP_SEMANTICS = can also "open" directories + h = CreateFile (name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (h == INVALID_HANDLE_VALUE) { + write_log (L"Stat CreateFile(%s) failed: %d\n", name, GetLastError ()); return -1; + } + ok = GetFileInformationByHandle (h, &fi); + CloseHandle (h); + + attr = 0; + ft.dwHighDateTime = ft.dwLowDateTime = 0; + if (ok) { + attr = fi.dwFileAttributes; + ft = fi.ftLastWriteTime; + statbuf->st_size = ((uae_u64)fi.nFileSizeHigh << 32) | fi.nFileSizeLow; } else { - statbuf->st_mode = (attr & FILE_ATTRIBUTE_READONLY) ? FILEFLAG_READ : FILEFLAG_READ | FILEFLAG_WRITE; - if (attr & FILE_ATTRIBUTE_ARCHIVE) - statbuf->st_mode |= FILEFLAG_ARCHIVE; - if (attr & FILE_ATTRIBUTE_DIRECTORY) - statbuf->st_mode |= FILEFLAG_DIR; - FileTimeToLocalFileTime (&ft,&lft); - statbuf->st_mtime = (long)((*(__int64 *)&lft-((__int64)(369*365+89)*(__int64)(24*60*60)*(__int64)10000000))/(__int64)10000000); + write_log (L"GetFileInformationByHandle(%s) failed: %d\n", name, GetLastError ()); + return -1; } + + statbuf->st_mode = (attr & FILE_ATTRIBUTE_READONLY) ? FILEFLAG_READ : FILEFLAG_READ | FILEFLAG_WRITE; + if (attr & FILE_ATTRIBUTE_ARCHIVE) + statbuf->st_mode |= FILEFLAG_ARCHIVE; + if (attr & FILE_ATTRIBUTE_DIRECTORY) + statbuf->st_mode |= FILEFLAG_DIR; + FileTimeToLocalFileTime (&ft,&lft); + statbuf->st_mtime = (long)((*(__int64 *)&lft-((__int64)(369*365+89)*(__int64)(24*60*60)*(__int64)10000000))/(__int64)10000000); + return 0; } diff --git a/od-win32/win32.h b/od-win32/win32.h index 6f9e4427..9ca52c5f 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,8 +19,8 @@ #define LANG_DLL 1 //#define WINUAEBETA L"" -#define WINUAEBETA L"Beta 10" -#define WINUAEDATE MAKEBD(2012, 1, 6) +#define WINUAEBETA L"Beta 11" +#define WINUAEDATE MAKEBD(2012, 1, 11) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 89d71132..ef79bc6f 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,19 @@ +Beta 11: + +- SocketBaseTagList() must not report unknown tag error unless tag is really unknown, not just + unsupported. SBTC_LOGx tags are now "supported" because some programs sets them and they also + do not want to get any errors. +- bsdsocket.library SBTC_IOERRNOSTRPTR, SBTC_S2ERRNOSTRPTR and SBTC_S2WERRNOSTRPTR implemented. +- bsdsocket.library SBTC_FDCALLBACK implemented. Should fix (SAS-C compiled only?) Unix ports that + use both socket and plain file FDs. +- Multiple bsdsocket emulation thread safety fixes. Should finally fix all YAM hangs. +- Directory filesystem internal file size access update, previously Examine() and friends returned old + file size if file size changed (either inside or outside of emulation) until file was closed. + (fixes Subversion bad request 400 error) +- Built-in zip unarchiver utf-8 encoded file name support implemented +- Vertical centering and small enough display size: vertical positioning was really wrong. + Beta 10: - RTG mode list should always list all monitors' supported resolutions. diff --git a/zfile_archive.cpp b/zfile_archive.cpp index 848b3538..80aa30a6 100644 --- a/zfile_archive.cpp +++ b/zfile_archive.cpp @@ -357,7 +357,11 @@ struct zvolume *archive_directory_zip (struct zfile *z) err = unzGetCurrentFileInfo (uz, &file_info, filename_inzip2, sizeof (filename_inzip2), NULL, 0, NULL, 0); if (err != UNZ_OK) return 0; - filename_inzip = au (filename_inzip2); + if (file_info.flag & (1 << 11)) { // UTF-8 encoded + filename_inzip = utf8u (filename_inzip2); + } else { + filename_inzip = au (filename_inzip2); + } dd = file_info.dosDate; t = fromdostime (dd); memset (&zai, 0, sizeof zai); -- 2.47.3