Implemented EnumProtocolA/W.
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index 38b423e..1e1aab8 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -472,7 +472,7 @@
winsock/libws2_32.@LIBEXT@: libuser32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
winspool/libwinspool.drv.@LIBEXT@: libadvapi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
wow32/libwow32.@LIBEXT@: libkernel32.@LIBEXT@
-wsock32/libwsock32.@LIBEXT@: libws2_32.@LIBEXT@ libntdll.@LIBEXT@
+wsock32/libwsock32.@LIBEXT@: libws2_32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
x11drv/libx11drv.@LIBEXT@: libuser32.@LIBEXT@ libgdi32.@LIBEXT@ libkernel32.@LIBEXT@
$(DLLFILES): dummy
diff --git a/dlls/wsock32/Makefile.in b/dlls/wsock32/Makefile.in
index a925ff3..4c3801b 100644
--- a/dlls/wsock32/Makefile.in
+++ b/dlls/wsock32/Makefile.in
@@ -7,7 +7,9 @@
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
-C_SRCS = socket.c
+C_SRCS = \
+ protocol.c \
+ socket.c
@MAKE_DLL_RULES@
diff --git a/dlls/wsock32/protocol.c b/dlls/wsock32/protocol.c
new file mode 100644
index 0000000..92f2aae
--- /dev/null
+++ b/dlls/wsock32/protocol.c
@@ -0,0 +1,250 @@
+/*
+ * WSOCK32 specific functions
+ *
+ * Copyright (C) 2001 Stefan Leichter
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include "winbase.h"
+#include "debugtools.h"
+#include "heap.h"
+#include "nspapi.h"
+#include "winsock.h"
+#include "wsipx.h"
+#include "wshisotp.h"
+
+DEFAULT_DEBUG_CHANNEL(winsock);
+
+/* name of the protocols
+ */
+static WCHAR NameIpx[] = {'I', 'P', 'X', '\0'};
+static WCHAR NameSpx[] = {'S', 'P', 'X', '\0'};
+static WCHAR NameSpxII[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
+static WCHAR NameTcp[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
+static WCHAR NameUdp[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
+
+/*****************************************************************************
+ * WSOCK32_EnterSingleProtocol [internal]
+ *
+ * enters the protocol informations of one given protocol into the
+ * given buffer. If the given buffer is too small only the required size for
+ * the protocols are returned.
+ *
+ * RETURNS
+ * The number of protocols entered into the buffer
+ *
+ * BUGS
+ * - only implemented for IPX, SPX, SPXII, TCP, UDP
+ * - there is no check that the operating system supports the returned
+ * protocols
+ */
+static INT WSOCK32_EnterSingleProtocol( INT iProtocol,
+ PROTOCOL_INFOA* lpBuffer,
+ LPDWORD lpSize, BOOL unicode)
+{ DWORD dwLength = 0, dwOldSize = *lpSize;
+ INT iAnz = 1;
+ WCHAR *lpProtName = NULL;
+
+ *lpSize = sizeof( PROTOCOL_INFOA);
+ switch (iProtocol) {
+ case IPPROTO_TCP :
+ dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameTcp)+1) :
+ WideCharToMultiByte( CP_ACP, 0, NameTcp, -1,
+ NULL, 0, NULL, NULL);
+ break;
+ case IPPROTO_UDP :
+ dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameUdp)+1) :
+ WideCharToMultiByte( CP_ACP, 0, NameUdp, -1,
+ NULL, 0, NULL, NULL);
+ break;
+ case NSPROTO_IPX :
+ dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameIpx)+1) :
+ WideCharToMultiByte( CP_ACP, 0, NameIpx, -1,
+ NULL, 0, NULL, NULL);
+ break;
+ case NSPROTO_SPX :
+ dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpx)+1) :
+ WideCharToMultiByte( CP_ACP, 0, NameSpx, -1,
+ NULL, 0, NULL, NULL);
+ break;
+ case NSPROTO_SPXII :
+ dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpxII)+1) :
+ WideCharToMultiByte( CP_ACP, 0, NameSpxII, -1,
+ NULL, 0, NULL, NULL);
+ break;
+ default:
+ *lpSize = 0;
+ if ((iProtocol == ISOPROTO_TP4) || (iProtocol == NSPROTO_SPX))
+ FIXME("Protocol <%s> not implemented\n",
+ (iProtocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
+ else
+ FIXME("unknown Protocol <0x%08x>\n", iProtocol);
+ break;
+ }
+ *lpSize += dwLength;
+
+ if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
+ return 0;
+
+ memset( lpBuffer, 0, dwOldSize);
+
+ lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
+ lpBuffer->iProtocol = iProtocol;
+
+ switch (iProtocol) {
+ case IPPROTO_TCP :
+ lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_EXPEDITED_DATA |
+ XP_GRACEFUL_CLOSE | XP_GUARANTEED_ORDER |
+ XP_GUARANTEED_DELIVERY;
+ lpBuffer->iAddressFamily = WS_AF_INET;
+ lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
+ lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
+ lpBuffer->iSocketType = SOCK_STREAM;
+ lpBuffer->dwMessageSize = 0;
+ lpProtName = NameTcp;
+ break;
+ case IPPROTO_UDP :
+ lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
+ XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
+ XP_CONNECTIONLESS;
+ lpBuffer->iAddressFamily = WS_AF_INET;
+ lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
+ lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
+ lpBuffer->iSocketType = SOCK_DGRAM;
+ lpBuffer->dwMessageSize = 65457; /* NT4 SP5 */
+ lpProtName = NameUdp;
+ break;
+ case NSPROTO_IPX :
+ lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
+ XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
+ XP_CONNECTIONLESS;
+ lpBuffer->iAddressFamily = WS_AF_IPX;
+ lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
+ lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
+ lpBuffer->iSocketType = SOCK_DGRAM;
+ lpBuffer->dwMessageSize = 576; /* NT4 SP5 */
+ lpProtName = NameIpx;
+ break;
+ case NSPROTO_SPX :
+ lpBuffer->dwServiceFlags = XP_FRAGMENTATION |
+ XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
+ XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
+ lpBuffer->iAddressFamily = WS_AF_IPX;
+ lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
+ lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
+ lpBuffer->iSocketType = 5;
+ lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
+ lpProtName = NameSpx;
+ break;
+ case NSPROTO_SPXII :
+ lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_GRACEFUL_CLOSE |
+ XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
+ XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
+ lpBuffer->iAddressFamily = WS_AF_IPX;
+ lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
+ lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
+ lpBuffer->iSocketType = 5;
+ lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
+ lpProtName = NameSpxII;
+ break;
+ }
+ if (unicode)
+ strcpyW( (LPWSTR)lpBuffer->lpProtocol, lpProtName);
+ else
+ WideCharToMultiByte( CP_ACP, 0, lpProtName, -1, lpBuffer->lpProtocol,
+ dwOldSize - iAnz * sizeof( PROTOCOL_INFOA), NULL, NULL);
+
+ return iAnz;
+}
+
+/*****************************************************************************
+ * WSOCK32_EnumProtocol [internal]
+ *
+ * Enters the information about installed protocols into a given buffer
+ *
+ * RETURNS
+ * SOCKET_ERROR if the buffer is to small for the requested protocol infos
+ * on success the number of protocols inside the buffer
+ *
+ * NOTE
+ * NT4SP5 does not return SPX if lpiProtocols == NULL
+ *
+ * BUGS
+ * - NT4SP5 returns in addition these list of NETBIOS protocols
+ * (address family 17), each entry two times one for socket type 2 and 5
+ *
+ * iProtocol lpProtocol
+ * 0x80000000 \Device\NwlnkNb
+ * 0xfffffffa \Device\NetBT_CBENT7
+ * 0xfffffffb \Device\Nbf_CBENT7
+ * 0xfffffffc \Device\NetBT_NdisWan5
+ * 0xfffffffd \Device\NetBT_El9202
+ * 0xfffffffe \Device\Nbf_El9202
+ * 0xffffffff \Device\Nbf_NdisWan4
+ *
+ * - there is no check that the operating system supports the returned
+ * protocols
+ */
+static INT WSOCK32_EnumProtocol( LPINT lpiProtocols, PROTOCOL_INFOA* lpBuffer,
+ LPDWORD lpdwLength, BOOL unicode)
+{ DWORD dwCurSize, dwOldSize = *lpdwLength, dwTemp;
+ INT anz = 0, i;
+ INT iLocal[] = { IPPROTO_TCP, IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPXII, 0};
+
+ if (!lpiProtocols) lpiProtocols = iLocal;
+
+ *lpdwLength = 0;
+ while ( *lpiProtocols )
+ { dwCurSize = 0;
+ WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
+
+ if ( lpBuffer && dwCurSize && ((*lpdwLength + dwCurSize) <= dwOldSize))
+ { /* reserve the required space for the current protocol_info after the
+ * last protocol_info before the start of the string buffer and adjust
+ * the references into the string buffer
+ */
+ memmove( &((char*)&lpBuffer[ anz])[dwCurSize],
+ &lpBuffer[ anz],
+ *lpdwLength - anz * sizeof( PROTOCOL_INFOA));
+ for (i=0; i < anz; i++)
+ lpBuffer[i].lpProtocol += dwCurSize;
+
+ dwTemp = dwCurSize;
+ anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
+ &dwTemp, unicode);
+ }
+
+ *lpdwLength += dwCurSize;
+ lpiProtocols++;
+ }
+
+ if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
+
+ return anz;
+}
+
+/*****************************************************************************
+ * EnumProtocolsA [WSOCK32.1111]
+ *
+ * see function WSOCK32_EnumProtocol for RETURNS, BUGS
+ */
+INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
+ LPDWORD lpdwLength)
+{
+ return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
+ lpdwLength, FALSE);
+}
+
+/*****************************************************************************
+ * EnumProtocolsW [WSOCK32.1112]
+ *
+ * see function WSOCK32_EnumProtocol for RETURNS, BUGS
+ */
+INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
+ LPDWORD lpdwLength)
+{
+ return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
+ lpdwLength, TRUE);
+}
diff --git a/dlls/wsock32/wsock32.spec b/dlls/wsock32/wsock32.spec
index ed3dc93..d5182b0 100644
--- a/dlls/wsock32/wsock32.spec
+++ b/dlls/wsock32/wsock32.spec
@@ -2,6 +2,7 @@
type win32
import ws2_32.dll
+import kernel32.dll
import ntdll.dll
debug_channels (winsock)
@@ -70,8 +71,8 @@
1108 stdcall s_perror(str) WS_s_perror
1109 stub GetAddressByNameA
1110 stub GetAddressByNameW
-#1111 stub EnumProtocolsA
-#1112 stub EnumProtocolsW
+1111 stdcall EnumProtocolsA(ptr ptr ptr) EnumProtocolsA
+1112 stdcall EnumProtocolsW(ptr ptr ptr) EnumProtocolsW
#1113 stub GetTypeByNameA
#1114 stub GetTypeByNameW
#1115 stub GetNameByTypeA
diff --git a/include/Makefile.in b/include/Makefile.in
index 648603b..372980f 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -41,6 +41,7 @@
mmsystem.h \
msacm.h \
msacmdlg.h \
+ nspapi.h \
ntsecapi.h \
oaidl.h \
objbase.h \
@@ -144,6 +145,8 @@
winver.h \
wnaspi32.h \
wownt32.h \
+ wshisotp.h \
+ wsipx.h \
wtypes.h \
zmouse.h
diff --git a/include/nspapi.h b/include/nspapi.h
new file mode 100644
index 0000000..e83447f
--- /dev/null
+++ b/include/nspapi.h
@@ -0,0 +1,69 @@
+/* NSPAPI.H -- winsock 1.1
+ * not supported on win95
+ */
+
+#ifndef _WINE_NSPAPI_
+#define _WINE_NSPAPI_
+
+#include "windef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+/*
+ * constants
+ */
+#define XP_CONNECTIONLESS 0x00000001
+#define XP_GUARANTEED_DELIVERY 0x00000002
+#define XP_GUARANTEED_ORDER 0x00000004
+#define XP_MESSAGE_ORIENTED 0x00000008
+#define XP_PSEUDO_STREAM 0x00000010
+#define XP_GRACEFUL_CLOSE 0x00000020
+#define XP_EXPEDITED_DATA 0x00000040
+#define XP_CONNECT_DATA 0x00000080
+#define XP_DISCONNECT_DATA 0x00000100
+#define XP_SUPPORTS_BROADCAST 0x00000200
+#define XP_SUPPORTS_MULTICAST 0x00000400
+#define XP_BANDWITH_ALLOCATION 0x00000800
+#define XP_FRAGMENTATION 0x00001000
+#define XP_ENCRYPTS 0x00002000
+
+/*
+ * structures
+ */
+typedef struct _PROTOCOL_INFOA
+{
+ DWORD dwServiceFlags;
+ INT iAddressFamily;
+ INT iMaxSockAddr;
+ INT iMinSockAddr;
+ INT iSocketType;
+ INT iProtocol;
+ DWORD dwMessageSize;
+ LPSTR lpProtocol;
+} PROTOCOL_INFOA;
+
+typedef struct _PROTOCOL_INFOW
+{
+ DWORD dwServiceFlags;
+ INT iAddressFamily;
+ INT iMaxSockAddr;
+ INT iMinSockAddr;
+ INT iSocketType;
+ INT iProtocol;
+ DWORD dwMessageSize;
+ LPWSTR lpProtocol;
+} PROTOCOL_INFOW;
+
+
+/*
+ * function prototypes
+ */
+
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* _WINE_NSPAPI_ */
diff --git a/include/wshisotp.h b/include/wshisotp.h
new file mode 100644
index 0000000..1387c78
--- /dev/null
+++ b/include/wshisotp.h
@@ -0,0 +1,22 @@
+/* WSHISOTP.H
+ */
+
+#ifndef _WINE_WSHISOTP_
+#define _WINE_WSHISOTP_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+/*
+ * constants
+ */
+#define ISOPROTO_TP4 29
+#define ISOPROTO_TP ISOPROTO_TP4
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* _WINE_WSHISOTP_ */
diff --git a/include/wsipx.h b/include/wsipx.h
new file mode 100644
index 0000000..d40839a
--- /dev/null
+++ b/include/wsipx.h
@@ -0,0 +1,23 @@
+/* WCIPX.H
+ */
+
+#ifndef _WINE_WCIPX_
+#define _WINE_WCIPX_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+/*
+ * constants
+ */
+#define NSPROTO_IPX 1000
+#define NSPROTO_SPX 1256
+#define NSPROTO_SPXII 1257
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* _WINE_WCIPX_ */