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.
535 lines
12 KiB
535 lines
12 KiB
//****************************************************************************
|
|
//
|
|
// Microsoft NT Remote Access Service
|
|
//
|
|
// Copyright 1992-93
|
|
//
|
|
//
|
|
// Revision History
|
|
//
|
|
//
|
|
// 6/2/92 Gurdeep Singh Pall Created
|
|
//
|
|
//
|
|
// Description: This file contains misellaneous functions used by rasman.
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <rasman.h>
|
|
#include <wanpub.h>
|
|
#include <raserror.h>
|
|
#include <stdarg.h>
|
|
#include <media.h>
|
|
#include "defs.h"
|
|
#include "structs.h"
|
|
#include "protos.h"
|
|
#include "globals.h"
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include "string.h"
|
|
#include <mprlog.h>
|
|
#include <rtutils.h>
|
|
#include "logtrdef.h"
|
|
#include "rpc.h"
|
|
#include "rasrpc.h"
|
|
#include "winsock2.h"
|
|
#include "svcguid.h"
|
|
|
|
#define QUERYBUFSIZE 1024
|
|
|
|
extern RPC_BINDING_HANDLE g_hBinding;
|
|
|
|
//
|
|
// commonly used handles are cached in the process's
|
|
// global memory
|
|
//
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Gets a free request buffer from the pool of buffers.
|
|
If there are no buffers available it blocks for one.
|
|
This is acceptable since the Requestor thread will be
|
|
releasing buffers fairly quickly - also, if this thread
|
|
does not block here it will be blocking for the Requestor
|
|
thread to complete the request anyway. Note: Before returning
|
|
it also ensures that this process has a handle to the
|
|
event used to signal completion of request.
|
|
|
|
Arguments
|
|
|
|
Returns Value
|
|
|
|
Nothing
|
|
|
|
--*/
|
|
|
|
RequestBuffer*
|
|
GetRequestBuffer ()
|
|
{
|
|
DWORD dwError;
|
|
RequestBuffer *pRequestBuffer = NULL;
|
|
|
|
//
|
|
// check to see if we are bound to the rpc server
|
|
// bind to the server if we aren't
|
|
//
|
|
if ( NULL == g_hBinding
|
|
&& NULL == g_fnServiceRequest)
|
|
{
|
|
if (NO_ERROR != (dwError = RasRpcConnect(NULL, NULL)))
|
|
{
|
|
RasmanOutputDebug ("Failed to connect to local server. %d\n",
|
|
dwError );
|
|
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
pRequestBuffer = LocalAlloc(LPTR,
|
|
sizeof(RequestBuffer)
|
|
+ REQUEST_BUFFER_SIZE);
|
|
|
|
done:
|
|
return pRequestBuffer;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Frees the request buffer, and, closes the wait event
|
|
handle which was duplicated for the calling process
|
|
in the GetRequestBuffer() API.
|
|
|
|
Arguments
|
|
|
|
Return Value
|
|
Nothing
|
|
|
|
--*/
|
|
|
|
VOID
|
|
FreeRequestBuffer (RequestBuffer *buffer)
|
|
{
|
|
LocalFree(buffer);
|
|
return;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
No queue really - just signals the other process
|
|
to service request.
|
|
|
|
Arguments
|
|
|
|
Return Value
|
|
Nothing
|
|
|
|
--*/
|
|
DWORD
|
|
PutRequestInQueue (HANDLE hConnection,
|
|
RequestBuffer *preqbuff,
|
|
DWORD dwSizeOfBuffer)
|
|
{
|
|
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (g_fnServiceRequest)
|
|
{
|
|
g_fnServiceRequest(preqbuff, dwSizeOfBuffer);
|
|
}
|
|
else
|
|
{
|
|
dwErr = RemoteSubmitRequest (hConnection,
|
|
(PBYTE) preqbuff,
|
|
dwSizeOfBuffer);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Copies params from one struct to another.
|
|
|
|
Arguments
|
|
|
|
Return Value
|
|
|
|
Nothing.
|
|
--*/
|
|
|
|
VOID
|
|
CopyParams (RAS_PARAMS *src, RAS_PARAMS *dest, DWORD numofparams)
|
|
{
|
|
WORD i ;
|
|
PBYTE temp ;
|
|
|
|
//
|
|
// first copy all the params into dest
|
|
//
|
|
memcpy (dest,
|
|
src,
|
|
numofparams*sizeof(RAS_PARAMS)) ;
|
|
|
|
//
|
|
// copy the strings:
|
|
//
|
|
temp = (PBYTE)dest + numofparams * sizeof(RAS_PARAMS) ;
|
|
|
|
for (i = 0; i < numofparams; i++)
|
|
{
|
|
if (src[i].P_Type == String)
|
|
{
|
|
dest[i].P_Value.String.Length =
|
|
src[i].P_Value.String.Length ;
|
|
|
|
dest[i].P_Value.String.Data = temp ;
|
|
|
|
memcpy (temp,
|
|
src[i].P_Value.String.Data,
|
|
src[i].P_Value.String.Length) ;
|
|
|
|
temp += src[i].P_Value.String.Length ;
|
|
|
|
}
|
|
else
|
|
{
|
|
dest[i].P_Value.Number = src[i].P_Value.Number ;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ConvParamPointerToOffset (RAS_PARAMS *params, DWORD numofparams)
|
|
{
|
|
WORD i ;
|
|
|
|
for (i = 0; i < numofparams; i++)
|
|
{
|
|
if (params[i].P_Type == String)
|
|
{
|
|
params[i].P_Value.String_OffSet.dwOffset =
|
|
(DWORD) (params[i].P_Value.String.Data - (PCHAR) params) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ConvParamOffsetToPointer (RAS_PARAMS *params, DWORD numofparams)
|
|
{
|
|
WORD i ;
|
|
|
|
for (i = 0; i < numofparams; i++)
|
|
{
|
|
if (params[i].P_Type == String)
|
|
{
|
|
params[i].P_Value.String.Data =
|
|
params[i].P_Value.String_OffSet.dwOffset
|
|
+ (PCHAR) params ;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Closes the handles for different objects opened by RASMAN process.
|
|
|
|
Arguments
|
|
|
|
Return Value
|
|
|
|
--*/
|
|
|
|
VOID
|
|
FreeNotifierHandle (HANDLE handle)
|
|
{
|
|
if ((handle != NULL) && (handle != INVALID_HANDLE_VALUE))
|
|
{
|
|
if (!CloseHandle (handle))
|
|
{
|
|
GetLastError () ;
|
|
}
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
DwRasGetHostByName(CHAR *pszHostName,
|
|
DWORD **ppdwAddress,
|
|
DWORD *pcAddresses)
|
|
{
|
|
WCHAR *pwszHostName = NULL;
|
|
DWORD dwErr = SUCCESS;
|
|
HANDLE hRnr;
|
|
PWSAQUERYSETW pQuery = NULL;
|
|
const static GUID ServiceGuid = SVCID_INET_HOSTADDRBYNAME;
|
|
DWORD dwQuerySize = QUERYBUFSIZE;
|
|
DWORD dwAddress = 0;
|
|
const static AFPROTOCOLS afProtocols[2] =
|
|
{
|
|
{AF_INET, IPPROTO_UDP},
|
|
{AF_INET, IPPROTO_TCP}
|
|
};
|
|
|
|
DWORD cAddresses = 0;
|
|
DWORD *pdwAddresses = NULL;
|
|
DWORD MaxAddresses = 5;
|
|
|
|
ASSERT(NULL != ppdwAddress);
|
|
ASSERT(NULL != pcAddresses);
|
|
|
|
if (NULL != pszHostName)
|
|
{
|
|
DWORD cch;
|
|
|
|
cch = MultiByteToWideChar(
|
|
CP_UTF8,
|
|
0,
|
|
pszHostName,
|
|
-1,
|
|
NULL,
|
|
0);
|
|
|
|
if(0 == cch)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
pwszHostName = LocalAlloc(LPTR, (cch + 1) * sizeof(WCHAR));
|
|
|
|
if(NULL == pwszHostName)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
cch = MultiByteToWideChar(
|
|
CP_UTF8,
|
|
0,
|
|
pszHostName,
|
|
-1,
|
|
pwszHostName,
|
|
cch);
|
|
if (0 == cch)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwErr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
if(NULL == (pQuery = LocalAlloc(LPTR, QUERYBUFSIZE)))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
if(NULL == (pdwAddresses = LocalAlloc(LPTR, 5 * sizeof(DWORD))))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
pdwAddresses[0] = 0x80461111;
|
|
pdwAddresses[1] = 0x80461111;
|
|
pdwAddresses[2] = 0x12345668;
|
|
pdwAddresses[3] = 0x12345668;
|
|
pdwAddresses[4] = 0x12345668;
|
|
cAddresses = 5;
|
|
|
|
*/
|
|
|
|
|
|
pQuery->lpszServiceInstanceName = pwszHostName;
|
|
pQuery->dwSize = QUERYBUFSIZE;
|
|
pQuery->dwNameSpace = NS_ALL;
|
|
pQuery->lpServiceClassId = (GUID *) &ServiceGuid;
|
|
pQuery->dwNumberOfProtocols = 2;
|
|
pQuery->lpafpProtocols = (AFPROTOCOLS *) afProtocols;
|
|
|
|
if((dwErr = WSALookupServiceBeginW(
|
|
pQuery,
|
|
LUP_RETURN_ADDR,
|
|
&hRnr)) == SOCKET_ERROR)
|
|
{
|
|
dwErr = WSAGetLastError();
|
|
goto done;
|
|
}
|
|
|
|
while(NO_ERROR == dwErr)
|
|
{
|
|
if(NO_ERROR == (dwErr = WSALookupServiceNextW(
|
|
hRnr,
|
|
0,
|
|
&dwQuerySize,
|
|
pQuery)))
|
|
{
|
|
DWORD iAddress;
|
|
|
|
for(iAddress = 0;
|
|
iAddress < pQuery->dwNumberOfCsAddrs;
|
|
iAddress++)
|
|
{
|
|
|
|
dwAddress =
|
|
* ((DWORD*)
|
|
&pQuery->lpcsaBuffer[iAddress].RemoteAddr.lpSockaddr->sa_data[2]);
|
|
|
|
//
|
|
// If we have run out of space to return, realloc the
|
|
// buffer
|
|
//
|
|
if(cAddresses == MaxAddresses)
|
|
{
|
|
BYTE *pTemp;
|
|
|
|
pTemp = LocalAlloc(LPTR, (MaxAddresses + 5) * sizeof(DWORD));
|
|
|
|
if(NULL == pTemp)
|
|
{
|
|
dwErr = GetLastError();
|
|
|
|
if(pdwAddresses != NULL)
|
|
{
|
|
LocalFree(pdwAddresses);
|
|
pdwAddresses = NULL;
|
|
}
|
|
|
|
goto done;
|
|
}
|
|
|
|
CopyMemory(pTemp,
|
|
(PBYTE) pdwAddresses,
|
|
cAddresses * sizeof(DWORD));
|
|
|
|
LocalFree(pdwAddresses);
|
|
pdwAddresses = (DWORD *) pTemp;
|
|
MaxAddresses += 5;
|
|
}
|
|
|
|
|
|
pdwAddresses[cAddresses] = dwAddress;
|
|
cAddresses += 1;
|
|
}
|
|
|
|
}
|
|
else if (SOCKET_ERROR == dwErr)
|
|
{
|
|
dwErr = WSAGetLastError();
|
|
|
|
if(WSAEFAULT == dwErr)
|
|
{
|
|
//
|
|
// Allocate a bigger buffer and continue
|
|
//
|
|
LocalFree(pQuery);
|
|
if(NULL == (pQuery = LocalAlloc(LPTR, dwQuerySize)))
|
|
{
|
|
dwErr = GetLastError();
|
|
break;
|
|
}
|
|
|
|
dwErr = NO_ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
WSALookupServiceEnd(hRnr);
|
|
|
|
#if 0
|
|
|
|
RasmanOutputDebug("RASMAN: RasGetHostByName: number of addresses=%d\n",
|
|
cAddresses);
|
|
|
|
{
|
|
DWORD i;
|
|
RasmanOutputDebug("RASMAN: addresses:");
|
|
for(i=0; i < cAddresses; i++)
|
|
{
|
|
RasmanOutputDebug("%x ", pdwAddresses[i]);
|
|
}
|
|
|
|
RasmanOutputDebug("\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
done:
|
|
|
|
*ppdwAddress = pdwAddresses;
|
|
*pcAddresses = cAddresses;
|
|
|
|
if(WSA_E_NO_MORE == dwErr)
|
|
{
|
|
dwErr = NO_ERROR;
|
|
}
|
|
|
|
if(NO_ERROR != dwErr)
|
|
{
|
|
//
|
|
// Map it to an error that says the destination
|
|
// is not reachable.
|
|
//
|
|
dwErr = ERROR_BAD_ADDRESS_SPECIFIED;
|
|
}
|
|
|
|
if(NULL != pwszHostName)
|
|
{
|
|
LocalFree(pwszHostName);
|
|
}
|
|
|
|
if(NULL != pQuery)
|
|
{
|
|
LocalFree(pQuery);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
#define RASMAN_OUTPUT_DEBUG_STATEMENTS 0
|
|
|
|
VOID
|
|
RasmanOutputDebug(
|
|
CHAR * Format,
|
|
...)
|
|
{
|
|
#if DBG
|
|
#if RASMAN_OUTPUT_DEBUG_STATEMENTS
|
|
CHAR pszTrace[4096];
|
|
va_list arglist;
|
|
|
|
*pszTrace = '\0';
|
|
|
|
va_start(arglist, Format);
|
|
vsprintf(pszTrace, Format, arglist);
|
|
va_end(arglist);
|
|
|
|
DbgPrint(pszTrace);
|
|
|
|
#endif
|
|
#endif
|
|
}
|
|
|