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.
1486 lines
40 KiB
1486 lines
40 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
Copyright (c) 1996 Hummingbird Corporation of Canada
|
|
|
|
|
|
Module Name:
|
|
|
|
wsock32.c
|
|
|
|
Abstract:
|
|
|
|
Contains Socks V4 support, written by Hummingbird corporation. Licensed from
|
|
Hummingbird for ulimited use by Microsoft. Ported to WININET code base.
|
|
|
|
Contents:
|
|
FindSocket
|
|
closesocket
|
|
connect
|
|
getpeername
|
|
ALL WSOCK32.DLL exports.
|
|
|
|
Author:
|
|
|
|
Arthur L Bierer (arthurbi) 13-Dec-1996
|
|
|
|
Environment:
|
|
|
|
Win32 user-mode DLL
|
|
|
|
Revision History:
|
|
|
|
13-Dec-1996 arthurbi
|
|
Created, removed flagrent calls to CRTs, and unchecked memory allocations.
|
|
|
|
29-Aug-1997 rfirth
|
|
Further reduced from general-purpose SOCKS implementation to Wininet-
|
|
specific SOCKS support
|
|
|
|
--*/
|
|
|
|
|
|
#define _WINSOCKAPI_
|
|
#include <windows.h>
|
|
#ifdef DO_FILE_CONFIG
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <io.h>
|
|
#include <malloc.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#ifdef OLD_SOCKS
|
|
|
|
struct User {
|
|
char *Name;
|
|
struct User *Next;
|
|
};
|
|
|
|
struct Server {
|
|
char *Name;
|
|
struct Server *Next;
|
|
unsigned short port;
|
|
};
|
|
|
|
struct Hosts {
|
|
struct User *Users;
|
|
struct Server *Servers;
|
|
unsigned long dst;
|
|
unsigned long mask;
|
|
unsigned short port;
|
|
unsigned char op;
|
|
unsigned char type;
|
|
struct Hosts *Next;
|
|
} *Head=NULL;
|
|
|
|
struct Sockets {
|
|
int s;
|
|
HWND hWnd;
|
|
unsigned int wMsg;
|
|
long lEvent;
|
|
unsigned long Blocking;
|
|
int type;
|
|
unsigned long ip;
|
|
unsigned short port;
|
|
struct Sockets *Next;
|
|
struct Sockets *Last;
|
|
int Socked:1;
|
|
} *SHead=NULL;
|
|
|
|
HANDLE SMutex;
|
|
|
|
#define CREATE_MUTEX() SMutex = CreateMutex(NULL, FALSE, NULL)
|
|
#define DELETE_MUTEX() if (SMutex) CloseHandle(SMutex)
|
|
#define ENTER_MUTEX() WaitForSingleObject(SMutex, INFINITE)
|
|
#define LEAVE_MUTEX() ReleaseMutex(SMutex)
|
|
|
|
#else
|
|
|
|
struct Hosts {
|
|
char * user;
|
|
int userlen;
|
|
unsigned long ip;
|
|
unsigned short port;
|
|
} *Head = NULL;
|
|
|
|
struct Sockets {
|
|
int s;
|
|
int type;
|
|
unsigned long ip;
|
|
unsigned short port;
|
|
struct Sockets * Next;
|
|
struct Sockets * Last;
|
|
int Socked : 1;
|
|
int Blocking : 1;
|
|
} *SHead = NULL;
|
|
|
|
CRITICAL_SECTION CritSec;
|
|
|
|
#define CREATE_MUTEX() InitializeCriticalSection(&CritSec)
|
|
#define DELETE_MUTEX() DeleteCriticalSection(&CritSec)
|
|
#define ENTER_MUTEX() EnterCriticalSection(&CritSec)
|
|
#define LEAVE_MUTEX() LeaveCriticalSection(&CritSec)
|
|
|
|
#endif
|
|
|
|
#define DENY 1
|
|
#define DIRECT 2
|
|
#define SOCKD 3
|
|
|
|
#define ANY 0
|
|
#define EQ 1
|
|
#define NEQ 2
|
|
#define LT 3
|
|
#define GT 4
|
|
#define LE 5
|
|
#define GE 6
|
|
|
|
|
|
/*
|
|
* Internet address (old style... should be updated)
|
|
*/
|
|
struct in_addr {
|
|
union {
|
|
struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
|
|
struct { unsigned short s_w1,s_w2; } S_un_w;
|
|
unsigned long S_addr;
|
|
} S_un;
|
|
#define s_addr S_un.S_addr
|
|
/* can be used for most tcp & ip code */
|
|
#define s_host S_un.S_un_b.s_b2
|
|
/* host on imp */
|
|
#define s_net S_un.S_un_b.s_b1
|
|
/* network */
|
|
#define s_imp S_un.S_un_w.s_w2
|
|
/* imp */
|
|
#define s_impno S_un.S_un_b.s_b4
|
|
/* imp # */
|
|
#define s_lh S_un.S_un_b.s_b3
|
|
/* logical host */
|
|
};
|
|
|
|
/*
|
|
* Socket address, internet style.
|
|
*/
|
|
struct sockaddr_in {
|
|
short sin_family;
|
|
unsigned short sin_port;
|
|
struct in_addr sin_addr;
|
|
char sin_zero[8];
|
|
};
|
|
|
|
struct servent {
|
|
char * s_name; /* official service name */
|
|
char * * s_aliases; /* alias list */
|
|
short s_port; /* port # */
|
|
char * s_proto; /* protocol to use */
|
|
};
|
|
|
|
struct hostent {
|
|
char * h_name; /* official name of host */
|
|
char * * h_aliases; /* alias list */
|
|
short h_addrtype; /* host address type */
|
|
short h_length; /* length of address */
|
|
char * * h_addr_list; /* list of addresses */
|
|
#define h_addr h_addr_list[0] /* address, for backward compat */
|
|
};
|
|
|
|
|
|
#define WSABASEERR 10000
|
|
#define WSAECONNREFUSED (WSABASEERR+61)
|
|
#define WSAEWOULDBLOCK (WSABASEERR+35)
|
|
#define WSAENOBUFS (WSABASEERR+55)
|
|
|
|
|
|
#define SOCKET_ERROR (-1)
|
|
#define INVALID_SOCKET (int)(~0)
|
|
|
|
/*
|
|
* Define flags to be used with the WSAAsyncSelect() call.
|
|
*/
|
|
#define FD_READ 0x01
|
|
#define FD_WRITE 0x02
|
|
#define FD_OOB 0x04
|
|
#define FD_ACCEPT 0x08
|
|
#define FD_CONNECT 0x10
|
|
#define FD_CLOSE 0x20
|
|
|
|
#define SOCK_STREAM 1 /* stream socket */
|
|
|
|
/*
|
|
* Commands for ioctlsocket(), taken from the BSD file fcntl.h.
|
|
*
|
|
*
|
|
* Ioctl's have the command encoded in the lower word,
|
|
* and the size of any in or out parameters in the upper
|
|
* word. The high 2 bits of the upper word are used
|
|
* to encode the in/out status of the parameter; for now
|
|
* we restrict parameters to at most 128 bytes.
|
|
*/
|
|
#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
|
|
#define IOC_VOID 0x20000000 /* no parameters */
|
|
#define IOC_OUT 0x40000000 /* copy out parameters */
|
|
#define IOC_IN 0x80000000 /* copy in parameters */
|
|
#define IOC_INOUT (IOC_IN|IOC_OUT)
|
|
/* 0x20000000 distinguishes new &
|
|
old ioctl's */
|
|
#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
|
|
|
|
#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
|
|
|
|
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
|
|
|
|
#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
|
|
#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
|
|
#define FIOASYNC _IOW('f', 125, unsigned long) /* set/clear async i/o */
|
|
|
|
#define SO_SET_SOCKS_FIREWALL 0xF0000
|
|
|
|
|
|
DWORD (WINAPI * VArecv)(int a,int b,int c, int d);
|
|
DWORD (WINAPI * VAsend)(int a,int b,int c, int d);
|
|
DWORD (WINAPI * VEnumProtocolsA)(int a,int b,int c);
|
|
DWORD (WINAPI * VEnumProtocolsW)(int a,int b,int c);
|
|
DWORD (WINAPI * VGetAddressByNameA)(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j);
|
|
DWORD (WINAPI * VGetAddressByNameW)(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j);
|
|
DWORD (WINAPI * VGetNameByTypeA)(int a,int b,int c);
|
|
DWORD (WINAPI * VGetNameByTypeW)(int a,int b,int c);
|
|
DWORD (WINAPI * VGetServiceA)(int a,int b,int c,int d,int e,int f,int g);
|
|
DWORD (WINAPI * VGetServiceW)(int a,int b,int c,int d,int e,int f,int g);
|
|
DWORD (WINAPI * VGetTypeByNameA)(int a,int b);
|
|
DWORD (WINAPI * VGetTypeByNameW)(int a,int b);
|
|
DWORD (WINAPI * VNPLoadNameSpaces)(int a,int b,int c);
|
|
DWORD (WINAPI * VSetServiceA)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * VSetServiceW)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * VTransmitFile)(int a,int b,int c,int d,int e,int f,int g);
|
|
DWORD (WINAPI * VWSAAsyncGetHostByAddr)(int a,int b,int c,int d,int e,int f,int g);
|
|
DWORD (WINAPI * VWSAAsyncGetHostByName)(int a,int b,int c,int d,int e);
|
|
DWORD (WINAPI * VWSAAsyncGetProtoByName)(int a,int b,int c,int d,int e);
|
|
DWORD (WINAPI * VWSAAsyncGetProtoByNumber)(int a,int b,int c,int d,int e);
|
|
DWORD (WINAPI * VWSAAsyncGetServByName)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * VWSAAsyncGetServByPort)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * VWSAAsyncSelect)(int s, HWND hWnd, unsigned int wMsg, long lEvent);
|
|
DWORD (WINAPI * VWSACancelAsyncRequest)(int a);
|
|
DWORD (WINAPI * VWSACancelBlockingCall)(void);
|
|
DWORD (WINAPI * VWSACleanup)(void);
|
|
DWORD (WINAPI * VWSAGetLastError)(void);
|
|
DWORD (WINAPI * VWSAIsBlocking)(void);
|
|
DWORD (WINAPI * VWSARecvEx)(int a,int b,int c,int d);
|
|
DWORD (WINAPI * VWSASetBlockingHook)(int a);
|
|
DWORD (WINAPI * VWSASetLastError)(int a);
|
|
DWORD (WINAPI * VWSAStartup)(int a,int b);
|
|
DWORD (WINAPI * VWSAUnhookBlockingHook)(void);
|
|
DWORD ( * VWSHEnumProtocols)(int a,int b,int c,int d);
|
|
DWORD (WINAPI * VWsControl)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * V__WSAFDIsSet)(int a,int b);
|
|
DWORD (WINAPI * Vaccept)(int a,int b,int c);
|
|
DWORD (WINAPI * Vbind)(int a,int b,int c);
|
|
DWORD (WINAPI * Vclosesocket)(int a);
|
|
DWORD (WINAPI * Vclosesockinfo)(int a);
|
|
DWORD (WINAPI * Vconnect)(int s, const struct sockaddr_in FAR *name, int namelen);
|
|
DWORD (WINAPI * Vdn_expand)(int a,int b,int c,int d,int e);
|
|
DWORD (WINAPI * Vgethostbyaddr)(int a,int b,int c);
|
|
struct hostent * (WINAPI * Vgethostbyname)(char *);
|
|
DWORD (WINAPI * Vgethostname)(int a,int b);
|
|
DWORD (WINAPI * Vgetnetbyname)(int a);
|
|
DWORD (WINAPI * Vgetpeername)(int s, struct sockaddr_in *name,int *namelen);
|
|
DWORD (WINAPI * Vgetprotobyname)(int a);
|
|
DWORD (WINAPI * Vgetprotobynumber)(int a);
|
|
struct servent * (WINAPI * Vgetservbyname)(const char FAR * name, const char FAR * proto);
|
|
DWORD (WINAPI * Vgetservbyport)(int a,int b);
|
|
DWORD (WINAPI * Vgetsockname)(int a,int b,int c);
|
|
DWORD (WINAPI * Vgetsockopt)(int a,int b,int c,int d,int e);
|
|
DWORD (WINAPI * Vhtonl)(int a);
|
|
DWORD (WINAPI * Vhtons)(int a);
|
|
DWORD (WINAPI * Vinet_addr)(char *p);
|
|
DWORD (WINAPI * Vinet_network)(int a);
|
|
DWORD (WINAPI * Vinet_ntoa)(int a);
|
|
DWORD (WINAPI * Vioctlsocket)(int s, long cmd, unsigned long *argp);
|
|
DWORD (WINAPI * Vlisten)(int a,int b);
|
|
DWORD (WINAPI * Vntohl)(int a);
|
|
DWORD (WINAPI * Vntohs)(int a);
|
|
DWORD (WINAPI * Vrcmd)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * Vrecv)(int a,int b,int c,int d);
|
|
DWORD (WINAPI * Vrecvfrom)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * Vrexec)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * Vrresvport)(int a);
|
|
DWORD (WINAPI * Vs_perror)(int a,int b);
|
|
DWORD (WINAPI * Vselect)(int a,int b,int c,int d,int e);
|
|
DWORD (WINAPI * Vsend)(int a,int b,int c,int d);
|
|
DWORD (WINAPI * Vsendto)(int a,int b,int c,int d,int e,int f);
|
|
DWORD (WINAPI * Vsethostname)(int a,int b);
|
|
DWORD (WINAPI * Vsetsockopt)(int s,int level,int optname,const char FAR * optval, int optlen);
|
|
DWORD (WINAPI * Vshutdown)(int a,int b);
|
|
DWORD (WINAPI * Vsocket)(int a,int b,int c);
|
|
DWORD (WINAPI * VWEP)(void);
|
|
DWORD (WINAPI * VAcceptEx)(int a,int b,int c,int d,int e,int f,int g,int h);
|
|
DWORD (WINAPI * VGetAcceptExSockaddrs)(int a,int b,int c,int d,int e,int f,int g,int h);
|
|
DWORD (WINAPI * VMigrateWinsockConfiguration)(int a,int b, int c);
|
|
DWORD (WINAPI * VWSApSetPostRoutine)(void *a);
|
|
|
|
BOOL (WINAPI * VPostMessage)(HWND hWnd, unsigned int wMsg, WPARAM wPAram, LPARAM lParam) = NULL;
|
|
|
|
BOOL MyPostMessage(HWND hWnd, unsigned int wMsg, WPARAM wParam, LPARAM lParam) {
|
|
if ( VPostMessage)
|
|
return(VPostMessage(hWnd,wMsg, wParam, lParam));
|
|
PostMessage(hWnd,wMsg, wParam, lParam);
|
|
}
|
|
|
|
struct Sockets *
|
|
FindSocket(
|
|
int s
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find or create SOCKS socket object. Returns with MUTEX held
|
|
|
|
Arguments:
|
|
|
|
s - associated socket handle
|
|
|
|
Return Value:
|
|
|
|
struct Sockets *
|
|
Success - address of Sockets object
|
|
|
|
Failure - NULL
|
|
|
|
--*/
|
|
|
|
{
|
|
struct Sockets *So;
|
|
|
|
ENTER_MUTEX();
|
|
|
|
So = SHead;
|
|
while (So) {
|
|
if (s == So->s) {
|
|
return So;
|
|
}
|
|
So = So->Next;
|
|
}
|
|
if (So = (struct Sockets *)LocalAlloc(LPTR, sizeof(struct Sockets))) {
|
|
So->s = s;
|
|
So->Next = SHead;
|
|
SHead = So;
|
|
if (So->Next) {
|
|
(So->Next)->Last = So;
|
|
}
|
|
}
|
|
return So;
|
|
}
|
|
|
|
//LPSTR
|
|
//NewString(
|
|
// IN LPCSTR String
|
|
// )
|
|
//
|
|
///*++
|
|
//
|
|
//Routine Description:
|
|
//
|
|
// kind of version of strdup() but using LocalAlloc to allocate memory
|
|
//
|
|
//Arguments:
|
|
//
|
|
// String - pointer to string to make copy of
|
|
//
|
|
//Return Value:
|
|
//
|
|
// LPSTR
|
|
// Success - pointer to duplicated string
|
|
// Failure - NULL
|
|
//
|
|
//--*/
|
|
//
|
|
//{
|
|
// int len = strlen(String) + 1;
|
|
// LPSTR string;
|
|
//
|
|
// if (string = (LPSTR)LocalAlloc(LMEM_FIXED, len)) {
|
|
// CopyMemory(string, String, len);
|
|
// }
|
|
// return string;
|
|
//}
|
|
|
|
|
|
DWORD WINAPI __WSAFDIsSet(int a,int b) {
|
|
return(V__WSAFDIsSet(a, b));
|
|
}
|
|
|
|
DWORD WINAPI accept(int a,int b,int c) {
|
|
return(Vaccept(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI Arecv(int a,int b,int c,int d) {
|
|
return(VArecv(a,b,c,d));
|
|
}
|
|
|
|
DWORD WINAPI Asend(int a,int b,int c,int d) {
|
|
|
|
return(VAsend(a,b,c,d));
|
|
}
|
|
|
|
DWORD WINAPI bind(int a,int b,int c) {
|
|
return(Vbind(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI AcceptEx(int a,int b,int c,int d,int e,int f,int g,int h) {
|
|
return(VAcceptEx(a,b,c,d,e,f,g,h));
|
|
}
|
|
|
|
DWORD WINAPI GetAcceptExSockaddrs(int a,int b,int c,int d,int e,int f,int g,int h) {
|
|
return(VGetAcceptExSockaddrs(a,b,c,d,e,f,g,h));
|
|
}
|
|
|
|
DWORD WINAPI MigrateWinsockConfiguration(int a,int b, int c) {
|
|
return(VMigrateWinsockConfiguration(a,b,c));
|
|
}
|
|
|
|
DWORD WINAPI WSApSetPostRoutine(void *a) {
|
|
VPostMessage=a;
|
|
return(VWSApSetPostRoutine(a));
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
closesocket(
|
|
int s
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Closes socket handle and destroys associated Sockets object if found
|
|
|
|
Arguments:
|
|
|
|
s - socket handle
|
|
|
|
Return Value:
|
|
|
|
int
|
|
Success - 0
|
|
|
|
Failure - -1
|
|
|
|
--*/
|
|
|
|
{
|
|
struct Sockets * So = FindSocket(s);
|
|
|
|
if (So == NULL) {
|
|
VWSASetLastError(WSAENOBUFS);
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
return SOCKET_ERROR;
|
|
}
|
|
if (So->Last == NULL) {
|
|
SHead = So->Next;
|
|
} else {
|
|
(So->Last)->Next = So->Next;
|
|
}
|
|
if (So->Next) {
|
|
(So->Next)->Last = So->Last;
|
|
}
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
LocalFree(So);
|
|
return Vclosesocket(s);
|
|
}
|
|
|
|
DWORD WINAPI closesockinfo(int a) {
|
|
return(Vclosesockinfo(a));
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
connect(
|
|
int s,
|
|
const struct sockaddr_in FAR * name,
|
|
int namelen
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Connect to remote host via SOCKS proxy. Modified from original. If we are
|
|
here then we are going specifically via a known SOCKS proxy. There is now
|
|
only one Hosts object, containing a single SOCKD socks proxy address and
|
|
user name
|
|
|
|
Arguments:
|
|
|
|
s - socket to connect
|
|
|
|
name - sockaddr of remote host
|
|
|
|
namelen - length of sockaddr
|
|
|
|
Return Value:
|
|
|
|
int
|
|
Success - 0
|
|
|
|
Failure - -1
|
|
|
|
--*/
|
|
|
|
{
|
|
unsigned long ip;
|
|
unsigned short port;
|
|
struct Hosts * pHost;
|
|
int serr;
|
|
int blocking;
|
|
struct Sockets * pSocket;
|
|
struct sockaddr_in sin;
|
|
struct {
|
|
unsigned char VN;
|
|
unsigned char CD;
|
|
unsigned short DSTPORT;
|
|
unsigned long DSTIP;
|
|
char UserId[255];
|
|
} request;
|
|
int length;
|
|
char response[256];
|
|
int val;
|
|
|
|
//
|
|
// get IP address and port we want to connect to on other side of firewall
|
|
//
|
|
|
|
port = name->sin_port;
|
|
ip = name->sin_addr.s_addr;
|
|
|
|
//
|
|
// initialize sockaddr for connecting to SOCKS firewall
|
|
//
|
|
|
|
memset(&sin, 0, sizeof(sin));
|
|
sin.sin_family = 2;
|
|
|
|
//
|
|
// initialize SOCKS request packet
|
|
//
|
|
|
|
request.VN = 4;
|
|
request.CD = 1;
|
|
request.DSTPORT = port;
|
|
request.DSTIP = ip;
|
|
|
|
pSocket = FindSocket(s);
|
|
if (pSocket == NULL) {
|
|
VWSASetLastError(WSAENOBUFS);
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
return SOCKET_ERROR;
|
|
}
|
|
pHost = Head;
|
|
if (!pHost || (pSocket->type != SOCK_STREAM) || (pSocket->Socked)) {
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
return Vconnect(s, name, namelen);
|
|
}
|
|
|
|
//
|
|
// get information from pSocket and pHost structures before releasing mutex
|
|
//
|
|
|
|
blocking = pSocket->Blocking;
|
|
pSocket->port = port;
|
|
pSocket->ip = ip;
|
|
memcpy(request.UserId, pHost->user, pHost->userlen);
|
|
length = pHost->userlen + 8; // 8 == sizeof fixed portion of request
|
|
sin.sin_port = pHost->port;
|
|
sin.sin_addr.s_addr = pHost->ip;
|
|
|
|
//
|
|
// from this point, we cannot touch pHost or pSocket until we take the mutex
|
|
// again
|
|
//
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
//
|
|
// put socket into blocking mode
|
|
//
|
|
|
|
val = 0;
|
|
Vioctlsocket(s, FIONBIO, &val);
|
|
|
|
//
|
|
// communicate with SOCKS firewall: send SOCKS request & receive response
|
|
//
|
|
|
|
serr = Vconnect(s, &sin, sizeof(sin));
|
|
if (serr != SOCKET_ERROR) {
|
|
serr = Vsend(s, (int)&request, length, 0);
|
|
if (serr == length) {
|
|
serr = Vrecv(s, (int)response, sizeof(response), 0);
|
|
}
|
|
}
|
|
|
|
//
|
|
// if originally non-blocking, make socket non-blocking again
|
|
//
|
|
|
|
if (blocking) {
|
|
Vioctlsocket(s, FIONBIO, &blocking);
|
|
}
|
|
|
|
//
|
|
// if success, mark the socket as being connected through firewall
|
|
//
|
|
|
|
if ((serr == SOCKET_ERROR) || (response[1] != 90)) {
|
|
VWSASetLastError(WSAECONNREFUSED);
|
|
serr = SOCKET_ERROR;
|
|
} else {
|
|
|
|
//
|
|
// if we can't find/crea
|
|
//
|
|
|
|
pSocket = FindSocket(s);
|
|
if (pSocket) {
|
|
pSocket->Socked = 1;
|
|
serr = 0;
|
|
} else {
|
|
VWSASetLastError(WSAENOBUFS);
|
|
serr = SOCKET_ERROR;
|
|
}
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
}
|
|
return serr;
|
|
}
|
|
|
|
DWORD WINAPI dn_expand(int a,int b,int c,int d,int e) {
|
|
return(Vdn_expand(a, b, c, d, e));
|
|
}
|
|
|
|
DWORD WINAPI EnumProtocolsA(int a,int b,int c) {
|
|
return(VEnumProtocolsA(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI EnumProtocolsW(int a,int b,int c) {
|
|
return(VEnumProtocolsW(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI GetAddressByNameA(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j) {
|
|
return(VGetAddressByNameA(a, b, c, d, e, f, g, h, i, j));
|
|
}
|
|
|
|
DWORD WINAPI GetAddressByNameW(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j) {
|
|
return(VGetAddressByNameW(a, b, c, d, e, f, g, h, i, j));
|
|
}
|
|
|
|
DWORD WINAPI gethostbyaddr(int a,int b,int c) {
|
|
return(Vgethostbyaddr(a, b, c));
|
|
}
|
|
|
|
struct hostent FAR * WINAPI gethostbyname(char *a) {
|
|
return(Vgethostbyname(a));
|
|
}
|
|
|
|
DWORD WINAPI gethostname(int a,int b) {
|
|
return(Vgethostname(a, b));
|
|
}
|
|
|
|
DWORD WINAPI GetNameByTypeA(int a,int b,int c) {
|
|
return(VGetNameByTypeA(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI GetNameByTypeW(int a,int b,int c) {
|
|
return(VGetNameByTypeW(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI getnetbyname(int a) {
|
|
return(Vgetnetbyname(a));
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
getpeername(
|
|
int s,
|
|
struct sockaddr_in * name,
|
|
int *namelen
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
description-of-function.
|
|
|
|
Arguments:
|
|
|
|
s -
|
|
|
|
name -
|
|
|
|
namelen -
|
|
|
|
Return Value:
|
|
|
|
int
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD ret;
|
|
struct Sockets *So;
|
|
|
|
ret = Vgetpeername(s, name, namelen);
|
|
if (ret == 0) {
|
|
So = FindSocket(s);
|
|
if (So) {
|
|
if (So->Socked) {
|
|
if (*namelen >= sizeof(struct sockaddr_in)) {
|
|
name->sin_port = So->port;
|
|
name->sin_addr.s_addr = So->ip;
|
|
}
|
|
}
|
|
} else {
|
|
VWSASetLastError(WSAENOBUFS);
|
|
ret = SOCKET_ERROR;
|
|
}
|
|
|
|
LEAVE_MUTEX();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
DWORD WINAPI getprotobyname(int a) {
|
|
return(Vgetprotobyname(a));
|
|
}
|
|
|
|
DWORD WINAPI getprotobynumber(int a) {
|
|
return(Vgetprotobynumber(a));
|
|
}
|
|
|
|
struct servent * WINAPI getservbyname(const char FAR * name, const char FAR * proto) {
|
|
return(Vgetservbyname(name, proto));
|
|
}
|
|
|
|
DWORD WINAPI getservbyport(int a,int b) {
|
|
return(Vgetservbyport(a, b));
|
|
}
|
|
|
|
DWORD WINAPI GetServiceA(int a,int b,int c,int d,int e,int f,int g) {
|
|
return(VGetServiceA(a, b, c, d, e, f, g));
|
|
}
|
|
|
|
DWORD WINAPI GetServiceW(int a,int b,int c,int d,int e,int f,int g) {
|
|
return(VGetServiceW(a, b, c, d, e, f, g));
|
|
}
|
|
|
|
DWORD WINAPI getsockname(int a,int b,int c) {
|
|
return(Vgetsockname(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI getsockopt(int a,int b,int c,int d,int e) {
|
|
return(Vgetsockopt(a, b, c, d, e));
|
|
}
|
|
|
|
DWORD WINAPI GetTypeByNameA(int a,int b) {
|
|
return(VGetTypeByNameA(a, b));
|
|
}
|
|
|
|
DWORD WINAPI GetTypeByNameW(int a,int b) {
|
|
return(VGetTypeByNameW(a, b));
|
|
}
|
|
|
|
DWORD WINAPI htonl(int a) {
|
|
return(Vhtonl(a));
|
|
}
|
|
|
|
DWORD WINAPI htons(int a) {
|
|
return(Vhtons(a));
|
|
}
|
|
|
|
DWORD WINAPI inet_addr(char *p) {
|
|
return(Vinet_addr(p));
|
|
}
|
|
|
|
DWORD WINAPI inet_network(int a) {
|
|
return(Vinet_network(a));
|
|
}
|
|
|
|
DWORD WINAPI inet_ntoa(int a) {
|
|
return(Vinet_ntoa(a));
|
|
}
|
|
|
|
DWORD WINAPI ioctlsocket(int s, long cmd, unsigned long *argp) {
|
|
if (cmd == FIONBIO) {
|
|
|
|
struct Sockets * So = FindSocket(s);
|
|
|
|
if (So == NULL) {
|
|
VWSASetLastError(WSAENOBUFS);
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
return SOCKET_ERROR;
|
|
}
|
|
So->Blocking = *argp ? 1 : 0;
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
}
|
|
return Vioctlsocket(s, cmd, argp);
|
|
}
|
|
|
|
DWORD WINAPI listen(int a,int b) {
|
|
return(Vlisten(a, b));
|
|
}
|
|
|
|
DWORD WINAPI NPLoadNameSpaces(int a,int b,int c) {
|
|
return(VNPLoadNameSpaces(a, b, c));
|
|
}
|
|
|
|
DWORD WINAPI ntohl(int a) {
|
|
return(Vntohl(a));
|
|
}
|
|
|
|
DWORD WINAPI ntohs(int a) {
|
|
return(Vntohs(a));
|
|
}
|
|
|
|
DWORD WINAPI rcmd(int a,int b,int c,int d,int e,int f) {
|
|
return(Vrcmd(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD WINAPI recv(int a,int b,int c,int d) {
|
|
return(Vrecv(a, b, c, d));
|
|
}
|
|
|
|
DWORD WINAPI recvfrom(int a,int b,int c,int d,int e,int f) {
|
|
return(Vrecvfrom(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD WINAPI rexec(int a,int b,int c,int d,int e,int f) {
|
|
return(Vrexec(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD WINAPI rresvport(int a) {
|
|
return(Vrresvport(a));
|
|
}
|
|
|
|
DWORD WINAPI s_perror(int a,int b) {
|
|
return(Vs_perror(a, b));
|
|
}
|
|
|
|
DWORD WINAPI select(int a,int b,int c,int d,int e) {
|
|
return(Vselect(a, b, c, d, e));
|
|
}
|
|
|
|
DWORD WINAPI send(int a,int b,int c,int d) {
|
|
return(Vsend(a, b, c, d));
|
|
}
|
|
|
|
DWORD WINAPI sendto(int a,int b,int c,int d,int e,int f) {
|
|
return(Vsendto(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD WINAPI sethostname(int a,int b) {
|
|
return(Vsethostname(a, b));
|
|
}
|
|
|
|
DWORD WINAPI SetServiceA(int a,int b,int c,int d,int e,int f) {
|
|
return(VSetServiceA(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD WINAPI SetServiceW(int a,int b,int c,int d,int e,int f) {
|
|
return(VSetServiceW(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
setsockopt(
|
|
int s,
|
|
int level,
|
|
int optname,
|
|
const char FAR * optval,
|
|
int optlen
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
If SO_SET_SOCKS_FIREWALL, create SOCKS information if it is new or changed
|
|
from current, else pass on the request to wsock32!setsockopt()
|
|
|
|
Arguments:
|
|
|
|
s - socket on which to set option
|
|
|
|
level - option type parameter (SO_SET_SOCKS_FIREWALL)
|
|
|
|
optname - option type sub-parameter (SOCKS firewall port # in host format)
|
|
|
|
optval - value to set (pointer to SOCKS information:
|
|
DWORD ip address;
|
|
LPSTR username
|
|
)
|
|
|
|
optlen - length of value (8)
|
|
|
|
Return Value:
|
|
|
|
DWORD
|
|
Success - 0
|
|
|
|
Failure - -1
|
|
|
|
--*/
|
|
|
|
{
|
|
int rc;
|
|
|
|
if (level != SO_SET_SOCKS_FIREWALL) {
|
|
rc = Vsetsockopt(s, level, optname, optval, optlen);
|
|
} else {
|
|
|
|
struct Hosts * pHost;
|
|
struct FirewallInfo {
|
|
DWORD ipAddress;
|
|
LPSTR userName;
|
|
} * pInfo = (struct FirewallInfo *)optval;
|
|
|
|
optname = Vhtons(optname);
|
|
|
|
ENTER_MUTEX();
|
|
|
|
if (pHost = Head) {
|
|
if ((pHost->ip != pInfo->ipAddress)
|
|
|| (pHost->port != optname)
|
|
|| (pHost->user && lstrcmp(pHost->user, pInfo->userName))) {
|
|
//char buf[256];
|
|
//wsprintf(buf,
|
|
// "throwing out: host: %d.%d.%d.%d:%d,%s; info: %d.%d.%d.%d:%d,%s\n",
|
|
// pHost->ip & 0xff,
|
|
// (pHost->ip >> 8) & 0xff,
|
|
// (pHost->ip >> 16) & 0xff,
|
|
// (pHost->ip >> 24) & 0xff,
|
|
// Vhtons(pHost->port) & 0xffff,
|
|
// pHost->user,
|
|
// pInfo->ipAddress & 0xff,
|
|
// (pInfo->ipAddress >> 8) & 0xff,
|
|
// (pInfo->ipAddress >> 16) & 0xff,
|
|
// (pInfo->ipAddress >> 24) & 0xff,
|
|
// Vhtons(optname) & 0xffff,
|
|
// pInfo->userName
|
|
// );
|
|
//OutputDebugString(buf);
|
|
LocalFree(pHost);
|
|
pHost = NULL;
|
|
}
|
|
}
|
|
if (!pHost) {
|
|
|
|
int userlen = lstrlen(pInfo->userName) + 1;
|
|
|
|
if (pHost = (struct Hosts *)LocalAlloc(LPTR,
|
|
sizeof(struct Hosts)
|
|
+ userlen
|
|
)) {
|
|
memcpy(pHost + 1, pInfo->userName, userlen);
|
|
pHost->user = (LPSTR)(pHost + 1);
|
|
pHost->userlen = userlen;
|
|
pHost->ip = pInfo->ipAddress;
|
|
pHost->port = (unsigned short)optname;
|
|
}
|
|
}
|
|
Head = pHost;
|
|
if (pHost) {
|
|
rc = 0;
|
|
} else {
|
|
VWSASetLastError(WSAENOBUFS);
|
|
rc = SOCKET_ERROR;
|
|
}
|
|
|
|
LEAVE_MUTEX();
|
|
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
DWORD WINAPI shutdown(int a,int b) {
|
|
return(Vshutdown(a, b));
|
|
}
|
|
|
|
DWORD WINAPI socket(int af,int type,int protocol) {
|
|
|
|
struct Sockets * So;
|
|
int s;
|
|
|
|
s = Vsocket(af, type, protocol);
|
|
if (s != INVALID_SOCKET) {
|
|
So = FindSocket(s);
|
|
if (So) {
|
|
So->type = type;
|
|
} else {
|
|
Vclosesocket(s);
|
|
VWSASetLastError(WSAENOBUFS);
|
|
s = INVALID_SOCKET;
|
|
}
|
|
LEAVE_MUTEX();
|
|
}
|
|
return s;
|
|
}
|
|
|
|
DWORD WINAPI TransmitFile(int a,int b,int c,int d,int e,int f,int g) {
|
|
return(VTransmitFile(a, b, c, d, e, f, g));
|
|
}
|
|
|
|
DWORD WINAPI WEP() {
|
|
return(VWEP());
|
|
}
|
|
|
|
DWORD WINAPI WSAAsyncGetHostByAddr(int a,int b,int c,int d,int e,int f,int g) {
|
|
return(VWSAAsyncGetHostByAddr(a, b, c, d, e, f, g));
|
|
}
|
|
|
|
DWORD WINAPI WSAAsyncGetHostByName(int a,int b,int c,int d,int e) {
|
|
return(VWSAAsyncGetHostByName(a, b, c, d, e));
|
|
}
|
|
|
|
DWORD WINAPI WSAAsyncGetProtoByName(int a,int b,int c,int d,int e) {
|
|
return(VWSAAsyncGetProtoByName(a, b, c, d, e));
|
|
}
|
|
|
|
DWORD WINAPI WSAAsyncGetProtoByNumber(int a,int b,int c,int d,int e) {
|
|
return(VWSAAsyncGetProtoByNumber(a, b, c, d, e));
|
|
}
|
|
|
|
DWORD WINAPI WSAAsyncGetServByName(int a,int b,int c,int d,int e,int f) {
|
|
return(VWSAAsyncGetServByName(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD WINAPI WSAAsyncGetServByPort(int a,int b,int c,int d,int e,int f) {
|
|
return(VWSAAsyncGetServByPort(a, b, c, d, e, f));
|
|
}
|
|
|
|
DWORD WINAPI WSAAsyncSelect(int s, HWND hWnd, unsigned int wMsg, long lEvent) {
|
|
return(VWSAAsyncSelect(s,hWnd,wMsg,lEvent));
|
|
}
|
|
|
|
DWORD WINAPI WSACancelAsyncRequest(int a) {
|
|
return(VWSACancelAsyncRequest(a));
|
|
}
|
|
|
|
DWORD WINAPI WSACancelBlockingCall() {
|
|
return(VWSACancelBlockingCall());
|
|
}
|
|
|
|
DWORD WINAPI WSACleanup() {
|
|
return(VWSACleanup());
|
|
}
|
|
|
|
DWORD WINAPI WSAGetLastError() {
|
|
return(VWSAGetLastError());
|
|
}
|
|
|
|
DWORD WINAPI WSAIsBlocking() {
|
|
return(VWSAIsBlocking());
|
|
}
|
|
|
|
DWORD WINAPI WSARecvEx(int a,int b,int c,int d) {
|
|
return(VWSARecvEx(a, b, c, d));
|
|
}
|
|
|
|
DWORD WINAPI WSASetBlockingHook(int a) {
|
|
return(VWSASetBlockingHook(a));
|
|
}
|
|
|
|
DWORD WINAPI WSASetLastError(int a) {
|
|
return(VWSASetLastError(a));
|
|
}
|
|
|
|
DWORD WINAPI WSAStartup(int a,int b) {
|
|
return(VWSAStartup(a, b));
|
|
}
|
|
|
|
DWORD WINAPI WSAUnhookBlockingHook() {
|
|
return(VWSAUnhookBlockingHook());
|
|
}
|
|
|
|
DWORD WINAPI WsControl(int a,int b,int c,int d,int e,int f) {
|
|
return(VWsControl(a,b,c,d,e,f));
|
|
}
|
|
|
|
DWORD WSHEnumProtocols(int a,int b, int c,int d) {
|
|
return(VWSHEnumProtocols(a,b,c,d));
|
|
}
|
|
|
|
//#ifdef DO_FILE_CONFIG
|
|
//
|
|
//void
|
|
//ParseList(char *List,struct Server **Head,int IsSvr) {
|
|
//
|
|
// char *p;
|
|
// char *p1;
|
|
// char *pTok;
|
|
// struct Server *tmp,*Current=NULL;
|
|
//
|
|
// *Head = NULL;
|
|
//
|
|
// if ( *(List+1) != '=')
|
|
// return;
|
|
// pTok = List+2;
|
|
// List=StrTokEx(&pTok,"\t ");
|
|
// p = StrTokEx(&List,",");
|
|
// while ( p) {
|
|
// if (IsSvr) {
|
|
// tmp = (struct Server *)LocalAlloc(LPTR, (sizeof(struct Server)));
|
|
// if ( tmp == NULL )
|
|
// return;
|
|
//
|
|
// p1 = strchr(p,':');
|
|
// if (p1) {
|
|
// *p1++ = 0;
|
|
// tmp->port = atoi(p1);
|
|
// }
|
|
// else
|
|
// tmp->port = 1080;
|
|
// }
|
|
// else {
|
|
// tmp = (struct Server *)LocalAlloc(LPTR, (sizeof(struct Server)));
|
|
// if ( tmp == NULL )
|
|
// return;
|
|
// }
|
|
// tmp->Name = NewString(p);
|
|
// tmp->Next = NULL;
|
|
// if (Current == NULL) {
|
|
// Current = *Head = tmp;
|
|
// }
|
|
// else {
|
|
// Current->Next = tmp;
|
|
// Current=tmp;
|
|
// }
|
|
// p = StrTokEx(&List,",");
|
|
// }
|
|
//}
|
|
//
|
|
//
|
|
//void
|
|
//LoadConfig(void) {
|
|
//
|
|
// struct Hosts *Current=NULL,*tmp;
|
|
// char Buffer[1024];
|
|
// FILE *f;
|
|
// char *p;
|
|
// char *ServerList;
|
|
// char *UserList;
|
|
// struct Server *Default=NULL;
|
|
// HKEY Key;
|
|
//
|
|
// GetSystemDirectory(Buffer,sizeof(Buffer));
|
|
// strcat(Buffer, "\\socks.cnf");
|
|
// f = fopen(Buffer,"rt");
|
|
// if ( f == NULL)
|
|
// return;
|
|
// if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\HummingBird", 0, KEY_QUERY_VALUE, &Key) == ERROR_SUCCESS) {
|
|
// int Type, Length=sizeof(Buffer);
|
|
// if ( RegQueryValueEx(Key, "SOCKS_SERVER", NULL, &Type, Buffer, &Length) == ERROR_SUCCESS) {
|
|
// Buffer[Length] = '\0';
|
|
// Default=LocalAlloc(LPTR, sizeof(struct Server));
|
|
// if ( Default == NULL )
|
|
// return;
|
|
//
|
|
// p = strchr(Buffer,':');
|
|
// if (p) {
|
|
// *p++ = 0;
|
|
// Default->port = atoi(p);
|
|
// }
|
|
// else
|
|
// Default->port = 1080;
|
|
// Default->Name = NewString(Buffer);
|
|
// Default->Next = NULL;
|
|
// }
|
|
// RegCloseKey(Key);
|
|
// }
|
|
//
|
|
// while ( fgets(Buffer,sizeof(Buffer)-1,f) != NULL) {
|
|
// Buffer[strlen(Buffer)-1]='\0';
|
|
// if ( Buffer[0] == '#')
|
|
// continue;
|
|
// tmp = (struct Hosts *) LocalAlloc(LPTR, sizeof(struct Hosts));
|
|
// if ( tmp == NULL )
|
|
// return;
|
|
//
|
|
// memset(tmp,0,sizeof(struct Hosts));
|
|
// ServerList=NULL;
|
|
// UserList=NULL;
|
|
// p = StrTokEx(&Buffer,"\t ");
|
|
// if ( p == NULL) {
|
|
// LocalFree(tmp);
|
|
// continue;
|
|
// }
|
|
// if ( lstrcmpi(p,"DENY") == 0) {
|
|
// tmp->type = DENY;
|
|
// } else if (lstrcmpi(p,"DIRECT") == 0) {
|
|
// tmp->type = DIRECT;
|
|
// } else if (lstrcmpi(p,"SOCKD") == 0) {
|
|
// tmp->type = SOCKD;
|
|
// } else {
|
|
// LocalFree(tmp);
|
|
// continue;
|
|
// }
|
|
//LookMore:
|
|
// p = StrTokEx(&Buffer,"\t ");
|
|
// if ( p == NULL) {
|
|
// LocalFree(tmp);
|
|
// continue;
|
|
// }
|
|
// if (*p == '*') {
|
|
// UserList=p;
|
|
// goto LookMore;
|
|
// }
|
|
// if (*p == '@') {
|
|
// ServerList=p;
|
|
// goto LookMore;
|
|
// }
|
|
// tmp->dst = Vinet_addr(p);
|
|
// p = StrTokEx(&Buffer,"\t ");
|
|
// if ( p == NULL) {
|
|
// LocalFree(tmp);
|
|
// continue;
|
|
// }
|
|
// tmp->mask = Vinet_addr(p);
|
|
// p = StrTokEx(&Buffer,"\t ");
|
|
// if (p) {
|
|
// if ( lstrcmpi(p,"EQ") == 0)
|
|
// tmp->op = EQ;
|
|
// else if ( lstrcmpi(p,"NEQ") == 0)
|
|
// tmp->op = NEQ;
|
|
// else if ( lstrcmpi(p,"LT") == 0)
|
|
// tmp->op = LT;
|
|
// else if ( lstrcmpi(p,"GT") == 0)
|
|
// tmp->op = GT;
|
|
// else if ( lstrcmpi(p,"LE") == 0)
|
|
// tmp->op = LE;
|
|
// else if ( lstrcmpi(p,"GE") == 0)
|
|
// tmp->op = GE;
|
|
// else {
|
|
// LocalFree(tmp);
|
|
// continue;
|
|
// }
|
|
// p = StrTokEx(&Buffer,"\t ");
|
|
// if ( p == NULL) {
|
|
// LocalFree(tmp);
|
|
// continue;
|
|
// }
|
|
// if ( isdigit(*p))
|
|
// tmp->port = atoi(p);
|
|
// else {
|
|
// struct servent *se;
|
|
// se=Vgetservbyname(p,"tcp");
|
|
// if ( se == NULL) {
|
|
// LocalFree(tmp);
|
|
// continue;
|
|
// }
|
|
// tmp->port = se->s_port;
|
|
// }
|
|
// }
|
|
// if ( UserList)
|
|
// ParseList(UserList,(struct Server **)&tmp->Users,0);
|
|
// if ( ServerList)
|
|
// ParseList(ServerList,&tmp->Servers,1);
|
|
// if ( (tmp->type == SOCKD) && (tmp->Servers == NULL))
|
|
// tmp->Servers=Default;
|
|
// if ( Current == NULL) {
|
|
// Head = Current = tmp;
|
|
// }
|
|
// else {
|
|
// Current->Next = tmp;
|
|
// Current = tmp;
|
|
// }
|
|
// }
|
|
// fclose(f);
|
|
//}
|
|
//
|
|
//#endif
|
|
|
|
HMODULE hModule = NULL;
|
|
int LoadCount = 0;
|
|
|
|
BOOL
|
|
WINAPI
|
|
DllMain(
|
|
IN HINSTANCE hInstance,
|
|
IN DWORD reason,
|
|
IN LPVOID Reserved
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
TCHAR szRegBuf[MAX_PATH+1];
|
|
DWORD dwRegBufSize = sizeof(szRegBuf);
|
|
DWORD dwRegType;
|
|
LONG lResult;
|
|
|
|
switch(reason) {
|
|
case DLL_PROCESS_DETACH:
|
|
if (LoadCount == 0) {
|
|
DELETE_MUTEX();
|
|
return 1;
|
|
}
|
|
if (--LoadCount == 0) {
|
|
FreeLibrary(hModule);
|
|
}
|
|
return 1;
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
case DLL_THREAD_ATTACH:
|
|
if (++LoadCount == 1) {
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return 1;
|
|
}
|
|
|
|
// Load an alternate Winsock DLL based on a registry value,
|
|
// in the event that a customer wants to load a different wsock32.
|
|
//
|
|
if (ERROR_SUCCESS == (lResult = RegOpenKeyEx(
|
|
HKEY_CURRENT_USER,
|
|
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hKey
|
|
)))
|
|
{
|
|
if (ERROR_SUCCESS == (lResult = RegQueryValueEx(
|
|
hKey,
|
|
TEXT("AlternateWinsock"),
|
|
NULL,
|
|
&dwRegType,
|
|
(LPBYTE) szRegBuf,
|
|
&dwRegBufSize
|
|
)) && dwRegType == REG_SZ) // only allow type REG_SZ
|
|
{
|
|
// Found a string, so try to load it as the alternate Winsock DLL.
|
|
hModule = LoadLibrary(szRegBuf);
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
hModule = LoadLibrary("WSOCK32.DLL");
|
|
}
|
|
|
|
if (hModule < (HMODULE) HINSTANCE_ERROR) {
|
|
MessageBox(NULL,
|
|
"Unable to find old WSOCK32.DLL named \"WSOCK32.DLL\".",
|
|
"Microsoft/Hummingbird SOCKS Shim",
|
|
MB_OK
|
|
);
|
|
LoadCount = 0;
|
|
return 0;
|
|
}
|
|
|
|
(FARPROC) VArecv=GetProcAddress(hModule,"Arecv");
|
|
(FARPROC) VAsend=GetProcAddress(hModule,"Asend");
|
|
(FARPROC) VEnumProtocolsA=GetProcAddress(hModule,"EnumProtocolsA");
|
|
(FARPROC) VEnumProtocolsW=GetProcAddress(hModule,"EnumProtocolsW");
|
|
(FARPROC) VGetAddressByNameA=GetProcAddress(hModule,"GetAddressByNameA");
|
|
(FARPROC) VGetAddressByNameW=GetProcAddress(hModule,"GetAddressByNameW");
|
|
(FARPROC) VGetNameByTypeA=GetProcAddress(hModule,"GetNameByTypeA");
|
|
(FARPROC) VGetNameByTypeW=GetProcAddress(hModule,"GetNameByTypeW");
|
|
(FARPROC) VGetServiceA=GetProcAddress(hModule,"GetServiceA");
|
|
(FARPROC) VGetServiceW=GetProcAddress(hModule,"GetServiceW");
|
|
(FARPROC) VGetTypeByNameA=GetProcAddress(hModule,"GetTypeByNameA");
|
|
(FARPROC) VGetTypeByNameW=GetProcAddress(hModule,"GetTypeByNameW");
|
|
(FARPROC) VNPLoadNameSpaces=GetProcAddress(hModule,"NPLoadNameSpaces");
|
|
(FARPROC) VSetServiceA=GetProcAddress(hModule,"SetServiceA");
|
|
(FARPROC) VSetServiceW=GetProcAddress(hModule,"SetServiceW");
|
|
(FARPROC) VTransmitFile=GetProcAddress(hModule,"TransmitFile");
|
|
(FARPROC) VWSAAsyncGetHostByAddr=GetProcAddress(hModule,"WSAAsyncGetHostByAddr");
|
|
(FARPROC) VWSAAsyncGetHostByName=GetProcAddress(hModule,"WSAAsyncGetHostByName");
|
|
(FARPROC) VWSAAsyncGetProtoByName=GetProcAddress(hModule,"WSAAsyncGetProtoByName");
|
|
(FARPROC) VWSAAsyncGetProtoByNumber=GetProcAddress(hModule,"WSAAsyncGetProtoByNumber");
|
|
(FARPROC) VWSAAsyncGetServByName=GetProcAddress(hModule,"WSAAsyncGetServByName");
|
|
(FARPROC) VWSAAsyncGetServByPort=GetProcAddress(hModule,"WSAAsyncGetServByPort");
|
|
(FARPROC) VWSAAsyncSelect=GetProcAddress(hModule,"WSAAsyncSelect");
|
|
(FARPROC) VWSACancelAsyncRequest=GetProcAddress(hModule,"WSACancelAsyncRequest");
|
|
(FARPROC) VWSACancelBlockingCall=GetProcAddress(hModule,"WSACancelBlockingCall");
|
|
(FARPROC) VWSACleanup=GetProcAddress(hModule,"WSACleanup");
|
|
(FARPROC) VWSAGetLastError=GetProcAddress(hModule,"WSAGetLastError");
|
|
(FARPROC) VWSAIsBlocking=GetProcAddress(hModule,"WSAIsBlocking");
|
|
(FARPROC) VWSARecvEx=GetProcAddress(hModule,"WSARecvEx");
|
|
(FARPROC) VWSASetBlockingHook=GetProcAddress(hModule,"WSASetBlockingHook");
|
|
(FARPROC) VWSASetLastError=GetProcAddress(hModule,"WSASetLastError");
|
|
(FARPROC) VWSAStartup=GetProcAddress(hModule,"WSAStartup");
|
|
(FARPROC) VWSAUnhookBlockingHook=GetProcAddress(hModule,"WSAUnhookBlockingHook");
|
|
(FARPROC) VWSHEnumProtocols=GetProcAddress(hModule,"WSHEnumProtocols");
|
|
(FARPROC) VWsControl=GetProcAddress(hModule,"WsControl");
|
|
(FARPROC) V__WSAFDIsSet=GetProcAddress(hModule,"__WSAFDIsSet");
|
|
(FARPROC) Vaccept=GetProcAddress(hModule,"accept");
|
|
(FARPROC) Vbind=GetProcAddress(hModule,"bind");
|
|
(FARPROC) Vclosesocket=GetProcAddress(hModule,"closesocket");
|
|
(FARPROC) Vclosesockinfo=GetProcAddress(hModule,"closesockinfo");
|
|
(FARPROC) Vconnect=GetProcAddress(hModule,"connect");
|
|
(FARPROC) Vdn_expand=GetProcAddress(hModule,"dn_expand");
|
|
(FARPROC) Vgethostbyaddr=GetProcAddress(hModule,"gethostbyaddr");
|
|
(FARPROC) Vgethostbyname=GetProcAddress(hModule,"gethostbyname");
|
|
(FARPROC) Vgethostname=GetProcAddress(hModule,"gethostname");
|
|
(FARPROC) Vgetnetbyname=GetProcAddress(hModule,"getnetbyname");
|
|
(FARPROC) Vgetpeername=GetProcAddress(hModule,"getpeername");
|
|
(FARPROC) Vgetprotobyname=GetProcAddress(hModule,"getprotobyname");
|
|
(FARPROC) Vgetprotobynumber=GetProcAddress(hModule,"getprotobynumber");
|
|
(FARPROC) Vgetservbyname=GetProcAddress(hModule,"getservbyname");
|
|
(FARPROC) Vgetservbyport=GetProcAddress(hModule,"getservbyport");
|
|
(FARPROC) Vgetsockname=GetProcAddress(hModule,"getsockname");
|
|
(FARPROC) Vgetsockopt=GetProcAddress(hModule,"getsockopt");
|
|
(FARPROC) Vhtonl=GetProcAddress(hModule,"htonl");
|
|
(FARPROC) Vhtons=GetProcAddress(hModule,"htons");
|
|
(FARPROC) Vinet_addr=GetProcAddress(hModule,"inet_addr");
|
|
(FARPROC) Vinet_network=GetProcAddress(hModule,"inet_network");
|
|
(FARPROC) Vinet_ntoa=GetProcAddress(hModule,"inet_ntoa");
|
|
(FARPROC) Vioctlsocket=GetProcAddress(hModule,"ioctlsocket");
|
|
(FARPROC) Vlisten=GetProcAddress(hModule,"listen");
|
|
(FARPROC) Vntohl=GetProcAddress(hModule,"ntohl");
|
|
(FARPROC) Vntohs=GetProcAddress(hModule,"ntohs");
|
|
(FARPROC) Vrcmd=GetProcAddress(hModule,"rcmd");
|
|
(FARPROC) Vrecv=GetProcAddress(hModule,"recv");
|
|
(FARPROC) Vrecvfrom=GetProcAddress(hModule,"recvfrom");
|
|
(FARPROC) Vrexec=GetProcAddress(hModule,"rexec");
|
|
(FARPROC) Vrresvport=GetProcAddress(hModule,"rresvport");
|
|
(FARPROC) Vs_perror=GetProcAddress(hModule,"s_perror");
|
|
(FARPROC) Vselect=GetProcAddress(hModule,"select");
|
|
(FARPROC) Vsend=GetProcAddress(hModule,"send");
|
|
(FARPROC) Vsendto=GetProcAddress(hModule,"sendto");
|
|
(FARPROC) Vsethostname=GetProcAddress(hModule,"sethostname");
|
|
(FARPROC) Vsetsockopt=GetProcAddress(hModule,"setsockopt");
|
|
(FARPROC) Vshutdown=GetProcAddress(hModule,"shutdown");
|
|
(FARPROC) Vsocket=GetProcAddress(hModule,"socket");
|
|
(FARPROC) VWEP=GetProcAddress(hModule,"WEP");
|
|
(FARPROC) VAcceptEx = GetProcAddress(hModule,"AcceptEx");
|
|
(FARPROC) VGetAcceptExSockaddrs = GetProcAddress(hModule,"GetAcceptExSockaddrs");
|
|
(FARPROC) VMigrateWinsockConfiguration = GetProcAddress(hModule,"MigrateWinsockConfiguration");
|
|
(FARPROC) VWSApSetPostRoutine = GetProcAddress(hModule,"WSApSetPostRoutine");
|
|
|
|
CREATE_MUTEX();
|
|
|
|
#ifdef DO_FILE_CONFIG
|
|
LoadConfig();
|
|
#endif
|
|
|
|
return 1;
|
|
}
|