WinSock2 extensions (again)

Started by
8 comments, last by nevernomore 18 years, 10 months ago
Hi, I asked a question in a different thread about loading the ConnectEx / DisconnectEx functions. I have tried to locate the problem and this is what I found: code:
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

guid = WSAID_CONNECTEX;

intResult = WSAIoctl(
s,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&guid,
sizeof(guid),
&lpfnConnectEx,
sizeof(lpfnConnectEx),
&dwBytes,
NULL,
NULL
);

WSAIoctl returns SOCKET_ERR0R with WSAEOPNOTSUPP However, the lpfnConnectEx is not NULL, and can be used When I use it it returns FALSE and WSAEINVAL I have checked all the arguments to the function, and they are all correct according to the MSDN reference page. Code:

memset(&addr, 0, sizeof(SOCKADDR_IN));

addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(1111);

lpOverlapped = new WSAOVERLAPPED;
memset(lpOverlapped, 0, sizeof(WSAOVERLAPPED));

bRet = lpfnConnectEx(
s,
(LPSOCKADDR)&addr,
sizeof(SOCKADDR_IN),
NULL,
0,
NULL,
lpOverlapped
);

Is there some way I can check the name of "lpfnConnectEx" to see that I have the correct function? Is the function supposed to be present in some DLL, and in that case which DLL? I can get the AcceptEx as well as the TransmitFile function this way, or I can load them from the mswsock.dll DLL, or just use them since they are in the header file MSWsock.h as well as the mswsock.lib, and get linked from the DLL automatically. ConnectEx / DisconnectEx / TransmitPackets I can't load from the same DLL, they don't seem to exist in it. I've read that these three functions are newer, do they need to be inited in some special way? I have WindowsXP SP2. Could this be something wrong with my DLL? I have tried on two different computers with the same results. Thx, /Erik
Advertisement
Have you tried linking to ws2_32.lib instead?
Yes, I'm linking to both of them.
ConnectEx / DisconnectEx are in neither.


I've tried this with those libraries as well as all others I found that had anything to do with WinSock:
HMODULE hDLL = LoadLibrary("mswsock.dll");if(hDLL == NULL)	printf("ERROR LoadLibrary: %d\n", GetLastError());else	printf("Library loaded!\n");FARPROC func = GetProcAddress(hDLL, "ConnectEx");if(func == NULL)	printf("ERROR GetProcAddress: %d\n", GetLastError());else	printf("Function address found!\n");FreeLibrary(hDLL);


ConnectEx is never found.
Is it supposed to be in the DLL?
What exactly does WSAIoctl do when loading a function, why am I supposed to do that instead of loading it from a DLL the normal way? (supposing it is in a DLL and not something else)

AcceptEx as well as TransmitFile are in the mswsock.dll
They are also in the mswsock.lib so I can just get the prototype from the MSWsock.h file and use them without loading them with WSAIoctl, I thought I had to do that with ConnectEx because it's not in a normal DLL...


EDIT:
This is what MSDN says about AcceptEx:
Requirements
Client ..._many systems_...
Server ..._many systems_...
Header Declared in Mswsock.h.
Library Link to Mswsock.lib.
DLL Requires Mswsock.dll.

On ConnectEx it doesnt list any DLL:
Requirements
Client Requires Windows XP.
Server Requires Windows Server 2003.
Header Declared in Mswsock.h.

[Edited by - Erik Rufelt on June 4, 2005 11:16:05 PM]
So just to clarify ...

You did in fact remove the mswsock.lib and replace it with ws2_32.lib and used the WSAIoctl() on the socket? You can't use the GetProcAddress method. If it did work to get those functions, it's undocumented and therefore unreliable.

Have you tried creating the socket with WSASocket()?

My socket class uses WSASocket and WSAIoctl to get those functions, and works just fine. I have not tried mixing and matching the API functions.

Robert
Thanks for your replies!

Yes I have tried that, I've made a small test app now, which only uses Ws2_32.lib and WSAIoctl()
I've compiled it on Visual C++ 2005 Express Beta, on VisualC++ 6.0, and CodeWarrior, with the same results.
Maybe you could paste into a "console" project to see if it's a system problem for me?
Here is the code:
#include <stdio.h>#define WIN32_LEAN_AND_MEAN#include <Winsock2.h>#include <MSWsock.h>int main() {	// App	int					iRet;			// Startup WinSock	WSADATA				wsaData;		printf("WSAStartup(...):\n");		iRet = WSAStartup(		MAKEWORD(2,2),		&wsaData	);	printf("iRet:                   %d\n", iRet);	printf("MAKEWORD(2,2):          %x\n", MAKEWORD(2,2));	printf("wsaData.wVersion:       %x\n", wsaData.wVersion);	printf("wsaData.wHighVersion:   %x\n", wsaData.wHighVersion);	printf("wsaData.szDescription:  %s\n", wsaData.szDescription);	printf("wsaData.szSystemStatus: %s\n", wsaData.szSystemStatus);			// Socket	SOCKET				s;		printf("\n\nWSASocket(...):\n");		s = WSASocket(		AF_INET,		SOCK_STREAM,		IPPROTO_TCP,		NULL,		0,		WS_OVERLAPPED	);	printf("s:                      %d\n", s);			// Load ConnectEx	GUID				GuidConnectEx	= WSAID_CONNECTEX;	LPFN_CONNECTEX		lpfnConnectEx	= NULL;	DWORD				dwBytes			= 0;		printf("\n\nWSAIoctl(...) for ConnectEx:\n");		iRet = WSAIoctl(		s,		SIO_GET_EXTENSION_FUNCTION_POINTER,		&GuidConnectEx,		sizeof(GuidConnectEx),		&lpfnConnectEx,		sizeof(lpfnConnectEx),		&dwBytes,		NULL,		NULL	);	printf("iRet:                   %d\n", iRet);	printf("sizeof(GuidConnectEx):  %d\n", sizeof(GuidConnectEx));	printf("lpfnConnectEx:          %x\n", lpfnConnectEx);	printf("sizeof(lpfnConnectEx):  %d\n", sizeof(lpfnConnectEx));	printf("dwBytes:                %d\n", dwBytes);	printf("WSAGetLastError():      %d\n", WSAGetLastError());			// Try ConnectEx	SOCKADDR_IN			addr;	BOOL				bRet;	OVERLAPPED			overlapped;		printf("\n\nlpfnConnectEx(...):\n");		memset(&addr, 0, sizeof(addr));		addr.sin_family = AF_INET;	addr.sin_addr.s_addr = inet_addr("127.0.0.1");	addr.sin_port = htons(88);		memset(&overlapped, 0, sizeof(overlapped));		dwBytes = 0;	bRet = lpfnConnectEx(		s,		(LPSOCKADDR)&addr,		sizeof(addr),		NULL,		0,		NULL,		&overlapped	);	printf("bRet:                   %d\n", bRet);	printf("sizeof(addr):           %d\n", sizeof(addr));	printf("WSAGetLastError():      %d\n", WSAGetLastError());					// Wait	char	str[255];	gets(str);		return 0;}
WSAStartup(...):
iRet: 0
MAKEWORD(2,2): 202
wsaData.wVersion: 202
wsaData.wHighVersion: 202
wsaData.szDescription: WinSock 2.0
wsaData.szSystemStatus: Running


WSASocket(...):
s: 1956


WSAIoctl(...) for ConnectEx:
iRet: 0
sizeof(GuidConnectEx): 16
lpfnConnectEx: 71a6a2d9
sizeof(lpfnConnectEx): 4
dwBytes: 4
WSAGetLastError(): 0

Worked great for me!

Windows XP SP2

Robert

Once again I have spent 5 hours trying to solve a coding problem that isn't in the code =)

Thank you very much
It's very strange.. I also have SP2..

Maybe I've disabled some services or something that are needed..
I will look elsewhere for the problem =)

thx,
/Erik
It started working after I deleted all the registry values for winsock and imported them from another computer where it worked.
I broke a networking app that I use to specify how much network bandwidth different programs can use in the process.. so perhaps it had changed something that broke the winsock extensions..
Your networking application probably installs a Layered Service Provider (LSP).

Start "winmsd" and look at the Components->Network->Protocol for the list of service providers loaded. MSAFD Tcpip should be the first.

when you call GET_EXTENSION_POINTER, winsock asks the topmost LSP for a pointer to its implementation of the extension function.

In your case, the LSP is probably broken. Instead of forwarding the request to the next provider in the chain, it returns an error.

BTW, PLEASE DON'T mess with the registry for winsock problems.

type "netsh winsock reset" to set your winsock configuration back to a known state.

This topic is closed to new replies.

Advertisement