2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 DLL
4 * FILE: include/ws2_32.h
5 * PURPOSE: WinSock 2 DLL header
8 /* INCLUDES ******************************************************************/
12 #include <ndk/iofuncs.h>
16 /* DATA **********************************************************************/
18 typedef struct _WSH_HELPER_CONTEXT
23 } WSH_HELPER_CONTEXT
, *PWAH_HELPER_CONTEXT
;
25 LPFN_WSASEND pWSASend
;
26 LPFN_WSARECV pWSARecv
;
27 LPFN_WSASENDTO pWSASendTo
;
28 LPFN_WSARECVFROM pWSARecvFrom
;
29 LPFN_WSAGETLASTERROR pWSAGetLastError
;
30 LPFN_WSACANCELBLOCKINGCALL pWSACancelBlockingCall
;
31 LPFN_WSASETBLOCKINGHOOK pWSASetBlockingHook
;
33 LPFN_WSASTARTUP pWSAStartup
;
34 LPFN_WSACLEANUP pWSACleanup
;
35 LPFN_GETSOCKOPT pGetSockOpt
;
36 LPFN_WSAIOCTL pWSAIoctl
;
38 #define APCH (HANDLE)'SOR '
40 /* FUNCTIONS *****************************************************************/
44 ApcThread(ULONG_PTR Context
)
51 DoSocketCancel(PVOID Context1
,
55 return STATUS_SUCCESS
;
60 DoSocketRequest(PVOID Context1
,
64 return STATUS_SUCCESS
;
69 ExitThreadApc(ULONG_PTR Context
)
71 PWAH_HELPER_CONTEXT HelperContext
= (PWAH_HELPER_CONTEXT
)Context
;
72 HMODULE DllHandle
= HelperContext
->DllHandle
;
74 /* Close the file handle */
75 CloseHandle(HelperContext
->FileHandle
);
77 /* Free the context */
78 HeapFree(GlobalHeap
, 0, HelperContext
);
80 /* Exit the thread and library */
81 FreeLibraryAndExitThread(DllHandle
, ERROR_SUCCESS
);
86 WahCloseHandleHelper(IN HANDLE HelperHandle
)
89 PWAH_HELPER_CONTEXT Context
= HelperHandle
;
91 /* Enter the prolog, make sure we're initialized */
92 ErrorCode
= WS2HELP_PROLOG();
93 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
95 /* Validate the handle */
96 if (!Context
) return ERROR_INVALID_PARAMETER
;
98 /* Queue an APC to exit the thread */
99 if (QueueUserAPC(ExitThreadApc
, Context
->ThreadHandle
, (ULONG_PTR
)Context
))
102 return ERROR_SUCCESS
;
106 /* We failed somewhere */
107 return ERROR_GEN_FAILURE
;
113 WahCloseSocketHandle(IN HANDLE HelperHandle
,
117 PWAH_HELPER_CONTEXT Context
= HelperHandle
;
119 /* Enter the prolog, make sure we're initialized */
120 ErrorCode
= WS2HELP_PROLOG();
121 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
123 /* Validate the handle */
124 if (!(Context
) || (Socket
== INVALID_SOCKET
) || !(Socket
))
126 /* Invalid handle and/or socket */
127 return ERROR_INVALID_PARAMETER
;
130 /* Just close the handle and return */
131 CloseHandle((HANDLE
)Socket
);
132 return ERROR_SUCCESS
;
137 WahCreateSocketHandle(IN HANDLE HelperHandle
,
142 DWORD Size
= sizeof(OpenType
);
143 DWORD CreateOptions
= 0;
145 OBJECT_ATTRIBUTES ObjectAttributes
;
146 PFILE_FULL_EA_INFORMATION Ea
;
148 CHAR EaBuffer
[sizeof(*Ea
) + sizeof(*EaData
)];
150 IO_STATUS_BLOCK IoStatusBlock
;
151 PWAH_HELPER_CONTEXT Context
= (PWAH_HELPER_CONTEXT
)HelperHandle
;
153 /* Enter the prolog, make sure we're initialized */
154 ErrorCode
= WS2HELP_PROLOG();
155 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
157 /* Validate the handle and pointer */
158 if (!(Context
) || !(Socket
))
160 /* Invalid handle and/or socket */
161 return ERROR_INVALID_PARAMETER
;
164 /* Set pointer to EA */
165 Ea
= (PFILE_FULL_EA_INFORMATION
)EaBuffer
;
167 /* Get the open type to determine the create options */
168 if ((pGetSockOpt(INVALID_SOCKET
,
172 (INT FAR
*)&Size
) == ERROR_SUCCESS
) && (OpenType
))
174 /* This is a sync open */
175 CreateOptions
= FILE_SYNCHRONOUS_IO_NONALERT
;
178 /* Initialize the attributes for the driver */
179 RtlInitUnicodeString(&Name
, L
"\\Device\\WS2IFSL\\NifsSct");
180 InitializeObjectAttributes(&ObjectAttributes
,
187 Ea
->NextEntryOffset
= 0;
189 Ea
->EaNameLength
= sizeof("NifsSct");
190 Ea
->EaValueLength
= sizeof(*EaData
);
191 RtlCopyMemory(Ea
->EaName
, "NifsSct", Ea
->EaNameLength
);
193 /* Get our EA data */
194 EaData
= (PWAH_EA_DATA
)(Ea
+ 1);
196 /* Write the EA Data */
197 EaData
->FileHandle
= Context
->FileHandle
;
198 EaData
->Context
= NULL
;
200 /* Call the driver */
201 Status
= NtCreateFile((PHANDLE
)Socket
,
206 FILE_ATTRIBUTE_NORMAL
,
211 sizeof(*Ea
) + sizeof(*EaData
));
213 /* Check for success */
214 if (NT_SUCCESS(Status
))
216 /* Write the socket handle */
217 EaData
->Context
=(HANDLE
)*Socket
;
219 /* Tell the driver about it */
220 if (DeviceIoControl((HANDLE
)*Socket
,
221 IOCTL_WS2IFSL_SET_HANDLE
,
230 ErrorCode
= NO_ERROR
;
234 /* We failed. Get the error and close the socket */
235 ErrorCode
= GetLastError();
236 CloseHandle((HANDLE
)*Socket
);
242 /* Create file failed, conver error code */
243 ErrorCode
= RtlNtStatusToDosError(Status
);
246 /* Return to caller */
252 WahDisableNonIFSHandleSupport(VOID
)
255 SC_HANDLE ServiceMgrHandle
, Ws2IfsHandle
;
257 /* Enter the prolog, make sure we're initialized */
258 ErrorCode
= WS2HELP_PROLOG();
259 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
261 /* Open the service DB */
262 ServiceMgrHandle
= OpenSCManager(NULL
,
263 SERVICES_ACTIVE_DATABASE
,
264 SC_MANAGER_CREATE_SERVICE
);
265 if (!ServiceMgrHandle
) return GetLastError();
267 /* Open the service */
268 Ws2IfsHandle
= OpenService(ServiceMgrHandle
, "WS2IFSL", SERVICE_ALL_ACCESS
);
270 /* Disable the servce */
271 ChangeServiceConfig(Ws2IfsHandle
,
283 /* Close the handles and return */
284 CloseServiceHandle(ServiceMgrHandle
);
285 CloseServiceHandle(Ws2IfsHandle
);
286 return ERROR_SUCCESS
;
291 WahEnableNonIFSHandleSupport(VOID
)
298 WahOpenHandleHelper(OUT PHANDLE HelperHandle
)
303 OBJECT_ATTRIBUTES ObjectAttributes
;
304 PFILE_FULL_EA_INFORMATION Ea
;
305 PWAH_EA_DATA2 EaData
;
306 CHAR EaBuffer
[sizeof(*Ea
) + sizeof(*EaData
)];
308 IO_STATUS_BLOCK IoStatusBlock
;
310 PWAH_HELPER_CONTEXT Context
;
312 /* Enter the prolog, make sure we're initialized */
313 ErrorCode
= WS2HELP_PROLOG();
314 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
316 /* Validate the pointer */
319 /* Invalid handle and/or socket */
320 return ERROR_INVALID_PARAMETER
;
323 /* Get ws2_32.dll's handle. We don't load it: it MUST be here */
324 hWs2_32
= GetModuleHandle ("WS2_32.DLL");
325 if (!hWs2_32
) return WSASYSCALLFAILURE
;
327 /* Dynamically load all its APIs */
328 if (!((pGetSockOpt
= (LPFN_GETSOCKOPT
)GetProcAddress(hWs2_32
, "getsockopt"))) ||
329 !((pSelect
= (LPFN_SELECT
)GetProcAddress(hWs2_32
, "select"))) ||
330 !((pWSACancelBlockingCall
= (LPFN_WSACANCELBLOCKINGCALL
)GetProcAddress(hWs2_32
, "WSACancelBlockingCall"))) ||
331 !((pWSACleanup
= (LPFN_WSACLEANUP
)GetProcAddress(hWs2_32
, "WSACleanup"))) ||
332 !((pWSAGetLastError
= (LPFN_WSAGETLASTERROR
)GetProcAddress(hWs2_32
, "WSAGetLastError"))) ||
333 !((pWSASetBlockingHook
= (LPFN_WSASETBLOCKINGHOOK
)GetProcAddress(hWs2_32
, "WSASetBlockingHook"))) ||
334 !((pWSARecv
= (LPFN_WSARECV
)GetProcAddress(hWs2_32
, "WSARecv"))) ||
335 !((pWSASend
= (LPFN_WSASEND
)GetProcAddress(hWs2_32
, "WSASend"))) ||
336 !((pWSASendTo
= (LPFN_WSASENDTO
)GetProcAddress(hWs2_32
, "WSASendTo"))) ||
337 !((pWSAStartup
= (LPFN_WSASTARTUP
)GetProcAddress(hWs2_32
, "WSAStartup"))) ||
338 !((pWSARecvFrom
= (LPFN_WSARECVFROM
)GetProcAddress(hWs2_32
, "WSARecvFrom"))) ||
339 !((pWSAIoctl
= (LPFN_WSAIOCTL
)GetProcAddress(hWs2_32
, "WSAIoctl"))))
341 /* Uh, guess we failed somewhere */
342 return WSASYSCALLFAILURE
;
345 /* Set pointer EA structure */
346 Ea
= (PFILE_FULL_EA_INFORMATION
)EaBuffer
;
348 /* Create the helper context */
349 Context
= HeapAlloc(GlobalHeap
, 0, sizeof(WSH_HELPER_CONTEXT
));
352 /* Create the special request thread */
353 Context
->ThreadHandle
= CreateThread(NULL
,
359 if (Context
->ThreadHandle
)
361 /* Create the attributes for the driver open */
362 RtlInitUnicodeString(&Name
, L
"\\Device\\WS2IFSL\\NifsPvd");
363 InitializeObjectAttributes(&ObjectAttributes
,
370 Ea
->NextEntryOffset
= 0;
372 Ea
->EaNameLength
= sizeof("NifsPvd");
373 Ea
->EaValueLength
= sizeof(*EaData
);
374 RtlCopyMemory(Ea
->EaName
, "NifsPvd", Ea
->EaNameLength
);
376 /* Get our EA data */
377 EaData
= (PWAH_EA_DATA2
)(Ea
+ 1);
379 /* Fill out the EA Data */
380 EaData
->ThreadHandle
= Context
->ThreadHandle
;
381 EaData
->RequestRoutine
= DoSocketRequest
;
382 EaData
->CancelRoutine
= DoSocketCancel
;
383 EaData
->ApcContext
= Context
;
384 EaData
->Reserved
= 0;
386 /* Call the driver */
387 Status
= NtCreateFile(&Context
->FileHandle
,
392 FILE_ATTRIBUTE_NORMAL
,
397 sizeof(*Ea
) + sizeof(*EaData
));
399 /* Check for success */
400 if (NT_SUCCESS(Status
))
402 /* Resume the thread and return a handle to the context */
403 ResumeThread(Context
->ThreadHandle
);
404 *HelperHandle
= (HANDLE
)Context
;
405 return ERROR_SUCCESS
;
409 /* Get the error code */
410 ErrorCode
= RtlNtStatusToDosError(Status
);
413 /* We failed, mark us as such */
414 Context
->FileHandle
= NULL
;
415 ResumeThread(Context
->ThreadHandle
);
419 /* Get the error code */
420 ErrorCode
= GetLastError();
423 /* If we got here, we failed, so free the context */
424 HeapFree(GlobalHeap
, 0, Context
);
428 /* Get the errror code */
429 ErrorCode
= GetLastError();
432 /* Return to caller */
438 WahCompleteRequest(IN HANDLE HelperHandle
,
440 IN LPWSAOVERLAPPED lpOverlapped
,
442 IN DWORD BytesTransferred
)
444 UNREFERENCED_PARAMETER(HelperHandle
);
445 UNREFERENCED_PARAMETER(Socket
);
446 UNREFERENCED_PARAMETER(lpOverlapped
);
447 UNREFERENCED_PARAMETER(ErrorCode
);
448 UNREFERENCED_PARAMETER(BytesTransferred
);
449 return ERROR_SUCCESS
;