mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
879 lines
18 KiB
879 lines
18 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
winsock.c
|
|
|
|
Abstract:
|
|
|
|
Common code for winsock-based datagram transports.
|
|
|
|
Author:
|
|
|
|
Dave Steckler (davidst) 15-Mar-1993
|
|
|
|
Revision History:
|
|
|
|
Jeff Roberts (jroberts) 02-Dec-1994
|
|
|
|
Separated the protocol-independent parts from the UDP- and
|
|
IPX-specific parts.
|
|
|
|
--*/
|
|
#include <stdlib.h>
|
|
|
|
#include <sysinc.h>
|
|
#include <rpc.h>
|
|
#include <rpcdcep.h>
|
|
#include <rpcerrp.h>
|
|
#include <rpctran.h>
|
|
#include <winsock.h>
|
|
|
|
#define MAX_PACKET_SIZE (1024)
|
|
|
|
struct ENDPOINT_INFO
|
|
{
|
|
SOCKET Socket;
|
|
unsigned Timeout;
|
|
};
|
|
|
|
//
|
|
// The protocol-specific file should define these fns.
|
|
//
|
|
RPC_STATUS RPC_ENTRY
|
|
RegisterEndpoint(
|
|
IN void * pServerAddress,
|
|
IN RPC_CHAR * pEndpoint,
|
|
OUT PDG_SERVER_TRANS_ADDRESS * ppTransAddress,
|
|
OUT RPC_CHAR PAPI * NetworkAddress,
|
|
IN unsigned int NetworkAddressLength //CLH 9/19/93
|
|
);
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
DeregisterEndpoint(
|
|
IN OUT PDG_SERVER_TRANS_ADDRESS * pServerTransAddress
|
|
);
|
|
|
|
int
|
|
SetTransportSpecificSocketOptions(
|
|
SOCKET Socket
|
|
);
|
|
|
|
RPC_STATUS
|
|
QueryClientEndpoint
|
|
(
|
|
IN void * pClientEndpoint,
|
|
OUT RPC_CHAR * pClientAddress
|
|
);
|
|
|
|
RPC_STATUS
|
|
CreateServerEndpoint(
|
|
IN char * pEndpoint,
|
|
IN void * pServerAddr
|
|
);
|
|
|
|
//
|
|
// The protocol-specific file can use these fns.
|
|
//
|
|
RPC_STATUS
|
|
MapStatusCode(
|
|
int SocketError,
|
|
RPC_STATUS Default
|
|
);
|
|
|
|
PDG_SERVER_TRANS_ADDRESS
|
|
CreateTransAddress(
|
|
void * pServerAddress,
|
|
RPC_CHAR * pEndpoint,
|
|
RPC_STATUS * pStatus
|
|
);
|
|
|
|
void DeleteTransAddress(
|
|
PDG_SERVER_TRANS_ADDRESS * ppTransAddress
|
|
);
|
|
|
|
|
|
#if defined(IPX)
|
|
|
|
#include <wsipx.h>
|
|
#include <wsnwlink.h>
|
|
#include <nspapi.h>
|
|
|
|
#include "dgipxs.h"
|
|
#include "dgipxs.c"
|
|
|
|
#elif defined(UDP)
|
|
|
|
#include "dgudps.h"
|
|
#include "dgudps.c"
|
|
|
|
#else
|
|
#error "unknown winsock protocol"
|
|
#endif
|
|
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
TransportUnload()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destructor for the server transport.
|
|
|
|
Arguments:
|
|
|
|
<none>
|
|
|
|
Return Value:
|
|
|
|
<none>
|
|
|
|
--*/
|
|
|
|
{
|
|
(void)WSACleanup();
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
ReceivePacket(
|
|
IN void *Address,
|
|
IN PDG_SERVER_TRANS_ADDRESS pTransAddress,
|
|
IN unsigned long LargestPacketSize,
|
|
IN char * pNcaPacketHeader,
|
|
IN unsigned * pDataLength,
|
|
unsigned long Timeout,
|
|
void * pClientEndpoint
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Receives a packet from the transport address the passed packet is
|
|
associated with.
|
|
|
|
Arguments:
|
|
|
|
pTransAddress - Server's transport address information.
|
|
|
|
LargestPacketSize - Size of largest packet we can accept.
|
|
|
|
pNcaPacketHeader - Pointer to buffer to place incoming pkt into.
|
|
|
|
pDataLength - Number of bytes read in.
|
|
|
|
Timeout - Receive timeout in milliseconds.
|
|
|
|
ppClientEndpoint - Pointer to the client address structure.
|
|
|
|
|
|
Return Value:
|
|
|
|
result of recv
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
{
|
|
unsigned SocketError;
|
|
int BytesReceived;
|
|
int FromLen=sizeof(struct sockaddr);
|
|
|
|
struct ENDPOINT_INFO * pInfo = (struct ENDPOINT_INFO *) pTransAddress->pTsap;
|
|
|
|
ADDRESS_TYPE * pSockaddr = (ADDRESS_TYPE *) pClientEndpoint;
|
|
|
|
if (Timeout != pInfo->Timeout)
|
|
{
|
|
pInfo->Timeout = Timeout;
|
|
setsockopt(pInfo->Socket,
|
|
SOL_SOCKET,
|
|
SO_RCVTIMEO,
|
|
(char *) &Timeout,
|
|
sizeof(Timeout)
|
|
);
|
|
//
|
|
// If we can't set the timeout, too bad. We will carry on anyway.
|
|
//
|
|
}
|
|
|
|
//
|
|
// Receive something on our socket.
|
|
//
|
|
BytesReceived = recvfrom(
|
|
pInfo->Socket, // socket
|
|
(char *)pNcaPacketHeader, // buffer
|
|
(int)LargestPacketSize, // buflen
|
|
0, // flags
|
|
(struct sockaddr *) pSockaddr, // where received from
|
|
&FromLen // received from length
|
|
);
|
|
|
|
//
|
|
// Did we get something?
|
|
//
|
|
if ((BytesReceived == SOCKET_ERROR) || (BytesReceived == 0))
|
|
{
|
|
return MapStatusCode(WSAGetLastError(), RPC_P_RECEIVE_FAILED);
|
|
}
|
|
else
|
|
{
|
|
*pDataLength = BytesReceived;
|
|
return RPC_S_OK;
|
|
}
|
|
}
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
RegisterAnyEndpoint(
|
|
IN void * pServerAddress,
|
|
OUT RPC_CHAR * pEndpointName,
|
|
OUT PDG_SERVER_TRANS_ADDRESS * ppServerTransAddress,
|
|
OUT RPC_CHAR PAPI * NetworkAddress,
|
|
IN unsigned int NetworkAddressLength, // CLH 9/19/93
|
|
IN unsigned int EndpointLength // CLH 9/19/93
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Figures out a unique endpoint and creates it.
|
|
|
|
Arguments:
|
|
|
|
pServerAddress - pointer to the DG_ADDRESS object we are associated with.
|
|
(see comments in RegisterEndpoint about why this is 'void *')
|
|
|
|
pEndpointName - Memory of at least MAX_ANY_ENDPOINT_NAME RPC_CHARS
|
|
in length. This will be filled in with the endpoint.
|
|
|
|
ppServerAddress - Where to place the newly created address.
|
|
|
|
NetworkAddress - Network address in string format - ie "11.2.39.56"
|
|
|
|
Return Value:
|
|
|
|
RPC_S_OK
|
|
<any error from RegisterEndpoint>
|
|
|
|
Revision History:
|
|
|
|
Connie Hoppe (CLH) (connieh) 8-Aug-93 Return Network Address
|
|
Connie Hoppe (CLH) (connieh) 17-Sep-93 Return err if addr len too small
|
|
Added NetworkAddresLength and
|
|
Endpointlength to i/f
|
|
15-Feb-94 Fixed to ask for an assigned endpoint
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
RPC_STATUS Status;
|
|
int i = 0;
|
|
|
|
if ( NetworkAddressLength < (2 * (NETADDR_LEN + 1)) )
|
|
return( RPC_P_NETWORK_ADDRESS_TOO_SMALL );
|
|
|
|
|
|
pEndpointName[0] = (RPC_CHAR)(i+'0');
|
|
pEndpointName[1] = '\0';
|
|
|
|
Status = RegisterEndpoint(
|
|
pServerAddress,
|
|
pEndpointName,
|
|
ppServerTransAddress,
|
|
NetworkAddress, //CLH 8/8/93
|
|
NetworkAddressLength //CLH 9/17/93
|
|
);
|
|
|
|
|
|
return Status;
|
|
|
|
|
|
}
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
SendPacketBack(
|
|
IN PDG_SERVER_TRANS_ADDRESS pTransAddress,
|
|
IN char * pNcaPacketHeader,
|
|
IN unsigned DataLength,
|
|
void * pClientEndpoint
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sends a packet back to the client it was received from.
|
|
|
|
Arguments:
|
|
|
|
|
|
pTransAddress - Server's transport address information.
|
|
|
|
pNcaPacketHeader - Pointer to buffer to place incoming pkt into.
|
|
|
|
pDataLength - Number of bytes read in.
|
|
|
|
pClientEndpoint - Pointer to the client address structure in
|
|
sockaddr format.
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
result of send
|
|
|
|
--*/
|
|
|
|
{
|
|
PDG_SERVER_TRANS_ADDRESS pTransportAddress =
|
|
(PDG_SERVER_TRANS_ADDRESS) pTransAddress;
|
|
|
|
unsigned BytesSent;
|
|
struct ENDPOINT_INFO *pInfo = (struct ENDPOINT_INFO *) pTransAddress->pTsap;
|
|
ADDRESS_TYPE * pSockaddr = (ADDRESS_TYPE *) pClientEndpoint;
|
|
|
|
BytesSent = sendto(
|
|
pInfo->Socket, // socket
|
|
pNcaPacketHeader, // buffer
|
|
DataLength, // buflen
|
|
0, // flags
|
|
(struct sockaddr *) pSockaddr, // address
|
|
sizeof(ADDRESS_TYPE) // svr addr size
|
|
);
|
|
|
|
if (BytesSent == DataLength)
|
|
{
|
|
return RPC_S_OK;
|
|
}
|
|
else
|
|
{
|
|
return MapStatusCode(WSAGetLastError(), RPC_P_SEND_FAILED);
|
|
}
|
|
}
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
ForwardPacket(
|
|
IN PDG_SERVER_TRANS_ADDRESS pTransAddress,
|
|
IN char * pNcaPacketHeader,
|
|
IN unsigned long DataLength,
|
|
void * pEndpoint
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sends a packet to the server it was originally destined for (that
|
|
is, the client had a dynamic endpoint it wished the enpoint mapper
|
|
to resolve and forward the packet to).
|
|
|
|
Arguments:
|
|
|
|
|
|
pTransAddress - Server's transport address information.
|
|
|
|
pNcaPacketHeader - Pointer to buffer to place incoming pkt into.
|
|
|
|
pDataLength - Number of bytes read in.
|
|
|
|
pEndpoint - Pointer to the server port num to forward to.
|
|
This is in string format.
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
result of send
|
|
|
|
Revision History:
|
|
Connie Hoppe (CLH) (connieh) 17-Feb-94 Created.
|
|
|
|
--*/
|
|
|
|
{
|
|
// If a transport had specific needs placed into the
|
|
// transport address, it would cast pTransAddress into
|
|
// its own trans address datastructure. UDP has
|
|
// no additional info.
|
|
|
|
PDG_SERVER_TRANS_ADDRESS pTransportAddress =
|
|
(PDG_SERVER_TRANS_ADDRESS) pTransAddress;
|
|
|
|
unsigned BytesSent;
|
|
struct ENDPOINT_INFO * pInfo = (struct ENDPOINT_INFO *) pTransAddress->pTsap;
|
|
ADDRESS_TYPE SockAddr;
|
|
|
|
//Create an endpoint from the enpoint string name.
|
|
|
|
if ((CreateServerEndpoint(((char*) pEndpoint), &SockAddr)) != RPC_S_OK)
|
|
{
|
|
return RPC_S_CANT_CREATE_ENDPOINT;
|
|
}
|
|
|
|
BytesSent = sendto(
|
|
pInfo->Socket, // socket
|
|
pNcaPacketHeader, // buffer
|
|
DataLength, // buflen
|
|
0, // flags
|
|
(struct sockaddr *) &SockAddr, // address
|
|
sizeof(ADDRESS_TYPE) // svr addr size
|
|
);
|
|
|
|
if (BytesSent == DataLength)
|
|
{
|
|
return RPC_S_OK;
|
|
}
|
|
else
|
|
{
|
|
return MapStatusCode(WSAGetLastError(), RPC_P_SEND_FAILED);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RPC_ENTRY
|
|
CloseClientEndpoint(
|
|
IN OUT ADDRESS_TYPE * pHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Deletes a "client handle"
|
|
|
|
Arguments:
|
|
|
|
The handle.
|
|
|
|
Return Value:
|
|
|
|
<none>
|
|
|
|
--*/
|
|
|
|
{
|
|
// nothing to do here on IPX or UDP.
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PDG_SERVER_TRANS_ADDRESS
|
|
CreateTransAddress(
|
|
void * pServerAddress,
|
|
RPC_CHAR * pEndpoint,
|
|
RPC_STATUS * pStatus
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Creates a new endpoint on this server.
|
|
|
|
Arguments:
|
|
|
|
pServerAddress - DG_ADDRESS object this endpoint is associated with. This
|
|
is a 'void *' instead of a PDG_ADDRESS because we don't want to include
|
|
or link in all the garbage associated with PDG_ADDRESS.
|
|
|
|
pEndpoint - Name of the endpoint to create.
|
|
|
|
pStatus - Where to place the output status.
|
|
RPC_S_OK
|
|
RPC_S_INVALID_ENDPOINT_FORMAT
|
|
|
|
Return Value:
|
|
|
|
<none>
|
|
|
|
Revision History:
|
|
Connie Hoppe (CLH) (connieh) 15-Feb-94 Fixed to return Endpoint.
|
|
--*/
|
|
|
|
{
|
|
|
|
long Endpoint;
|
|
int EndpointLength;
|
|
int i;
|
|
int SockStatus;
|
|
int Socket;
|
|
int PacketType;
|
|
PDG_SERVER_TRANS_ADDRESS pTransAddress;
|
|
|
|
int length;
|
|
SOCKET PortUsed;
|
|
char PortAscii[10];
|
|
UNICODE_STRING UnicodePortNum;
|
|
ANSI_STRING AsciiPortNum;
|
|
ADDRESS_TYPE ReceiveAddr;
|
|
struct ENDPOINT_INFO * pInfo;
|
|
int NewSize = 0x40000;
|
|
|
|
//
|
|
// Convert the endpoint to a number.
|
|
//
|
|
EndpointLength = RpcpStringLength(pEndpoint);
|
|
|
|
for (i=0, Endpoint=0 ; i< EndpointLength ; i++)
|
|
{
|
|
if ( ((char)pEndpoint[i] >= '0') && ((char)pEndpoint[i] <= '9'))
|
|
{
|
|
Endpoint *= 10;
|
|
Endpoint += (char)pEndpoint[i]-'0';
|
|
|
|
// Watch out for overflow.
|
|
if (Endpoint > 0x10000)
|
|
{
|
|
*pStatus = RPC_S_INVALID_ENDPOINT_FORMAT;
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*pStatus = RPC_S_INVALID_ENDPOINT_FORMAT;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create a socket.
|
|
//
|
|
Socket = socket(ADDRESS_FAMILY, SOCK_DGRAM, PROTOCOL);
|
|
if (Socket == INVALID_SOCKET)
|
|
{
|
|
*pStatus = RPC_S_CANT_CREATE_ENDPOINT;
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Set transport-variable options.
|
|
//
|
|
SockStatus = SetTransportSpecificSocketOptions(Socket);
|
|
if (NO_ERROR != SockStatus)
|
|
{
|
|
closesocket(Socket);
|
|
*pStatus = MapStatusCode(SockStatus, RPC_S_INTERNAL_ERROR);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// set socket recv buffer size..
|
|
//
|
|
|
|
SockStatus = setsockopt(Socket,
|
|
SOL_SOCKET,
|
|
SO_RCVBUF,
|
|
(char *) &NewSize,
|
|
sizeof(NewSize)
|
|
);
|
|
|
|
//
|
|
// Create a binding to that socket.
|
|
//
|
|
InitLocalAddress(ReceiveAddr, (unsigned short) Endpoint);
|
|
|
|
//Bind the socket to the port number.
|
|
SockStatus = bind(
|
|
Socket,
|
|
(struct sockaddr *)&ReceiveAddr,
|
|
sizeof(ReceiveAddr)
|
|
);
|
|
|
|
if (SockStatus == SOCKET_ERROR)
|
|
{
|
|
SockStatus = WSAGetLastError();
|
|
|
|
switch (SockStatus)
|
|
{
|
|
case WSAEADDRINUSE:
|
|
{
|
|
*pStatus= RPC_S_DUPLICATE_ENDPOINT;
|
|
break;
|
|
}
|
|
|
|
case WSAENOBUFS:
|
|
{
|
|
*pStatus= RPC_S_OUT_OF_MEMORY;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
#ifdef DEBUGRPC
|
|
DbgPrint("RPC DG: surprising error 0x%lx (%lu) from bind()\n",
|
|
SockStatus, SockStatus);
|
|
#endif
|
|
*pStatus= RPC_S_CANT_CREATE_ENDPOINT;
|
|
}
|
|
}
|
|
closesocket(Socket);
|
|
return NULL;
|
|
}
|
|
|
|
length = sizeof ( ReceiveAddr );
|
|
|
|
//Puts the string name of the endpoint used into ReceiveAddr.sin_port
|
|
|
|
if (getsockname ( Socket, (struct sockaddr *) &ReceiveAddr, &length ))
|
|
{
|
|
*pStatus = RPC_S_CANT_CREATE_ENDPOINT;
|
|
closesocket(Socket);
|
|
return(NULL);
|
|
}
|
|
|
|
//
|
|
// If we asked for a specific port(endpoint != 0), return it
|
|
// Otherwise, fetch the assigned port number (asssigned during the bind)
|
|
// and stuff it into the given endpoint structure in appropriate format.
|
|
if (Endpoint == 0)
|
|
{
|
|
PortUsed = GetSocket(ReceiveAddr);
|
|
|
|
_itoa ( PortUsed, PortAscii, 10 );
|
|
|
|
RtlInitAnsiString ( &AsciiPortNum, PortAscii);
|
|
RtlAnsiStringToUnicodeString( &UnicodePortNum, &AsciiPortNum, TRUE );
|
|
memcpy ( pEndpoint, UnicodePortNum.Buffer,
|
|
UnicodePortNum.Length + sizeof(UNICODE_NULL) );
|
|
|
|
RtlFreeUnicodeString ( &UnicodePortNum );
|
|
}
|
|
|
|
|
|
// Allocate mem for the TransAddress
|
|
pTransAddress = I_RpcAllocate(sizeof(DG_SERVER_TRANS_ADDRESS) +
|
|
sizeof(struct ENDPOINT_INFO));
|
|
if (pTransAddress == 0)
|
|
{
|
|
*pStatus = RPC_S_OUT_OF_MEMORY;
|
|
closesocket(Socket);
|
|
return NULL;
|
|
}
|
|
|
|
pTransAddress->pServerAddress = pServerAddress;
|
|
|
|
pInfo = (struct ENDPOINT_INFO *) &pTransAddress[1];
|
|
|
|
pInfo->Socket = Socket;
|
|
pInfo->Timeout = INFINITE;
|
|
|
|
pTransAddress->pTsap = pInfo;
|
|
|
|
*pStatus = RPC_S_OK;
|
|
|
|
return pTransAddress;
|
|
}
|
|
|
|
|
|
void
|
|
DeleteTransAddress(
|
|
PDG_SERVER_TRANS_ADDRESS * ppTransAddress
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destroys an endpoint.
|
|
|
|
Arguments:
|
|
|
|
<none>
|
|
|
|
Return Value:
|
|
|
|
<none> RRR
|
|
|
|
--*/
|
|
|
|
{
|
|
struct ENDPOINT_INFO * pInfo = (struct ENDPOINT_INFO *) (*ppTransAddress)->pTsap;
|
|
|
|
if (pInfo->Socket != INVALID_SOCKET)
|
|
{
|
|
closesocket(pInfo->Socket);
|
|
pInfo->Socket = INVALID_SOCKET;
|
|
pInfo->Timeout = INFINITE;
|
|
}
|
|
}
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
StartListening(
|
|
IN PDG_SERVER_TRANS_ADDRESS pTransAddress
|
|
)
|
|
{
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
SetBufferLength(
|
|
IN void PAPI * Endpoint,
|
|
IN unsigned Length
|
|
)
|
|
{
|
|
struct ENDPOINT_INFO * pInfo = (struct ENDPOINT_INFO *) Endpoint;
|
|
int SockStatus;
|
|
|
|
SockStatus = setsockopt(pInfo->Socket,
|
|
SOL_SOCKET,
|
|
SO_RCVBUF,
|
|
(char *) &Length,
|
|
sizeof(Length)
|
|
);
|
|
|
|
if (SockStatus == SOCKET_ERROR)
|
|
{
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
|
|
DG_RPC_SERVER_TRANSPORT_INFO TransportInformation = {
|
|
RPC_TRANSPORT_INTERFACE_VERSION,
|
|
MAX_PACKET_SIZE,
|
|
sizeof(ADDRESS_TYPE),
|
|
sizeof(SOCKET),
|
|
ADDRESS_STRING_SIZE,
|
|
ENDPOINT_STRING_SIZE,
|
|
|
|
TransportUnload,
|
|
ReceivePacket,
|
|
RegisterEndpoint,
|
|
DeregisterEndpoint,
|
|
RegisterAnyEndpoint,
|
|
SendPacketBack,
|
|
ForwardPacket,
|
|
CloseClientEndpoint,
|
|
QueryClientAddress,
|
|
QueryClientEndpoint,
|
|
StartListening,
|
|
SetBufferLength
|
|
};
|
|
|
|
|
|
PDG_RPC_SERVER_TRANSPORT_INFO
|
|
TransportLoad(
|
|
RPC_CHAR * pProtocolSequence
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the "psuedo constructor" for the server transport object.
|
|
This is the exported entry point into this dll.
|
|
|
|
Arguments:
|
|
|
|
pProtocolSequence - The protocol sequence we're running on.
|
|
|
|
Return Value:
|
|
|
|
Pointer to a DG_UDP_SERVER_TRANSPORT if successful, otherwise NULL.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
WSADATA Data;
|
|
RPC_STATUS Status = 0;
|
|
|
|
//
|
|
// Initialize Winsock.
|
|
//
|
|
Status = WSAStartup(
|
|
0x0101, // version required
|
|
&Data
|
|
);
|
|
|
|
if (Status != 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return(&TransportInformation);
|
|
|
|
}
|
|
|
|
|
|
RPC_STATUS
|
|
MapStatusCode(
|
|
int SocketError,
|
|
RPC_STATUS Default
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Maps a winsock return value into a RPC_STATUS.
|
|
|
|
Arguments:
|
|
|
|
ErrorCode - Input error code.
|
|
|
|
Return Value:
|
|
|
|
mapped status code
|
|
|
|
--*/
|
|
|
|
{
|
|
RPC_STATUS Status;
|
|
|
|
switch (SocketError)
|
|
{
|
|
case 0:
|
|
{
|
|
Status = RPC_S_OK;
|
|
break;
|
|
}
|
|
|
|
case WSAETIMEDOUT:
|
|
{
|
|
Status = RPC_P_TIMEOUT;
|
|
break;
|
|
}
|
|
|
|
case WSAENOBUFS:
|
|
{
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
break;
|
|
}
|
|
|
|
case WSAEMSGSIZE:
|
|
{
|
|
Status = RPC_P_OVERSIZE_PACKET;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
#ifdef DEBUGRPC
|
|
PrintToDebugger("RPC DG: Winsock error %d\n", SocketError);
|
|
#endif
|
|
Status = Default;
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
|