Leaked source code of windows server 2003
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.
 
 
 
 
 
 

358 lines
7.5 KiB

//
// DWINSOCK.C Dynamic WinSock
//
// Functions for dynamically linking to
// best available WinSock.
//
// Dynamically links to WS2_32.DLL or
// if WinSock 2 isn't available, it
// dynamically links to WSOCK32.DLL.
//
//
#include "dnwsocki.h"
#if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
//
// Globals
//
HINSTANCE g_hWinSock2 = NULL;
//
// Declare global function pointers
//
#define DWINSOCK_GLOBAL
#include "dwnsock2.inc"
#endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
//
// Internal Functions and data
//
#ifndef DPNBUILD_NOWINSOCK2
static BOOL MapWinsock2FunctionPointers(void);
#endif // ! DPNBUILD_NOWINSOCK2
#ifndef DPNBUILD_NOIPX
static char NibbleToHex(BYTE b);
static void BinToHex(PBYTE pBytes, int nNbrBytes, LPSTR lpStr);
static int IPXAddressToString(LPSOCKADDR_IPX pAddr,
DWORD dwAddrLen,
LPTSTR lpAddrStr,
LPDWORD pdwStrLen);
#endif // ! DPNBUILD_NOIPX
////////////////////////////////////////////////////////////
#undef DPF_MODNAME
#define DPF_MODNAME "DWSInitWinSock"
int DWSInitWinSock( void )
{
WORD wVersionRequested;
WSADATA wsaData;
int iReturn;
#ifdef DPNBUILD_ONLYWINSOCK2
//
// Use Winsock 2.
//
wVersionRequested = MAKEWORD(2, 2);
#else // ! DPNBUILD_ONLYWINSOCK2
//
// Assume we will use Winsock 1.
//
wVersionRequested = MAKEWORD(1, 1);
#ifndef DPNBUILD_NOWINSOCK2
//
// Try to load Winsock 2 if allowed.
//
#ifndef DPNBUILD_NOREGISTRY
if (g_dwWinsockVersion != 1)
#endif // ! DPNBUILD_NOREGISTRY
{
#ifdef WIN95
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
if ((g_dwWinsockVersion == 2) || // if we explicitly are supposed to use WS2, or
(! GetVersionEx(&osvi)) || // if we can't get the OS information, or
(osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) || // if it's not Win9x, or
(HIBYTE(HIWORD(osvi.dwBuildNumber)) != 4) || // it's not the Win98 major version number, or
(LOBYTE(HIWORD(osvi.dwBuildNumber)) != 10)) // it's not Win98's minor version number (Gold = build 1998, SE = build 2222)
#endif // WIN95
{
g_hWinSock2 = LoadLibrary(TEXT("WS2_32.DLL"));
if (g_hWinSock2 != NULL)
{
//
// Use GetProcAddress to initialize
// the function pointers
//
if (!MapWinsock2FunctionPointers())
{
iReturn = -1;
goto Failure;
}
wVersionRequested = MAKEWORD(2, 2);
}
}
}
#endif // ! DPNBUILD_NOWINSOCK2
#endif // ! DPNBUILD_ONLYWINSOCK2
//
// Call WSAStartup()
//
iReturn = WSAStartup(wVersionRequested, &wsaData);
if (iReturn != 0)
{
goto Failure;
}
DPFX(DPFPREP, 3, "Using WinSock version %i.%i",
LOBYTE( wsaData.wVersion ), HIBYTE( wsaData.wVersion ) );
if (wVersionRequested != wsaData.wVersion)
{
DPFX(DPFPREP, 0, "WinSock version %i.%i in use doesn't match version requested %i.%i!",
LOBYTE( wsaData.wVersion ), HIBYTE( wsaData.wVersion ),
LOBYTE( wVersionRequested ), HIBYTE( wVersionRequested ) );
iReturn = -1;
goto Failure;
}
DNASSERT(iReturn == 0);
Exit:
return iReturn;
Failure:
#if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
if (g_hWinSock2 != NULL)
{
FreeLibrary(g_hWinSock2);
g_hWinSock2 = NULL;
}
#endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
DNASSERT(iReturn != 0);
goto Exit;
}
#undef DPF_MODNAME
////////////////////////////////////////////////////////////
void DWSFreeWinSock(void)
{
WSACleanup();
#if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
if (g_hWinSock2 != NULL)
{
FreeLibrary(g_hWinSock2);
g_hWinSock2 = NULL;
}
#endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
}
#if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
//**********************************************************************
// ------------------------------
// GetWinsockVersion - get the version of Winsock
//
// Entry: Nothing
//
// Exit: Winsock version
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "GetWinsockVersion"
int GetWinsockVersion( void )
{
return ((g_hWinSock2 != NULL) ? 2 : 1);
}
//**********************************************************************
#endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
#ifndef DPNBUILD_NOIPX
//
// Workaround for WSAAddressToString()/IPX bug
//
int IPXAddressToStringNoSocket(LPSOCKADDR pSAddr,
DWORD dwAddrLen,
LPSTR lpAddrStr,
LPDWORD pdwStrLen)
{
char szAddr[32];
char szTmp[20];
LPSOCKADDR_IPX pAddr = (LPSOCKADDR_IPX) pSAddr;
//
// Check destination length
//
if (*pdwStrLen < 27)
{
WSASetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
//
// Convert network number
//
BinToHex((PBYTE)&pAddr->sa_netnum, 4, szTmp);
strcpy(szAddr, szTmp);
strcat(szAddr, ",");
// Node Number
BinToHex((PBYTE)&pAddr->sa_nodenum, 6, szTmp);
strcat(szAddr, szTmp);
strcpy(lpAddrStr, szAddr);
*pdwStrLen = strlen(szAddr);
return 0;
}
////////////////////////////////////////////////////////////
char NibbleToHex(BYTE b)
{
if (b < 10)
return (b + '0');
return (b - 10 + 'A');
}
void BinToHex(PBYTE pBytes, int nNbrBytes, LPSTR lpStr)
{
BYTE b;
while(nNbrBytes--)
{
// High order nibble first
b = (*pBytes >> 4);
*lpStr = NibbleToHex(b);
lpStr++;
// Then low order nibble
b = (*pBytes & 0x0F);
*lpStr = NibbleToHex(b);
lpStr++;
pBytes++;
}
*lpStr = '\0';
}
////////////////////////////////////////////////////////////
//
// Workaround for WSAAddressToString()/IPX bug
//
int IPXAddressToString(LPSOCKADDR_IPX pAddr,
DWORD dwAddrLen,
LPTSTR lpAddrStr,
LPDWORD pdwStrLen)
{
char szAddr[32];
char szTmp[20];
//
// Check destination length
//
if (*pdwStrLen < 27)
{
WSASetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
//
// Convert network number
//
BinToHex((PBYTE)&pAddr->sa_netnum, 4, szTmp);
strcpy(szAddr, szTmp);
strcat(szAddr, ",");
// Node Number
BinToHex((PBYTE)&pAddr->sa_nodenum, 6, szTmp);
strcat(szAddr, szTmp);
strcat(szAddr, ":");
// IPX Address Socket number
BinToHex((PBYTE)&pAddr->sa_socket, 2, szTmp);
strcat(szAddr, szTmp);
#ifdef UNICODE
//
// Convert inet_ntoa string to wide char
//
int nRet = MultiByteToWideChar(CP_ACP,
0,
szAddr,
-1,
lpAddrStr,
*pdwStrLen);
if (nRet == 0)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
WSASetLastError(WSAEFAULT);
}
else
{
WSASetLastError(WSAEINVAL);
}
return SOCKET_ERROR;
}
#else
//
// ANSI -- Check the string length
//
if (strlen(szAddr) > *pdwStrLen)
{
WSASetLastError(WSAEFAULT);
*pdwStrLen = strlen(szAddr);
return SOCKET_ERROR;
}
strcpy(lpAddrStr, szAddr);
*pdwStrLen = strlen(szAddr);
#endif // UNICODE
return 0;
}
#endif DPNBUILD_NOIPX
////////////////////////////////////////////////////////////
#ifndef DPNBUILD_NOWINSOCK2
BOOL MapWinsock2FunctionPointers(void)
{
//
// This variable must be declared
// with this name in order to use
// #define DWINSOCK_GETPROCADDRESS
//
BOOL fOK = TRUE;
#define DWINSOCK_GETPROCADDRESS
#include "dwnsock2.inc"
return fOK;
}
#endif // DPNBUILD_NOWINSOCK2