[ws2_32]
[reactos.git] / reactos / dll / win32 / ws2_32_new / src / startup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: startup.c
5 * PURPOSE: Startup/Cleanup Support
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ws2_32.h>
12
13 //#define NDEBUG
14 #include <debug.h>
15
16 /* DATA **********************************************************************/
17
18 PWS_SOCK_POST_ROUTINE WsSockPostRoutine = NULL;
19 CRITICAL_SECTION WsStartupLock;
20
21 #define WsStartupLock() EnterCriticalSection(&WsStartupLock);
22 #define WsStartupUnlock() LeaveCriticalSection(&WsStartupLock);
23
24 /* FUNCTIONS *****************************************************************/
25
26 VOID
27 WSAAPI
28 WsCreateStartupSynchronization(VOID)
29 {
30 /* Initialize the startup lock */
31 InitializeCriticalSection(&WsStartupLock);
32 }
33
34 VOID
35 WSAAPI
36 WsDestroyStartupSynchronization(VOID)
37 {
38 /* Destroy the startup lock */
39 DeleteCriticalSection(&WsStartupLock);
40 }
41
42 /*
43 * @implemented
44 */
45 BOOL
46 WSAAPI
47 WSApSetPostRoutine(PVOID Routine)
48 {
49 /* Set the post routine */
50 DPRINT("WSApSetPostRoutine: %p\n", Routine);
51 WsSockPostRoutine = (PWS_SOCK_POST_ROUTINE)Routine;
52 return ERROR_SUCCESS;
53 }
54
55 /*
56 * @implemented
57 */
58 INT
59 WSAAPI
60 WSACleanup(VOID)
61 {
62 PWSPROCESS Process;
63 PWSTHREAD Thread;
64 INT ErrorCode;
65 LONG RefCount;
66 DPRINT("WSACleanup\n");
67
68 /* Enter startup lock */
69 WsStartupLock();
70
71 /* Enter prolog */
72 if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS)
73 {
74 /* Decrement process reference count and check if it's zero */
75 if (!(RefCount = InterlockedDecrement(&Process->RefCount)))
76 {
77 /* It's zero, destroy the process structure */
78 WsProcDelete(Process);
79 }
80 else if (RefCount == 1 && WsAsyncThreadInitialized)
81 {
82 /* Kill async thread */
83 WsAsyncTerminateThread();
84 }
85
86 /* Return success */
87 ErrorCode = ERROR_SUCCESS;
88 }
89 else
90 {
91 /* Weren't initialized */
92 SetLastError(ErrorCode);
93 ErrorCode = SOCKET_ERROR;
94 }
95
96 /* Release startup lock */
97 WsStartupUnlock();
98
99 /* Done */
100 return ErrorCode;
101 }
102
103 /*
104 * @implemented
105 */
106 INT
107 WINAPI
108 WSAStartup(IN WORD wVersionRequested,
109 OUT LPWSADATA lpWSAData)
110 {
111 WORD VersionReturned = 0;
112 DWORD ErrorCode = ERROR_SUCCESS;
113 PWSPROCESS CurrentProcess;
114 DPRINT("WSAStartup: %wx\n", wVersionRequested);
115
116 /* Make sure that we went through DLL Init */
117 if (!WsDllHandle) return WSASYSNOTREADY;
118
119 /* Check which version is being requested */
120 switch (LOBYTE(wVersionRequested))
121 {
122 case 0:
123
124 /* We don't support this unknown version */
125 ErrorCode = WSAVERNOTSUPPORTED;
126 break;
127
128 case 1:
129 /* We support only 1.0 and 1.1 */
130 if (HIBYTE(wVersionRequested) == 0)
131 {
132 /* Caller wants 1.0, return it */
133 VersionReturned = wVersionRequested;
134 }
135 else
136 {
137 /* The only other version we support is 1.1 */
138 VersionReturned = MAKEWORD(1, 1);
139 }
140 break;
141
142 case 2:
143 /* We support only 2.0, 2.1 and 2.2 */
144 if (HIBYTE(wVersionRequested) <= 2)
145 {
146 /* Caller wants 2.0-2.2, return it */
147 VersionReturned = MAKEWORD(2, HIBYTE(wVersionRequested));
148 }
149 else
150 {
151 /* The highest version we support is 2.2 */
152 VersionReturned = MAKEWORD(2, 2);
153 }
154 break;
155
156 default:
157
158 /* Return 2.2 */
159 VersionReturned = MAKEWORD(2, 2);;
160 break;
161 }
162
163 /* Return the Version Requested, unless error */
164 lpWSAData->wVersion = VersionReturned;
165
166 /* We support Winsock 2.2 */
167 lpWSAData->wHighVersion = MAKEWORD(2,2);
168 lstrcpy(lpWSAData->szDescription, "WinSock 2.2");
169 lstrcpy(lpWSAData->szSystemStatus, "Running");
170
171 /*
172 * On Winsock 1, the following values are returned.
173 * Taken straight from a Winsock Test app on Windows.
174 */
175 if (LOBYTE(wVersionRequested) == 1)
176 {
177 lpWSAData->iMaxSockets = 32767;
178 lpWSAData->iMaxUdpDg = 65467;
179 }
180 else
181 {
182 lpWSAData->iMaxSockets = 0;
183 lpWSAData->iMaxUdpDg = 0;
184 }
185
186 /* Enter the startup syncronization lock */
187 WsStartupLock();
188
189 /* Now setup all our objects */
190 while (TRUE)
191 {
192 /* Make sure we don't already have a process */
193 CurrentProcess = WsGetProcess();
194 if (CurrentProcess) break;
195
196 /* Setup the process object support */
197 ErrorCode = WsProcStartup();
198 if (ErrorCode != ERROR_SUCCESS) break;
199
200 /* Setup the process object support */
201 ErrorCode = WsSockStartup();
202 if (ErrorCode != ERROR_SUCCESS) break;
203
204 /* Setup the process object support */
205 ErrorCode = WsThreadStartup();
206 if (ErrorCode != ERROR_SUCCESS) break;
207
208 /* Try getting the process now */
209 CurrentProcess = WsGetProcess();
210 if (!CurrentProcess)
211 {
212 /* Something is weird... */
213 ErrorCode = WSASYSNOTREADY;
214 break;
215 }
216 }
217
218 /* Check if all worked */
219 if (ErrorCode == ERROR_SUCCESS)
220 {
221 /* Set the requested version */
222 WsProcSetVersion(CurrentProcess, wVersionRequested);
223
224 /* Increase the reference count */
225 InterlockedIncrement(&CurrentProcess->RefCount);
226 }
227
228 /* Leave the startup lock */
229 WsStartupUnlock();
230
231 /* Return any Error */
232 return ErrorCode;
233 }