@@ -167,12 +167,11 @@ GetTdiTypeId(
167167 switch (Level )
168168 {
169169 case SOL_SOCKET :
170- * TdiType = INFO_TYPE_ADDRESS_OBJECT ;
170+ * TdiType = INFO_TYPE_CONNECTION ;
171171 switch (OptionName )
172172 {
173173 case SO_KEEPALIVE :
174- /* FIXME: Return proper option */
175- ASSERT (FALSE);
174+ * TdiId = TCP_SOCKET_KEEPALIVE ;
176175 break ;
177176 default :
178177 break ;
@@ -352,6 +351,9 @@ WSHIoctl(
352351 OUT LPBOOL NeedsCompletion )
353352{
354353 INT res ;
354+ PSOCKET_CONTEXT Context = HelperDllSocketContext ;
355+ PTCP_REQUEST_SET_INFORMATION_EX Info ;
356+ PQUEUED_REQUEST Queued , NextQueued ;
355357
356358 if (IoControlCode == SIO_GET_INTERFACE_LIST )
357359 {
@@ -362,6 +364,67 @@ WSHIoctl(
362364 NeedsCompletion );
363365 return res ;
364366 }
367+ else if (IoControlCode == SIO_KEEPALIVE_VALS )
368+ {
369+ if (!InputBuffer || InputBufferLength != sizeof (struct tcp_keepalive ))
370+ {
371+ return WSAEINVAL ;
372+ }
373+
374+ Info = HeapAlloc (GetProcessHeap (), 0 , sizeof (* Info ) + InputBufferLength );
375+ if (!Info )
376+ return WSAENOBUFS ;
377+
378+ Info -> ID .toi_entity .tei_entity = Context -> AddrFileEntityType ;
379+ Info -> ID .toi_entity .tei_instance = Context -> AddrFileInstance ;
380+ Info -> ID .toi_class = INFO_CLASS_PROTOCOL ;
381+ Info -> ID .toi_type = INFO_TYPE_CONNECTION ;
382+ Info -> ID .toi_id = TCP_SOCKET_KEEPALIVEVALS ;
383+ Info -> BufferSize = InputBufferLength ;
384+ memcpy (Info -> Buffer , InputBuffer , InputBufferLength );
385+
386+ if (Context -> SocketState == SocketStateCreated )
387+ {
388+ if (Context -> RequestQueue )
389+ {
390+ Queued = Context -> RequestQueue ;
391+ while ((NextQueued = Queued -> Next ))
392+ {
393+ Queued = NextQueued ;
394+ }
395+
396+ Queued -> Next = HeapAlloc (GetProcessHeap (), 0 , sizeof (QUEUED_REQUEST ));
397+ if (!Queued -> Next )
398+ {
399+ HeapFree (GetProcessHeap (), 0 , Info );
400+ return WSAENOBUFS ;
401+ }
402+
403+ NextQueued = Queued -> Next ;
404+ NextQueued -> Next = NULL ;
405+ NextQueued -> Info = Info ;
406+ }
407+ else
408+ {
409+ Context -> RequestQueue = HeapAlloc (GetProcessHeap (), 0 , sizeof (QUEUED_REQUEST ));
410+ if (!Context -> RequestQueue )
411+ {
412+ HeapFree (GetProcessHeap (), 0 , Info );
413+ return WSAENOBUFS ;
414+ }
415+
416+ Context -> RequestQueue -> Next = NULL ;
417+ Context -> RequestQueue -> Info = Info ;
418+ }
419+
420+ return 0 ;
421+ }
422+
423+ res = SendRequest (Info , sizeof (* Info ) + Info -> BufferSize , IOCTL_TCP_SET_INFORMATION_EX );
424+
425+ HeapFree (GetProcessHeap (), 0 , Info );
426+ return res ;
427+ }
365428
366429 UNIMPLEMENTED ;
367430
@@ -690,9 +753,11 @@ WSHSetSocketInformation(
690753 return 0 ;
691754
692755 case SO_KEEPALIVE :
693- /* FIXME -- We'll send this to TCPIP */
694- DPRINT1 ("Set: SO_KEEPALIVE not yet supported\n" );
695- return 0 ;
756+ if (OptionLength < sizeof (DWORD ))
757+ {
758+ return WSAEFAULT ;
759+ }
760+ break ;
696761
697762 default :
698763 /* Invalid option */
0 commit comments