diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 38b423ece2f..1e1aab8d1b4 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -472,7 +472,7 @@ winnls/libwinnls32.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@ 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 a925ff329d5..4c3801b809c 100644 --- a/dlls/wsock32/Makefile.in +++ b/dlls/wsock32/Makefile.in @@ -7,7 +7,9 @@ MODULE = wsock32 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 00000000000..92f2aae3b15 --- /dev/null +++ b/dlls/wsock32/protocol.c @@ -0,0 +1,250 @@ +/* + * WSOCK32 specific functions + * + * Copyright (C) 2001 Stefan Leichter + */ + +#include "config.h" + +#include +#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 ed3dc93f51c..d5182b093b3 100644 --- a/dlls/wsock32/wsock32.spec +++ b/dlls/wsock32/wsock32.spec @@ -2,6 +2,7 @@ name wsock32 type win32 import ws2_32.dll +import kernel32.dll import ntdll.dll debug_channels (winsock) @@ -70,8 +71,8 @@ debug_channels (winsock) 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 648603b9fe6..372980fa3ec 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -41,6 +41,7 @@ INSTALLED_INCLUDES = \ mmsystem.h \ msacm.h \ msacmdlg.h \ + nspapi.h \ ntsecapi.h \ oaidl.h \ objbase.h \ @@ -144,6 +145,8 @@ INSTALLED_INCLUDES = \ 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 00000000000..e83447fa594 --- /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 00000000000..1387c78d0b4 --- /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 00000000000..d40839ac66e --- /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_ */