602 lines
13 KiB
C++
602 lines
13 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) Microsoft Corporation, 1991 - 1999
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
svrbind.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This file contains the implementation of the server binding handle
|
|||
|
class, SVR_BINDING_HANDLE.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Michael Montague (mikemon) 23-Nov-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <precomp.hxx>
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::InsureRealBindingHandle (
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method is used to insure that we have transformed this binding
|
|||
|
handle into a real full fledged binding handle. If we do not
|
|||
|
have a real binding handle, then we attempt to create one.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK will be returned if we successfully obtain a real binding
|
|||
|
handle. Otherwise, the result of trying to create a binding handle
|
|||
|
will be returned; see DCE_BINDING::CreateBindingHandle for a list
|
|||
|
of error codes.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if (RealBindingHandle == 0)
|
|||
|
{
|
|||
|
|
|||
|
RealBindingHandle = DceBinding->CreateBindingHandle(&Status);
|
|||
|
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
{
|
|||
|
RealBindingHandle = 0;
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
// This binding needs to transfer its ObjectUuid, if any,
|
|||
|
// to the new binding. It is not possible to efficiently add
|
|||
|
// the object uuid to the DceBinding first.
|
|||
|
|
|||
|
if (InqIfNullObjectUuid() == 0)
|
|||
|
{
|
|||
|
RealBindingHandle->SetObjectUuid(InqPointerAtObjectUuid());
|
|||
|
}
|
|||
|
|
|||
|
DceBinding = 0;
|
|||
|
}
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
SVR_BINDING_HANDLE::SVR_BINDING_HANDLE (
|
|||
|
IN DCE_BINDING * DceBinding,
|
|||
|
IN RPC_CHAR * DynamicEndpoint,
|
|||
|
IN OUT RPC_STATUS *Status
|
|||
|
) : BINDING_HANDLE(Status)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This constructor is trivial. We just stash the binding information
|
|||
|
and dynamic endpoint away for future use.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DceBinding - Supplies the binding information. Ownership of this
|
|||
|
object passes to this routine.
|
|||
|
|
|||
|
DynamicEndpoint - Supplies the dynamic endpoint for the rpc address
|
|||
|
corresponding to this binding. Ownership of this object passes
|
|||
|
to this routine.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ObjectType = SVR_BINDING_HANDLE_TYPE;
|
|||
|
this->DceBinding = DceBinding;
|
|||
|
RealBindingHandle = 0;
|
|||
|
|
|||
|
if( DynamicEndpoint )
|
|||
|
{
|
|||
|
EndpointIsDynamic = 1;
|
|||
|
DceBinding->AddEndpoint(DynamicEndpoint);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
EndpointIsDynamic = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
SVR_BINDING_HANDLE::~SVR_BINDING_HANDLE (
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Since ownership of the binding information passed to the constructor
|
|||
|
of this instance, we need to delete the binding information now.
|
|||
|
Actually, before we can delete the binding information we need to
|
|||
|
check to see if ownership has passed to the real binding handle.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (DceBinding != 0)
|
|||
|
delete DceBinding;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
inline HANDLE_TYPE // Return SVR_BINDING_HANDLE_TYPE.
|
|||
|
SVR_BINDING_HANDLE::Type (
|
|||
|
)
|
|||
|
{
|
|||
|
UNUSED(this);
|
|||
|
|
|||
|
return (SVR_BINDING_HANDLE_TYPE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
SVR_BINDING_HANDLE::MakePartiallyBound(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called by RPC_SERVER::NsBindingsModify(). We just
|
|||
|
remove the endpoint information from DceBinding member variable.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (EndpointIsDynamic)
|
|||
|
{
|
|||
|
DceBinding->MakePartiallyBound();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::SendReceive (
|
|||
|
IN OUT PRPC_MESSAGE Message
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We need to transport the server binding handle into a full fledged
|
|||
|
binding handle, and then let the full fledged binding handle take
|
|||
|
care of performing the requested operation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Message - Supplies and returns information describing the remote
|
|||
|
procedure call to be sent.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
For possible return codes, see DCE_BINDING::CreateBindingHandle and
|
|||
|
SendReceive.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = InsureRealBindingHandle();
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return(Status);
|
|||
|
return(RealBindingHandle->SendReceive(Message));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::NegotiateTransferSyntax (
|
|||
|
IN OUT PRPC_MESSAGE Message
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We need to transport the server binding handle into a full fledged
|
|||
|
binding handle, and then let the full fledged binding handle take
|
|||
|
care of performing the requested operation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Message - Supplies and returns information describing the buffer
|
|||
|
we need to allocate.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
For possible return codes, see DCE_BINDING::CreateBindingHandle and
|
|||
|
the different flavors of NegotiateTransferSyntax.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = InsureRealBindingHandle();
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return(Status);
|
|||
|
return(RealBindingHandle->NegotiateTransferSyntax(Message));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::GetBuffer (
|
|||
|
IN OUT PRPC_MESSAGE Message,
|
|||
|
IN UUID *ObjectUuid
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We need to transport the server binding handle into a full fledged
|
|||
|
binding handle, and then let the full fledged binding handle take
|
|||
|
care of performing the requested operation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Message - Supplies and returns information describing the buffer
|
|||
|
we need to allocate.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
For possible return codes, see DCE_BINDING::CreateBindingHandle and
|
|||
|
the different flavors of GetBuffer.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = InsureRealBindingHandle();
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return(Status);
|
|||
|
return(RealBindingHandle->GetBuffer(Message, ObjectUuid));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
SVR_BINDING_HANDLE::FreeBuffer (
|
|||
|
IN PRPC_MESSAGE Message
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We need to transport the server binding handle into a full fledged
|
|||
|
binding handle, and then let the full fledged binding handle take
|
|||
|
care of performing the requested operation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Message - Supplies the buffer to be freed.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = InsureRealBindingHandle();
|
|||
|
ASSERT(Status == RPC_S_OK);
|
|||
|
RealBindingHandle->FreeBuffer(Message);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::BindingCopy (
|
|||
|
OUT BINDING_HANDLE * PAPI * DestinationBinding,
|
|||
|
IN unsigned int MaintainContext
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We need to copy this binding handle. This is relatively easy to
|
|||
|
do: we just need to duplicate the binding information and construct
|
|||
|
another server binding handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DestinationBinding - Returns a copy of this binding handle.
|
|||
|
|
|||
|
MaintainContext - Supplies a flag that indicates whether or not context
|
|||
|
is being maintained over this binding handle. A non-zero value
|
|||
|
indicates that context is being maintained.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - This indicates that there is not enough memory
|
|||
|
to allocate a new binding handle.
|
|||
|
|
|||
|
RPC_S_OK - We successfully copied this binding handle.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
SVR_BINDING_HANDLE * Binding;
|
|||
|
DCE_BINDING * DceBinding;
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if (RealBindingHandle != 0)
|
|||
|
return(RealBindingHandle->BindingCopy(DestinationBinding,
|
|||
|
MaintainContext));
|
|||
|
|
|||
|
// Even if the binding is really dynamic, the endpoint has
|
|||
|
// been added to the DceBinding in the constructor.
|
|||
|
|
|||
|
DceBinding = this->DceBinding->DuplicateDceBinding();
|
|||
|
if (DceBinding == 0)
|
|||
|
{
|
|||
|
*DestinationBinding = 0;
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
|
|||
|
Binding = new SVR_BINDING_HANDLE(DceBinding,0, &Status);
|
|||
|
*DestinationBinding = Binding;
|
|||
|
if (Binding == 0)
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::BindingFree (
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
The application wants to free this binding handle. If there is a real
|
|||
|
binding handle, we need to invoke BindingFree on it as well; otherwise,
|
|||
|
all we have got to do is to delete it.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - This value will be returned, unless an error occurs in the
|
|||
|
BindingFree operation invoked on the real binding handle.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if (RealBindingHandle != 0)
|
|||
|
{
|
|||
|
Status = RealBindingHandle->BindingFree();
|
|||
|
RealBindingHandle = 0;
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
delete this;
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::ToStringBinding (
|
|||
|
OUT RPC_CHAR PAPI * PAPI * StringBinding
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We need to convert the binding handle into a string binding. We
|
|||
|
can just use the information in this server binding handle to
|
|||
|
create the string binding.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
StringBinding - Returns the string representation of the binding
|
|||
|
handle.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The operation completed successfully.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - We do not have enough memory available to
|
|||
|
allocate space for the string binding.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (RealBindingHandle != 0)
|
|||
|
return(RealBindingHandle->ToStringBinding(StringBinding));
|
|||
|
|
|||
|
*StringBinding = DceBinding->StringBindingCompose(
|
|||
|
InqPointerAtObjectUuid());
|
|||
|
if (*StringBinding == 0)
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::ToStaticStringBinding (
|
|||
|
OUT RPC_CHAR PAPI * PAPI * StringBinding
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We need to convert the binding handle into a string binding. We
|
|||
|
can just use the information in this server binding handle to
|
|||
|
create the string binding.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
StringBinding - Returns the string representation of the binding
|
|||
|
handle.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The operation completed successfully.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - We do not have enough memory available to
|
|||
|
allocate space for the string binding.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
RPC_CHAR __RPC_FAR * CopiedStringBinding;
|
|||
|
RPC_UUID *MyUuid = 0;
|
|||
|
DCE_BINDING *MyDceBinding;
|
|||
|
|
|||
|
if (RealBindingHandle != 0)
|
|||
|
{
|
|||
|
Status = RealBindingHandle->ToStringBinding(StringBinding);
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
{
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
if (EndpointIsDynamic == 0)
|
|||
|
{
|
|||
|
return RPC_S_OK;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The endpoint is dynamic, need to strip it out
|
|||
|
//
|
|||
|
CopiedStringBinding = (RPC_CHAR *)
|
|||
|
_alloca( (RpcpStringLength(StringBinding)+1)*(sizeof(RPC_CHAR)) );
|
|||
|
if (CopiedStringBinding == 0)
|
|||
|
{
|
|||
|
return (RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
RpcpStringCopy(CopiedStringBinding, StringBinding);
|
|||
|
|
|||
|
MyDceBinding = new DCE_BINDING(CopiedStringBinding,&Status);
|
|||
|
|
|||
|
if ( MyDceBinding == 0 )
|
|||
|
{
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
|
|||
|
if ( Status != RPC_S_OK )
|
|||
|
{
|
|||
|
delete MyDceBinding;
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
MyUuid = InqPointerAtObjectUuid();
|
|||
|
MyDceBinding = DceBinding;
|
|||
|
}
|
|||
|
|
|||
|
*StringBinding = MyDceBinding->StringBindingCompose(
|
|||
|
MyUuid,
|
|||
|
EndpointIsDynamic);
|
|||
|
|
|||
|
if (DceBinding != MyDceBinding)
|
|||
|
{
|
|||
|
delete MyDceBinding;
|
|||
|
}
|
|||
|
|
|||
|
if (*StringBinding == 0)
|
|||
|
{
|
|||
|
return RPC_S_OUT_OF_MEMORY;
|
|||
|
}
|
|||
|
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::InquireDynamicEndpoint (
|
|||
|
OUT RPC_CHAR PAPI * PAPI * DynamicEndpoint
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to obtain the dynamic endpoint from a binding
|
|||
|
handle which was created from an rpc address. If there is a dynamic
|
|||
|
endpoint, we just need to duplicate it, and return a pointer to it.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DynamicEndpoint - Returns a pointer to the dynamic endpoint, it is
|
|||
|
always set to zero.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The operation completed successfully.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - Unable to allocate memory for the endpoint string.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (EndpointIsDynamic == 1 && DceBinding)
|
|||
|
{
|
|||
|
*DynamicEndpoint = DuplicateStringPAPI(DceBinding->InqEndpoint());
|
|||
|
if (*DynamicEndpoint == 0)
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*DynamicEndpoint = 0;
|
|||
|
}
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::PrepareBindingHandle (
|
|||
|
IN TRANS_INFO * TransportInterface,
|
|||
|
IN DCE_BINDING * DceBinding
|
|||
|
)
|
|||
|
{
|
|||
|
UNUSED(this);
|
|||
|
UNUSED(TransportInterface);
|
|||
|
UNUSED(DceBinding);
|
|||
|
|
|||
|
ASSERT( 0 );
|
|||
|
return RPC_S_OK;
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::ResolveBinding (
|
|||
|
IN PRPC_CLIENT_INTERFACE RpcClientInterface
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = InsureRealBindingHandle();
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return (Status);
|
|||
|
return(RealBindingHandle->ResolveBinding(RpcClientInterface));
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::BindingReset (
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = InsureRealBindingHandle();
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return(Status);
|
|||
|
Status = RealBindingHandle->BindingReset();
|
|||
|
if (Status == RPC_S_OK)
|
|||
|
{
|
|||
|
EndpointIsDynamic = 0;
|
|||
|
}
|
|||
|
return (Status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SVR_BINDING_HANDLE::InquireTransportType(
|
|||
|
OUT unsigned int PAPI *Type
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = InsureRealBindingHandle();
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return(Status);
|
|||
|
return(RealBindingHandle->InquireTransportType(Type));
|
|||
|
}
|
|||
|
|