2020-09-30 17:17:25 +02:00

142 lines
2.5 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
socket.c
Abstract:
Implement the following Winsock APIs:
socket
closesocket
shutdown
Revision History:
06/01/2000 davidx
Created it.
--*/
#include "precomp.h"
SOCKET WSAAPI
socket(
IN int af,
IN int type,
IN int protocol
)
/*++
Routine Description:
Refer to XAPI SDK documentation.
--*/
{
const WSAPROTOCOL_INFOW* protoinfo;
PCB* pcb;
WinsockApiProlog_(socket, INVALID_SOCKET);
err = MatchTcpipProtocol(af, type, protocol, &protoinfo);
WinsockApiCheckError_(INVALID_SOCKET);
if (type == 0) type = protoinfo->iSocketType;
if (protocol == 0) protocol = protoinfo->iProtocol;
pcb = PcbCreate(type, protocol, 0);
if (!pcb) {
WinsockApiReturnError_(WSAENOBUFS, INVALID_SOCKET);
}
// Initialize socket information here
pcb->protocolFlags = protoinfo->dwServiceFlags1;
PcbInsertToList(pcb);
return (SOCKET) pcb;
}
int WSAAPI
closesocket(
IN SOCKET s
)
/*++
Routine Description:
Refer to XAPI SDK documentation.
--*/
{
WinsockApiPrologSockLock_(closesocket, SOCKET_ERROR);
err = pcb ? PcbClose(pcb, FALSE) : NETERR_PARAM;
MapNtStatusToWinsockError_(err);
// NOTE: PcbClose will always close the socket.
// So there is no need for us to call SockUnlock here.
WinsockApiCheckError_(SOCKET_ERROR);
return NO_ERROR;
}
int WSAAPI
shutdown(
IN SOCKET s,
IN int how
)
/*++
Routine Description:
Refer to XAPI SDK documentation.
--*/
{
BYTE flags;
WinsockApiPrologSockLock_(shutdown, SOCKET_ERROR);
WinsockApiParamCheck_(
how == SD_SEND ||
how == SD_RECEIVE ||
how == SD_BOTH);
switch (how) {
case SD_SEND:
flags = PCBFLAG_SEND_SHUTDOWN;
break;
case SD_RECEIVE:
flags = PCBFLAG_RECV_SHUTDOWN;
break;
default:
flags = PCBFLAG_SEND_SHUTDOWN|PCBFLAG_RECV_SHUTDOWN;
break;
}
if (IsDgramPcb(pcb)) {
err = PcbShutdownDgram(pcb, flags);
} else {
if (!IsPcbConnected(pcb)) {
WinsockApiGotoExit_(WSAENOTCONN);
}
err = TcbShutdown((TCB*) pcb, flags, TRUE);
}
MapNtStatusToWinsockError_(err);
WinsockApiExitSockUnlock_(NO_ERROR, SOCKET_ERROR);
}