Sign in to follow this  
Erik Rufelt

WinSock2 extensions (again)

Recommended Posts

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

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this