From 18fda2a86c81a933b08b2fa2c6fe7f4d8248424c Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Thu, 15 Sep 2011 15:21:57 +0000 Subject: [PATCH] Correctly store protocol names at the end of the EnumProtocols buffer. Added Windows 98 WSHEnumProtocols function. --- src/ipxwrapper.def | 1 + src/mswsock.def | 1 + src/mswsock_stubs.txt | 1 + src/winsock.c | 72 +++++++++++++++++++++++++++++++++++-------- src/wsock32.def | 1 + src/wsock32_stubs.txt | 1 + 6 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/ipxwrapper.def b/src/ipxwrapper.def index d373277..14ec9c9 100644 --- a/src/ipxwrapper.def +++ b/src/ipxwrapper.def @@ -14,3 +14,4 @@ EXPORTS EnumProtocolsW WSARecvEx ioctlsocket + WSHEnumProtocols diff --git a/src/mswsock.def b/src/mswsock.def index 8d79981..ac24993 100644 --- a/src/mswsock.def +++ b/src/mswsock.def @@ -32,3 +32,4 @@ EXPORTS rresvport @30 s_perror @31 sethostname @32 + WSHEnumProtocols @2026 diff --git a/src/mswsock_stubs.txt b/src/mswsock_stubs.txt index e7f9373..3bc0062 100644 --- a/src/mswsock_stubs.txt +++ b/src/mswsock_stubs.txt @@ -31,3 +31,4 @@ rresvport s_perror sethostname inet_addr +WSHEnumProtocols:0 diff --git a/src/winsock.c b/src/winsock.c index 2339996..c737d9a 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -38,6 +38,10 @@ typedef struct _PROTOCOL_INFO { void *lpProtocol ; } PROTOCOL_INFO; +static size_t strsize(void *str, BOOL unicode) { + return unicode ? 2 + wcslen(str)*2 : 1 + strlen(str); +} + static int do_EnumProtocols(LPINT protocols, LPVOID buf, LPDWORD bsptr, BOOL unicode) { int bufsize = *bsptr, rval, i, want_ipx = 0; @@ -61,28 +65,66 @@ static int do_EnumProtocols(LPINT protocols, LPVOID buf, LPDWORD bsptr, BOOL uni if(want_ipx) { for(i = 0; i < rval; i++) { if(pinfo[i].iProtocol == NSPROTO_IPX) { - break; + return rval; } } - if(i == rval) { - *bsptr += sizeof(PROTOCOL_INFO); - rval++; - } + *bsptr += sizeof(PROTOCOL_INFO) + (unicode ? 8 : 4); if(*bsptr > bufsize) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return -1; } - pinfo[i].dwServiceFlags = 5641; - pinfo[i].iAddressFamily = AF_IPX; - pinfo[i].iMaxSockAddr = 16; - pinfo[i].iMinSockAddr = 14; - pinfo[i].iSocketType = SOCK_DGRAM; - pinfo[i].iProtocol = NSPROTO_IPX; - pinfo[i].dwMessageSize = 576; - pinfo[i].lpProtocol = unicode ? (char*)L"IPX" : "IPX"; + /* Make sure there is space between the last PROTOCOL_INFO structure + * and the protocol names for the extra structure. + */ + + size_t slen = 0, off = 0; + + for(i = 0; i < rval; i++) { + slen += strsize(pinfo[i].lpProtocol, unicode); + } + + char *name_buf = malloc(slen); + if(!name_buf) { + SetLastError(ERROR_OUTOFMEMORY); + return -1; + } + + for(i = 0; i < rval; i++) { + slen = strsize(pinfo[i].lpProtocol, unicode); + memcpy(name_buf + off, pinfo[i].lpProtocol, slen); + + off += slen; + } + + char *name_dest = ((char*)buf) + sizeof(PROTOCOL_INFO) * (rval + 1); + + memcpy(name_dest, name_buf, off); + free(name_buf); + + if(unicode) { + wcscpy((wchar_t*)(name_dest + off), L"IPX"); + }else{ + strcpy(name_dest + off, "IPX"); + } + + for(i = 0, off = 0; i < rval; i++) { + pinfo[i].lpProtocol = name_dest + off; + off += strsize(pinfo[i].lpProtocol, unicode); + } + + int ipx_off = rval++; + + pinfo[ipx_off].dwServiceFlags = 5641; + pinfo[ipx_off].iAddressFamily = AF_IPX; + pinfo[ipx_off].iMaxSockAddr = 16; + pinfo[ipx_off].iMinSockAddr = 14; + pinfo[ipx_off].iSocketType = SOCK_DGRAM; + pinfo[ipx_off].iProtocol = NSPROTO_IPX; + pinfo[ipx_off].dwMessageSize = 576; + pinfo[ipx_off].lpProtocol = name_dest + off; } return rval; @@ -96,6 +138,10 @@ INT APIENTRY EnumProtocolsW(LPINT protocols, LPVOID buf, LPDWORD bsptr) { return do_EnumProtocols(protocols, buf, bsptr, TRUE); } +INT WINAPI WSHEnumProtocols(LPINT protocols, LPWSTR ign, LPVOID buf, LPDWORD bsptr) { + return do_EnumProtocols(protocols, buf, bsptr, FALSE); +} + SOCKET WSAAPI socket(int af, int type, int protocol) { log_printf("socket(%d, %d, %d)", af, type, protocol); diff --git a/src/wsock32.def b/src/wsock32.def index 331f976..0dd5187 100644 --- a/src/wsock32.def +++ b/src/wsock32.def @@ -50,6 +50,7 @@ EXPORTS __WSAFDIsSet @151 WEP @500 WSApSetPostRoutine @1000 + WSHEnumProtocols @1005 inet_network @1100 getnetbyname @1101 rcmd @1102 diff --git a/src/wsock32_stubs.txt b/src/wsock32_stubs.txt index d396e83..f353af9 100644 --- a/src/wsock32_stubs.txt +++ b/src/wsock32_stubs.txt @@ -73,3 +73,4 @@ NPLoadNameSpaces TransmitFile AcceptEx GetAcceptExSockaddrs +WSHEnumProtocols:0