if (Flags & TDI_DISCONNECT_RELEASE)
{
- /* FIXME */
- LibTCPClose(Connection->SocketContext);
+ Status = LibTCPShutdown(Connection->SocketContext, 0, 1);
}
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
{
- /* FIXME */
- LibTCPClose(Connection->SocketContext);
+ Status = LibTCPShutdown(Connection->SocketContext, 1, 1);
}
- Status = STATUS_SUCCESS;
-
- DbgPrint("LibTCPClose: %x\n", Status);
+ DbgPrint("LibTCPShutdown: %x\n", Status);
UnlockObject(Connection, OldIrql);
struct tcp_pcb *LibTCPListen(struct tcp_pcb *pcb, u8_t backlog);
err_t LibTCPSend(struct tcp_pcb *pcb, void *dataptr, u16_t len);
err_t LibTCPConnect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port);
+err_t LibTCPShutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx);
err_t LibTCPClose(struct tcp_pcb *pcb);
err_t LibTCPGetPeerName(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t *port);
err_t LibTCPGetHostName(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t *port);
return ERR_MEM;
}
+struct shutdown_callback_msg
+{
+ /* Synchronization */
+ KEVENT Event;
+
+ /* Input */
+ struct tcp_pcb *Pcb;
+ int shut_rx;
+ int shut_tx;
+
+ /* Output */
+ err_t Error;
+};
+
+static
+void
+LibTCPShutdownCallback(void *arg)
+{
+ struct shutdown_callback_msg *msg = arg;
+
+ msg->Error = tcp_shutdown(msg->Pcb, msg->shut_rx, msg->shut_tx);
+
+ KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
+}
+
+err_t
+LibTCPShutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
+{
+ struct shutdown_callback_msg *msg;
+ err_t ret;
+
+ DbgPrint("[lwIP, LibTCPShutdown] Called\n");
+
+ if (!pcb)
+ {
+ DbgPrint("[lwIP, LibTCPShutdown] Done... NO pcb\n");
+ return ERR_CLSD;
+ }
+
+ msg = ExAllocatePool(NonPagedPool, sizeof(struct shutdown_callback_msg));
+ if (msg)
+ {
+ KeInitializeEvent(&msg->Event, NotificationEvent, FALSE);
+
+ msg->Pcb = pcb;
+ msg->shut_rx = shut_rx;
+ msg->shut_tx = shut_tx;
+
+ tcpip_callback_with_block(LibTCPShutdownCallback, msg, 1);
+
+ if (WaitForEventSafely(&msg->Event))
+ ret = msg->Error;
+ else
+ ret = ERR_CLSD;
+
+ ExFreePool(msg);
+
+ DbgPrint("[lwIP, LibTCPShutdown] pcb = 0x%x\n", pcb);
+
+ DbgPrint("[lwIP, LibTCPShutdown] Done\n");
+
+ return ret;
+ }
+
+ return ERR_MEM;
+}
+
struct close_callback_msg
{
/* Synchronization */