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 /* DATA **********************************************************************/
14 typedef struct _WSH_HELPER_CONTEXT
19 } WSH_HELPER_CONTEXT
, *PWAH_HELPER_CONTEXT
;
21 LPFN_WSASEND pWSASend
;
22 LPFN_WSARECV pWSARecv
;
23 LPFN_WSASENDTO pWSASendTo
;
24 LPFN_WSARECVFROM pWSARecvFrom
;
25 LPFN_WSAGETLASTERROR pWSAGetLastError
;
26 LPFN_WSACANCELBLOCKINGCALL pWSACancelBlockingCall
;
27 LPFN_WSASETBLOCKINGHOOK pWSASetBlockingHook
;
29 LPFN_WSASTARTUP pWSAStartup
;
30 LPFN_WSACLEANUP pWSACleanup
;
31 LPFN_GETSOCKOPT pGetSockOpt
;
32 LPFN_WSAIOCTL pWSAIoctl
;
34 #define APCH (HANDLE)'SOR '
36 /* FUNCTIONS *****************************************************************/
40 ApcThread(ULONG_PTR Context
)
47 DoSocketCancel(PVOID Context1
,
51 return STATUS_SUCCESS
;
56 DoSocketRequest(PVOID Context1
,
60 return STATUS_SUCCESS
;
65 ExitThreadApc(ULONG_PTR Context
)
67 PWAH_HELPER_CONTEXT HelperContext
= (PWAH_HELPER_CONTEXT
)Context
;
68 HMODULE DllHandle
= HelperContext
->DllHandle
;
70 /* Close the file handle */
71 CloseHandle(HelperContext
->FileHandle
);
73 /* Free the context */
74 HeapFree(GlobalHeap
, 0, HelperContext
);
76 /* Exit the thread and library */
77 FreeLibraryAndExitThread(DllHandle
, ERROR_SUCCESS
);
82 WahCloseHandleHelper(IN HANDLE HelperHandle
)
85 PWAH_HELPER_CONTEXT Context
= HelperHandle
;
87 /* Enter the prolog, make sure we're initialized */
88 ErrorCode
= WS2HELP_PROLOG();
89 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
91 /* Validate the handle */
92 if (!Context
) return ERROR_INVALID_PARAMETER
;
94 /* Queue an APC to exit the thread */
95 if (QueueUserAPC(ExitThreadApc
, Context
->ThreadHandle
, (ULONG_PTR
)Context
))
102 /* We failed somewhere */
103 return ERROR_GEN_FAILURE
;
109 WahCloseSocketHandle(IN HANDLE HelperHandle
,
113 PWAH_HELPER_CONTEXT Context
= HelperHandle
;
115 /* Enter the prolog, make sure we're initialized */
116 ErrorCode
= WS2HELP_PROLOG();
117 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
119 /* Validate the handle */
120 if (!(Context
) || (Socket
== INVALID_SOCKET
) || !(Socket
))
122 /* Invalid handle and/or socket */
123 return ERROR_INVALID_PARAMETER
;
126 /* Just close the handle and return */
127 CloseHandle((HANDLE
)Socket
);
128 return ERROR_SUCCESS
;
133 WahCreateSocketHandle(IN HANDLE HelperHandle
,
138 DWORD Size
= sizeof(OpenType
);
139 DWORD CreateOptions
= 0;
141 OBJECT_ATTRIBUTES ObjectAttributes
;
142 PFILE_FULL_EA_INFORMATION Ea
;
144 CHAR EaBuffer
[sizeof(*Ea
) + sizeof(*EaData
)];
146 IO_STATUS_BLOCK IoStatusBlock
;
147 PWAH_HELPER_CONTEXT Context
= (PWAH_HELPER_CONTEXT
)HelperHandle
;
149 /* Enter the prolog, make sure we're initialized */
150 ErrorCode
= WS2HELP_PROLOG();
151 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
153 /* Validate the handle and pointer */
154 if (!(Context
) || !(Socket
))
156 /* Invalid handle and/or socket */
157 return ERROR_INVALID_PARAMETER
;
160 /* Set pointer to EA */
161 Ea
= (PFILE_FULL_EA_INFORMATION
)EaBuffer
;
163 /* Get the open type to determine the create options */
164 if ((pGetSockOpt(INVALID_SOCKET
,
168 (INT FAR
*)&Size
) == ERROR_SUCCESS
) && (OpenType
))
170 /* This is a sync open */
171 CreateOptions
= FILE_SYNCHRONOUS_IO_NONALERT
;
174 /* Initialize the attributes for the driver */
175 RtlInitUnicodeString(&Name
, L
"\\Device\\WS2IFSL\\NifsSct");
176 InitializeObjectAttributes(&ObjectAttributes
,
183 Ea
->NextEntryOffset
= 0;
185 Ea
->EaNameLength
= sizeof("NifsSct");
186 Ea
->EaValueLength
= sizeof(*EaData
);
187 RtlCopyMemory(Ea
->EaName
, "NifsSct", Ea
->EaNameLength
);
189 /* Get our EA data */
190 EaData
= (PWAH_EA_DATA
)(Ea
+ 1);
192 /* Write the EA Data */
193 EaData
->FileHandle
= Context
->FileHandle
;
194 EaData
->Context
= NULL
;
196 /* Call the driver */
197 Status
= NtCreateFile((PHANDLE
)Socket
,
202 FILE_ATTRIBUTE_NORMAL
,
207 sizeof(*Ea
) + sizeof(*EaData
));
209 /* Check for success */
210 if (NT_SUCCESS(Status
))
212 /* Write the socket handle */
213 EaData
->Context
=(HANDLE
)*Socket
;
215 /* Tell the driver about it */
216 if (DeviceIoControl((HANDLE
)*Socket
,
217 IOCTL_WS2IFSL_SET_HANDLE
,
226 ErrorCode
= NO_ERROR
;
230 /* We failed. Get the error and close the socket */
231 ErrorCode
= GetLastError();
232 CloseHandle((HANDLE
)*Socket
);
238 /* Create file failed, conver error code */
239 ErrorCode
= RtlNtStatusToDosError(Status
);
242 /* Return to caller */
248 WahDisableNonIFSHandleSupport(VOID
)
251 SC_HANDLE ServiceMgrHandle
, Ws2IfsHandle
;
253 /* Enter the prolog, make sure we're initialized */
254 ErrorCode
= WS2HELP_PROLOG();
255 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
257 /* Open the service DB */
258 ServiceMgrHandle
= OpenSCManager(NULL
,
259 SERVICES_ACTIVE_DATABASE
,
260 SC_MANAGER_CREATE_SERVICE
);
261 if (!ServiceMgrHandle
) return GetLastError();
263 /* Open the service */
264 Ws2IfsHandle
= OpenService(ServiceMgrHandle
, "WS2IFSL", SERVICE_ALL_ACCESS
);
266 /* Disable the servce */
267 ChangeServiceConfig(Ws2IfsHandle
,
279 /* Close the handles and return */
280 CloseServiceHandle(ServiceMgrHandle
);
281 CloseServiceHandle(Ws2IfsHandle
);
282 return ERROR_SUCCESS
;
287 WahEnableNonIFSHandleSupport(VOID
)
294 WahOpenHandleHelper(OUT PHANDLE HelperHandle
)
299 OBJECT_ATTRIBUTES ObjectAttributes
;
300 PFILE_FULL_EA_INFORMATION Ea
;
301 PWAH_EA_DATA2 EaData
;
302 CHAR EaBuffer
[sizeof(*Ea
) + sizeof(*EaData
)];
304 IO_STATUS_BLOCK IoStatusBlock
;
306 PWAH_HELPER_CONTEXT Context
;
308 /* Enter the prolog, make sure we're initialized */
309 ErrorCode
= WS2HELP_PROLOG();
310 if (ErrorCode
!= ERROR_SUCCESS
) return ErrorCode
;
312 /* Validate the pointer */
315 /* Invalid handle and/or socket */
316 return ERROR_INVALID_PARAMETER
;
319 /* Get ws2_32.dll's handle. We don't load it: it MUST be here */
320 hWs2_32
= GetModuleHandle ("WS2_32.DLL");
321 if (!hWs2_32
) return WSASYSCALLFAILURE
;
323 /* Dynamically load all its APIs */
324 if (!((pGetSockOpt
= (LPFN_GETSOCKOPT
)GetProcAddress(hWs2_32
, "getsockopt"))) ||
325 !((pSelect
= (LPFN_SELECT
)GetProcAddress(hWs2_32
, "select"))) ||
326 !((pWSACancelBlockingCall
= (LPFN_WSACANCELBLOCKINGCALL
)GetProcAddress(hWs2_32
, "WSACancelBlockingCall"))) ||
327 !((pWSACleanup
= (LPFN_WSACLEANUP
)GetProcAddress(hWs2_32
, "WSACleanup"))) ||
328 !((pWSAGetLastError
= (LPFN_WSAGETLASTERROR
)GetProcAddress(hWs2_32
, "WSAGetLastError"))) ||
329 !((pWSASetBlockingHook
= (LPFN_WSASETBLOCKINGHOOK
)GetProcAddress(hWs2_32
, "WSASetBlockingHook"))) ||
330 !((pWSARecv
= (LPFN_WSARECV
)GetProcAddress(hWs2_32
, "WSARecv"))) ||
331 !((pWSASend
= (LPFN_WSASEND
)GetProcAddress(hWs2_32
, "WSASend"))) ||
332 !((pWSASendTo
= (LPFN_WSASENDTO
)GetProcAddress(hWs2_32
, "WSASendTo"))) ||
333 !((pWSAStartup
= (LPFN_WSASTARTUP
)GetProcAddress(hWs2_32
, "WSAStartup"))) ||
334 !((pWSARecvFrom
= (LPFN_WSARECVFROM
)GetProcAddress(hWs2_32
, "WSARecvFrom"))) ||
335 !((pWSAIoctl
= (LPFN_WSAIOCTL
)GetProcAddress(hWs2_32
, "WSAIoctl"))))
337 /* Uh, guess we failed somewhere */
338 return WSASYSCALLFAILURE
;
341 /* Set pointer EA structure */
342 Ea
= (PFILE_FULL_EA_INFORMATION
)EaBuffer
;
344 /* Create the helper context */
345 Context
= HeapAlloc(GlobalHeap
, 0, sizeof(WSH_HELPER_CONTEXT
));
348 /* Create the special request thread */
349 Context
->ThreadHandle
= CreateThread(NULL
,
355 if (Context
->ThreadHandle
)
357 /* Create the attributes for the driver open */
358 RtlInitUnicodeString(&Name
, L
"\\Device\\WS2IFSL\\NifsPvd");
359 InitializeObjectAttributes(&ObjectAttributes
,
366 Ea
->NextEntryOffset
= 0;
368 Ea
->EaNameLength
= sizeof("NifsPvd");
369 Ea
->EaValueLength
= sizeof(*EaData
);
370 RtlCopyMemory(Ea
->EaName
, "NifsPvd", Ea
->EaNameLength
);
372 /* Get our EA data */
373 EaData
= (PWAH_EA_DATA2
)(Ea
+ 1);
375 /* Fill out the EA Data */
376 EaData
->ThreadHandle
= Context
->ThreadHandle
;
377 EaData
->RequestRoutine
= DoSocketRequest
;
378 EaData
->CancelRoutine
= DoSocketCancel
;
379 EaData
->ApcContext
= Context
;
380 EaData
->Reserved
= 0;
382 /* Call the driver */
383 Status
= NtCreateFile(&Context
->FileHandle
,
388 FILE_ATTRIBUTE_NORMAL
,
393 sizeof(*Ea
) + sizeof(*EaData
));
395 /* Check for success */
396 if (NT_SUCCESS(Status
))
398 /* Resume the thread and return a handle to the context */
399 ResumeThread(Context
->ThreadHandle
);
400 *HelperHandle
= (HANDLE
)Context
;
401 return ERROR_SUCCESS
;
405 /* Get the error code */
406 ErrorCode
= RtlNtStatusToDosError(Status
);
409 /* We failed, mark us as such */
410 Context
->FileHandle
= NULL
;
411 ResumeThread(Context
->ThreadHandle
);
415 /* Get the error code */
416 ErrorCode
= GetLastError();
419 /* If we got here, we failed, so free the context */
420 HeapFree(GlobalHeap
, 0, Context
);
424 /* Get the errror code */
425 ErrorCode
= GetLastError();
428 /* Return to caller */
434 WahCompleteRequest(IN HANDLE HelperHandle
,
436 IN LPWSAOVERLAPPED lpOverlapped
,
438 IN DWORD BytesTransferred
)
440 UNREFERENCED_PARAMETER(HelperHandle
);
441 UNREFERENCED_PARAMETER(Socket
);
442 UNREFERENCED_PARAMETER(lpOverlapped
);
443 UNREFERENCED_PARAMETER(ErrorCode
);
444 UNREFERENCED_PARAMETER(BytesTransferred
);
445 return ERROR_SUCCESS
;