* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "stdafx.h"
// Purpose of this file is to implement an intermediate layer to our network
// services, the winsock.
// This intermediate layer will be able to function with and without a working
// winsock being present.
// The attempt to activate the winsock happens as would normally be expected,
// through the calling application's entry point to us, WSAStartup.
// Name of the winsock we would like to load.
// Diffs between OSs, Win32s is out in the cold if running 32 bits unless
// they also have a winsock name wsock32.dll.
#ifdef XP_WIN16
#define SZWINSOCK "winsock.dll"
#else
#define SZWINSOCK "wsock32.dll"
#endif
// Here is the enumeration for the winsock functions we have currently
// overridden (needed to run). Add more when needed.
// We use these to access proc addresses, and to hold a table of strings
// to obtain the proc addresses.
enum SockProc {
sp_WSAAsyncGetHostByName = 0,
sp_WSAAsyncSelect,
sp_WSACleanup,
sp_WSAGetLastError,
sp_WSASetLastError,
sp_WSAStartup,
sp___WSAFDIsSet,
sp_accept,
sp_bind,
sp_closesocket,
sp_connect,
sp_gethostbyname,
sp_gethostbyaddr,
sp_gethostname,
sp_getpeername,
sp_getsockname,
sp_getsockopt,
sp_getprotobyname,
sp_htonl,
sp_htons,
sp_inet_addr,
sp_ioctlsocket,
sp_listen,
sp_ntohl,
sp_ntohs,
sp_recv,
sp_recvfrom,
sp_select,
sp_send,
sp_sendto,
sp_setsockopt,
sp_shutdown,
sp_socket,
sp_inet_ntoa,
sp_MaxProcs // Total count.
};
// Array of function names used in GetProcAddress to fill in our
// proc array when needed.
// This array must match the enumerations exactly.
char *spName[(SockProc)sp_MaxProcs] = {
"WSAAsyncGetHostByName",
"WSAAsyncSelect",
"WSACleanup",
"WSAGetLastError",
"WSASetLastError",
"WSAStartup",
"__WSAFDIsSet",
"accept",
"bind",
"closesocket",
"connect",
"gethostbyname",
"gethostbyaddr",
"gethostname",
"getpeername",
"getsockname",
"getsockopt",
"getprotobyname",
"htonl",
"htons",
"inet_addr",
"ioctlsocket",
"listen",
"ntohl",
"ntohs",
"recv",
"recvfrom",
"select",
"send",
"sendto",
"setsockopt",
"shutdown",
"socket",
"inet_ntoa"
};
// Array of proc addresses to the winsock functions.
// These can be NULL, indicating their absence (as in the case we couldn't
// load the winsock.dll or one of the functions wasn't loaded).
// The procs assigned in must corellate with the enumerations exactly.
FARPROC spArray[(SockProc)sp_MaxProcs];
// Typedef all the different types of functions that we must cast the
// procs to in order to call without the compiler barfing.
// Prefix is always sp.
// Retval is next, spelled out.
// Parameters in their order are next, spelled out.
typedef int (PASCAL FAR *sp_int_WORD_LPWSADATA)(WORD, LPWSADATA);
typedef int (PASCAL FAR *sp_int_void)(void);
typedef HANDLE (PASCAL FAR *sp_HANDLE_HWND_uint_ccharFARp_charFARp_int)(HWND, unsigned int, const char FAR *, char FAR *, int);
typedef int (PASCAL FAR *sp_int_SOCKET_HWND_uint_long)(SOCKET, HWND, unsigned int, long);
typedef void (PASCAL FAR *sp_void_int)(int);
typedef int (PASCAL FAR *sp_int_SOCKET_fdsetFARp)(SOCKET, fd_set FAR *);
typedef SOCKET(PASCAL FAR *sp_SOCKET_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_csockaddrFARp_int)(SOCKET, const struct sockaddr FAR *, int);
typedef int (PASCAL FAR *sp_int_SOCKET)(SOCKET);
typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp)(const char FAR *);
typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp_int_int)(const char FAR *, int, int);
typedef int (PASCAL FAR *sp_int_charFARp_int)(char FAR *, int);
typedef int (PASCAL FAR *sp_int_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_int_int_charFARp_intFARp)(SOCKET, int, int, char FAR *, int FAR *);
typedef u_long (PASCAL FAR *sp_ulong_ulong)(u_long);
typedef u_short (PASCAL FAR *sp_ushort_ushort)(u_short);
typedef unsigned long (PASCAL FAR *sp_ulong_ccharFARp)(const char FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_long_ulongFARp)(SOCKET, long, u_long FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_int)(SOCKET, int);
typedef int (PASCAL FAR *sp_int_SOCKET_charFARp_int_int)(SOCKET, char FAR *, int, int);
typedef int (PASCAL FAR *sp_int_SOCKET_charFARp_int_int_sockaddrFARp_intFARp)(SOCKET, char FAR *, int, int, struct sockaddr FAR*, int FAR *);
typedef int (PASCAL FAR *sp_int_int_fdsetFARp_fdsetFARp_fdsetFARp_ctimevalFARp)(int, fd_set FAR *, fd_set FAR *, fd_set FAR *, const struct timeval FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_ccharFARp_int_int)(SOCKET, const char FAR *, int, int);
typedef int (PASCAL FAR *sp_int_SOCKET_ccharFARp_int_int_csockaddrFARp_int)(SOCKET, const char FAR *, int, int, const struct sockaddr FAR*, int);
typedef int (PASCAL FAR *sp_int_SOCKET_int_int_ccharFARp_int)(SOCKET, int, int, const char FAR *, int);
typedef SOCKET (PASCAL FAR *sp_SOCKET_int_int_int)(int, int, int);
typedef char FAR * (PASCAL FAR *sp_charFARp_in_addr)(struct in_addr in);
typedef struct protoent FAR * (PASCAL FAR *sp_protoentFARcchar)(const char FAR *);
// Handle to the winsock, if loaded.
HINSTANCE hWinsock = NULL;
#ifdef XP_WIN16
// Last error code for the winsock.
int ispError = 0;
#endif
// Quick macro to tell if the winsock has actually loaded for a particular
// function.
// Debug version is a little more strict to make sure you get the names right.