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.
2132 lines
56 KiB
2132 lines
56 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
olddb.c
|
|
|
|
Contents:
|
|
old getxbyy emulations
|
|
|
|
Abstract:
|
|
|
|
This module contains support for the getprotobyY WinSock APIs.
|
|
|
|
Author:
|
|
|
|
David Treadwell (davidtr) 29-Jun-1992
|
|
|
|
Revision History:
|
|
|
|
02-Feb-1994 rfirth Modified for Chicago/Snowball
|
|
|
|
MohsinA, 13-Mar-96. Winsock2 RnR re-routing.
|
|
v11_App
|
|
=> wsock32: getxbyy()
|
|
=> ws2_32: ws2_getxbyy()
|
|
=> wsock32: GETXBYYSP_getxbyy()
|
|
|
|
|
|
|
|
--*/
|
|
|
|
#include "winsockp.h"
|
|
#include "nspmisc.h"
|
|
#include <nspapi.h>
|
|
#ifndef CHICAGO
|
|
#define SOCKAPI WSAAPI
|
|
#else // CHICAGO
|
|
#include "imported.h"
|
|
#endif // CHICAGO
|
|
|
|
struct servent FAR *
|
|
_pgetservebyport(
|
|
IN const int port,
|
|
IN const FAR char *name
|
|
);
|
|
|
|
struct servent FAR *
|
|
_pgetservebyname(
|
|
IN const FAR char *name,
|
|
IN const FAR char *proto
|
|
);
|
|
|
|
CopyServentToBuffer (
|
|
IN char FAR * Buffer,
|
|
IN int BufferLength,
|
|
IN LPSERVENT Servent
|
|
);
|
|
|
|
|
|
//
|
|
// private prototypes
|
|
//
|
|
|
|
#ifdef CHICAGO
|
|
HANDLE
|
|
AsyncGetServByYCommon(
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN char FAR * Name,
|
|
IN char FAR * Protocol,
|
|
IN int Port,
|
|
IN char FAR * Buffer,
|
|
IN int BufferLength
|
|
);
|
|
|
|
extern HANDLE GenerateNextTaskHandle(VOID);
|
|
|
|
|
|
#else
|
|
|
|
#define FSTRCPY strcpy
|
|
#define FSTRLEN strlen
|
|
|
|
#endif // CHICAGO
|
|
|
|
//
|
|
// macros
|
|
//
|
|
|
|
#define h_addr_ptrs ACCESS_THREAD_DATA( h_addr_ptrs, GETHOST )
|
|
#define host ACCESS_THREAD_DATA( host, GETHOST )
|
|
#define host_aliases ACCESS_THREAD_DATA( host_aliases, GETHOST )
|
|
#define hostbuf ACCESS_THREAD_DATA( hostbuf, GETHOST )
|
|
#define host_addr ACCESS_THREAD_DATA( host_addr, GETHOST )
|
|
#define hostaddr ACCESS_THREAD_DATA( hostaddr, GETHOST )
|
|
#define host_addrs ACCESS_THREAD_DATA( host_addrs, GETHOST )
|
|
#define HOSTDB ACCESS_THREAD_DATA( HOSTDB, GETHOST )
|
|
|
|
#if defined(CHICAGO)
|
|
#ifdef WIN32
|
|
#define _fmemcmp memcmp
|
|
#define _gethtbyaddr(addr, len, type) GetHostentFromAddress(pThread, addr, len, type)
|
|
#endif
|
|
|
|
|
|
//
|
|
// manifests
|
|
//
|
|
|
|
#if PACKETSZ > 1024
|
|
#define MAXPACKET PACKETSZ
|
|
#else
|
|
#define MAXPACKET 1024
|
|
#endif
|
|
|
|
//
|
|
// private types
|
|
//
|
|
|
|
typedef union {
|
|
HEADER hdr;
|
|
unsigned char buf[MAXPACKET];
|
|
} querybuf;
|
|
|
|
typedef union {
|
|
long al;
|
|
char ac;
|
|
} align;
|
|
|
|
|
|
//
|
|
// private prototypes
|
|
//
|
|
|
|
LPHOSTENT
|
|
getanswer(
|
|
IN LPSOCK_THREAD pThread,
|
|
OUT querybuf * answer,
|
|
OUT LPDWORD TimeToLive,
|
|
IN int anslen,
|
|
IN int iquery
|
|
);
|
|
|
|
LPHOSTENT
|
|
GetHostentByAttribute(
|
|
IN LPSOCK_THREAD pThread,
|
|
IN LPSTR Name,
|
|
IN LPBYTE Address
|
|
);
|
|
|
|
DWORD
|
|
CopyHostentToBuffer(
|
|
char FAR *Buffer,
|
|
int BufferLength,
|
|
PHOSTENT Hostent
|
|
);
|
|
|
|
|
|
#endif // CHICAGO
|
|
|
|
LPHOSTENT
|
|
_pgethostbyaddr(
|
|
const char FAR *addr,
|
|
int len,
|
|
int type
|
|
);
|
|
|
|
int
|
|
_pgethostname(
|
|
char FAR * addr,
|
|
int len
|
|
);
|
|
|
|
//
|
|
// data
|
|
//
|
|
|
|
extern GUID HostnameGuid;
|
|
|
|
|
|
#if OLDXBYY
|
|
|
|
INT
|
|
APIENTRY
|
|
__GetAddressByNameA (
|
|
IN DWORD dwNameSpace,
|
|
IN LPGUID lpServiceType,
|
|
IN LPTSTR lpServiceName,
|
|
IN LPINT lpiProtocols,
|
|
IN DWORD dwResolution,
|
|
IN LPSERVICE_ASYNC_INFO lpServiceAsyncInfo OPTIONAL,
|
|
IN OUT LPVOID lpCsaddrBuffer,
|
|
IN OUT LPDWORD lpdwBufferLength,
|
|
IN OUT LPTSTR lpAliasBuffer,
|
|
IN OUT LPDWORD lpdwAliasBufferLength
|
|
);
|
|
|
|
#endif
|
|
|
|
//
|
|
// functions
|
|
//
|
|
|
|
|
|
|
|
// ws2_32 RnR re-routing, MohsinA, 13-Mar-96.
|
|
|
|
struct servent FAR *
|
|
SOCKAPI
|
|
getservbyname(
|
|
const char FAR * name,
|
|
const char FAR * proto
|
|
)
|
|
{
|
|
struct servent FAR * se;
|
|
|
|
|
|
#ifndef CHICAGO
|
|
#undef getservbyname
|
|
extern struct servent * PASCAL getservbyname( const char * name, const char
|
|
* proto );
|
|
WS_ENTER( "getservbyname", (PVOID)name, (PVOID)proto, NULL, NULL );
|
|
se = getservbyname( name, proto );
|
|
|
|
WS_EXIT( "getservbyname", (INT)se, (BOOLEAN)( se == NULL ) );
|
|
|
|
#else // CHICAGO
|
|
WS_TRACE(NAME,">getservbyname(name=%s,proto=%x) => ws2",
|
|
name, proto, 0 );
|
|
|
|
se = ( * ws2_getservbyname )( name, proto );
|
|
|
|
WS_TRACE(NAME,"<getservbyname(name=%s,..) <= ws2: se=%x",
|
|
name, se, 0 );
|
|
#endif // CHICAGO
|
|
|
|
return se;
|
|
}
|
|
|
|
struct servent FAR *
|
|
SOCKAPI
|
|
GETXBYYSP_getservbyname(
|
|
const char FAR * name,
|
|
const char FAR * proto
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get service information corresponding to a service name and
|
|
protocol.
|
|
|
|
Arguments:
|
|
|
|
name - A pointer to a service name.
|
|
|
|
proto - A pointer to a protocol name. If this is NULL,
|
|
getservbyname() returns the first service entry for which the
|
|
name matches the s_name or one of the s_aliases. Otherwise
|
|
getservbyname() matches both the name and the proto.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, getservbyname() returns a pointer to the servent
|
|
structure described above. Otherwise it returns a NULL pointer and
|
|
a specific error number may be retrieved by calling
|
|
WSAGetLastError().
|
|
|
|
--*/
|
|
|
|
{
|
|
return(_pgetservebyname(name, proto));
|
|
}
|
|
|
|
struct servent FAR *
|
|
SOCKAPI
|
|
getservbyport(
|
|
int port,
|
|
const char FAR * proto
|
|
)
|
|
{
|
|
struct servent FAR * se;
|
|
|
|
#ifndef CHICAGO
|
|
#undef getservbyport
|
|
extern struct servent * PASCAL getservbyport( int port, const char * proto )
|
|
;
|
|
|
|
WS_ENTER( "getservbyport", (PVOID)port, (PVOID)proto, NULL, NULL );
|
|
|
|
se = getservbyport( port, proto );
|
|
|
|
WS_EXIT( "getservbyport", (INT)se, (BOOLEAN)( se == NULL ) );
|
|
#else // CHICAGO
|
|
WS_TRACE(NAME,">getservbyport(port/netbyteorder=%x,proto=%x) => ws2",
|
|
port, proto, 0 );
|
|
|
|
se = ( * ws2_getservbyport )( port, proto );
|
|
|
|
WS_TRACE(NAME,"<getservbyport(port=%d,..) <= ws2: se=%x",
|
|
port, se, 0 );
|
|
|
|
#endif // CHICAGO
|
|
return se;
|
|
}
|
|
|
|
struct servent FAR *
|
|
SOCKAPI
|
|
GETXBYYSP_getservbyport(
|
|
int port,
|
|
const char FAR * proto
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get service information corresponding to a port and protocol.
|
|
|
|
Arguments:
|
|
|
|
port - The port for a service, in network byte order.
|
|
|
|
proto - A pointer to a protocol name. If this is NULL,
|
|
getservbyport() returns the first service entry for which the
|
|
port matches the s_port. Otherwise getservbyport() matches both
|
|
the port and the proto.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
return(_pgetservebyport(port, proto));
|
|
}
|
|
|
|
|
|
|
|
#if !defined(CHICAGO) || defined(WIN32)
|
|
|
|
// ws2_32 RnR re-routing, MohsinA, 13-Mar-96.
|
|
HANDLE
|
|
SOCKAPI
|
|
WSAAsyncGetServByName(
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN const char FAR * Name,
|
|
IN const char FAR * Protocol,
|
|
IN char FAR * Buffer,
|
|
IN int BufferLength
|
|
)
|
|
{
|
|
HANDLE val;
|
|
|
|
#ifndef CHICAGO
|
|
#undef WSAAsyncGetServByName
|
|
extern HANDLE PASCAL WSAAsyncGetServByName( HWND hWnd, unsigned int wMsg,
|
|
const char FAR * Name, const char FAR * Protocol, char FAR * Buffer,
|
|
int BufferLength );
|
|
|
|
WS_ENTER( "WSAAsyncGetServByName", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Name, (PVOID)Protocol );
|
|
|
|
val = WSAAsyncGetServByName( hWnd, wMsg, Name, Protocol, Buffer, BufferLength );
|
|
|
|
WS_EXIT( "WSAAsyncGetServByName", (INT)val, (BOOLEAN)( val == NULL ) );
|
|
#else // CHICAGO
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT((">WSAAsyncGetServByName(hWnd=%d,wMsg=%d,Name=%s,\n\t",
|
|
hWnd, wMsg, Name ));
|
|
DLL_PRINT(("Protocol=%s, Buffer[%d] @ %x) => ws2.\n",
|
|
Protocol, BufferLength, Buffer ));
|
|
}
|
|
val = ( * ws2_WSAAsyncGetServByName )(
|
|
hWnd, wMsg, Name, Protocol, Buffer, BufferLength );
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT(("<WSAAsyncGetServByName <= ws2: HANDLE=%x.\n", val ));
|
|
}
|
|
#endif // CHICAGO
|
|
|
|
return val;
|
|
}
|
|
|
|
//
|
|
// N.B. WIN95 does not implement asynchrnous support for getservbyname
|
|
// or getservbyport. Sicne these operations are always local ones,
|
|
// providing an Asynch version seems unnecessary. It makes one wonder
|
|
// why NT bothers with it, but since it does, the code for doing it
|
|
// remains. arnoldm
|
|
|
|
HANDLE
|
|
SOCKAPI
|
|
GETXBYYSP_WSAAsyncGetServByName(
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN const char FAR * Name,
|
|
IN const char FAR * Protocol,
|
|
IN char FAR * Buffer,
|
|
IN int BufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is an asynchronous version of getservbyname(), and is
|
|
used to retrieve service information corresponding to a service
|
|
name. The Windows Sockets implementation initiates the operation
|
|
and returns to the caller immediately, passing back an asynchronous
|
|
task handle which the application may use to identify the operation.
|
|
When the operation is completed, the results (if any) are copied
|
|
into the buffer provided by the caller and a message is sent to the
|
|
application's window.
|
|
|
|
When the asynchronous operation is complete the application's window
|
|
hWnd receives message wMsg. The wParam argument contains the
|
|
asynchronous task handle as returned by the original function call.
|
|
The high 16 bits of lParam contain any error code. The error code
|
|
may be any error as defined in winsock.h. An error code of zero
|
|
indicates successful completion of the asynchronous operation. On
|
|
successful completion, the buffer supplied to the original function
|
|
call contains a hostent structure. To access the elements of this
|
|
structure, the original buffer address should be cast to a hostent
|
|
structure pointer and accessed as appropriate.
|
|
|
|
Note that if the error code is WSAENOBUFS, it indicates that the
|
|
size of the buffer specified by buflen in the original call was too
|
|
small to contain all the resultant information. In this case, the
|
|
low 16 bits of lParam contain the size of buffer required to supply
|
|
ALL the requisite information. If the application decides that the
|
|
partial data is inadequate, it may reissue the
|
|
WSAAsyncGetHostByAddr() function call with a buffer large enough to
|
|
receive all the desired information (i.e. no smaller than the low
|
|
16 bits of lParam).
|
|
|
|
The error code and buffer length should be extracted from the lParam
|
|
using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in
|
|
winsock.h as:
|
|
|
|
#define WSAGETASYNCERROR(lParam) HIWORD(lParam)
|
|
#define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)
|
|
|
|
The use of these macros will maximize the portability of the source
|
|
code for the application.
|
|
|
|
The buffer supplied to this function is used by the Windows Sockets
|
|
implementation to construct a hostent structure together with the
|
|
contents of data areas referenced by members of the same hostent
|
|
structure. To avoid the WSAENOBUFS error noted above, the
|
|
application should provide a buffer of at least MAXGETHOSTSTRUCT
|
|
bytes (as defined in winsock.h).
|
|
|
|
Arguments:
|
|
|
|
hWnd - The handle of the window which should receive a message when
|
|
the asynchronous request completes.
|
|
|
|
wMsg - The message to be received when the asynchronous request
|
|
completes.
|
|
|
|
name - A pointer to a service name.
|
|
|
|
proto - A pointer to a protocol name. This may be NULL, in which
|
|
case WSAAsyncGetServByName() will search for the first service
|
|
entry for which s_name or one of the s_aliases matches the given
|
|
name. Otherwise WSAAsyncGetServByName() matches both name and
|
|
proto.
|
|
|
|
buf - A pointer to the data area to receive the servent data. Note
|
|
that this must be larger than the size of a servent structure.
|
|
This is because the data area supplied is used by the Windows
|
|
Sockets implementation to contain not only a servent structure
|
|
but any and all of the data which is referenced by members of the
|
|
servent structure. It is recommended that you supply a buffer of
|
|
MAXGETHOSTSTRUCT bytes.
|
|
|
|
buflen The size of data area buf above.
|
|
|
|
Return Value:
|
|
|
|
The return value specifies whether or not the asynchronous operation
|
|
was successfully initiated. Note that it does not imply success or
|
|
failure of the operation itself.
|
|
|
|
If the operation was successfully initiated, WSAAsyncGetHostByAddr()
|
|
returns a nonzero value of type HANDLE which is the asynchronous
|
|
task handle for the request. This value can be used in two ways.
|
|
It can be used to cancel the operation using
|
|
WSACancelAsyncRequest(). It can also be used to match up
|
|
asynchronous operations and completion messages, by examining the
|
|
wParam message argument.
|
|
|
|
If the asynchronous operation could not be initiated,
|
|
WSAAsyncGetHostByAddr() returns a zero value, and a specific error
|
|
number may be retrieved by calling WSAGetLastError().
|
|
|
|
--*/
|
|
|
|
{
|
|
#ifndef CHICAGO
|
|
PWINSOCK_CONTEXT_BLOCK contextBlock;
|
|
DWORD taskHandle;
|
|
PCHAR localName;
|
|
|
|
WS_ENTER( "GETXBYYSP_WSAAsyncGetServByName", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Name, (PVOID)Buffer );
|
|
|
|
if ( !SockEnterApi( FALSE, TRUE, FALSE ) ) {
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize the async thread if it hasn't already been started.
|
|
//
|
|
|
|
if ( !SockCheckAndInitAsyncThread( ) ) {
|
|
// !!! better error code?
|
|
SetLastError( WSAENOBUFS );
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Get an async context block.
|
|
//
|
|
|
|
contextBlock = SockAllocateContextBlock( );
|
|
if ( contextBlock == NULL ) {
|
|
SetLastError( WSAENOBUFS );
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate a buffer to copy the name into. We must preserve the
|
|
// name until we're done using it, since the application may
|
|
// reuse the buffer.
|
|
//
|
|
|
|
localName = ALLOCATE_HEAP( strlen(Name) + 1 );
|
|
if ( localName == NULL ) {
|
|
SockFreeContextBlock( contextBlock );
|
|
SetLastError( WSAENOBUFS );
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
strcpy( localName, Name );
|
|
|
|
//
|
|
// Initialize the context block for this operation.
|
|
//
|
|
|
|
contextBlock->OpCode = WS_OPCODE_GET_SERV_BY_NAME;
|
|
contextBlock->Overlay.AsyncGetServ.hWnd = hWnd;
|
|
contextBlock->Overlay.AsyncGetServ.wMsg = wMsg;
|
|
contextBlock->Overlay.AsyncGetServ.Filter = localName;
|
|
contextBlock->Overlay.AsyncGetServ.Protocol = (PCHAR)Protocol;;
|
|
contextBlock->Overlay.AsyncGetServ.Buffer = Buffer;
|
|
contextBlock->Overlay.AsyncGetServ.BufferLength = BufferLength;
|
|
|
|
//
|
|
// Save the task handle so that we can return it to the caller.
|
|
// After we post the context block, we're not allowed to access
|
|
// it in any way.
|
|
//
|
|
|
|
taskHandle = contextBlock->TaskHandle;
|
|
|
|
//
|
|
// Queue the request to the async thread.
|
|
//
|
|
|
|
SockQueueRequestToAsyncThread( contextBlock );
|
|
|
|
IF_DEBUG(ASYNC_GETXBYY) {
|
|
WS_PRINT(( "WSAAsyncGetServByAddr successfully posted request, "
|
|
"handle = %lx\n", taskHandle ));
|
|
}
|
|
|
|
WS_ASSERT( sizeof(taskHandle) == sizeof(HANDLE) );
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByName", (INT)taskHandle, FALSE );
|
|
return (HANDLE)taskHandle;
|
|
|
|
#else // CHICAGO
|
|
|
|
extern char * d_ascii( char * s, int n );
|
|
LPSOCK_THREAD pThread;
|
|
HANDLE ret;
|
|
|
|
if (!enterAPI(FALSE, TRUE, FALSE, &pThread)) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// BUGBUG - what about parameter validation/UAEs?
|
|
//
|
|
WS_TRACE(NAME,"GETXBYYSP_WSAAsyncGetServByName(%s)",Name,0,0);
|
|
|
|
ret = AsyncGetServByYCommon(hWnd,
|
|
wMsg,
|
|
(LPSTR)Name,
|
|
(LPSTR)Protocol,
|
|
0,
|
|
Buffer,
|
|
BufferLength
|
|
);
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT(("GETXBYYSP_WSAAsyncGetServByName(%s)<%d\n Buffer=\n",
|
|
Name,ret));
|
|
|
|
// Print the first 120 chars of buffer.
|
|
|
|
DLL_PRINT(("%s\n", d_ascii(&Buffer[ 0],60)));
|
|
DLL_PRINT(("%s\n", d_ascii(&Buffer[60],60)));
|
|
}
|
|
|
|
return ret;
|
|
#endif // CHICAGO
|
|
}
|
|
|
|
|
|
|
|
// ws2_32 RnR re-routing, MohsinA, 13-Mar-96.
|
|
|
|
HANDLE
|
|
SOCKAPI
|
|
WSAAsyncGetServByPort(
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN int Port,
|
|
IN const char FAR * Protocol,
|
|
IN char FAR * Buffer,
|
|
IN int BufferLength
|
|
)
|
|
{
|
|
HANDLE val;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
#undef WSAAsyncGetServByPort
|
|
extern HANDLE PASCAL WSAAsyncGetServByPort( HWND hWnd, unsigned int wMsg,
|
|
int Port, const char FAR * Protocol, char FAR * Buffer,
|
|
int BufferLength );
|
|
|
|
WS_ENTER( "WSAAsyncGetServByPort", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Port, (PVOID)Protocol );
|
|
|
|
val = WSAAsyncGetServByPort( hWnd, wMsg, Port, Protocol, Buffer, BufferLength );
|
|
|
|
WS_EXIT( "WSAAsyncGetServByPort", (INT)val, (BOOLEAN)( val == NULL ) );
|
|
|
|
#else // CHICAGO
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT((">WSAAsyncGetServByPort(hWnd=%d,wMsg=%d,Port=%d,\n\t",
|
|
hWnd, wMsg, Port ));
|
|
DLL_PRINT(("Protocol=%s, Buffer[%d] @ %x) => ws2.\n",
|
|
Protocol, BufferLength, Buffer ));
|
|
}
|
|
|
|
val = ( * ws2_WSAAsyncGetServByPort )(
|
|
hWnd, wMsg, Port, Protocol, Buffer, BufferLength );
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT(("<WSAAsyncGetServByPort <= ws2: HANDLE=%x.\n", val ));
|
|
}
|
|
#endif // CHICAGO
|
|
|
|
return val;
|
|
}
|
|
|
|
|
|
HANDLE
|
|
SOCKAPI
|
|
GETXBYYSP_WSAAsyncGetServByPort(
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN int Port,
|
|
IN const char FAR * Protocol,
|
|
IN char FAR * Buffer,
|
|
IN int BufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is an asynchronous version of getservbyport(), and is
|
|
used to retrieve service information corresponding to a port number.
|
|
The Windows Sockets implementation initiates the operation and
|
|
returns to the caller immediately, passing back an asynchronous task
|
|
handle which the application may use to identify the operation.
|
|
When the operation is completed, the results (if any) are copied
|
|
into the buffer provided by the caller and a message is sent to the
|
|
application's window.
|
|
|
|
When the asynchronous operation is complete the application's window
|
|
hWnd receives message wMsg. The wParam argument contains the
|
|
asynchronous task handle as returned by the original function call.
|
|
The high 16 bits of lParam contain any error code. The error code
|
|
may be any error as defined in winsock.h. An error code of zero
|
|
indicates successful completion of the asynchronous operation. On
|
|
successful completion, the buffer supplied to the original function
|
|
call contains a servent structure. To access the elements of this
|
|
structure, the original buffer address should be cast to a servent
|
|
structure pointer and accessed as appropriate.
|
|
|
|
Note that if the error code is WSAENOBUFS, it indicates that the
|
|
size of the buffer specified by buflen in the original call was too
|
|
small to contain all the resultant information. In this case, the
|
|
low 16 bits of lParam contain the size of buffer required to supply
|
|
ALL the requisite information. If the application decides that the
|
|
partial data is inadequate, it may reissue the
|
|
WSAAsyncGetServByPort() function call with a buffer large enough to
|
|
receive all the desired information (i.e. no smaller than the low
|
|
16 bits of lParam).
|
|
|
|
The error code and buffer length should be extracted from the lParam
|
|
using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in
|
|
winsock.h as:
|
|
|
|
#define WSAGETASYNCERROR(lParam) HIWORD(lParam)
|
|
#define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)
|
|
|
|
The use of these macros will maximize the portability of the source
|
|
code for the application.
|
|
|
|
|
|
The buffer supplied to this function is used by the Windows Sockets
|
|
implementation to construct a servent structure together with the
|
|
contents of data areas referenced by members of the same servent
|
|
structure. To avoid the WSAENOBUFS error noted above, the
|
|
application should provide a buffer of at least MAXGETHOSTSTRUCT
|
|
bytes (as defined in winsock.h).
|
|
|
|
Arguments:
|
|
|
|
hWnd - The handle of the window which should receive a message when
|
|
the asynchronous request completes.
|
|
|
|
wMsg - The message to be received when the asynchronous request
|
|
completes.
|
|
|
|
port - The port for the service, in network byte order.
|
|
|
|
proto - A pointer to a protocol name. This may be NULL, in which
|
|
case WSAAsyncGetServByPort() will search for the first service
|
|
entry for which s_port match the given port. Otherwise
|
|
WSAAsyncGetServByPort() matches both port and proto.
|
|
|
|
buf - A pointer to the data area to receive the servent data. Note
|
|
that this must be larger than the size of a servent structure.
|
|
This is because the data area supplied is used by the Windows
|
|
Sockets implementation to contain not only a servent structure
|
|
but any and all of the data which is referenced by members of the
|
|
servent structure. It is recommended that you supply a buffer of
|
|
MAXGETHOSTSTRUCT bytes.
|
|
|
|
buflen The size of data area buf above.
|
|
|
|
Return Value:
|
|
|
|
The return value specifies whether or not the asynchronous operation
|
|
was successfully initiated. Note that it does not imply success or
|
|
failure of the operation itself.
|
|
|
|
If the operation was successfully initiated, WSAAsyncGetServByPort()
|
|
returns a nonzero value of type HANDLE which is the asynchronous
|
|
task handle for the request. This value can be used in two ways.
|
|
It can be used to cancel the operation using
|
|
WSACancelAsyncRequest(). It can also be used to match up
|
|
asynchronous operations and completion messages, by examining the
|
|
wParam message argument.
|
|
|
|
If the asynchronous operation could not be initiated,
|
|
WSAAsyncGetServByPort() returns a zero value, and a specific error
|
|
number may be retrieved by calling WSAGetLastError().
|
|
|
|
--*/
|
|
|
|
{
|
|
#ifndef CHICAGO
|
|
PWINSOCK_CONTEXT_BLOCK contextBlock;
|
|
DWORD taskHandle;
|
|
|
|
WS_ENTER( "GETXBYYSP_WSAAsyncGetServByPort", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Port, Buffer );
|
|
|
|
if ( !SockEnterApi( FALSE, TRUE, FALSE ) ) {
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByPort", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize the async thread if it hasn't already been started.
|
|
//
|
|
|
|
if ( !SockCheckAndInitAsyncThread( ) ) {
|
|
// !!! better error code?
|
|
SetLastError( WSAENOBUFS );
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByPort", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Get an async context block.
|
|
//
|
|
|
|
contextBlock = SockAllocateContextBlock( );
|
|
if ( contextBlock == NULL ) {
|
|
SetLastError( WSAENOBUFS );
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByPort", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize the context block for this operation.
|
|
//
|
|
|
|
contextBlock->OpCode = WS_OPCODE_GET_SERV_BY_PORT;
|
|
contextBlock->Overlay.AsyncGetServ.hWnd = hWnd;
|
|
contextBlock->Overlay.AsyncGetServ.wMsg = wMsg;
|
|
contextBlock->Overlay.AsyncGetServ.Filter = (PVOID)Port;
|
|
contextBlock->Overlay.AsyncGetServ.Protocol = (PCHAR)Protocol;
|
|
contextBlock->Overlay.AsyncGetServ.Buffer = Buffer;
|
|
contextBlock->Overlay.AsyncGetServ.BufferLength = BufferLength;
|
|
|
|
//
|
|
// Save the task handle so that we can return it to the caller.
|
|
// After we post the context block, we're not allowed to access
|
|
// it in any way.
|
|
//
|
|
|
|
taskHandle = contextBlock->TaskHandle;
|
|
|
|
//
|
|
// Queue the request to the async thread.
|
|
//
|
|
|
|
SockQueueRequestToAsyncThread( contextBlock );
|
|
|
|
IF_DEBUG(ASYNC_GETXBYY) {
|
|
WS_PRINT(( "GETXBYYSP_WSAAsyncGetServByPort successfully posted request,"
|
|
"handle = %lx\n", taskHandle ));
|
|
}
|
|
|
|
WS_ASSERT( sizeof(taskHandle) == sizeof(HANDLE) );
|
|
WS_EXIT( "GETXBYYSP_WSAAsyncGetServByPort", (INT)taskHandle, FALSE );
|
|
return (HANDLE)taskHandle;
|
|
|
|
#else // CHICAGO
|
|
|
|
LPSOCK_THREAD pThread;
|
|
|
|
if (!enterAPI(FALSE, TRUE, FALSE, &pThread)) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// BUGBUG - what about parameter validation/UAEs?
|
|
//
|
|
|
|
return AsyncGetServByYCommon(hWnd,
|
|
wMsg,
|
|
NULL,
|
|
(LPSTR)Protocol,
|
|
Port,
|
|
Buffer,
|
|
BufferLength
|
|
);
|
|
|
|
#endif // CHICAGO
|
|
}
|
|
|
|
#ifdef CHICAGO
|
|
|
|
HANDLE
|
|
AsyncGetServByYCommon(
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN char FAR * Name,
|
|
IN char FAR * Protocol,
|
|
IN int Port,
|
|
IN char FAR * Buffer,
|
|
IN int BufferLength
|
|
)
|
|
{
|
|
LPSERVENT returnServ;
|
|
UINT requiredBufferLength = 0;
|
|
BOOL posted;
|
|
LPARAM lParam;
|
|
UINT error;
|
|
HANDLE handle;
|
|
|
|
//
|
|
// Get the necessary information.
|
|
//
|
|
|
|
if (Name) {
|
|
|
|
WS_TRACE(NAME,"AsyncGetServByYCommon(Name=%s,Protocol=%s)",
|
|
Name,Protocol,0);
|
|
|
|
returnServ = getservbyname(Name, Protocol);
|
|
} else {
|
|
|
|
WS_TRACE(NAME,"AsyncGetServByYCommon(Port=%s,Protocol=%s)",
|
|
Port,Protocol,0);
|
|
|
|
returnServ = getservbyport(Port, Protocol);
|
|
}
|
|
|
|
//
|
|
// Copy the servent structure to the output buffer.
|
|
//
|
|
|
|
if (returnServ != NULL) {
|
|
WS_TRACE(NAME,"AsyncGetServByYCommon, copying Buffer.",0,0,0);
|
|
|
|
requiredBufferLength = CopyServentToBuffer(Buffer,
|
|
BufferLength,
|
|
returnServ
|
|
);
|
|
if (requiredBufferLength > (UINT)BufferLength) {
|
|
WS_TRACE(NAME,"AsyncGetServByYCommon, no Buffer %d>%d.",
|
|
requiredBufferLength, BufferLength,0);
|
|
error = WSAENOBUFS;
|
|
} else {
|
|
WS_TRACE(NAME,"AsyncGetServByYCommon, Buffer copied ok.",
|
|
0,0,0);
|
|
error = NO_ERROR;
|
|
}
|
|
} else {
|
|
error = WSAGetLastError();
|
|
|
|
WS_TRACE(NAME,"AsyncGetServByYCommon, failed with %d",
|
|
error,0,0);
|
|
}
|
|
|
|
//
|
|
// We return a handle and an async message even if we failed
|
|
//
|
|
|
|
handle = GenerateNextTaskHandle();
|
|
|
|
//
|
|
// Build lParam for the message we'll post to the application.
|
|
// The high 16 bits are the error code, the low 16 bits are
|
|
// the minimum buffer size required for the operation.
|
|
//
|
|
|
|
lParam = WSAMAKEASYNCREPLY(requiredBufferLength, error);
|
|
|
|
//
|
|
// Post a message to the application indication that the data it
|
|
// requested is available.
|
|
//
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT(("AsyncGetServByYCommon: posting(%d,%d,%d,%8x).\n",
|
|
hWnd, wMsg, handle, lParam ));
|
|
}
|
|
|
|
posted = PostMessage(hWnd, wMsg, (WPARAM)handle, lParam);
|
|
|
|
//
|
|
// !!! Need a mechanism to repost if the post failed!
|
|
//
|
|
|
|
if (!posted) { // BUGBUG - whatdowedo?whatdowedo
|
|
|
|
WS_PRINT(("Error: AsyncGetServByYCommon:"
|
|
" PostMessage(%04x, %04x, %04x, %08lx) failed\r\n",
|
|
hWnd, wMsg, handle, lParam ));
|
|
}
|
|
|
|
return handle;
|
|
}
|
|
#endif
|
|
|
|
#endif // WIN32
|
|
|
|
|
|
//
|
|
// functions
|
|
//
|
|
|
|
|
|
|
|
// ===================================================================
|
|
// MohsinA, 13-Mar-96.
|
|
|
|
LPHOSTENT
|
|
SOCKAPI
|
|
gethostbyname(
|
|
IN const char FAR * name
|
|
)
|
|
{
|
|
LPHOSTENT he;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
#undef gethostbyname
|
|
extern struct hostent * PASCAL gethostbyname( const char * name );
|
|
|
|
WS_ENTER( "getbyhostname", (PVOID)name, NULL, NULL, NULL );
|
|
|
|
he = gethostbyname( name );
|
|
|
|
WS_EXIT( "gethostbyname", (INT)he, (BOOLEAN)( he == NULL ) );
|
|
|
|
#else // CHICAGO
|
|
|
|
WS_TRACE(NAME,">gethostbyname(name=%s) => ws2", name, 0, 0 );
|
|
|
|
he = ( * ws2_gethostbyname )( name );
|
|
|
|
WS_TRACE(NAME,"<gethostbyname(name=%s) <= ws2: he=%x.", name, he, 0 );
|
|
|
|
#endif // CHICAGO
|
|
|
|
return he;
|
|
}
|
|
|
|
|
|
|
|
LPHOSTENT
|
|
SOCKAPI
|
|
GETXBYYSP_gethostbyname(
|
|
IN const char FAR * name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get host information corresponding to a hostname.
|
|
|
|
Arguments:
|
|
|
|
name - A pointer to the name of the host.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, gethostbyname() returns a pointer to the hostent
|
|
structure described above. Otherwise it returns a NULL pointer and
|
|
a specific error number may be retrieved by calling
|
|
WSAGetLastError().
|
|
|
|
--*/
|
|
|
|
{
|
|
#if !defined(CHICAGO) || defined(WIN32)
|
|
|
|
BYTE buffer[2048];
|
|
DWORD bufferSize;
|
|
BYTE aliasBuffer[512];
|
|
DWORD aliasBufferSize;
|
|
INT count;
|
|
INT index;
|
|
DWORD protocols[3];
|
|
char *bp;
|
|
PCSADDR_INFO csaddrInfo;
|
|
PSOCKADDR_IN sockaddrIn;
|
|
PCHAR s;
|
|
DWORD i;
|
|
INT err;
|
|
|
|
#ifdef CHICAGO
|
|
LPSOCK_THREAD pThread;
|
|
#endif
|
|
|
|
WS_ENTER( "gethostbyname", (PVOID)name, NULL, NULL, NULL );
|
|
|
|
if ( !SockEnterApi( FALSE, TRUE, TRUE ) ) {
|
|
WS_EXIT( "gethostbyname", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef OHARE
|
|
// call autodial hook if installed
|
|
if (g_pfnAutoDialHook)
|
|
(*g_pfnAutoDialHook)(AUTODIAL_GETHOSTBYNAME,(LPCVOID) name);
|
|
|
|
#endif // OHARE
|
|
|
|
//
|
|
// Set the DNR error code to 0 so that we know if it changes to
|
|
// something more appropriate.
|
|
//
|
|
|
|
SockThreadDnrErrorCode = NO_ERROR;
|
|
|
|
protocols[0] = IPPROTO_TCP;
|
|
protocols[1] = IPPROTO_UDP;
|
|
protocols[2] = 0;
|
|
bufferSize = sizeof(buffer);
|
|
aliasBufferSize = sizeof(aliasBuffer);
|
|
|
|
#if OLDXBYY
|
|
count = __GetAddressByNameA(
|
|
#else
|
|
count = GetAddressByNameA(
|
|
#endif
|
|
0,
|
|
&HostnameGuid,
|
|
(char *)name,
|
|
protocols,
|
|
RES_GETHOSTBYNAME,
|
|
NULL,
|
|
buffer,
|
|
&bufferSize,
|
|
aliasBuffer,
|
|
&aliasBufferSize
|
|
);
|
|
|
|
if ( count <= 0 ) {
|
|
|
|
err = SockThreadDnrErrorCode;
|
|
|
|
if ( err >= WSAHOST_NOT_FOUND && err <= WSANO_DATA ) {
|
|
SetLastError( err );
|
|
} else {
|
|
SetLastError( WSANO_DATA );
|
|
}
|
|
|
|
WS_EXIT( "gethostbyname", 0, TRUE );
|
|
return((struct hostent *) NULL);
|
|
}
|
|
|
|
//
|
|
// Copy the CSADDR information to a hostent structure.
|
|
//
|
|
|
|
host.h_addr_list = h_addr_ptrs;
|
|
host.h_length = sizeof (unsigned long);
|
|
host.h_addrtype = AF_INET;
|
|
host.h_aliases = host_aliases;
|
|
|
|
//
|
|
// Copy over the IP addresses for the host.
|
|
//
|
|
|
|
bp = hostbuf;
|
|
csaddrInfo = (PCSADDR_INFO)buffer;
|
|
|
|
for ( index = 0; index < count && (DWORD)bp - (DWORD)hostbuf < BUFSIZ; index++ ) {
|
|
|
|
sockaddrIn = (PSOCKADDR_IN)csaddrInfo->RemoteAddr.lpSockaddr;
|
|
|
|
host.h_addr_list[index] = bp;
|
|
bp += 4;
|
|
*((long *)host.h_addr_list[index]) = sockaddrIn->sin_addr.s_addr;
|
|
csaddrInfo++;
|
|
}
|
|
|
|
//
|
|
// Copy over the host name and alias information. If we got back
|
|
// aliases, assume that the first one is the real host name. If
|
|
// we didn't get aliases, use the passed-in host name.
|
|
//
|
|
|
|
s = aliasBuffer;
|
|
|
|
if ( *s == '\0' ) {
|
|
|
|
FSTRCPY( bp, name );
|
|
host.h_name = bp;
|
|
host_aliases[0] = NULL;
|
|
|
|
} else {
|
|
|
|
FSTRCPY( bp, s );
|
|
host.h_name = bp;
|
|
|
|
//
|
|
// Copy over the aliases.
|
|
//
|
|
|
|
for ( i = 0, s += FSTRLEN( s ) + 1, bp += FSTRLEN( bp ) + 1;
|
|
i < MAXALIASES && *s != '\0' && (DWORD)bp - (DWORD)hostbuf < BUFSIZ;
|
|
i++, s += FSTRLEN( s ) + 1, bp += FSTRLEN( bp ) + 1 ) {
|
|
|
|
FSTRCPY( bp, s );
|
|
host.h_aliases[i] = bp;
|
|
}
|
|
|
|
host_aliases[i] = NULL;
|
|
}
|
|
|
|
|
|
SockThreadProcessingGetXByY = FALSE;
|
|
WS_EXIT( "gethostbyname", (INT)&host, FALSE );
|
|
|
|
return (&host);
|
|
|
|
#else // WIN32
|
|
|
|
LPSOCK_THREAD pThread;
|
|
LPHOSTENT lpHostent;
|
|
|
|
WS_ENTER("gethostbyname", (PVOID)name, NULL, NULL, NULL);
|
|
|
|
if (!SockEnterApi(TRUE, TRUE, TRUE)) {
|
|
WS_EXIT("gethostbyname", 0, TRUE);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// if the name looks ok, try to resolve it
|
|
//
|
|
|
|
if (VerifyName((LPSTR)name)) {
|
|
lpHostent = GetHostentByAttribute(pThread, (LPSTR)name, NULL);
|
|
} else {
|
|
|
|
//
|
|
// the name was bad
|
|
//
|
|
|
|
WSASetLastError(WSANO_RECOVERY);
|
|
lpHostent = NULL;
|
|
}
|
|
|
|
SockThreadProcessingGetXByY = FALSE;
|
|
|
|
WS_EXIT("gethostbyname", (INT)lpHostent, lpHostent ? FALSE : TRUE);
|
|
|
|
return lpHostent;
|
|
|
|
#endif // defined(WIN32)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ws2_32 RnR re-routing, MohsinA, 13-Mar-96.
|
|
|
|
LPHOSTENT
|
|
SOCKAPI
|
|
gethostbyaddr(
|
|
IN const char FAR * addr,
|
|
IN int len,
|
|
IN int type
|
|
)
|
|
{
|
|
LPHOSTENT he;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
#undef gethostbyaddr
|
|
extern struct hostent * PASCAL gethostbyaddr( const char * name, int len,
|
|
int type );
|
|
|
|
WS_ENTER( "gethostbyaddr", (PVOID)addr, (PVOID)len, (PVOID)type, NULL );
|
|
|
|
he = gethostbyaddr( addr, len, type );
|
|
|
|
WS_EXIT( "gethostbyaddr", (INT)he, (BOOLEAN)( he == NULL ) );
|
|
|
|
#else // CHICAGO
|
|
DWORD inaddr=0L;
|
|
|
|
if( addr ) inaddr = *(DWORD*) addr; // else zero.
|
|
|
|
WS_TRACE(NAME,">gethostbyaddr(inaddr=%lx,len=%d,type=%d) => ws2",
|
|
inaddr, len,type );
|
|
|
|
he = ( * ws2_gethostbyaddr )( addr, len, type );
|
|
|
|
|
|
IF_DEBUG( NAME ){
|
|
if( he ){
|
|
DLL_PRINT(("<gethostbyaddr() <= ws2_32: %lx and h_name=%s.",
|
|
he, he->h_name ));
|
|
}else{
|
|
DLL_PRINT(("<gethostbyaddr(inaddr=%lx) <= NULL, failed.\n",
|
|
inaddr ));
|
|
}
|
|
}
|
|
|
|
#endif // CHICAGO
|
|
|
|
return he;
|
|
}
|
|
|
|
LPHOSTENT
|
|
SOCKAPI
|
|
GETXBYYSP_gethostbyaddr(
|
|
IN const char FAR * addr,
|
|
IN int len,
|
|
IN int type
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get host information corresponding to an address.
|
|
|
|
Arguments:
|
|
|
|
addr - A pointer to an address in network byte order.
|
|
|
|
len - The length of the address, which must be 4 for PF_INET addresses.
|
|
|
|
type - The type of the address, which must be PF_INET.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, gethostbyaddr() pointer to the hostent structure
|
|
described above. Otherwise it returns a NULL pointer and a specific
|
|
error number may be retrieved by calling WSAGetLastError().
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return(_pgethostbyaddr(addr, len, type));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ===================================================================
|
|
// ws2_32 RnR re-routing, MohsinA, 13-Mar-96.
|
|
|
|
HANDLE
|
|
SOCKAPI
|
|
WSAAsyncGetHostByName(
|
|
HWND hWnd,
|
|
unsigned int wMsg,
|
|
const char FAR * Name,
|
|
char FAR * Buffer,
|
|
int BufferLength
|
|
)
|
|
{
|
|
HANDLE val;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
#undef WSAAsyncGetHostByName
|
|
extern HANDLE PASCAL WSAAsyncGetHostByName( HWND hWnd, unsigned int wMsg,
|
|
char const FAR * Name, char FAR * Buffer, int BufferLength );
|
|
|
|
WS_ENTER( "WSAAsyncGetHostByName", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Name, Buffer );
|
|
|
|
val = WSAAsyncGetHostByName( hWnd, wMsg, Name, Buffer, BufferLength );
|
|
|
|
WS_EXIT( "WSAAsyncGetHostByName", (INT)val, (BOOLEAN)( val == NULL ) );
|
|
|
|
#else // CHICAGO
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT((">WSAAsyncGetHostByName(hWnd=%d,wMsg=%d,Name @ %x,\n\t",
|
|
hWnd, wMsg, Name ));
|
|
DLL_PRINT(("Buffer[%d] @ %x) => ws2.\n",
|
|
BufferLength, Buffer));
|
|
}
|
|
|
|
val = ( * ws2_WSAAsyncGetHostByName )(
|
|
hWnd, wMsg, Name, Buffer, BufferLength );
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT(("<WSAAsyncGetHostByName <= ws2: HANDLE=%x.\n", val ));
|
|
}
|
|
|
|
#endif // CHICAGO
|
|
|
|
return val;
|
|
}
|
|
|
|
|
|
HANDLE
|
|
SOCKAPI
|
|
GETXBYYSP_WSAAsyncGetHostByName(
|
|
HWND hWnd,
|
|
unsigned int wMsg,
|
|
const char FAR * Name,
|
|
char FAR * Buffer,
|
|
int BufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is an asynchronous version of gethostbyname(), and is
|
|
used to retrieve host name and address information corresponding to
|
|
a hostname. The Windows Sockets implementation initiates the
|
|
operation and returns to the caller immediately, passing back an
|
|
asynchronous task handle which the application may use to identify
|
|
the operation. When the operation is completed, the results (if
|
|
any) are copied into the buffer provided by the caller and a message
|
|
is sent to the application's window.
|
|
|
|
When the asynchronous operation is complete the application's window
|
|
hWnd receives message wMsg. The wParam argument contains the
|
|
asynchronous task handle as returned by the original function call.
|
|
The high 16 bits of lParam contain any error code. The error code
|
|
may be any error as defined in winsock.h. An error code of zero
|
|
indicates successful completion of the asynchronous operation. On
|
|
successful completion, the buffer supplied to the original function
|
|
call contains a hostent structure. To access the elements of this
|
|
structure, the original buffer address should be cast to a hostent
|
|
structure pointer and accessed as appropriate.
|
|
|
|
Note that if the error code is WSAENOBUFS, it indicates that the
|
|
size of the buffer specified by buflen in the original call was too
|
|
small to contain all the resultant information. In this case, the
|
|
low 16 bits of lParam contain the size of buffer required to supply
|
|
ALL the requisite information. If the application decides that the
|
|
partial data is inadequate, it may reissue the
|
|
WSAAsyncGetHostByName() function call with a buffer large enough to
|
|
receive all the desired information (i.e. no smaller than the low
|
|
16 bits of lParam).
|
|
|
|
The error code and buffer length should be extracted from the lParam
|
|
using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in
|
|
winsock.h as:
|
|
|
|
#define WSAGETASYNCERROR(lParam) HIWORD(lParam)
|
|
#define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)
|
|
|
|
The use of these macros will maximize the portability of the source
|
|
code for the application.
|
|
|
|
The buffer supplied to this function is used by the Windows Sockets
|
|
implementation to construct a hostent structure together with the
|
|
contents of data areas referenced by members of the same hostent
|
|
structure. To avoid the WSAENOBUFS error noted above, the
|
|
application should provide a buffer of at least MAXGETHOSTSTRUCT
|
|
bytes (as defined in winsock.h).
|
|
|
|
Arguments:
|
|
|
|
hWnd - The handle of the window which should receive a message when
|
|
the asynchronous request completes.
|
|
|
|
wMsg - The message to be received when the asynchronous request
|
|
completes.
|
|
|
|
name - A pointer to the name of the host.
|
|
|
|
buf - A pointer to the data area to receive the hostent data. Note
|
|
that this must be larger than the size of a hostent structure.
|
|
This is because the data area supplied is used by the Windows
|
|
Sockets implementation to contain not only a hostent structure
|
|
but any and all of the data which is referenced by members of the
|
|
hostent structure. It is recommended that you supply a buffer of
|
|
MAXGETHOSTSTRUCT bytes.
|
|
|
|
buflen - The size of data area buf above.
|
|
|
|
Return Value:
|
|
|
|
The return value specifies whether or not the asynchronous operation
|
|
was successfully initiated. Note that it does not imply success or
|
|
failure of the operation itself.
|
|
|
|
If the operation was successfully initiated, WSAAsyncGetHostByName()
|
|
returns a nonzero value of type HANDLE which is the asynchronous
|
|
task handle for the request. This value can be used in two ways.
|
|
It can be used to cancel the operation using
|
|
WSACancelAsyncRequest(). It can also be used to match up
|
|
asynchronous operations and completion messages, by examining the
|
|
wParam message argument.
|
|
|
|
If the asynchronous operation could not be initiated,
|
|
WSAAsyncGetHostByName() returns a zero value, and a specific error
|
|
number may be retrieved by calling WSAGetLastError().
|
|
|
|
--*/
|
|
|
|
{
|
|
PWINSOCK_CONTEXT_BLOCK contextBlock;
|
|
#ifdef CHICAGO
|
|
HANDLE taskHandle;
|
|
#else
|
|
DWORD taskHandle;
|
|
#endif
|
|
PCHAR localName;
|
|
|
|
#ifdef CHICAGO
|
|
LPSOCK_THREAD pThread;
|
|
|
|
GET_THREAD_DATA(pThread);
|
|
#endif
|
|
|
|
WS_ENTER( "WSAAsyncGetHostByName", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Name, Buffer );
|
|
|
|
if ( !SockEnterApi( FALSE, TRUE, FALSE ) ) {
|
|
WS_EXIT( "WSAAsyncGetHostByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize the async thread if it hasn't already been started.
|
|
//
|
|
|
|
if ( !SockCheckAndInitAsyncThread( ) ) {
|
|
// !!! better error code?
|
|
WSASetLastError( WSAENOBUFS );
|
|
WS_EXIT( "WSAAsyncGetHostByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Get an async context block.
|
|
//
|
|
|
|
contextBlock = SockAllocateContextBlock( );
|
|
if ( contextBlock == NULL ) {
|
|
WSASetLastError( WSAENOBUFS );
|
|
WS_EXIT( "WSAAsyncGetHostByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate a buffer to copy the name into. We must preserve the
|
|
// name until we're done using it, since the application may
|
|
// reuse the buffer.
|
|
//
|
|
|
|
localName = ALLOCATE_HEAP( FSTRLEN(Name) + 1 );
|
|
if ( localName == NULL ) {
|
|
SockFreeContextBlock( contextBlock );
|
|
WSASetLastError( WSAENOBUFS );
|
|
WS_EXIT( "WSAAsyncGetHostByName", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
FSTRCPY( localName, Name );
|
|
|
|
//
|
|
// Initialize the context block for this operation.
|
|
//
|
|
|
|
contextBlock->OpCode = WS_OPCODE_GET_HOST_BY_NAME;
|
|
contextBlock->Overlay.AsyncGetHost.hWnd = hWnd;
|
|
contextBlock->Overlay.AsyncGetHost.wMsg = wMsg;
|
|
contextBlock->Overlay.AsyncGetHost.Filter = localName;
|
|
contextBlock->Overlay.AsyncGetHost.Buffer = Buffer;
|
|
contextBlock->Overlay.AsyncGetHost.BufferLength = BufferLength;
|
|
|
|
//
|
|
// Save the task handle so that we can return it to the caller.
|
|
// After we post the context block, we're not allowed to access
|
|
// it in any way.
|
|
//
|
|
|
|
taskHandle = contextBlock->TaskHandle;
|
|
|
|
//
|
|
// Queue the request to the async thread.
|
|
//
|
|
|
|
SockQueueRequestToAsyncThread( contextBlock );
|
|
|
|
IF_DEBUG(ASYNC_GETXBYY) {
|
|
WS_PRINT(( "WSAAsyncGetHostByName successfully posted request, "
|
|
"handle = %x\r\n", taskHandle ));
|
|
}
|
|
|
|
WS_ASSERT( sizeof(taskHandle) == sizeof(HANDLE) );
|
|
WS_EXIT( "WSAAsyncGetHostByName", (INT)taskHandle, FALSE );
|
|
return (HANDLE)taskHandle;
|
|
|
|
} // WSAAsyncGetHostByName
|
|
|
|
|
|
|
|
// ws2_32 RnR re-routing, MohsinA, 13-Mar-96.
|
|
|
|
HANDLE
|
|
SOCKAPI
|
|
WSAAsyncGetHostByAddr(
|
|
HWND hWnd,
|
|
unsigned int wMsg,
|
|
const char FAR * Address,
|
|
int Length,
|
|
int Type,
|
|
char FAR * Buffer,
|
|
int BufferLength
|
|
)
|
|
{
|
|
HANDLE val;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
#undef WSAAsyncGetHostByAddr
|
|
extern HANDLE PASCAL WSAAsyncGetHostByAddr( HWND hWnd, unsigned int wMsg,
|
|
const char FAR * Address, int Length, int Type, char FAR * Buffer,
|
|
int BufferLength );
|
|
|
|
WS_ENTER( "WSAAsyncGetHostByAddr", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Address,(PVOID)Length );
|
|
|
|
val = WSAAsyncGetHostByAddr( hWnd, wMsg, Address, Length, Type, Buffer, BufferLength );
|
|
|
|
WS_EXIT( "WSAAsyncGetHostByAddr", (INT)val, (BOOLEAN)( val == NULL ) );
|
|
|
|
#else // CHICAGO
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT((">WSAAsyncGetHostByAddr(hWnd=%d,wMsg=%d,Address=%x,\n\t",
|
|
hWnd, wMsg, Address ));
|
|
DLL_PRINT(("Length=%d, Type=%d, Buffer[%d] @ %x) => ws2.\n",
|
|
Length, Type, BufferLength, Buffer ));
|
|
}
|
|
|
|
val = ( * ws2_WSAAsyncGetHostByAddr )(
|
|
hWnd, wMsg, Address, Length,
|
|
Type, Buffer, BufferLength );
|
|
|
|
IF_DEBUG( NAME ){
|
|
DLL_PRINT(("<WSAAsyncGetHostByAddr <= ws2: HANDLE=%x.\n", val ));
|
|
}
|
|
|
|
#endif // CHICAGO
|
|
|
|
return val;
|
|
}
|
|
|
|
HANDLE
|
|
SOCKAPI
|
|
GETXBYYSP_WSAAsyncGetHostByAddr(
|
|
HWND hWnd,
|
|
unsigned int wMsg,
|
|
const char FAR * Address,
|
|
int Length,
|
|
int Type,
|
|
char FAR * Buffer,
|
|
int BufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is an asynchronous version of gethostbyaddr(), and is
|
|
used to retrieve host name and address information corresponding to
|
|
a network address. The Windows Sockets implementation initiates the
|
|
operation and returns to the caller immediately, passing back an
|
|
asynchronous task handle which the application may use to identify
|
|
the operation. When the operation is completed, the results (if
|
|
any) are copied into the buffer provided by the caller and a message
|
|
is sent to the application's window.
|
|
|
|
When the asynchronous operation is complete the application's window
|
|
hWnd receives message wMsg. The wParam argument contains the
|
|
asynchronous task handle as returned by the original function call.
|
|
The high 16 bits of lParam contain any error code. The error code
|
|
may be any error as defined in winsock.h. An error code of zero
|
|
indicates successful completion of the asynchronous operation. On
|
|
successful completion, the buffer supplied to the original function
|
|
call contains a hostent structure. To access the elements of this
|
|
structure, the original buffer address should be cast to a hostent
|
|
structure pointer and accessed as appropriate.
|
|
|
|
Note that if the error code is WSAENOBUFS, it indicates that the
|
|
size of the buffer specified by buflen in the original call was too
|
|
small to contain all the resultant information. In this case, the
|
|
low 16 bits of lParam contain the size of buffer required to supply
|
|
ALL the requisite information. If the application decides that the
|
|
partial data is inadequate, it may reissue the
|
|
WSAAsyncGetHostByAddr() function call with a buffer large enough to
|
|
receive all the desired information (i.e. no smaller than the low
|
|
16 bits of lParam).
|
|
|
|
The error code and buffer length should be extracted from the lParam
|
|
using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in
|
|
winsock.h as:
|
|
|
|
#define WSAGETASYNCERROR(lParam) HIWORD(lParam)
|
|
#define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)
|
|
|
|
The use of these macros will maximize the portability of the source
|
|
code for the application.
|
|
|
|
The buffer supplied to this function is used by the Windows Sockets
|
|
implementation to construct a hostent structure together with the
|
|
contents of data areas referenced by members of the same hostent
|
|
structure. To avoid the WSAENOBUFS error noted above, the
|
|
application should provide a buffer of at least MAXGETHOSTSTRUCT
|
|
bytes (as defined in winsock.h).
|
|
|
|
Arguments:
|
|
|
|
hWnd - The handle of the window which should receive a message when
|
|
the asynchronous request completes.
|
|
|
|
wMsg - The message to be received when the asynchronous request
|
|
completes.
|
|
|
|
addr - A pointer to the network address for the host. Host
|
|
addresses are stored in network byte order.
|
|
|
|
len - The length of the address, which must be 4 for PF_INET.
|
|
|
|
type - The type of the address, which must be PF_INET.
|
|
|
|
buf - A pointer to the data area to receive the hostent data. Note
|
|
that this must be larger than the size of a hostent structure.
|
|
This is because the data area supplied is used by the Windows
|
|
Sockets implementation to contain not only a hostent structure
|
|
but any and all of the data which is referenced by members of the
|
|
hostent structure. It is recommended that you supply a buffer of
|
|
MAXGETHOSTSTRUCT bytes.
|
|
|
|
buflen - The size of data area buf above.
|
|
|
|
Return Value:
|
|
|
|
The return value specifies whether or not the asynchronous operation
|
|
was successfully initiated. Note that it does not imply success or
|
|
failure of the operation itself.
|
|
|
|
If the operation was successfully initiated, WSAAsyncGetHostByAddr()
|
|
returns a nonzero value of type HANDLE which is the asynchronous
|
|
task handle for the request. This value can be used in two ways.
|
|
It can be used to cancel the operation using
|
|
WSACancelAsyncRequest(). It can also be used to match up
|
|
asynchronous operations and completion messages, by examining the
|
|
wParam message argument.
|
|
|
|
If the asynchronous operation could not be initiated,
|
|
WSAAsyncGetHostByAddr() returns a zero value, and a specific error
|
|
number may be retrieved by calling WSAGetLastError().
|
|
|
|
--*/
|
|
|
|
{
|
|
PWINSOCK_CONTEXT_BLOCK contextBlock;
|
|
#ifdef CHICAGO
|
|
HANDLE taskHandle;
|
|
#else
|
|
DWORD taskHandle;
|
|
#endif
|
|
PCHAR localAddress;
|
|
|
|
#ifdef CHICAGO
|
|
LPSOCK_THREAD pThread;
|
|
|
|
GET_THREAD_DATA(pThread);
|
|
#endif
|
|
|
|
WS_ENTER( "WSAAsyncGetHostByAddr", (PVOID)hWnd, (PVOID)wMsg, (PVOID)Address, Buffer );
|
|
|
|
if ( !SockEnterApi( TRUE, TRUE, FALSE ) ) {
|
|
WS_EXIT( "WSAAsyncGetHostByAddr", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize the async thread if it hasn't already been started.
|
|
//
|
|
|
|
if ( !SockCheckAndInitAsyncThread( ) ) {
|
|
// !!! better error code?
|
|
WSASetLastError( WSAENOBUFS );
|
|
WS_EXIT( "WSAAsyncGetHostByAddr", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Get an async context block.
|
|
//
|
|
|
|
contextBlock = SockAllocateContextBlock( );
|
|
if ( contextBlock == NULL ) {
|
|
WSASetLastError( WSAENOBUFS );
|
|
WS_EXIT( "WSAAsyncGetHostByAddr", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate a buffer to copy the address into. We must preserve the
|
|
// name until we're done using it, since the application may reuse
|
|
// the buffer.
|
|
//
|
|
|
|
localAddress = ALLOCATE_HEAP( Length );
|
|
if ( localAddress == NULL ) {
|
|
SockFreeContextBlock( contextBlock );
|
|
WSASetLastError( WSAENOBUFS );
|
|
WS_EXIT( "WSAAsyncGetHostByAddr", 0, TRUE );
|
|
return NULL;
|
|
}
|
|
|
|
RtlCopyMemory( localAddress, Address, Length );
|
|
|
|
//
|
|
// Initialize the context block for this operation.
|
|
//
|
|
|
|
contextBlock->OpCode = WS_OPCODE_GET_HOST_BY_ADDR;
|
|
contextBlock->Overlay.AsyncGetHost.hWnd = hWnd;
|
|
contextBlock->Overlay.AsyncGetHost.wMsg = wMsg;
|
|
contextBlock->Overlay.AsyncGetHost.Filter = localAddress;
|
|
contextBlock->Overlay.AsyncGetHost.Length = Length;
|
|
contextBlock->Overlay.AsyncGetHost.Type = Type;
|
|
contextBlock->Overlay.AsyncGetHost.Buffer = Buffer;
|
|
contextBlock->Overlay.AsyncGetHost.BufferLength = BufferLength;
|
|
|
|
//
|
|
// Save the task handle so that we can return it to the caller.
|
|
// After we post the context block, we're not allowed to access
|
|
// it in any way.
|
|
//
|
|
|
|
taskHandle = contextBlock->TaskHandle;
|
|
|
|
//
|
|
// Queue the request to the async thread.
|
|
//
|
|
|
|
SockQueueRequestToAsyncThread( contextBlock );
|
|
|
|
IF_DEBUG(ASYNC_GETXBYY) {
|
|
WS_PRINT(( "WSAAsyncGetHostByAddr successfully posted request, "
|
|
"handle = %x\r\n", taskHandle ));
|
|
}
|
|
|
|
WS_ASSERT( sizeof(taskHandle) == sizeof(HANDLE) );
|
|
WS_EXIT( "WSAAsyncGetHostByAddr", (INT)taskHandle, FALSE );
|
|
return (HANDLE)taskHandle;
|
|
|
|
} // WSAAsyncGetHostByAddr
|
|
|
|
#if !defined(CHICAGO) || defined(WIN32)
|
|
|
|
|
|
VOID
|
|
SockProcessAsyncGetHost (
|
|
IN DWORD TaskHandle,
|
|
IN DWORD OpCode,
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN char FAR *Filter,
|
|
IN int Length,
|
|
IN int Type,
|
|
IN char FAR *Buffer,
|
|
IN int BufferLength
|
|
)
|
|
{
|
|
PHOSTENT returnHost;
|
|
DWORD requiredBufferLength = 0;
|
|
BOOL posted;
|
|
LPARAM lParam;
|
|
DWORD error;
|
|
|
|
extern DWORD SockCancelledAsyncTaskHandle;
|
|
extern DWORD SockCurrentAsyncThreadTaskHandle;
|
|
|
|
WS_ASSERT( OpCode == WS_OPCODE_GET_HOST_BY_ADDR ||
|
|
OpCode == WS_OPCODE_GET_HOST_BY_NAME );
|
|
|
|
#if DBG
|
|
WSASetLastError( NO_ERROR );
|
|
#endif
|
|
|
|
//
|
|
// Get the necessary information.
|
|
//
|
|
|
|
if ( OpCode == WS_OPCODE_GET_HOST_BY_ADDR ) {
|
|
returnHost = gethostbyaddr( Filter, Length, Type );
|
|
} else {
|
|
returnHost = gethostbyname( Filter );
|
|
}
|
|
|
|
//
|
|
// Free the filter space, it is no longer used.
|
|
//
|
|
|
|
FREE_HEAP( Filter );
|
|
|
|
//
|
|
// Hold the lock that protects the async thread context block queue
|
|
// while we do this. This prevents a race between this thread and
|
|
// any thread invoking WSACancelAsyncRequest().
|
|
//
|
|
|
|
SockAcquireGlobalLockExclusive( );
|
|
|
|
//
|
|
// If this request was cancelled, just return.
|
|
//
|
|
|
|
if ( TaskHandle == SockCancelledAsyncTaskHandle ) {
|
|
IF_DEBUG(ASYNC_GETXBYY) {
|
|
WS_PRINT(( "SockProcessAsyncGetHost: task handle %lx cancelled\r\n",
|
|
TaskHandle ));
|
|
}
|
|
SockReleaseGlobalLock( );
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Copy the hostent structure to the output buffer.
|
|
//
|
|
|
|
if ( returnHost != NULL ) {
|
|
|
|
requiredBufferLength = CopyHostentToBuffer(
|
|
Buffer,
|
|
BufferLength,
|
|
returnHost
|
|
);
|
|
|
|
if ( requiredBufferLength > (DWORD)BufferLength ) {
|
|
error = WSAENOBUFS;
|
|
} else {
|
|
error = NO_ERROR;
|
|
}
|
|
|
|
} else {
|
|
|
|
error = WSAGetLastError( );
|
|
WS_ASSERT( error != NO_ERROR );
|
|
}
|
|
|
|
SockReleaseGlobalLock( );
|
|
|
|
//
|
|
// Build lParam for the message we'll post to the application.
|
|
// The high 16 bits are the error code, the low 16 bits are
|
|
// the minimum buffer size required for the operation.
|
|
//
|
|
|
|
lParam = WSAMAKEASYNCREPLY( requiredBufferLength, error );
|
|
|
|
//
|
|
// Set the current async thread task handle to 0 so that if a cancel
|
|
// request comes in after this point it is failed properly.
|
|
//
|
|
|
|
SockCurrentAsyncThreadTaskHandle = 0;
|
|
|
|
//
|
|
// Post a message to the application indication that the data it
|
|
// requested is available.
|
|
//
|
|
|
|
WS_ASSERT( sizeof(TaskHandle) == sizeof(HANDLE) );
|
|
|
|
#ifdef CHICAGO
|
|
#define SockPostRoutine PostMessage
|
|
#endif
|
|
|
|
posted = SockPostRoutine( hWnd, wMsg, (WPARAM)TaskHandle, lParam );
|
|
|
|
//
|
|
// !!! Need a mechanism to repost if the post failed!
|
|
//
|
|
|
|
if ( !posted ) {
|
|
WS_PRINT(( "SockProcessAsyncGetHost: PostMessage failed: %ld\r\n",
|
|
WSAGetLastError( ) ));
|
|
WS_ASSERT( FALSE );
|
|
}
|
|
|
|
return;
|
|
|
|
} // SockProcessAsyncGetHost
|
|
|
|
#endif // WIN32
|
|
|
|
|
|
// RnR re-routing to ws2_32.dll, MohsinA, 13-Mar-96.
|
|
|
|
|
|
int
|
|
GETXBYYSP_gethostname(
|
|
OUT char *name,
|
|
IN int namelen
|
|
)
|
|
{
|
|
return(_pgethostname(name, namelen));
|
|
}
|
|
|
|
|
|
int
|
|
SOCKAPI
|
|
gethostname(
|
|
OUT char FAR * name,
|
|
IN int namelen
|
|
)
|
|
{
|
|
int retval;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
#undef gethostname
|
|
extern int gethostname( char * name, int namelen );
|
|
|
|
WS_ENTER( "gethostname", name, (PVOID)namelen, NULL, NULL );
|
|
|
|
retval = gethostname( name, namelen );
|
|
|
|
WS_EXIT( "gethostname", retval, (BOOLEAN)( retval == SOCKET_ERROR ) );
|
|
|
|
#else // CHICAGO
|
|
|
|
WS_TRACE(NAME,">gethostname(name @ %x, namelen=%d) => ws2",
|
|
name, namelen, 0 );
|
|
|
|
retval = ( ws2_gethostname )( name, namelen );
|
|
|
|
WS_TRACE(NAME,"<gethostname() <= ws2: retval=%d.",
|
|
retval, 0, 0 );
|
|
|
|
#endif // CHICAGO
|
|
|
|
return retval;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
|
|
VOID
|
|
SockProcessAsyncGetServ (
|
|
IN DWORD TaskHandle,
|
|
IN DWORD OpCode,
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN char FAR *Filter,
|
|
IN char FAR *Protocol,
|
|
IN char FAR *Buffer,
|
|
IN int BufferLength
|
|
)
|
|
{
|
|
PSERVENT returnServ;
|
|
DWORD requiredBufferLength = 0;
|
|
BOOL posted;
|
|
LPARAM lParam;
|
|
DWORD error;
|
|
|
|
WS_ASSERT( OpCode == WS_OPCODE_GET_SERV_BY_NAME ||
|
|
OpCode == WS_OPCODE_GET_SERV_BY_PORT );
|
|
|
|
#if DBG
|
|
SetLastError( NO_ERROR );
|
|
#endif
|
|
|
|
//
|
|
// Get the necessary information.
|
|
//
|
|
|
|
if ( OpCode == WS_OPCODE_GET_SERV_BY_NAME ) {
|
|
returnServ = getservbyname( Filter, Protocol );
|
|
FREE_HEAP( Filter );
|
|
} else {
|
|
returnServ = getservbyport( (int)Filter, Protocol );
|
|
}
|
|
|
|
//
|
|
// Copy the servent structure to the output buffer.
|
|
//
|
|
|
|
if ( returnServ != NULL ) {
|
|
|
|
requiredBufferLength = CopyServentToBuffer(
|
|
Buffer,
|
|
BufferLength,
|
|
returnServ
|
|
);
|
|
|
|
if ( requiredBufferLength > (DWORD)BufferLength ) {
|
|
error = WSAENOBUFS;
|
|
} else {
|
|
error = NO_ERROR;
|
|
}
|
|
|
|
} else {
|
|
|
|
error = GetLastError( );
|
|
WS_ASSERT( error != NO_ERROR );
|
|
}
|
|
|
|
//
|
|
// Build lParam for the message we'll post to the application.
|
|
// The high 16 bits are the error code, the low 16 bits are
|
|
// the minimum buffer size required for the operation.
|
|
//
|
|
|
|
lParam = WSAMAKEASYNCREPLY( requiredBufferLength, error );
|
|
|
|
//
|
|
// If this request was cancelled, just return.
|
|
//
|
|
|
|
if ( TaskHandle == SockCancelledAsyncTaskHandle ) {
|
|
IF_DEBUG(ASYNC_GETXBYY) {
|
|
WS_PRINT(( "SockProcessAsyncGetServ: task handle %lx cancelled\n",
|
|
TaskHandle ));
|
|
}
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Set the current async thread task handle to 0 so that if a cancel
|
|
// request comes in after this point it is failed properly.
|
|
//
|
|
|
|
SockCurrentAsyncThreadTaskHandle = 0;
|
|
|
|
//
|
|
// Post a message to the application indication that the data it
|
|
// requested is available.
|
|
//
|
|
|
|
WS_ASSERT( sizeof(TaskHandle) == sizeof(HANDLE) );
|
|
posted = SockPostRoutine( hWnd, wMsg, (WPARAM)TaskHandle, lParam );
|
|
|
|
//
|
|
// !!! Need a mechanism to repost if the post failed!
|
|
//
|
|
|
|
if ( !posted ) {
|
|
WS_PRINT(( "SockProcessAsyncGetServ: PostMessage failed: %ld\n",
|
|
GetLastError( ) ));
|
|
WS_ASSERT( FALSE );
|
|
}
|
|
|
|
return;
|
|
|
|
} // SockProcessAsyncGetServ
|
|
|
|
#endif // CHICAGO
|