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