Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

382 lines
8.3 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
addrconv.c
Abstract:
This module contains address conversion routines.
Author:
Keith Moore (keithmo) 8-Jan-1996
Revision History:
--*/
#define UNICODE
#include "winsockp.h"
PWINSOCK_HELPER_DLL_INFO
SockFindHelperDllForAddressFamily(
INT AddressFamily
);
BOOL
SockIsAddressFamilySupported(
IN PWINSOCK_MAPPING Mapping,
IN INT AddressFamily
);
int
WSPAPI
WSPAddressToString(
LPSOCKADDR lpsaAddress,
DWORD dwAddressLength,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
LPWSTR lpszAddressString,
LPDWORD lpdwAddressStringLength,
LPINT lpErrno
)
/*++
Routine Description:
This routine converts all components of a SOCKADDR structure into a human-
readable string representation of the address. This is used mainly for
display purposes.
Arguments:
lpsaAddress - Points to a SOCKADDR structure to translate into a string.
dwAddressLength - The length of the Address SOCKADDR.
lpProtocolInfo - The WSAPROTOCOL_INFOW struct for a particular provider.
lpszAddressString - A buffer which receives the human-readable address
string.
lpdwAddressStringLength - The length of the AddressString buffer. Returns
the length of the string actually copied into the buffer.
lpErrno - A pointer to the error code.
Return Value:
If no error occurs, WSPAddressToString() returns 0. Otherwise, it returns
SOCKET_ERROR, and a specific error code is available in lpErrno.
--*/
{
PWINSOCK_HELPER_DLL_INFO helperDll;
//
// Find a helper DLL supporting this address family.
//
helperDll = SockFindHelperDllForAddressFamily( (INT)lpsaAddress->sa_family );
if( helperDll == NULL ||
helperDll->WSHAddressToString == NULL ) {
*lpErrno = WSA_INVALID_PARAMETER;
return SOCKET_ERROR;
}
if( dwAddressLength < (DWORD)helperDll->MinSockaddrLength ) {
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
*lpErrno = helperDll->WSHAddressToString(
lpsaAddress,
dwAddressLength,
lpProtocolInfo,
lpszAddressString,
lpdwAddressStringLength
);
return ( *lpErrno == 0 ) ? NO_ERROR : SOCKET_ERROR;
} // WSPAddressToString
int
WSPAPI
WSPStringToAddress(
LPWSTR AddressString,
INT AddressFamily,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
LPSOCKADDR lpAddress,
LPINT lpAddressLength,
LPINT lpErrno
)
/*++
Routine Description:
This routine converts a human-readable string to a socket address
structure (SOCKADDR) suitable for pass to Windows Sockets routines which
take such a structure. Any missing components of the address will be
defaulted to a reasonable value if possible. For example, a missing port
number will be defaulted to zero.
Arguments:
AddressString - Points to the zero-terminated human-readable string to
convert.
AddressFamily - The address family to which the string belongs, or
AF_UNSPEC if it is unknown.
lpProtocolInfo - The provider's WSAPROTOCOL_INFOW struct.
lpAddress - A buffer which is filled with a single SOCKADDR structure.
lpAddressLength - The length of the Address buffer. Returns the size of
the resultant SOCKADDR structure.
lpErrno - A pointer to the error code.
Return Value:
If no error occurs, WSPStringToAddress() returns 0. Otherwise, a value
of SOCKET_ERROR is returned, and a specific error code is available
in lpErrno.
--*/
{
PWINSOCK_HELPER_DLL_INFO helperDll;
//
// Find a helper DLL supporting this address family.
//
helperDll = SockFindHelperDllForAddressFamily( AddressFamily );
if( helperDll == NULL ||
helperDll->WSHStringToAddress == NULL ) {
*lpErrno = WSA_INVALID_PARAMETER;
return SOCKET_ERROR;
}
if( *lpAddressLength < helperDll->MinSockaddrLength ) {
*lpErrno = WSAEFAULT;
return SOCKET_ERROR;
}
*lpErrno = helperDll->WSHStringToAddress(
AddressString,
AddressFamily,
lpProtocolInfo,
lpAddress,
lpAddressLength
);
return ( *lpErrno == 0 ) ? NO_ERROR : SOCKET_ERROR;
} // WSPStringToAddress
PWINSOCK_HELPER_DLL_INFO
SockFindHelperDllForAddressFamily(
INT AddressFamily
)
{
PLIST_ENTRY listEntry;
PWINSOCK_HELPER_DLL_INFO helperDll;
INT error;
PWSTR transportList;
PWSTR currentTransport;
PWINSOCK_MAPPING mapping;
//
// Acquire the global sockets lock and search the list of helper
// DLLs for one which supports this address family.
//
SockAcquireGlobalLockExclusive();
for( listEntry = SockHelperDllListHead.Flink;
listEntry != &SockHelperDllListHead;
listEntry = listEntry->Flink ) {
helperDll = CONTAINING_RECORD(
listEntry,
WINSOCK_HELPER_DLL_INFO,
HelperDllListEntry
);
IF_DEBUG( HELPER_DLL ) {
WS_PRINT(( "SockFindHelperDllForAddressFamily: examining DLL at %lx for AF %ld\n",
helperDll, AddressFamily ));
}
//
// Check to see whether the DLL supports the address family.
//
if( SockIsAddressFamilySupported(
helperDll->Mapping,
AddressFamily
) ) {
//
// Found a match.
//
SockReleaseGlobalLock();
return helperDll;
}
}
//
// We don't have any loaded DLLs that support this address family.
// Attempt to find a DLL in the registry that can handle the
// specified address family. First get the REG_MULTI_SZ that contains
// the list of transports that have winsock support.
//
error = SockLoadTransportList( &transportList );
if( error != NO_ERROR ) {
SockReleaseGlobalLock();
return NULL;
}
//
// Loop through the transports looking for one which will support
// the socket we're opening.
//
for( currentTransport = transportList;
*currentTransport != UNICODE_NULL;
currentTransport += wcslen( currentTransport ) + 1 ) {
//
// Load the list of triples supported by this transport.
//
error = SockLoadTransportMapping( currentTransport, &mapping );
if( error != NO_ERROR ) {
WS_PRINT((
"SockLoadTransportMapping( %ws ) failed: %ld\n",
currentTransport,
error
));
continue;
}
//
// Determine whether the triple of the socket we're opening is
// in this transport's mapping.
//
if( SockIsAddressFamilySupported(
mapping,
AddressFamily
) ) {
//
// The address family is supported. Load the helper DLL for the
// transport.
//
error = SockLoadHelperDll( currentTransport, mapping, &helperDll );
//
// If we couldn't load the DLL, continue looking for a helper
// DLL that will support this triple.
//
if( error == NO_ERROR ) {
//
// Success!
//
SockReleaseGlobalLock();
return helperDll;
}
}
//
// This transport does not support the socket we're opening.
// Free the memory that held the mapping and try the next
// transport in the list.
//
FREE_HEAP( mapping );
}
SockReleaseGlobalLock();
//
// Bummer.
//
return NULL;
} // SockFindHelperDllForAddressFamily
BOOL
SockIsAddressFamilySupported(
IN PWINSOCK_MAPPING Mapping,
IN INT AddressFamily
)
{
ULONG i;
//
// Loop through the mapping attempting to find the address family.
//
for ( i = 0; i < Mapping->Rows; i++ ) {
if ( (INT)Mapping->Mapping[i].AddressFamily == AddressFamily ) {
return TRUE;
}
}
return FALSE;
} // SockIsAddressFamilySupported