Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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
}