1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Test for send/sendto
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <apitest.h>
9 #include <winsock2.h>
10 
11 #define WIN32_NO_STATUS
12 #include <ndk/mmfuncs.h>
13 #include <ndk/rtlfuncs.h>
14 
15 static
16 PVOID
17 AllocateReadOnly(
18     _In_ SIZE_T SizeRequested)
19 {
20     NTSTATUS Status;
21     SIZE_T Size = PAGE_ROUND_UP(SizeRequested);
22     PVOID VirtualMemory = NULL;
23 
24     Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READONLY);
25     if (!NT_SUCCESS(Status))
26         return NULL;
27 
28     return VirtualMemory;
29 }
30 
31 static
32 VOID
33 FreeReadOnly(
34     _In_ PVOID VirtualMemory)
35 {
36     NTSTATUS Status;
37     SIZE_T Size = 0;
38 
39     Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
40     ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
41 }
42 
43 static
44 VOID
45 test_send(void)
46 {
47     SOCKET sock;
48     int ret;
49     int error;
50     PVOID buffer;
51     ULONG bufferSize;
52     struct sockaddr_in addr;
53 
54     bufferSize = 32;
55     buffer = AllocateReadOnly(bufferSize);
56     ok(buffer != NULL, "AllocateReadOnly failed\n");
57     if (!buffer)
58     {
59         skip("No memory\n");
60         return;
61     }
62 
63     ret = send(0, NULL, 0, 0);
64     error = WSAGetLastError();
65     ok(ret == SOCKET_ERROR, "send returned %d\n", ret);
66     ok(error == WSAENOTSOCK, "error = %d\n", error);
67 
68     ret = send(0, buffer, bufferSize, 0);
69     error = WSAGetLastError();
70     ok(ret == SOCKET_ERROR, "send returned %d\n", ret);
71     ok(error == WSAENOTSOCK, "error = %d\n", error);
72 
73     sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
74     ok(sock != INVALID_SOCKET, "socket failed\n");
75     if (sock == INVALID_SOCKET)
76     {
77         skip("No socket\n");
78         FreeReadOnly(buffer);
79         return;
80     }
81 
82     ret = send(sock, NULL, 0, 0);
83     error = WSAGetLastError();
84     ok(ret == SOCKET_ERROR, "send returned %d\n", ret);
85     ok(error == WSAENOTCONN, "error = %d\n", error);
86 
87     ret = send(sock, buffer, bufferSize, 0);
88     error = WSAGetLastError();
89     ok(ret == SOCKET_ERROR, "send returned %d\n", ret);
90     ok(error == WSAENOTCONN, "error = %d\n", error);
91 
92     memset(&addr, 0, sizeof(addr));
93     addr.sin_family = AF_INET;
94     addr.sin_addr.s_addr = inet_addr("8.8.8.8");
95     addr.sin_port = htons(53);
96     ret = connect(sock, (const struct sockaddr *)&addr, sizeof(addr));
97     error = WSAGetLastError();
98     ok(ret == 0, "connect returned %d\n", ret);
99     ok(error == 0, "error = %d\n", error);
100 
101     ret = send(sock, NULL, 0, 0);
102     error = WSAGetLastError();
103     ok(ret == 0, "send returned %d\n", ret);
104     ok(error == 0, "error = %d\n", error);
105 
106     ret = send(sock, buffer, bufferSize, 0);
107     error = WSAGetLastError();
108     ok(ret == bufferSize, "send returned %d\n", ret);
109     ok(error == 0, "error = %d\n", error);
110 
111     closesocket(sock);
112 
113     FreeReadOnly(buffer);
114 }
115 
116 static
117 VOID
118 test_sendto(void)
119 {
120     SOCKET sock;
121     int ret;
122     int error;
123     PVOID buffer;
124     ULONG bufferSize;
125     struct sockaddr_in addr;
126 
127     bufferSize = 32;
128     buffer = AllocateReadOnly(bufferSize);
129     ok(buffer != NULL, "AllocateReadOnly failed\n");
130     if (!buffer)
131     {
132         skip("No memory\n");
133         return;
134     }
135 
136     memset(&addr, 0, sizeof(addr));
137     addr.sin_family = AF_INET;
138     addr.sin_addr.s_addr = inet_addr("8.8.8.8");
139     addr.sin_port = htons(53);
140 
141     ret = sendto(0, NULL, 0, 0, (const struct sockaddr *)&addr, sizeof(addr));
142     error = WSAGetLastError();
143     ok(ret == SOCKET_ERROR, "sendto returned %d\n", ret);
144     ok(error == WSAENOTSOCK, "error = %d\n", error);
145 
146     ret = sendto(0, buffer, bufferSize, 0, (const struct sockaddr *)&addr, sizeof(addr));
147     error = WSAGetLastError();
148     ok(ret == SOCKET_ERROR, "sendto returned %d\n", ret);
149     ok(error == WSAENOTSOCK, "error = %d\n", error);
150 
151     sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
152     ok(sock != INVALID_SOCKET, "socket failed\n");
153     if (sock == INVALID_SOCKET)
154     {
155         skip("No socket\n");
156         FreeReadOnly(buffer);
157         return;
158     }
159 
160     ret = sendto(sock, NULL, 0, 0, (const struct sockaddr *)&addr, sizeof(addr));
161     error = WSAGetLastError();
162     ok(ret == 0, "sendto returned %d\n", ret);
163     ok(error == 0, "error = %d\n", error);
164 
165     ret = sendto(sock, buffer, bufferSize, 0, (const struct sockaddr *)&addr, sizeof(addr));
166     error = WSAGetLastError();
167     ok(ret == bufferSize, "sendto returned %d\n", ret);
168     ok(error == 0, "error = %d\n", error);
169 
170     closesocket(sock);
171 
172     FreeReadOnly(buffer);
173 }
174 
175 START_TEST(send)
176 {
177     int ret;
178     WSADATA wsad;
179 
180     ret = WSAStartup(MAKEWORD(2, 2), &wsad);
181     ok(ret == 0, "WSAStartup failed with %d\n", ret);
182     test_send();
183     test_sendto();
184     WSACleanup();
185 }
186