771 lines
22 KiB
C++
771 lines
22 KiB
C++
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1993 - 1999
|
||
|
||
Module Name:
|
||
|
||
epmgmt.c
|
||
|
||
Abstract:
|
||
|
||
We implement the endpoint mapper management routines: RpcMgmtEpEltInqBegin,
|
||
RpcMgmtEpEltInqDone, RpcMgmtEpEltInqNext, and RpcMgmtEpUnregister.
|
||
|
||
Author:
|
||
|
||
Michael Montague (mikemon) 14-Apr-1993
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include <precomp.hxx>
|
||
#include <epmp.h>
|
||
#include <twrproto.h>
|
||
#include <epmap.h>
|
||
#include <charconv.hxx>
|
||
|
||
#define EP_INQUIRY_CONTEXT_MAGIC_VALUE 0xBAD00DADL
|
||
|
||
typedef struct _EP_INQUIRY_CONTEXT
|
||
{
|
||
unsigned long MagicValue;
|
||
RPC_BINDING_HANDLE BindingHandle;
|
||
ept_lookup_handle_t ContextHandle;
|
||
unsigned long InquiryType;
|
||
RPC_IF_ID IfId;
|
||
unsigned long VersOption;
|
||
UUID ObjectUuid;
|
||
} EP_INQUIRY_CONTEXT;
|
||
|
||
#define NOMOREEPS 0xFFFFFFFEL
|
||
|
||
#define NOMOREEPS_HANDLE ((ept_lookup_handle_t)ULongToPtr(NOMOREEPS))
|
||
// const ept_lookup_handle_t NOMOREEPS_HANDLE = (ept_lookup_handle_t)ULongToPtr(NOMOREEPS);
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
RpcMgmtEpEltInqBegin (
|
||
IN RPC_BINDING_HANDLE EpBinding OPTIONAL,
|
||
IN unsigned long InquiryType,
|
||
IN RPC_IF_ID __RPC_FAR * IfId OPTIONAL,
|
||
IN unsigned long VersOption OPTIONAL,
|
||
IN UUID __RPC_FAR * ObjectUuid OPTIONAL,
|
||
OUT RPC_EP_INQ_HANDLE __RPC_FAR * InquiryContext
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is used to create an inquiry context for viewing the elements
|
||
in a local or remote endpoint mapper database.
|
||
|
||
Arguments:
|
||
|
||
EpBinding - Optionally supplies a binding indicating the endpoint mapper on
|
||
which host should be interogated. The binding must have a nil object
|
||
uuid; otherwise, EPT_S_CANT_PERFORM_OP will be returned. To specify
|
||
this host (meaning the one the application is running on), specify NULL
|
||
for this argument. Only the network address and transport type will
|
||
be used from the binding handle.
|
||
|
||
InquiryType - Supplies the type of interogation to be performed; this must
|
||
be one of: RPC_C_EP_ALL_ELTS, RPC_C_EP_MATCH_BY_IF,
|
||
RPC_C_EP_MATCH_BY_OBJ, and RPC_C_EP_MATCH_BY_BOTH.
|
||
|
||
IfId - Optionally supplies the interface identifier we are interogating
|
||
the endpoint mapper with. This argument must be supplied when the
|
||
inquiry type is RPC_C_EP_MATCH_BY_IF or RPC_C_EP_MATCH_BY_BOTH;
|
||
otherwise, this argument is ignored and NULL can be supplied.
|
||
|
||
VersOption - Optionally supplies a flag specifying how interface versions
|
||
are to be matched. This argument must be supplied when IfId is
|
||
supplied; otherwise, this argument is ignored. Valid values for this
|
||
flag are: RPC_C_VERS_ALL, RPC_C_VERS_COMPATIBLE, RPC_C_VERS_EXACT,
|
||
RPC_C_VERS_MAJOR_ONLY, and RPC_C_VERS_UPTO.
|
||
|
||
ObjectUuid - Optionally supplies the object uuid find in the endpoint
|
||
mapper database. This argument must be supplied when the inquiry
|
||
typedef is RPC_C_EP_MATCH_BY_OBJ or RPC_EP_MATCH_BY_BOTH; otherwise,
|
||
this argument is ignored and NULL can be supplied.
|
||
|
||
InquiryContext - Returns a context handle which can be passed to
|
||
RpcMgmtEpEltInqNext to obtain the results of the interogation of the
|
||
endpoint mapper database.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_INVALID_ARG
|
||
EPT_S_CANT_PERFORM_OP
|
||
RPC_S_OUT_OF_MEMORY
|
||
|
||
--*/
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
RPC_CHAR __RPC_FAR * ProtocolSequence;
|
||
RPC_CHAR __RPC_FAR * NetworkAddress;
|
||
RPC_CHAR __RPC_FAR * Options;
|
||
EP_INQUIRY_CONTEXT __RPC_FAR * EpInquiryContext;
|
||
unsigned Timeout;
|
||
|
||
switch ( InquiryType )
|
||
{
|
||
case RPC_C_EP_ALL_ELTS :
|
||
IfId = 0;
|
||
ObjectUuid = 0;
|
||
break;
|
||
|
||
case RPC_C_EP_MATCH_BY_IF :
|
||
ObjectUuid = 0;
|
||
// no break
|
||
case RPC_C_EP_MATCH_BY_BOTH :
|
||
if ( IfId == 0 )
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
|
||
if ( ( VersOption != RPC_C_VERS_ALL )
|
||
&& ( VersOption != RPC_C_VERS_COMPATIBLE )
|
||
&& ( VersOption != RPC_C_VERS_EXACT )
|
||
&& ( VersOption != RPC_C_VERS_MAJOR_ONLY )
|
||
&& ( VersOption != RPC_C_VERS_UPTO ) )
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
|
||
if ( ( InquiryType == RPC_C_EP_MATCH_BY_BOTH )
|
||
&& ( ObjectUuid == 0 ) )
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
break;
|
||
|
||
case RPC_C_EP_MATCH_BY_OBJ :
|
||
IfId = 0;
|
||
if ( ObjectUuid == 0 )
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
|
||
// At this point, we have validated the InquiryType, IfId, VersOption,
|
||
// and ObjectUuid parameters.
|
||
|
||
if ( EpBinding != 0 )
|
||
{
|
||
UUID Uuid;
|
||
int Result;
|
||
RPC_CHAR __RPC_FAR * StringBinding;
|
||
|
||
RpcStatus = RpcBindingInqObject(EpBinding, &Uuid);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
Result = UuidIsNil(&Uuid, &RpcStatus);
|
||
if ( Result == 0 )
|
||
{
|
||
return(EPT_S_CANT_PERFORM_OP);
|
||
}
|
||
|
||
RpcStatus = RpcBindingToStringBinding(EpBinding, &StringBinding);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = RpcStringBindingParse(StringBinding, 0, &ProtocolSequence,
|
||
&NetworkAddress, 0, &Options);
|
||
RpcStringFree(&StringBinding);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = RpcMgmtInqComTimeout(EpBinding, &Timeout);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
RpcStringFree(&ProtocolSequence);
|
||
RpcStringFree(&NetworkAddress);
|
||
RpcStringFree(&Options);
|
||
return(RpcStatus);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
NetworkAddress = 0;
|
||
ProtocolSequence = 0;
|
||
Options = 0;
|
||
Timeout = RPC_C_BINDING_DEFAULT_TIMEOUT;
|
||
}
|
||
|
||
// When we reach here, the EpBinding will have been validated, and the
|
||
// network address and protocol sequence to be used to reach the endpoint
|
||
// mapper have been determined.
|
||
|
||
// Thus all of the arguments will have been validated.
|
||
|
||
EpInquiryContext = (EP_INQUIRY_CONTEXT __RPC_FAR *) I_RpcAllocate(
|
||
sizeof(EP_INQUIRY_CONTEXT));
|
||
if ( EpInquiryContext == 0 )
|
||
{
|
||
if (EpBinding != 0)
|
||
{
|
||
RpcStringFree(&ProtocolSequence);
|
||
RpcStringFree(&NetworkAddress);
|
||
RpcStringFree(&Options);
|
||
}
|
||
return(RPC_S_OUT_OF_MEMORY);
|
||
}
|
||
|
||
RpcStatus = BindToEpMapper(&(EpInquiryContext->BindingHandle),
|
||
NetworkAddress,
|
||
ProtocolSequence,
|
||
Options,
|
||
Timeout,
|
||
INFINITE, // CallTimeout
|
||
NULL // AuthInfo
|
||
);
|
||
|
||
if (EpBinding != 0)
|
||
{
|
||
RpcStringFree(&ProtocolSequence);
|
||
RpcStringFree(&NetworkAddress);
|
||
RpcStringFree(&Options);
|
||
}
|
||
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
EpInquiryContext->MagicValue = EP_INQUIRY_CONTEXT_MAGIC_VALUE;
|
||
EpInquiryContext->ContextHandle = 0;
|
||
EpInquiryContext->InquiryType = InquiryType;
|
||
if ( IfId != 0 )
|
||
{
|
||
EpInquiryContext->IfId = *IfId;
|
||
}
|
||
EpInquiryContext->VersOption = VersOption;
|
||
if ( ObjectUuid != 0 )
|
||
{
|
||
EpInquiryContext->ObjectUuid = *ObjectUuid;
|
||
}
|
||
|
||
*InquiryContext = (RPC_EP_INQ_HANDLE)EpInquiryContext;
|
||
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
RpcMgmtEpEltInqDone (
|
||
IN OUT RPC_EP_INQ_HANDLE __RPC_FAR * InquiryContext
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
The context handle used to interogate an endpoint mapper database is
|
||
cleaned up in this routine.
|
||
|
||
Arguments:
|
||
|
||
InquiryContext - Supplies the context handle to be deleted; on return,
|
||
it will be set to zero.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK - Everything worked out just fine.
|
||
|
||
RPC_S_INVALID_ARG - The supplied value supplied for the inquiry context
|
||
is not an endpoint mapper inquiry context.
|
||
|
||
--*/
|
||
{
|
||
EP_INQUIRY_CONTEXT __RPC_FAR * EpInquiryContext =
|
||
(EP_INQUIRY_CONTEXT __RPC_FAR *) *InquiryContext;
|
||
|
||
if ( EpInquiryContext->MagicValue != EP_INQUIRY_CONTEXT_MAGIC_VALUE )
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
|
||
RpcBindingFree(&(EpInquiryContext->BindingHandle));
|
||
|
||
if ( (EpInquiryContext->ContextHandle != 0) &&
|
||
(EpInquiryContext->ContextHandle != NOMOREEPS_HANDLE) )
|
||
{
|
||
RpcSsDestroyClientContext(&(EpInquiryContext->ContextHandle));
|
||
}
|
||
|
||
I_RpcFree(EpInquiryContext);
|
||
*InquiryContext = 0;
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
RpcMgmtEpEltInqNextW (
|
||
IN RPC_EP_INQ_HANDLE InquiryContext,
|
||
OUT RPC_IF_ID __RPC_FAR * IfId,
|
||
OUT RPC_BINDING_HANDLE __RPC_FAR * Binding OPTIONAL,
|
||
OUT UUID __RPC_FAR * ObjectUuid OPTIONAL,
|
||
OUT unsigned short __RPC_FAR * __RPC_FAR * Annotation OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the unicode thunk to RpcMgmtEpEltInqNextA.
|
||
|
||
--*/
|
||
{
|
||
unsigned char * AnsiAnnotation;
|
||
RPC_STATUS RpcStatus;
|
||
|
||
RpcStatus = RpcMgmtEpEltInqNextA( InquiryContext,
|
||
IfId,
|
||
Binding,
|
||
ObjectUuid,
|
||
Annotation ? &AnsiAnnotation : 0
|
||
);
|
||
|
||
if ( (RpcStatus == RPC_S_OK) && (Annotation) )
|
||
{
|
||
RpcStatus = A2WAttachHelper((char *)AnsiAnnotation, Annotation);
|
||
I_RpcFree(AnsiAnnotation);
|
||
}
|
||
|
||
return RpcStatus;
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
RpcMgmtEpEltInqNextA (
|
||
IN RPC_EP_INQ_HANDLE InquiryContext,
|
||
OUT RPC_IF_ID __RPC_FAR * IfId,
|
||
OUT RPC_BINDING_HANDLE __RPC_FAR * Binding OPTIONAL,
|
||
OUT UUID __RPC_FAR * ObjectUuid OPTIONAL,
|
||
OUT unsigned char __RPC_FAR * __RPC_FAR * Annotation OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
An application will use this routine to obtain the results of an
|
||
interogation of the endpoint mapper database.
|
||
|
||
Arguments:
|
||
|
||
InquiryContext - Supplies a context handle for the interogation.
|
||
|
||
IfId - Returns the interface identifier of the element which was
|
||
found in the endpoint mapper database.
|
||
|
||
Binding - Optionally returns the binding handle contained in the element.
|
||
|
||
Annotation - Optionally returns the annotation stored in the element.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK - We have successfully returned an element from the endpoint
|
||
mapper database.
|
||
|
||
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to perform the
|
||
operation.
|
||
|
||
RPC_S_INVALID_ARG - The supplied value for the inquiry context is not
|
||
a valid endpoint mapper inquiry context.
|
||
|
||
EPT_S_CANT_PERFORM_OP -
|
||
|
||
RPC_X_NO_MORE_ENTRIES - No more entries are available. This will be
|
||
returned after all of the entries have been returned from the
|
||
endpoint mapper.
|
||
|
||
--*/
|
||
{
|
||
EP_INQUIRY_CONTEXT __RPC_FAR * EpInquiryContext =
|
||
(EP_INQUIRY_CONTEXT __RPC_FAR *) InquiryContext;
|
||
unsigned long Returned;
|
||
ept_entry_t EpEntry;
|
||
error_status ErrorStatus;
|
||
RPC_STATUS RpcStatus = RPC_S_OK;
|
||
unsigned char __RPC_FAR * StringBinding;
|
||
unsigned char __RPC_FAR * ProtocolSequence;
|
||
unsigned char __RPC_FAR * Endpoint;
|
||
unsigned char __RPC_FAR * NWAddress = 0;
|
||
|
||
if ( EpInquiryContext->MagicValue != EP_INQUIRY_CONTEXT_MAGIC_VALUE )
|
||
{
|
||
return(RPC_S_INVALID_ARG);
|
||
}
|
||
|
||
if ( EpInquiryContext->ContextHandle == NOMOREEPS_HANDLE )
|
||
{
|
||
return (RPC_X_NO_MORE_ENTRIES);
|
||
}
|
||
|
||
while (1)
|
||
{
|
||
|
||
EpEntry.tower = 0;
|
||
RpcTryExcept
|
||
{
|
||
ept_lookup(EpInquiryContext->BindingHandle,
|
||
EpInquiryContext->InquiryType, &(EpInquiryContext->ObjectUuid),
|
||
&(EpInquiryContext->IfId), EpInquiryContext->VersOption,
|
||
&(EpInquiryContext->ContextHandle), 1, &Returned, &EpEntry,
|
||
&ErrorStatus);
|
||
}
|
||
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
||
{
|
||
RpcStatus = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
if ( RpcStatus == RPC_S_OK )
|
||
{
|
||
if ( ErrorStatus == EP_S_NOT_REGISTERED )
|
||
{
|
||
RpcStatus = RPC_X_NO_MORE_ENTRIES;
|
||
}
|
||
else if ( ErrorStatus != 0 )
|
||
{
|
||
RpcStatus = EPT_S_CANT_PERFORM_OP;
|
||
}
|
||
}
|
||
|
||
if ( ( RpcStatus == RPC_S_OK )
|
||
&& ( Returned != 1 ) )
|
||
{
|
||
RpcStatus = EPT_S_CANT_PERFORM_OP;
|
||
}
|
||
|
||
if (EpInquiryContext->ContextHandle == 0)
|
||
{
|
||
EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
|
||
}
|
||
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
if (RpcStatus == RPC_S_SERVER_UNAVAILABLE)
|
||
{
|
||
RpcStatus = RPC_X_NO_MORE_ENTRIES;
|
||
}
|
||
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = TowerExplode(EpEntry.tower, IfId, 0,
|
||
(char __RPC_FAR * __RPC_FAR *) &ProtocolSequence,
|
||
(char __RPC_FAR * __RPC_FAR *) &Endpoint,
|
||
(char __RPC_FAR * __RPC_FAR *) &NWAddress
|
||
);
|
||
|
||
MIDL_user_free(EpEntry.tower);
|
||
if (RpcStatus != RPC_S_OK)
|
||
{
|
||
if ( (EpInquiryContext->ContextHandle == 0) || (EpInquiryContext->ContextHandle == NOMOREEPS_HANDLE) )
|
||
{
|
||
EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
|
||
return(RPC_X_NO_MORE_ENTRIES);
|
||
}
|
||
else
|
||
{
|
||
RpcStatus = RPC_S_OK;
|
||
continue;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//Tower Explode returned Success
|
||
if ( Binding != 0 )
|
||
{
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = RpcStringBindingComposeA(0,
|
||
ProtocolSequence, NWAddress,
|
||
Endpoint, 0, &StringBinding);
|
||
if ( RpcStatus == RPC_S_OK )
|
||
{
|
||
RpcStatus = RpcBindingFromStringBindingA(
|
||
StringBinding,
|
||
Binding
|
||
);
|
||
RpcStringFreeA(&StringBinding);
|
||
}
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
RpcStringFreeA(&ProtocolSequence);
|
||
RpcStringFreeA(&Endpoint);
|
||
if (NWAddress != 0)
|
||
{
|
||
RpcStringFreeA(&NWAddress);
|
||
}
|
||
|
||
if ( (EpInquiryContext->ContextHandle == 0) || (EpInquiryContext->ContextHandle == NOMOREEPS_HANDLE) )
|
||
{
|
||
EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
|
||
return(RPC_X_NO_MORE_ENTRIES);
|
||
}
|
||
else
|
||
{
|
||
RpcStatus = RPC_S_OK;
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (ObjectUuid != 0)
|
||
{
|
||
memcpy(ObjectUuid, &EpEntry.object, sizeof(UUID));
|
||
}
|
||
|
||
RpcStringFreeA(&ProtocolSequence);
|
||
RpcStringFreeA(&Endpoint);
|
||
if (NWAddress != 0)
|
||
{
|
||
RpcStringFreeA(&NWAddress);
|
||
}
|
||
}
|
||
|
||
if ( Annotation != 0 )
|
||
{
|
||
*Annotation = (unsigned char __RPC_FAR *) I_RpcAllocate(
|
||
strlen((LPCSTR) EpEntry.annotation) + 1);
|
||
if ( *Annotation == 0 )
|
||
{
|
||
return(RPC_S_OUT_OF_MEMORY);
|
||
}
|
||
strcpy((LPSTR) *Annotation, (LPCSTR) EpEntry.annotation);
|
||
}
|
||
|
||
//MIDL_user_free(EpEntry.tower);
|
||
break;
|
||
}
|
||
|
||
if (EpInquiryContext->ContextHandle == 0)
|
||
{
|
||
EpInquiryContext->ContextHandle = NOMOREEPS_HANDLE;
|
||
}
|
||
|
||
return(RpcStatus);
|
||
|
||
}
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
RpcMgmtEpUnregister (
|
||
IN RPC_BINDING_HANDLE EpBinding OPTIONAL,
|
||
IN RPC_IF_ID __RPC_FAR * IfId,
|
||
IN RPC_BINDING_HANDLE Binding,
|
||
IN UUID __RPC_FAR * ObjectUuid OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is used by management applications to remote server address
|
||
information from a local or remote endpoint map.
|
||
|
||
Arguments:
|
||
|
||
EpBinding - Optionally supplies a binding handle specifying which host
|
||
from which to unregister remote server address information. To
|
||
specify this host, supply zero for this argument. If a binding
|
||
handle is supplied, then the object uuid in the binding handle must
|
||
be zero.
|
||
|
||
IfId - Supplies the interface identifier to be removed from the endpoint
|
||
mapper database.
|
||
|
||
Binding - Supplies the binding handle to be removed from the endpoint
|
||
mapper database.
|
||
|
||
ObjectUuid - Optionally supplies an object uuid to be removed; a value
|
||
of zero indicates there is no object uuid to be removed.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK -
|
||
|
||
EPT_S_NOT_REGISTERED -
|
||
|
||
EPT_S_CANT_PERFORM_OP -
|
||
|
||
--*/
|
||
{
|
||
UUID Uuid;
|
||
RPC_STATUS RpcStatus;
|
||
int Result;
|
||
|
||
RPC_CHAR * ProtocolSequence;
|
||
RPC_CHAR * NetworkAddress;
|
||
RPC_CHAR * Options;
|
||
RPC_CHAR * StringBinding;
|
||
|
||
unsigned char __RPC_FAR * AnsiProtocolSequence;
|
||
unsigned char __RPC_FAR * AnsiNetworkAddress;
|
||
unsigned char __RPC_FAR * AnsiEndpoint;
|
||
unsigned char __RPC_FAR * AnsiStringBinding;
|
||
|
||
RPC_BINDING_HANDLE EpBindingHandle;
|
||
unsigned long UuidFlag;
|
||
unsigned long ErrorStatus;
|
||
twr_t __RPC_FAR * Tower;
|
||
RPC_TRANSFER_SYNTAX TransferSyntax;
|
||
unsigned Timeout;
|
||
|
||
if ( EpBinding != 0 )
|
||
{
|
||
RpcStatus = RpcBindingInqObject(EpBinding, &Uuid);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
Result = UuidIsNil(&Uuid, &RpcStatus);
|
||
if ( Result == 0 )
|
||
{
|
||
return(EPT_S_CANT_PERFORM_OP);
|
||
}
|
||
|
||
RpcStatus = RpcBindingToStringBinding(EpBinding, &StringBinding);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = RpcStringBindingParse( StringBinding,
|
||
0,
|
||
&ProtocolSequence,
|
||
&NetworkAddress,
|
||
0,
|
||
&Options);
|
||
RpcStringFree(&StringBinding);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = RpcMgmtInqComTimeout(EpBinding, &Timeout);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
RpcStringFree(&ProtocolSequence);
|
||
RpcStringFree(&NetworkAddress);
|
||
RpcStringFree(&Options);
|
||
return(RpcStatus);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
NetworkAddress = 0;
|
||
ProtocolSequence = 0;
|
||
Options = 0;
|
||
Timeout = RPC_C_BINDING_DEFAULT_TIMEOUT;
|
||
}
|
||
|
||
// When we reach here, the EpBinding will have been validated, and the
|
||
// network address and protocol sequence to be used to reach the endpoint
|
||
// mapper have been determined.
|
||
|
||
RpcStatus = BindToEpMapper( &EpBindingHandle,
|
||
NetworkAddress,
|
||
ProtocolSequence,
|
||
Options,
|
||
Timeout,
|
||
INFINITE, // CallTimeout
|
||
NULL // AuthInfo
|
||
);
|
||
|
||
RpcStringFree(&ProtocolSequence);
|
||
RpcStringFree(&NetworkAddress);
|
||
RpcStringFree(&Options);
|
||
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = RpcBindingToStringBindingA(Binding, &AnsiStringBinding);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = RpcStringBindingParseA( AnsiStringBinding,
|
||
0,
|
||
&AnsiProtocolSequence,
|
||
&AnsiNetworkAddress,
|
||
&AnsiEndpoint,
|
||
0);
|
||
RpcStringFree(&StringBinding);
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
RpcStatus = TowerConstruct( IfId,
|
||
&TransferSyntax,
|
||
(LPSTR) AnsiProtocolSequence,
|
||
(LPSTR) AnsiEndpoint,
|
||
(LPSTR) AnsiNetworkAddress,
|
||
&Tower);
|
||
|
||
RpcStringFreeA(&AnsiProtocolSequence);
|
||
RpcStringFreeA(&AnsiNetworkAddress);
|
||
RpcStringFreeA(&AnsiEndpoint);
|
||
|
||
if ( RpcStatus != RPC_S_OK )
|
||
{
|
||
return(RpcStatus);
|
||
}
|
||
|
||
if ( ObjectUuid != 0 )
|
||
{
|
||
Uuid = *ObjectUuid;
|
||
UuidFlag = 1;
|
||
}
|
||
else
|
||
{
|
||
UuidFlag = 0;
|
||
}
|
||
|
||
ASSERT( RpcStatus == RPC_S_OK );
|
||
|
||
RpcTryExcept
|
||
{
|
||
ept_mgmt_delete(EpBindingHandle, UuidFlag, &Uuid, Tower, &ErrorStatus);
|
||
}
|
||
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
||
{
|
||
RpcStatus = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
if ( RpcStatus == RPC_S_OK )
|
||
{
|
||
if ( ErrorStatus != 0 )
|
||
{
|
||
RpcStatus = EPT_S_NOT_REGISTERED;
|
||
}
|
||
}
|
||
else
|
||
if ( RpcStatus == RPC_S_SERVER_UNAVAILABLE )
|
||
{
|
||
RpcStatus = EPT_S_NOT_REGISTERED;
|
||
}
|
||
|
||
RpcBindingFree(&EpBindingHandle);
|
||
return(RpcStatus);
|
||
}
|
||
|