diff --git a/reactos/dll/win32/ws2_32/misc/dllmain.c b/reactos/dll/win32/ws2_32/misc/dllmain.c
index 18b1a02f7a3..c9e07cb4c9f 100644
--- a/reactos/dll/win32/ws2_32/misc/dllmain.c
+++ b/reactos/dll/win32/ws2_32/misc/dllmain.c
@@ -166,7 +166,7 @@ socket(IN INT af,
IN INT type,
IN INT protocol)
{
- return WSASocketA(af,
+ return WSASocketW(af,
type,
protocol,
NULL,
diff --git a/reactos/drivers/network/afd/afd/info.c b/reactos/drivers/network/afd/afd/info.c
index 32c02bb85c1..3339f339b67 100644
--- a/reactos/drivers/network/afd/afd/info.c
+++ b/reactos/drivers/network/afd/afd/info.c
@@ -49,9 +49,9 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
break;
case AFD_INFO_RECEIVE_CONTENT_SIZE:
- /* Only touch InfoReq if we actually have a valid connection.
+ /* Only touch InfoReq if a socket has been set up.
Behaviour was verified under WinXP SP2. */
- if(FCB->Connection.Handle)
+ if(FCB->AddressFile.Object)
InfoReq->Information.Ulong = FCB->Recv.Content - FCB->Recv.BytesUsed;
break;
diff --git a/rostests/apitests/directory.rbuild b/rostests/apitests/directory.rbuild
index 372db3db1e8..85e422f710b 100644
--- a/rostests/apitests/directory.rbuild
+++ b/rostests/apitests/directory.rbuild
@@ -23,4 +23,8 @@
+
+
+
+
diff --git a/rostests/apitests/ws2_32/helpers.c b/rostests/apitests/ws2_32/helpers.c
new file mode 100644
index 00000000000..9033aed184f
--- /dev/null
+++ b/rostests/apitests/ws2_32/helpers.c
@@ -0,0 +1,65 @@
+/*
+ * PROJECT: ws2_32.dll API tests
+ * LICENSE: GPLv2 or any later version
+ * FILE: apitests/ws2_32/helpers.c
+ * PURPOSE: Helper functions for the socket tests
+ * COPYRIGHT: Copyright 2008 Colin Finck
+ */
+
+#include "ws2_32.h"
+
+int CreateSocket(PTESTINFO pti, SOCKET* psck)
+{
+ /* Create the socket */
+ *psck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ TEST(*psck != INVALID_SOCKET);
+
+ if(*psck == INVALID_SOCKET)
+ {
+ printf("Winsock error code is %u\n", WSAGetLastError());
+ WSACleanup();
+ return APISTATUS_ASSERTION_FAILED;
+ }
+
+ return APISTATUS_NORMAL;
+}
+
+int ConnectToReactOSWebsite(PTESTINFO pti, SOCKET sck)
+{
+ int iResult;
+ struct hostent* host;
+ struct sockaddr_in sa;
+
+ /* Connect to "www.reactos.org" */
+ host = gethostbyname("www.reactos.org");
+
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = *(u_long*)host->h_addr_list[0];
+ sa.sin_port = htons(80);
+
+ SCKTEST(connect(sck, (struct sockaddr *)&sa, sizeof(sa)));
+
+ return APISTATUS_NORMAL;
+}
+
+int GetRequestAndWait(PTESTINFO pti, SOCKET sck)
+{
+ const char szGetRequest[] = "GET / HTTP/1.0\r\n\r\n";
+ int iResult;
+ struct fd_set readable;
+
+ /* Send the GET request */
+ SCKTEST(send(sck, szGetRequest, strlen(szGetRequest), 0));
+ TEST(iResult == strlen(szGetRequest));
+
+ /* Shutdown the SEND connection */
+ SCKTEST(shutdown(sck, SD_SEND));
+
+ /* Wait until we're ready to read */
+ FD_ZERO(&readable);
+ FD_SET(sck, &readable);
+
+ SCKTEST(select(0, &readable, NULL, NULL, NULL));
+
+ return APISTATUS_NORMAL;
+}
diff --git a/rostests/apitests/ws2_32/testlist.c b/rostests/apitests/ws2_32/testlist.c
new file mode 100644
index 00000000000..fa579807f3f
--- /dev/null
+++ b/rostests/apitests/ws2_32/testlist.c
@@ -0,0 +1,33 @@
+/*
+ * PROJECT: ws2_32.dll API tests
+ * LICENSE: GPLv2 or any later version
+ * FILE: apitests/ws2_32/testlist.c
+ * PURPOSE: Test list file
+ * COPYRIGHT: Copyright 2008 Colin Finck
+ */
+
+#ifndef _WS2_32_TESTLIST_H
+#define _WS2_32_TESTLIST_H
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+#include "ws2_32.h"
+
+/* include the tests */
+#include "tests/ioctlsocket.c"
+#include "tests/recv.c"
+
+/* The List of tests */
+TESTENTRY TestList[] =
+{
+ { L"ioctlsocket", Test_ioctlsocket },
+ { L"recv", Test_recv }
+};
+
+/* The function that gives us the number of tests */
+INT NumTests(void)
+{
+ return ARRAY_SIZE(TestList);
+}
+
+#endif
diff --git a/rostests/apitests/ws2_32/tests/ioctlsocket.c b/rostests/apitests/ws2_32/tests/ioctlsocket.c
new file mode 100644
index 00000000000..2d291f7eb4e
--- /dev/null
+++ b/rostests/apitests/ws2_32/tests/ioctlsocket.c
@@ -0,0 +1,83 @@
+/*
+ * PROJECT: ws2_32.dll API tests
+ * LICENSE: GPLv2 or any later version
+ * FILE: apitests/ws2_32/tests/ioctlsocket.c
+ * PURPOSE: Tests for the ioctlsocket function
+ * COPYRIGHT: Copyright 2008 Colin Finck
+ */
+
+#include "../ws2_32.h"
+
+/* For valid test results, the ReactOS Website needs to return at least 2 bytes on a "GET / HTTP/1.0" request. */
+INT
+Test_ioctlsocket(PTESTINFO pti)
+{
+ LPSTR pszBuf;
+ int iResult;
+ SOCKET sck;
+ ULONG BytesAvailable;
+ ULONG BytesToRead;
+ WSADATA wdata;
+
+ /* Start up Winsock */
+ TEST(WSAStartup(MAKEWORD(2, 2), &wdata) == 0);
+
+ /* If we call ioctlsocket without a socket, it should return with an error and do nothing. */
+ BytesAvailable = 0xdeadbeef;
+ TEST(ioctlsocket(0, FIONREAD, &BytesAvailable) == SOCKET_ERROR);
+ TEST(BytesAvailable == 0xdeadbeef);
+
+ /* Create the socket */
+ iResult = CreateSocket(pti, &sck);
+ if(iResult != APISTATUS_NORMAL)
+ return iResult;
+
+ /* Now we can pass at least a socket, but we have no connection yet. The function should return 0. */
+ BytesAvailable = 0xdeadbeef;
+ TEST(ioctlsocket(sck, FIONREAD, &BytesAvailable) == 0);
+ TEST(BytesAvailable == 0);
+
+ /* Connect to "www.reactos.org" */
+ iResult = ConnectToReactOSWebsite(pti, sck);
+ if(iResult != APISTATUS_NORMAL)
+ return iResult;
+
+ /* Even with a connection, there shouldn't be any bytes available. */
+ TEST(ioctlsocket(sck, FIONREAD, &BytesAvailable) == 0);
+ TEST(BytesAvailable == 0);
+
+ /* Send the GET request */
+ iResult = GetRequestAndWait(pti, sck);
+ if(iResult != APISTATUS_NORMAL)
+ return iResult;
+
+ /* Try ioctlsocket with FIONREAD. There should be bytes available now. */
+ SCKTEST(ioctlsocket(sck, FIONREAD, &BytesAvailable));
+ TEST(BytesAvailable != 0);
+
+ /* Get half of the data */
+ BytesToRead = BytesAvailable / 2;
+ pszBuf = (LPSTR) HeapAlloc(g_hHeap, 0, BytesToRead);
+ SCKTEST(recv(sck, pszBuf, BytesToRead, 0));
+ HeapFree(g_hHeap, 0, pszBuf);
+
+ BytesToRead = BytesAvailable - BytesToRead;
+
+ /* Now try ioctlsocket again. BytesAvailable should be at the value saved in BytesToRead now. */
+ SCKTEST(ioctlsocket(sck, FIONREAD, &BytesAvailable));
+ TEST(BytesAvailable == BytesToRead);
+
+ /* Read those bytes */
+ pszBuf = (LPSTR) HeapAlloc(g_hHeap, 0, BytesToRead);
+ SCKTEST(recv(sck, pszBuf, BytesToRead, 0));
+ HeapFree(g_hHeap, 0, pszBuf);
+
+ /* Try it for the last time. BytesAvailable should be at 0 now. */
+ SCKTEST(ioctlsocket(sck, FIONREAD, &BytesAvailable));
+ TEST(BytesAvailable == 0);
+
+ closesocket(sck);
+ WSACleanup();
+
+ return APISTATUS_NORMAL;
+}
diff --git a/rostests/apitests/ws2_32/tests/recv.c b/rostests/apitests/ws2_32/tests/recv.c
new file mode 100644
index 00000000000..4df6c0ecabd
--- /dev/null
+++ b/rostests/apitests/ws2_32/tests/recv.c
@@ -0,0 +1,69 @@
+/*
+ * PROJECT: ws2_32.dll API tests
+ * LICENSE: GPLv2 or any later version
+ * FILE: apitests/ws2_32/tests/recv.c
+ * PURPOSE: Tests for the recv function
+ * COPYRIGHT: Copyright 2008 Colin Finck
+ */
+
+#include "../ws2_32.h"
+
+#define RECV_BUF 4
+
+/* For valid test results, the ReactOS Website needs to return at least 8 bytes on a "GET / HTTP/1.0" request.
+ Also the first 4 bytes and the last 4 bytes need to be different.
+ Both factors usually apply on standard HTTP responses. */
+INT
+Test_recv(PTESTINFO pti)
+{
+ const char szDummyBytes[RECV_BUF] = {0xFF, 0x00, 0xFF, 0x00};
+
+ char szBuf1[RECV_BUF];
+ char szBuf2[RECV_BUF];
+ int iResult;
+ SOCKET sck;
+ WSADATA wdata;
+
+ /* Start up Winsock */
+ TEST(WSAStartup(MAKEWORD(2, 2), &wdata) == 0);
+
+ /* If we call recv without a socket, it should return with an error and do nothing. */
+ memcpy(szBuf1, szDummyBytes, RECV_BUF);
+ TEST(recv(0, szBuf1, RECV_BUF, 0) == SOCKET_ERROR);
+ TEST(!memcmp(szBuf1, szDummyBytes, RECV_BUF));
+
+ /* Create the socket */
+ iResult = CreateSocket(pti, &sck);
+ if(iResult != APISTATUS_NORMAL)
+ return iResult;
+
+ /* Now we can pass at least a socket, but we have no connection yet. Should return with an error and do nothing. */
+ memcpy(szBuf1, szDummyBytes, RECV_BUF);
+ TEST(recv(sck, szBuf1, RECV_BUF, 0) == SOCKET_ERROR);
+ TEST(!memcmp(szBuf1, szDummyBytes, RECV_BUF));
+
+ /* Connect to "www.reactos.org" */
+ iResult = ConnectToReactOSWebsite(pti, sck);
+ if(iResult != APISTATUS_NORMAL)
+ return iResult;
+
+ /* Send the GET request */
+ iResult = GetRequestAndWait(pti, sck);
+ if(iResult != APISTATUS_NORMAL)
+ return iResult;
+
+ /* Receive the data.
+ MSG_PEEK will not change the internal number of bytes read, so that a subsequent request should return the same bytes again. */
+ SCKTEST(recv(sck, szBuf1, RECV_BUF, MSG_PEEK));
+ SCKTEST(recv(sck, szBuf2, RECV_BUF, 0));
+ TEST(!memcmp(szBuf1, szBuf2, RECV_BUF));
+
+ /* The last recv() call moved the internal file pointer, so that the next request should return different data. */
+ SCKTEST(recv(sck, szBuf1, RECV_BUF, 0));
+ TEST(memcmp(szBuf1, szBuf2, RECV_BUF));
+
+ closesocket(sck);
+ WSACleanup();
+
+ return APISTATUS_NORMAL;
+}
diff --git a/rostests/apitests/ws2_32/ws2_32.c b/rostests/apitests/ws2_32/ws2_32.c
new file mode 100644
index 00000000000..42e8a9b68eb
--- /dev/null
+++ b/rostests/apitests/ws2_32/ws2_32.c
@@ -0,0 +1,24 @@
+/*
+ * PROJECT: ws2_32.dll API tests
+ * LICENSE: GPLv2 or any later version
+ * FILE: apitests/ws2_32/ws2_32.c
+ * PURPOSE: Program entry point
+ * COPYRIGHT: Copyright 2008 Colin Finck
+ */
+
+#include "ws2_32.h"
+
+HANDLE g_hHeap;
+
+BOOL
+IsFunctionPresent(LPWSTR lpszFunction)
+{
+ return TRUE;
+}
+
+int wmain()
+{
+ g_hHeap = GetProcessHeap();
+
+ return TestMain(L"ws2_32_apitests", L"ws2_32.dll");
+}
diff --git a/rostests/apitests/ws2_32/ws2_32.h b/rostests/apitests/ws2_32/ws2_32.h
new file mode 100644
index 00000000000..6fe52408fe8
--- /dev/null
+++ b/rostests/apitests/ws2_32/ws2_32.h
@@ -0,0 +1,36 @@
+/*
+ * PROJECT: ws2_32.dll API tests
+ * LICENSE: GPLv2 or any later version
+ * FILE: apitests/ws2_32/ws2_32.h
+ * PURPOSE: Main header file
+ * COPYRIGHT: Copyright 2008 Colin Finck
+ */
+
+#ifndef _WS2_32_APITESTS_H
+#define _WS2_32_APITESTS_H
+
+#include
+
+#include "../apitest.h"
+
+/* Simple macro for executing a socket command and doing cleanup operations in case of a failure */
+#define SCKTEST(_cmd_) \
+ iResult = _cmd_; \
+ TEST(iResult != SOCKET_ERROR); \
+ if(iResult == SOCKET_ERROR) \
+ { \
+ printf("Winsock error code is %u\n", WSAGetLastError()); \
+ closesocket(sck); \
+ WSACleanup(); \
+ return APISTATUS_ASSERTION_FAILED; \
+ }
+
+/* helpers.c */
+int CreateSocket(PTESTINFO pti, SOCKET* sck);
+int ConnectToReactOSWebsite(PTESTINFO pti, SOCKET sck);
+int GetRequestAndWait(PTESTINFO pti, SOCKET sck);
+
+/* ws2_32.c */
+extern HANDLE g_hHeap;
+
+#endif
diff --git a/rostests/apitests/ws2_32/ws2_32.rbuild b/rostests/apitests/ws2_32/ws2_32.rbuild
new file mode 100644
index 00000000000..e86f3cc04f8
--- /dev/null
+++ b/rostests/apitests/ws2_32/ws2_32.rbuild
@@ -0,0 +1,11 @@
+
+ 0x0501
+ apitest
+ kernel32
+ user32
+ shell32
+ ws2_32
+ helpers.c
+ testlist.c
+ ws2_32.c
+