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.
909 lines
20 KiB
909 lines
20 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
tower.c
|
|
|
|
Abstract:
|
|
|
|
This file contains encoding/decoding for the tower representation
|
|
of the binding information that DCE runtime uses.
|
|
|
|
TowerConstruct/TowerExplode will be called by the Runtime EpResolveBinding
|
|
on the client side, TowerExplode will be called by the Endpoint Mapper
|
|
and in addition the name service may call TowerExplode, TowerConstruct.
|
|
|
|
Author:
|
|
|
|
Bharat Shah (barats) 3-23-92
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <sysinc.h>
|
|
#include <rpc.h>
|
|
#include "rpcndr.h"
|
|
#include <epmp.h>
|
|
#include "twrtypes.h"
|
|
#include <twrproto.h>
|
|
|
|
|
|
#ifndef NTENV
|
|
#define StringCompareA RpcpStringCompare
|
|
#define StringLengthA RpcpStringLength
|
|
#else
|
|
#define StringCompareA _stricmp
|
|
#define StringLengthA strlen
|
|
#endif
|
|
|
|
#ifndef UNALIGNED
|
|
#error UNALIGNED not defined by sysinc.h or its includes and is needed.
|
|
#endif
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
#ifdef WIN32
|
|
/*
|
|
Some Spc specific stuff
|
|
*/
|
|
|
|
#define NP_TRANSPORTID_SPC 0x10
|
|
#define NP_TOWERS_SPC 0x04
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef WIN
|
|
#pragma code_seg("MISC_SEG")
|
|
#endif
|
|
|
|
#define MAKEPORT(a, b) ((unsigned short)(((unsigned char)(a)) | ((unsigned short)((unsigned char)(b))) << 8))
|
|
|
|
|
|
void RPC_ENTRY
|
|
GetNWStyleName(
|
|
OUT char __RPC_FAR * string,
|
|
IN char __RPC_FAR * netaddr,
|
|
IN int sizeofname
|
|
);
|
|
|
|
extern void ByteSwapUuid(IN OUT UUID __RPC_FAR *pUuid);
|
|
|
|
|
|
RPC_STATUS
|
|
Floor0or1ToId(
|
|
IN PFLOOR_0OR1 Floor,
|
|
OUT PGENERIC_ID Id
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function extracts Xfer Syntax or If info from a
|
|
a DCE tower Floor 0 or 1 encoding
|
|
|
|
Arguments:
|
|
|
|
Floor - A pointer to Floor0 or Floor 1 encoding
|
|
Id -
|
|
|
|
Return Value:
|
|
EP_S_CANT_PERFORM_OP - The Encoding for the floor [0 or 1] is incorrect.
|
|
|
|
--*/
|
|
{
|
|
if (Floor->FloorId != UUID_ENCODING)
|
|
{
|
|
return (EP_S_CANT_PERFORM_OP);
|
|
}
|
|
|
|
RpcpMemoryCopy((char PAPI *)&Id->Uuid, (char PAPI *) &Floor->Uuid,
|
|
sizeof(UUID));
|
|
|
|
Id->MajorVersion = Floor->MajorVersion;
|
|
Id->MinorVersion = Floor->MinorVersion;
|
|
|
|
#ifdef MAC
|
|
ByteSwapUuid(&Id->Uuid) ;
|
|
ByteSwapShort(Id->MajorVersion) ;
|
|
ByteSwapShort(Id->MinorVersion) ;
|
|
#endif
|
|
|
|
return(RPC_S_OK);
|
|
}
|
|
|
|
|
|
RPC_STATUS
|
|
CopyIdToFloor(
|
|
OUT PFLOOR_0OR1 Floor,
|
|
IN PGENERIC_ID Id
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function constructs FLOOR 0 or 1 from the given IF-id or Transfer
|
|
Syntax Id.
|
|
|
|
Arguments:
|
|
|
|
Floor - Pointer to Floor 0 or 1 structure that will be constructed
|
|
|
|
Id - Pointer to If-id or Xfer Syntax Id.
|
|
|
|
Return Value:
|
|
|
|
RPC_S_OK
|
|
|
|
--*/
|
|
{
|
|
|
|
Floor->FloorId = UUID_ENCODING;
|
|
Floor->ProtocolIdByteCount = sizeof(Floor->Uuid) + sizeof(Floor->FloorId)
|
|
+ sizeof(Floor->MajorVersion);
|
|
Floor->AddressByteCount = sizeof(Floor->MinorVersion);
|
|
|
|
#ifdef MAC
|
|
ByteSwapShort(Floor->ProtocolIdByteCount) ;
|
|
ByteSwapShort(Floor->AddressByteCount) ;
|
|
#endif
|
|
|
|
RpcpMemoryCopy((char PAPI *) &Floor->Uuid, (char PAPI *) &Id->Uuid,
|
|
sizeof(UUID));
|
|
|
|
Floor->MajorVersion = Id->MajorVersion;
|
|
Floor->MinorVersion = Id->MinorVersion;
|
|
|
|
#ifdef MAC
|
|
ByteSwapShort(Floor->MajorVersion) ;
|
|
ByteSwapShort(Floor->MinorVersion) ;
|
|
ByteSwapUuid(&Floor->Uuid) ;
|
|
#endif
|
|
|
|
return(RPC_S_OK);
|
|
}
|
|
|
|
#ifdef WIN
|
|
#pragma code_seg()
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
SpcTowerConstruct(
|
|
IN char PAPI * Endpoint,
|
|
OUT UNALIGNED unsigned short PAPI * Floors,
|
|
OUT UNALIGNED unsigned long PAPI * ByteCount,
|
|
OUT unsigned char PAPI * UNALIGNED PAPI * Tower
|
|
)
|
|
{
|
|
unsigned long TowerSize;
|
|
UNALIGNED PFLOOR_234 Floor;
|
|
|
|
*Floors = NP_TOWERS_SPC;
|
|
TowerSize = ((Endpoint == NULL) || (*Endpoint == '\0')) ?
|
|
2 : (StringLengthA(Endpoint) + 1);
|
|
TowerSize += sizeof(FLOOR_234) - 2;
|
|
|
|
if ((*Tower = (unsigned char *)I_RpcAllocate(*ByteCount = TowerSize)) == NULL)
|
|
{
|
|
return (RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
|
|
Floor = (PFLOOR_234) *Tower;
|
|
|
|
Floor->ProtocolIdByteCount = 1;
|
|
Floor->FloorId = (unsigned char)(NP_TRANSPORTID_SPC & 0xFF);
|
|
if ((Endpoint) && (*Endpoint))
|
|
{
|
|
RpcpMemoryCopy((char PAPI *)&Floor->Data[0], Endpoint,
|
|
(Floor->AddressByteCount = StringLengthA(Endpoint)+1));
|
|
}
|
|
else
|
|
{
|
|
Floor->AddressByteCount = 2;
|
|
Floor->Data[0] = 0;
|
|
}
|
|
|
|
return(RPC_S_OK);
|
|
}
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
SpcTowerExplode(
|
|
IN char PAPI * Tower,
|
|
OUT char PAPI * UNALIGNED PAPI * Protseq,
|
|
OUT char PAPI * UNALIGNED PAPI * Endpoint,
|
|
OUT char PAPI * UNALIGNED PAPI * NetworkAddress
|
|
)
|
|
{
|
|
|
|
UNALIGNED PFLOOR_234 Floor = (PFLOOR_234) Tower;
|
|
|
|
if (NetworkAddress != 0)
|
|
{
|
|
*NetworkAddress = 0;
|
|
}
|
|
|
|
if (Protseq != NULL)
|
|
{
|
|
*Protseq = I_RpcAllocate(StringLengthA("ncalrpc") + 1);
|
|
if (*Protseq == NULL)
|
|
{
|
|
return(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
RpcpMemoryCopy(*Protseq, "ncalrpc", StringLengthA("ncalrpc") + 1);
|
|
}
|
|
|
|
if (Endpoint == NULL)
|
|
{
|
|
return (RPC_S_OK);
|
|
}
|
|
|
|
|
|
*Endpoint = I_RpcAllocate(Floor->AddressByteCount);
|
|
if (*Endpoint == NULL)
|
|
{
|
|
if (Protseq != NULL)
|
|
{
|
|
I_RpcFree(*Protseq);
|
|
}
|
|
return(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
RpcpMemoryCopy(*Endpoint, (char PAPI *)&Floor->Data[0],
|
|
Floor->AddressByteCount);
|
|
|
|
|
|
return(RPC_S_OK);
|
|
|
|
}
|
|
|
|
#endif // WIN32
|
|
|
|
#ifdef WIN
|
|
#pragma code_seg("MISC_SEG")
|
|
#endif
|
|
|
|
RPC_STATUS
|
|
GetProtseqAndEndpointFromFloor3(
|
|
IN PFLOOR_234 Floor,
|
|
OUT char PAPI * PAPI * Protseq,
|
|
OUT char PAPI * PAPI * Endpoint,
|
|
OUT char PAPI * PAPI * NWAddress
|
|
)
|
|
{
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function extracts the Protocol Sequence and Endpoint info
|
|
from a "Lower Tower" representation
|
|
|
|
Arguments:
|
|
|
|
Floor - Pointer to Floor2 structure.
|
|
|
|
Protseq - A pointer that will contain Protocol seq on return
|
|
The memory will be allocated by this routins and caller
|
|
will have to free this memory.
|
|
|
|
Endpoint- A pointer that will contain Endpoint on return
|
|
The memory will be allocated by this routins and caller
|
|
will have to free this memory.
|
|
|
|
Return Value:
|
|
|
|
RPC_S_OK
|
|
|
|
RPC_S_OUT_OF_MEMORY - There is no memory to return Protseq or Endpoint str.
|
|
|
|
EP_S_CANT_PERFORM_OP - Lower Tower Encoding is incorrect.
|
|
--*/
|
|
|
|
unsigned short Type = Floor->FloorId, ProtocolType;
|
|
RPC_STATUS Status;
|
|
|
|
ProtocolType = Floor->FloorId;
|
|
Floor = NEXTFLOOR(PFLOOR_234, Floor);
|
|
#ifdef MAC
|
|
ByteSwapShort(Floor->ProtocolIdByteCount) ;
|
|
ByteSwapShort(Floor->AddressByteCount) ;
|
|
#endif
|
|
|
|
|
|
switch(ProtocolType)
|
|
|
|
{
|
|
|
|
#ifdef WIN32
|
|
case SPC:
|
|
Status = SpcTowerExplode((unsigned char PAPI *)Floor,
|
|
Protseq, Endpoint, NWAddress);
|
|
break;
|
|
#endif /*WIN32*/
|
|
|
|
case CONNECTIONFUL:
|
|
case CONNECTIONLESS:
|
|
|
|
/*
|
|
|
|
First take a crack at parsing the predefined
|
|
towers .. if that fails we do the inefficient thing
|
|
of looking in the registry for tansport id->protseq mapping
|
|
and then load the [client side] dll and call the dlls
|
|
TowerExplode .. if it provided one.
|
|
|
|
*/
|
|
|
|
Status = ExplodePredefinedTowers((unsigned char PAPI *)Floor,
|
|
Protseq,Endpoint,NWAddress);
|
|
|
|
if (Status == RPC_S_INVALID_RPC_PROTSEQ)
|
|
{
|
|
|
|
if (NWAddress != 0)
|
|
{
|
|
*NWAddress = 0;
|
|
}
|
|
|
|
Status = OsfTowerExplode((unsigned char PAPI *) Floor,
|
|
Protseq, Endpoint, NWAddress);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
Status = EP_S_CANT_PERFORM_OP;
|
|
|
|
}
|
|
|
|
return(Status);
|
|
}
|
|
|
|
|
|
void RPC_ENTRY
|
|
GetNWStyleName(
|
|
OUT char __RPC_FAR * string,
|
|
IN char __RPC_FAR * netaddr,
|
|
IN int sizeofname
|
|
)
|
|
{
|
|
|
|
unsigned char c;
|
|
int i;
|
|
|
|
string[0] = '~';
|
|
|
|
/* Convert the network number. */
|
|
for (i = 0; i < sizeofname; i++)
|
|
{
|
|
c = netaddr[i];
|
|
if (c < 0xA0)
|
|
string[2*i+1] = ((c & 0xF0) >> 4) + '0';
|
|
else
|
|
string[2*i+1] = ((c & 0xF0) >> 4) + 'A' - 10;
|
|
if ((c & 0x0F) < 0x0A)
|
|
string[2*i+2] = (c & 0x0F) + '0';
|
|
else
|
|
string[2*i+2] = (c & 0x0F) + 'A' - 10;
|
|
}
|
|
|
|
|
|
/* Append a null. */
|
|
string[2*sizeofname+1] = '\0';
|
|
|
|
}
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
ExplodePredefinedTowers(
|
|
IN unsigned char __RPC_FAR * Tower,
|
|
OUT char __RPC_FAR * UNALIGNED __RPC_FAR * Protseq,
|
|
OUT char __RPC_FAR * UNALIGNED __RPC_FAR * Endpoint,
|
|
OUT char __RPC_FAR * UNALIGNED __RPC_FAR * NWAddress
|
|
)
|
|
{
|
|
UNALIGNED PFLOOR_234 Floor = (PFLOOR_234) Tower;
|
|
UNALIGNED PFLOOR_234 FloorNext;
|
|
RPC_STATUS Status = RPC_S_OK;
|
|
char __RPC_FAR * ProtocolSequence;
|
|
unsigned short PortNum;
|
|
#ifdef WIN
|
|
static char Tmp[8];
|
|
#endif
|
|
unsigned short ProtocolType;
|
|
unsigned char __RPC_FAR * Addr;
|
|
|
|
switch (ProtocolType = Floor->FloorId)
|
|
|
|
{
|
|
|
|
case NCACN_NP:
|
|
case NCACN_AT_DSP:
|
|
case NCACN_NB:
|
|
if (Endpoint != 0)
|
|
{
|
|
*Endpoint = I_RpcAllocate(Floor->AddressByteCount);
|
|
if (*Endpoint == 0)
|
|
{
|
|
return(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
RpcpMemoryCopy(*Endpoint, (char PAPI *)&Floor->Data[0],
|
|
Floor->AddressByteCount);
|
|
}
|
|
if (Floor->FloorId == NCACN_NP)
|
|
{
|
|
ProtocolSequence = "ncacn_np";
|
|
}
|
|
else
|
|
if (Floor->FloorId == NCACN_AT_DSP)
|
|
{
|
|
ProtocolSequence = "ncacn_at_dsp";
|
|
}
|
|
else
|
|
{
|
|
FloorNext = NEXTFLOOR(PFLOOR_234, Floor);
|
|
|
|
switch (FloorNext->FloorId)
|
|
{
|
|
case NB_NBID:
|
|
ProtocolSequence = "ncacn_nb_nb";
|
|
break;
|
|
case NB_IPID:
|
|
ProtocolSequence = "ncacn_nb_tcp";
|
|
break;
|
|
case NB_IPXID:
|
|
ProtocolSequence = "ncacn_nb_ipx";
|
|
break;
|
|
case NB_XNSID:
|
|
ProtocolSequence = "ncacn_nb_xns";
|
|
break;
|
|
default:
|
|
if (Endpoint != 0)
|
|
{
|
|
I_RpcFree(Endpoint);
|
|
}
|
|
return (RPC_S_INVALID_RPC_PROTSEQ);
|
|
}
|
|
} //else
|
|
break;
|
|
|
|
case NCACN_IP_TCP:
|
|
case NCADG_IP_UDP:
|
|
case NCACN_SPX:
|
|
case NCADG_IPX:
|
|
if (Floor->FloorId == NCACN_IP_TCP)
|
|
{
|
|
ProtocolSequence = "ncacn_ip_tcp";
|
|
}
|
|
else
|
|
if (Floor->FloorId == NCADG_IP_UDP)
|
|
{
|
|
ProtocolSequence = "ncadg_ip_udp";
|
|
}
|
|
else
|
|
if (Floor->FloorId == NCACN_SPX)
|
|
{
|
|
ProtocolSequence = "ncacn_spx";
|
|
}
|
|
else
|
|
{
|
|
ProtocolSequence = "ncadg_ipx";
|
|
}
|
|
|
|
if (Endpoint != 0)
|
|
{
|
|
*Endpoint = I_RpcAllocate(6);
|
|
if (*Endpoint == 0)
|
|
{
|
|
return(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
RpcpMemoryCopy(&PortNum,(char PAPI *)&Floor->Data[0],sizeof(PortNum));
|
|
#ifdef WIN
|
|
_ultoa(ByteSwapShort(PortNum), Tmp, 10);
|
|
_fstrcpy(*Endpoint, Tmp);
|
|
#else
|
|
#ifndef MAC
|
|
RpcItoa(ByteSwapShort(PortNum), *Endpoint, 10);
|
|
#else
|
|
RpcItoa(PortNum, *Endpoint, 10);
|
|
#endif
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case NCACN_VNS_SPP:
|
|
ProtocolSequence = "ncacn_vns_spp";
|
|
PortNum = MAKEPORT(Floor->Data[1], Floor->Data[0]) ;
|
|
|
|
if (Endpoint != 0)
|
|
{
|
|
*Endpoint = I_RpcAllocate(6);
|
|
if (*Endpoint == 0)
|
|
{
|
|
return(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
|
|
#ifdef WIN
|
|
RpcItoa(PortNum , Tmp, 10);
|
|
_fstrcpy(*Endpoint, Tmp);
|
|
#else
|
|
RpcItoa(PortNum, *Endpoint, 10) ;
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return (RPC_S_INVALID_RPC_PROTSEQ);
|
|
|
|
}
|
|
|
|
if (Protseq != 0)
|
|
{
|
|
*Protseq = I_RpcAllocate(StringLengthA(ProtocolSequence) + 1);
|
|
if (*Protseq == 0)
|
|
{
|
|
if (Endpoint != 0)
|
|
{
|
|
I_RpcFree(*Endpoint);
|
|
*Endpoint = 0;
|
|
}
|
|
return(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
|
|
RpcpMemoryCopy(*Protseq, ProtocolSequence, StringLengthA(ProtocolSequence) + 1);
|
|
}
|
|
|
|
if (NWAddress != 0)
|
|
{
|
|
|
|
Floor = (PFLOOR_234)NEXTFLOOR(PFLOOR_234, Floor);
|
|
|
|
if (Floor->AddressByteCount == 0)
|
|
{
|
|
*NWAddress = 0;
|
|
return (RPC_S_OK);
|
|
}
|
|
switch (ProtocolType)
|
|
{
|
|
|
|
case NCACN_NP:
|
|
case NCACN_NB:
|
|
case NCACN_AT_DSP:
|
|
case NCACN_VNS_SPP:
|
|
|
|
//these have strings as their nw addresses
|
|
*NWAddress = I_RpcAllocate(Floor->AddressByteCount);
|
|
if (*NWAddress == 0)
|
|
{
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
break;
|
|
}
|
|
RpcpMemoryCopy(*NWAddress, &Floor->Data[0], Floor->AddressByteCount);
|
|
break;
|
|
|
|
case NCACN_IP_TCP:
|
|
case NCADG_IP_UDP:
|
|
|
|
if (Floor->AddressByteCount != 4)
|
|
{
|
|
Status = RPC_S_INVALID_RPC_PROTSEQ;
|
|
break;
|
|
}
|
|
*NWAddress = I_RpcAllocate(16+1); //255.255.255.255 + 1
|
|
if (*NWAddress == 0)
|
|
{
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
break;
|
|
}
|
|
Addr = &Floor->Data[0];
|
|
RpcpStringPrintfA(*NWAddress, "%d.%d.%d.%d", Addr[0], Addr[1], Addr[2], Addr[3]);
|
|
break;
|
|
|
|
case NCACN_SPX:
|
|
case NCADG_IPX:
|
|
|
|
if (Floor->AddressByteCount != 10)
|
|
{
|
|
Status = RPC_S_INVALID_RPC_PROTSEQ;
|
|
break;
|
|
}
|
|
*NWAddress = I_RpcAllocate(2*Floor->AddressByteCount+2);
|
|
if (*NWAddress == 0)
|
|
{
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
break;
|
|
}
|
|
GetNWStyleName(*NWAddress, &Floor->Data[0],Floor->AddressByteCount);
|
|
break;
|
|
|
|
default:
|
|
Status = RPC_S_INVALID_RPC_PROTSEQ;
|
|
} // switch
|
|
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
if (Endpoint != 0)
|
|
{
|
|
I_RpcFree(*Endpoint);
|
|
*Endpoint = 0;
|
|
}
|
|
if (Protseq != 0)
|
|
{
|
|
I_RpcFree(*Protseq);
|
|
*Protseq = 0;
|
|
}
|
|
return(Status);
|
|
}
|
|
|
|
}
|
|
|
|
return (RPC_S_OK);
|
|
}
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
TowerExplode(
|
|
IN twr_p_t Tower,
|
|
OUT RPC_IF_ID PAPI * Ifid, OPTIONAL
|
|
OUT RPC_TRANSFER_SYNTAX PAPI * XferId, OPTIONAL
|
|
OUT char PAPI * PAPI * Protseq, OPTIONAL
|
|
OUT char PAPI * PAPI * Endpoint, OPTIONAL
|
|
OUT char PAPI * PAPI * NWAddress OPTIONAL
|
|
)
|
|
/*++
|
|
|
|
|
|
Routine Description:
|
|
|
|
This function converts a DCE tower representation of various binding
|
|
information to binding info that is suitable to MS runtime.
|
|
Specically it returns Ifid, Xferid, Protseq and Endpoint information
|
|
encoded in the tower.
|
|
|
|
Arguments:
|
|
|
|
Tower - Tower encoding.
|
|
|
|
Ifid - A pointer to Ifid
|
|
|
|
Xferid - A pointer to Xferid
|
|
|
|
Protseq - A pointer to pointer returning Protseq
|
|
|
|
Endpoint- A pointer to pointer returning Endpoint
|
|
|
|
Return Value:
|
|
|
|
RPC_S_OK
|
|
|
|
EP_S_CANT_PERFORM_OP - Error while parsing the Tower encoding
|
|
|
|
RPC_S_OUT_OF_MEMORY - There is no memory to return Protseq and Endpoint
|
|
strings.
|
|
--*/
|
|
{
|
|
PFLOOR_0OR1 Floor;
|
|
PFLOOR_234 Floor234;
|
|
unsigned short FloorCount;
|
|
RPC_STATUS err = 0;
|
|
|
|
FloorCount = *((unsigned short PAPI *)&Tower->tower_octet_string);
|
|
#ifdef MAC
|
|
ByteSwapShort(FloorCount) ;
|
|
#endif
|
|
|
|
Floor = (PFLOOR_0OR1)
|
|
((unsigned short PAPI *)&Tower->tower_octet_string + 1);
|
|
|
|
#ifdef MAC
|
|
ByteSwapShort(Floor->ProtocolIdByteCount) ;
|
|
ByteSwapShort(Floor->AddressByteCount) ;
|
|
#endif
|
|
//Process Floor 0 Interface Spec.
|
|
if (Ifid != NULL)
|
|
{
|
|
err = Floor0or1ToId(Floor, (PGENERIC_ID) Ifid);
|
|
}
|
|
|
|
Floor = NEXTFLOOR(PFLOOR_0OR1, Floor);
|
|
|
|
#ifdef MAC
|
|
ByteSwapShort(Floor->ProtocolIdByteCount) ;
|
|
ByteSwapShort(Floor->AddressByteCount) ;
|
|
#endif
|
|
|
|
//Now we point to and process Floor 1 Transfer Syntax Spec.
|
|
if ((!err) && (XferId != NULL))
|
|
{
|
|
err = Floor0or1ToId(Floor, (PGENERIC_ID) XferId);
|
|
}
|
|
|
|
if (err)
|
|
{
|
|
return(err);
|
|
}
|
|
|
|
Floor234 = (PFLOOR_234)NEXTFLOOR(PFLOOR_0OR1, Floor);
|
|
#ifdef MAC
|
|
ByteSwapShort(Floor234->ProtocolIdByteCount) ;
|
|
ByteSwapShort(Floor234->AddressByteCount) ;
|
|
#endif
|
|
|
|
//Now Floor234 points to Floor 2. RpcProtocol [Connect-Datagram]
|
|
|
|
err = GetProtseqAndEndpointFromFloor3(Floor234, Protseq,Endpoint,NWAddress);
|
|
|
|
return(err);
|
|
}
|
|
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
TowerConstruct(
|
|
IN RPC_IF_ID PAPI * Ifid,
|
|
IN RPC_TRANSFER_SYNTAX PAPI * Xferid,
|
|
IN char PAPI * RpcProtocolSequence,
|
|
IN char PAPI * Endpoint, OPTIONAL
|
|
IN char PAPI * NWAddress, OPTIONAL
|
|
OUT twr_t PAPI * PAPI * Tower
|
|
)
|
|
/*++
|
|
|
|
|
|
Routine Description:
|
|
|
|
This function constructs a DCE tower representation from
|
|
Protseq, Endpoint, XferId and IfId
|
|
|
|
Arguments:
|
|
|
|
Ifid - A pointer to Ifid
|
|
|
|
Xferid - A pointer to Xferid
|
|
|
|
Protseq - A pointer to Protseq
|
|
|
|
Endpoint- A pointer to Endpoint
|
|
|
|
Tower - The constructed tower returmed - The memory is allocated
|
|
by the routine and caller will have to free it.
|
|
|
|
Return Value:
|
|
|
|
RPC_S_OK
|
|
|
|
EP_S_CANT_PERFORM_OP - Error while parsing the Tower encoding
|
|
|
|
RPC_S_OUT_OF_MEMORY - There is no memory to return the constructed
|
|
Tower.
|
|
--*/
|
|
{
|
|
|
|
unsigned short Numfloors, PAPI *FloorCnt;
|
|
twr_t PAPI * Twr;
|
|
PFLOOR_0OR1 Floor;
|
|
PFLOOR_234 Floor234, Floor234_1;
|
|
RPC_STATUS Status;
|
|
unsigned long TowerLen, ByteCount;
|
|
char PAPI * UpperTower;
|
|
unsigned short ProtocolType;
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
if ( StringCompareA(RpcProtocolSequence, "ncalrpc") == 0 )
|
|
{
|
|
ProtocolType = SPC;
|
|
Status = SpcTowerConstruct(Endpoint, &Numfloors,
|
|
&ByteCount, &UpperTower);
|
|
}
|
|
else
|
|
|
|
#endif // WIN32
|
|
|
|
{
|
|
|
|
if ( (RpcProtocolSequence[0] == 'n')
|
|
&& (RpcProtocolSequence[1] == 'c')
|
|
&& (RpcProtocolSequence[2] == 'a')
|
|
&& (RpcProtocolSequence[3] == 'c')
|
|
&& (RpcProtocolSequence[4] == 'n')
|
|
&& (RpcProtocolSequence[5] == '_'))
|
|
{
|
|
ProtocolType = CONNECTIONFUL;
|
|
}
|
|
else
|
|
|
|
if ( (RpcProtocolSequence[0] == 'n')
|
|
&& (RpcProtocolSequence[1] == 'c')
|
|
&& (RpcProtocolSequence[2] == 'a')
|
|
&& (RpcProtocolSequence[3] == 'd')
|
|
&& (RpcProtocolSequence[4] == 'g')
|
|
&& (RpcProtocolSequence[5] == '_'))
|
|
{
|
|
ProtocolType = CONNECTIONLESS;
|
|
}
|
|
|
|
else
|
|
{
|
|
return(RPC_S_INVALID_RPC_PROTSEQ);
|
|
}
|
|
|
|
Status = OsfTowerConstruct(
|
|
RpcProtocolSequence,
|
|
Endpoint,
|
|
NWAddress,
|
|
&Numfloors,
|
|
&ByteCount,
|
|
&UpperTower
|
|
);
|
|
}
|
|
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
return (Status);
|
|
}
|
|
|
|
TowerLen = 2 + ByteCount;
|
|
TowerLen += 2 * sizeof(FLOOR_0OR1) + sizeof(FLOOR_2) ; // BUGBUG:extra tower pad
|
|
|
|
if ( (*Tower = Twr = I_RpcAllocate((unsigned int)TowerLen+4)) == NULL)
|
|
{
|
|
I_RpcFree(UpperTower);
|
|
return(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
|
|
Twr->tower_length = TowerLen;
|
|
|
|
FloorCnt = (unsigned short PAPI *)&Twr->tower_octet_string;
|
|
*FloorCnt = Numfloors;
|
|
|
|
#ifdef MAC
|
|
ByteSwapShort(*FloorCnt) ;
|
|
#endif
|
|
|
|
Floor = (PFLOOR_0OR1)(FloorCnt+1);
|
|
|
|
//Floor 0 - IfUuid and IfVersion
|
|
CopyIdToFloor(Floor, (PGENERIC_ID)Ifid);
|
|
Floor++;
|
|
|
|
//Floor 1 - XferUuid and XferVersion
|
|
CopyIdToFloor(Floor, (PGENERIC_ID)Xferid);
|
|
|
|
//Floor 2
|
|
//ProtocolId = CONNECTIONFUL/CONNECTIONLESS/SPC and Address = 0(ushort)
|
|
Floor234 = (PFLOOR_234) (Floor + 1);
|
|
Floor234->ProtocolIdByteCount = 1;
|
|
Floor234->FloorId = (byte) ProtocolType;
|
|
Floor234->Data[0] = 0x0;
|
|
Floor234->Data[1] = 0x0;
|
|
Floor234->AddressByteCount = 2;
|
|
|
|
//Floor 3,4,5.. use the tower encoded by the Transports
|
|
Floor234_1 = NEXTFLOOR(PFLOOR_234, Floor234);
|
|
#ifdef MAC
|
|
ByteSwapShort(Floor234->ProtocolIdByteCount) ;
|
|
ByteSwapShort(Floor234->AddressByteCount) ;
|
|
#endif
|
|
|
|
RpcpMemoryCopy((char PAPI *)Floor234_1, (char PAPI *)UpperTower,
|
|
(size_t)ByteCount);
|
|
I_RpcFree(UpperTower);
|
|
|
|
return(RPC_S_OK);
|
|
}
|
|
|
|
#ifdef WIN
|
|
#pragma code_seg()
|
|
#endif
|
|
|
|
#pragma pack()
|
|
|