- Implement LibTCPShutdown
[IP]
- Replace an incredibly broken implementation of TCPDisconnect which caused memory corruption with a working one using LibTCPShutdown

svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52200
This commit is contained in:
Cameron Gutman 2011-06-12 18:25:16 +00:00
parent b3b5468071
commit ade9312f85
3 changed files with 71 additions and 7 deletions

View file

@ -316,19 +316,15 @@ NTSTATUS TCPDisconnect
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);

View file

@ -18,6 +18,7 @@ err_t LibTCPBind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port);
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);

View file

@ -517,6 +517,73 @@ LibTCPConnect(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 */