diff --git a/native/doscalls.c b/native/doscalls.c index 89e63ee..281341f 100644 --- a/native/doscalls.c +++ b/native/doscalls.c @@ -235,11 +235,13 @@ LX_NATIVE_MODULE_INIT({ if (!initDoscalls()) return NULL; }) LX_NATIVE_EXPORT(DosQueryCurrentDir, 274), LX_NATIVE_EXPORT(DosQueryCurrentDisk, 275), LX_NATIVE_EXPORT(DosQueryFHState, 276), + LX_NATIVE_EXPORT(DosQueryFSAttach, 277), LX_NATIVE_EXPORT(DosQueryFileInfo, 279), LX_NATIVE_EXPORT(DosWaitChild, 280), LX_NATIVE_EXPORT(DosRead, 281), LX_NATIVE_EXPORT(DosWrite, 282), LX_NATIVE_EXPORT(DosExecPgm, 283), + LX_NATIVE_EXPORT(DosSetProcessCp, 289), LX_NATIVE_EXPORT(DosQueryCp, 291), LX_NATIVE_EXPORT(DosExitList, 296), LX_NATIVE_EXPORT(DosAllocMem, 299), @@ -267,6 +269,7 @@ LX_NATIVE_MODULE_INIT({ if (!initDoscalls()) return NULL; }) LX_NATIVE_EXPORT(DosSubFreeMem, 346), LX_NATIVE_EXPORT(DosQuerySysInfo, 348), LX_NATIVE_EXPORT(DosSetExceptionHandler, 354), + LX_NATIVE_EXPORT(DosUnsetExceptionHandler, 355), LX_NATIVE_EXPORT(DosQuerySysState, 368), LX_NATIVE_EXPORT(DosSetSignalExceptionFocus, 378), LX_NATIVE_EXPORT(DosEnterMustComplete, 380), @@ -650,6 +653,13 @@ APIRET DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD rec) return NO_ERROR; } // DosSetExceptionHandler +// !!! FIXME: this is obviously not correct. +APIRET DosUnsetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD rec) +{ + TRACE_NATIVE("DosUnsetExceptionHandler(%p)", rec); + return NO_ERROR; +} // DosSetExceptionHandler + ULONG _DosFlatToSel(PVOID ptr) { TRACE_NATIVE("DosFlatToSel(%p)", ptr); @@ -3010,7 +3020,6 @@ static APIRET16 bridge16to32_DosSemSet(uint8 *args) return DosSemSet(sem); } // bridge16to32_DosSemSet - APIRET DosCloseMutexSem(HMTX hmtx) { TRACE_NATIVE("DosCloseMutexSem(%u)", (uint) hmtx); @@ -3029,5 +3038,21 @@ APIRET DosCloseMutexSem(HMTX hmtx) return ERROR_INVALID_HANDLE; } // DosCloseMutexSem +APIRET DosSetProcessCp(ULONG cp) +{ + TRACE_NATIVE("DosSetProcessCp(%u)", (unsigned int) cp); + if (cp != 437) { // United States + FIXME("non-US codepages unsupported at the moment"); + return ERROR_INVALID_CODE_PAGE; + } + return NO_ERROR; +} // DosSetProcessCp + +APIRET DosQueryFSAttach(PSZ pszDeviceName, ULONG ulOrdinal, ULONG ulFSAInfoLevel, PFSQBUFFER2 pfsqb, PULONG pcbBuffLength) +{ + TRACE_NATIVE("DosQueryFSAttach('%s', %u, %u, %p, %p)", pszDeviceName, (unsigned int) ulOrdinal, (unsigned int) ulFSAInfoLevel, pfsqb, pcbBuffLength); + return ERROR_INVALID_FUNCTION; +} // DosQueryFSAttach + // end of doscalls.c ... diff --git a/native/doscalls.h b/native/doscalls.h index 8df7019..8f77c3c 100644 --- a/native/doscalls.h +++ b/native/doscalls.h @@ -342,6 +342,17 @@ typedef struct CHAR achName[CCHMAXPATHCOMP]; } FILEFINDBUF4, *PFILEFINDBUF4; +typedef struct +{ + USHORT iType; + USHORT cbName; + USHORT cbFSDName; + USHORT cbFSAData; + UCHAR szName[1]; + UCHAR szFSDName[1]; + UCHAR rgFSAData[1]; +} FSQBUFFER2, *PFSQBUFFER2; + enum { DEVINFO_PRINTER, @@ -393,6 +404,7 @@ OS2EXPORT APIRET OS2API DosExitList(ULONG ordercode, PFNEXITLIST pfn); OS2EXPORT APIRET OS2API DosCreateEventSem(PSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState); OS2EXPORT APIRET OS2API DosCreateMutexSem(PSZ pszName, PHMTX phmtx, ULONG flAttr, BOOL32 fState); OS2EXPORT APIRET OS2API DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec); +OS2EXPORT APIRET OS2API DosUnsetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec); OS2EXPORT ULONG OS2API DosFlatToSel(VOID); OS2EXPORT APIRET OS2API DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes); OS2EXPORT APIRET OS2API DosSetRelMaxFH(PLONG pcbReqCount, PULONG pcbCurMaxFH); @@ -447,6 +459,8 @@ OS2EXPORT APIRET OS2API DosSetMaxFH(ULONG cFH); OS2EXPORT APIRET OS2API DosQueryThreadContext(TID tid, ULONG level, PCONTEXTRECORD pcxt); OS2EXPORT ULONG OS2API DosSelToFlat(VOID); OS2EXPORT APIRET OS2API DosCloseMutexSem(HMTX hmtx); +OS2EXPORT APIRET OS2API DosSetProcessCp(ULONG cp); +OS2EXPORT APIRET OS2API DosQueryFSAttach(PSZ pszDeviceName, ULONG ulOrdinal, ULONG ulFSAInfoLevel, PFSQBUFFER2 pfsqb, PULONG pcbBuffLength); #ifdef __cplusplus } diff --git a/native/tcpip32.c b/native/tcpip32.c index 9f3e886..e117ab7 100644 --- a/native/tcpip32.c +++ b/native/tcpip32.c @@ -1,6 +1,7 @@ #include "os2native.h" #include "tcpip32.h" +#include #include #include #include @@ -17,6 +18,26 @@ int OS2_sock_init(void) return 1; // always succeeds. } // OS2_sock_init +// !!! FIXME: currently expects you're doing IPv4 +static void mapOS2SockAddrIn(const OS2_sockaddr *os2addr, struct sockaddr_in *bsdaddr) +{ + const OS2_sockaddr_in *os2addrin = (const OS2_sockaddr_in *) os2addr; + memset(bsdaddr, '\0', sizeof (*bsdaddr)); + bsdaddr->sin_family = AF_INET; + bsdaddr->sin_port = os2addrin->sin_port; + bsdaddr->sin_addr.s_addr = os2addrin->sin_addr.s_addr; +} // mapOS2SockAddrIn + +// !!! FIXME: currently expects you're doing IPv4 +static void mapBSDSockAddrIn(const struct sockaddr_in *bsdaddr, OS2_sockaddr *os2addr) +{ + OS2_sockaddr_in *os2addrin = (OS2_sockaddr_in *) os2addr; + memset(os2addrin, '\0', sizeof (*os2addrin)); + os2addrin->sin_family = OS2_AF_INET; + os2addrin->sin_port = bsdaddr->sin_port; + os2addrin->sin_addr.s_addr = bsdaddr->sin_addr.s_addr; +} // mapBSDSockAddrIn + static int mapOS2MsgFlags(const int os2flags) { int bsdflags = 0; @@ -57,10 +78,7 @@ int OS2_connect(int sock, const struct OS2_sockaddr *os2addr, int addrlen) } struct sockaddr_in bsdaddr; - memset(&bsdaddr, '\0', sizeof (bsdaddr)); - bsdaddr.sin_family = AF_INET; - bsdaddr.sin_port = ((const OS2_sockaddr_in *) os2addr)->sin_port; - bsdaddr.sin_addr.s_addr = ((const OS2_sockaddr_in *) os2addr)->sin_addr.s_addr; + mapOS2SockAddrIn(os2addr, &bsdaddr); return connect(sock, &bsdaddr, (socklen_t) sizeof (bsdaddr)); } // OS2_connect @@ -215,22 +233,197 @@ int OS2_os2_select(int *socks, int noreads, int nowrites, int noexcept, long tim return poll(origfds, nfds, timeout * 1000); } // OS2_os2_select +int OS2_getsockname(int sock, OS2_sockaddr *os2name, int *os2namelen) +{ + TRACE_NATIVE("getsockname(%d, %p, %p)", sock, os2name, os2namelen); + + struct sockaddr_in bsdaddr; + socklen_t namelen = sizeof (bsdaddr); + const int rc = getsockname(sock, &bsdaddr, &namelen); + if (rc == -1) { + return -1; + } else if (bsdaddr.sin_family != AF_INET) { + FIXME("this only deals with IPv4 at the moment"); + return -1; + } else if (*os2namelen < sizeof (OS2_sockaddr_in)) { + return -1; + } + + mapBSDSockAddrIn(&bsdaddr, os2name); + *os2namelen = sizeof (OS2_sockaddr_in); + return rc; +} // OS2_getsockname + +int OS2_bind(int sock, const OS2_sockaddr *os2name, int os2namelen) +{ + TRACE_NATIVE("bind(%d, %p, %d)", sock, os2name, os2namelen); + struct sockaddr_in bsdaddr; + mapOS2SockAddrIn(os2name, &bsdaddr); + return bind(sock, (struct sockaddr *) &bsdaddr, sizeof (bsdaddr)); +} // OS2_bind + +int OS2_listen(int sock, int backlog) +{ + TRACE_NATIVE("listen(%d, %d)", sock, backlog); + return listen(sock, backlog); +} // OS2_listen + +int OS2_accept(int sock, OS2_sockaddr *os2name, int *os2namelen) +{ + TRACE_NATIVE("bind(%d, %p, %p)", sock, os2name, os2namelen); + struct sockaddr_in bsdaddr; + socklen_t bsdaddrlen = sizeof (bsdaddr); + const int retval = accept(sock, (struct sockaddr *) &bsdaddr, &bsdaddrlen); + + if (os2name != NULL) { + mapBSDSockAddrIn(&bsdaddr, os2name); + } + + if (os2namelen != NULL) { + *os2namelen = sizeof (OS2_sockaddr_in); + } + + return retval; +} // OS2_accept + +static int mapOS2SocketOption(const int os2name) +{ + switch (os2name) { + #define MAPSOOPT(f) case OS2_##f: return f + MAPSOOPT(SO_DEBUG); + MAPSOOPT(SO_ACCEPTCONN); + MAPSOOPT(SO_REUSEADDR); + MAPSOOPT(SO_KEEPALIVE); + MAPSOOPT(SO_DONTROUTE); + MAPSOOPT(SO_BROADCAST); + //MAPSOOPT(SO_USELOOPBACK); + MAPSOOPT(SO_LINGER); + MAPSOOPT(SO_OOBINLINE); + //MAPSOOPT(SO_L_BROADCAST); + //MAPSOOPT(SO_RCV_SHUTDOWN); + //MAPSOOPT(SO_SND_SHUTDOWN); + MAPSOOPT(SO_REUSEPORT); + //MAPSOOPT(SO_TTCP); + MAPSOOPT(SO_SNDBUF); + MAPSOOPT(SO_RCVBUF); + MAPSOOPT(SO_SNDLOWAT); + MAPSOOPT(SO_RCVLOWAT); + MAPSOOPT(SO_SNDTIMEO); + MAPSOOPT(SO_RCVTIMEO); + MAPSOOPT(SO_ERROR); + MAPSOOPT(SO_TYPE); + //MAPSOOPT(SO_OPTIONS); + #undef MAPSOOPT + default: break; + } + + FIXME("unsupported OS/2 socket option"); + return 0; +} // mapOS2SocketOption + +int OS2_setsockopt(int sock, int os2level, int os2name, const void *value, int len) +{ + const int bsdname = mapOS2SocketOption(os2name); + const int bsdlevel = SOL_SOCKET; + if (!bsdname) { + return -1; + } else if (os2level != OS2_SOL_SOCKET) { + return -1; + } + return setsockopt(sock, bsdlevel, bsdname, value, len); +} // OS2_setsockopt + +int OS2_gettimeofday(OS2_timeval *os2tv, OS2_timezone *os2tz) +{ + struct timeval bsdtv; + struct timezone bsdtz; + const int retval = gettimeofday(&bsdtv, &bsdtz); + + if (os2tv) { + os2tv->tv_sec = bsdtv.tv_sec; + os2tv->tv_usec = bsdtv.tv_usec; + } + + if (os2tz) { + os2tz->tz_minuteswest = bsdtz.tz_minuteswest; + os2tz->tz_dsttime = bsdtz.tz_dsttime; + } + + return retval; +} // OS2_gettimeofday + +// SOCKS support... + +int OS2_Rgetsockname(int sock, OS2_sockaddr *os2name, int *os2namelen) +{ + // !!! FIXME: this doesn't talk to a SOCKS proxy at all. + TRACE_NATIVE("Rgetsockname(%d, %p, %p)", sock, os2name, os2namelen); + return OS2_getsockname(sock, os2name, os2namelen); +} // OS2_Rgetsockname + +int OS2_Rbind(int sock, OS2_sockaddr *os2name, int os2namelen, OS2_sockaddr *os2remote) +{ + // !!! FIXME: this doesn't talk to a SOCKS proxy at all. + TRACE_NATIVE("Rbind(%d, %p, %d, %p)", sock, os2name, os2namelen, os2remote); + return OS2_bind(sock, os2name, os2namelen); +} // OS2_Rbind + +int OS2_Raccept(int sock, OS2_sockaddr *os2name, int *os2namelen) +{ + // !!! FIXME: this doesn't talk to a SOCKS proxy at all. + TRACE_NATIVE("Raccept(%d, %p, %p)", sock, os2name, os2namelen); + return OS2_accept(sock, os2name, os2namelen); +} // OS2_Raccept + +int OS2_Rconnect(int sock, const OS2_sockaddr *os2name, int os2namelen) +{ + // !!! FIXME: this doesn't talk to a SOCKS proxy at all. + TRACE_NATIVE("Rconnect(%d, %p, %d)", sock, os2name, os2namelen); + return OS2_connect(sock, os2name, os2namelen); +} // OS2_Rconnect + +int OS2_Rlisten(int sock, int backlog) +{ + // !!! FIXME: this doesn't talk to a SOCKS proxy at all. + TRACE_NATIVE("Rlisten(%d, %d)", sock, backlog); + return OS2_listen(sock, backlog); +} // OS2_Rlisten + +OS2_hostent *OS2_Rgethostbyname(const char *name) +{ + // !!! FIXME: this doesn't talk to a SOCKS proxy at all. + TRACE_NATIVE("Rgethostbyname('%s')", name); + return OS2_gethostbyname(name); +} // OS2_Rgethostbyname + LX_NATIVE_MODULE_INIT() + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_accept, "accept", 1), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_bind, "bind", 2), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_connect, "connect", 3), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getsockname, "getsockname", 6), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_listen, "listen", 9), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_recv, "recv", 10), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_os2_select, "os2_select", 12), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_send, "send", 13), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_setsockopt, "setsockopt", 15), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_socket, "socket", 16), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_soclose, "soclose", 17), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_errno, "sock_errno", 20), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_shutdown, "shutdown", 25), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_init, "sock_init", 26), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_select, "select", 32), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gettimeofday, "gettimeofday", 102), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_addr, "inet_addr", 105), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_ntoa, "inet_ntoa", 110), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gethostbyname, "gethostbyname", 111), - LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getservbyname, "getservbyname",124), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getservbyname, "getservbyname", 124), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Raccept, "Raccept", 156), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rbind, "Rbind", 157), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rconnect, "Rconnect", 158), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgetsockname, "Rgetsockname", 159), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rlisten, "Rlisten", 160), + LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgethostbyname, "Rgethostbyname", 161), LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_htons, "htons", 205) LX_NATIVE_MODULE_INIT_END() diff --git a/native/tcpip32.h b/native/tcpip32.h index a9fb943..9572181 100644 --- a/native/tcpip32.h +++ b/native/tcpip32.h @@ -30,6 +30,33 @@ extern "C" { #define OS2_SOCK_STREAM 1 #define OS2_SOCK_DGRAM 2 +#define OS2_SOL_SOCKET 0xffff + +#define OS2_SO_DEBUG 0x0001 +#define OS2_SO_ACCEPTCONN 0x0002 +#define OS2_SO_REUSEADDR 0x0004 +#define OS2_SO_KEEPALIVE 0x0008 +#define OS2_SO_DONTROUTE 0x0010 +#define OS2_SO_BROADCAST 0x0020 +#define OS2_SO_USELOOPBACK 0x0040 +#define OS2_SO_LINGER 0x0080 +#define OS2_SO_OOBINLINE 0x0100 +#define OS2_SO_L_BROADCAST 0x0200 +#define OS2_SO_RCV_SHUTDOWN 0x0400 +#define OS2_SO_SND_SHUTDOWN 0x0800 +#define OS2_SO_REUSEPORT 0x1000 +#define OS2_SO_TTCP 0x2000 +#define OS2_SO_SNDBUF 0x1001 +#define OS2_SO_RCVBUF 0x1002 +#define OS2_SO_SNDLOWAT 0x1003 +#define OS2_SO_RCVLOWAT 0x1004 +#define OS2_SO_SNDTIMEO 0x1005 +#define OS2_SO_RCVTIMEO 0x1006 +#define OS2_SO_ERROR 0x1007 +#define OS2_SO_TYPE 0x1008 +#define OS2_SO_OPTIONS 0x1010 + + #pragma pack(push, 1) typedef struct OS2_sockaddr { @@ -82,6 +109,12 @@ typedef struct OS2_timeval sint32 tv_sec; sint32 tv_usec; } OS2_timeval; + +typedef struct OS2_timezone +{ + sint32 tz_minuteswest; + sint32 tz_dsttime; +} OS2_timezone; #pragma pack(pop) OS2EXPORT int OS2API OS2_sock_init(void); @@ -99,6 +132,17 @@ OS2EXPORT char * OS2API OS2_inet_ntoa(OS2_in_addr os2inaddr); OS2EXPORT OS2_servent * OS2API OS2_getservbyname(const char *name, const char *proto); OS2EXPORT int OS2API OS2_select(int sock, OS2_fd_set *readfds, OS2_fd_set *writefds, OS2_fd_set *errorfds, OS2_timeval *timeout); OS2EXPORT int OS2API OS2_os2_select(int *socks, int noreads, int nowrites, int noexcept, long timeout); +OS2EXPORT int OS2API OS2_getsockname(int sock, OS2_sockaddr *os2name, int *namelen); +OS2EXPORT int OS2API OS2_setsockopt(int sock, int os2level, int os2name, const void *value, int len); +OS2EXPORT int OS2API OS2_bind(int sock, const OS2_sockaddr *os2name, int os2namelen); +OS2EXPORT int OS2API OS2_accept(int sock, OS2_sockaddr *os2name, int *os2namelen); +OS2EXPORT int OS2API OS2_Rgetsockname(int sock, OS2_sockaddr *os2name, int *namelen); +OS2EXPORT int OS2API OS2_Rbind(int sock, OS2_sockaddr *os2name, int os2namelen, OS2_sockaddr *os2remote); +OS2EXPORT int OS2API OS2_Raccept(int sock, OS2_sockaddr *os2name, int *os2namelen); +OS2EXPORT int OS2API OS2_Rconnect(int sock, const OS2_sockaddr *os2name, int os2namelen); +OS2EXPORT int OS2API OS2_Rlisten(int sock, int backlog); +OS2EXPORT OS2_hostent * OS2API OS2_Rgethostbyname(const char *name); +OS2EXPORT int OS2API OS2_gettimeofday(OS2_timeval *os2tv, OS2_timezone *os2tz); #ifdef __cplusplus }