//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1990 - 1999 // // File: handle.hxx // //-------------------------------------------------------------------------- /* -------------------------------------------------------------------- Microsoft OS/2 LAN Manager Copyright(c) Microsoft Corp., 1990 -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- File: handle.hxx Description: All of the classes in the handle management layer which are common to both the client runtime and the server runtime are in this file. The classes used only by the server runtime live in hndlsvr.hxx. The classes described here are independent of specific RPC protocol as well as transport. The class GENERIC_OBJECT is used is the root for the handle class hierarchy. It provides dynamic type checking for all handles. The MESSAGE_OBJECT class provides a common protocol for all of the handle types which know to send and receive messages. The CCONNECTION class represents a call handle on the client side. The BINDING_HANDLE class is a binding handle as used by a client to perform remote procedure calls. GENERIC_OBJECT MESSAGE_OBJECT CCONNECTION BINDING_HANDLE History : mikemon ??-??-?? Beginning of time (at least for this file). mikemon 12-28-90 Cleaned up the comments. Kamen Moutafov (kamenm) Jan-2000 Support for multiple transfer syntaxes Kamen Moutafov (KamenM) Dec 99 - Feb 2000 - Support for cell debugging stuff -------------------------------------------------------------------- */ #ifndef __HANDLE_HXX__ #define __HANDLE_HXX__ // These are the types for all of the handles visible outside of the // RPC runtime. Since they are just defines, we might as well stick // the server handle types here as well. #define OBJECT_DELETED 0x00000001 #define DG_CCALL_TYPE 0x00000004 #define DG_SCALL_TYPE 0x00000008 #define DG_BINDING_HANDLE_TYPE 0x00000010 #define OSF_CCALL_TYPE 0x00000020 #define OSF_SCALL_TYPE 0x00000040 #define OSF_CCONNECTION_TYPE 0x00000080 #define OSF_SCONNECTION_TYPE 0x00000100 #define OSF_CASSOCIATION_TYPE 0x00000200 #define OSF_ASSOCIATION_TYPE 0x00000400 #define OSF_ADDRESS_TYPE 0x00000800 #define LRPC_CCALL_TYPE 0x00001000 #define LRPC_SCALL_TYPE 0x00002000 #define LRPC_CASSOCIATION_TYPE 0x00004000 #define LRPC_SASSOCIATION_TYPE 0x00008000 #define LRPC_BINDING_HANDLE_TYPE 0x00010000 #define SVR_BINDING_HANDLE_TYPE 0x00020000 #define DG_CCONNECTION_TYPE 0x00040000 #define DG_SCONNECTION_TYPE 0x00080000 #define OSF_BINDING_HANDLE_TYPE 0x00100000 #define DG_CALLBACK_TYPE 0x00200000 #define DG_ADDRESS_TYPE 0x00400000 #define LRPC_ADDRESS_TYPE 0x00800000 #define DG_CASSOCIATION_TYPE 0x01000000 #define DG_SASSOCIATION_TYPE 0x02000000 #define CONTEXT_TYPE 0x04000000 #define HTTP_CLIENT_IN_CHANNEL 0x10000000 #define HTTP_CLIENT_OUT_CHANNEL 0x10000010 typedef int HANDLE_TYPE; // // define the base types // #define CALL_TYPE (DG_CCALL_TYPE \ | DG_SCALL_TYPE \ | OSF_CCALL_TYPE \ | OSF_SCALL_TYPE \ | LRPC_CCALL_TYPE \ | LRPC_SCALL_TYPE \ | DG_CALLBACK_TYPE) #define BINDING_HANDLE_TYPE (OSF_BINDING_HANDLE_TYPE \ | DG_BINDING_HANDLE_TYPE \ | LRPC_BINDING_HANDLE_TYPE \ | SVR_BINDING_HANDLE_TYPE ) #define CCALL_TYPE (DG_CCALL_TYPE \ | OSF_CCALL_TYPE \ | LRPC_CCALL_TYPE) #define SCALL_TYPE (DG_SCALL_TYPE \ | DG_CALLBACK_TYPE \ | OSF_SCALL_TYPE \ | LRPC_SCALL_TYPE ) typedef struct { RPC_BINDING_HANDLE hCall; PRPC_ASYNC_STATE pAsync; void *Context; RPC_ASYNC_EVENT Event; } RPC_APC_INFO; RPC_HTTP_TRANSPORT_CREDENTIALS_W *ConvertToUnicodeHttpTransportCredentials ( const IN RPC_HTTP_TRANSPORT_CREDENTIALS_A *SourceCredentials ); void WipeOutAuthIdentity ( IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity ); void FreeHttpTransportCredentials ( IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *Credentials ); RPC_HTTP_TRANSPORT_CREDENTIALS_W *DuplicateHttpTransportCredentials ( const IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *SourceCredentials ); RPC_STATUS DecryptAuthIdentity ( IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity ); /* -------------------------------------------------------------------- GENERIC_OBJECT : The GENERIC_OBJECT class serves as the base for all handles used by the RPC runtime. It provides type checking of handles. The type checking is provided in two different ways: (1) At the front of every object is an unsigned long. This is set to a specific (magic) value which is checked whenever the handle is validated. NOTE: Every handle which the user gives us is validated. (2) We also can dynamically determine the type of the object. -------------------------------------------------------------------- */ // This is the magic value we stick in the front of every valid // GENERIC_OBJECT. #define MAGICLONG 0x89ABCDEF #define MAGICLONGDEAD 0x99DEAD99 extern RPC_STATUS CaptureLogonid( LUID * LogonId ); extern RPC_STATUS CaptureModifiedId(LUID *ModifiedId); class THREAD; class NO_VTABLE GENERIC_OBJECT { // This instance variable contains a magic value which is used to // validate handles. unsigned long MagicLong; protected: HANDLE_TYPE ObjectType; GENERIC_OBJECT () { MagicLong = MAGICLONG; #ifdef DEBUGRPC ObjectType = 0; #endif } ~GENERIC_OBJECT () { MagicLong = MAGICLONGDEAD; #ifdef DEBUGRPC ASSERT( ObjectType ); #endif } public: // Predicate to test for a valid handle. Note that HandleType may // specify more than one type of handle. This works because the handle // types are specified as bits in an unsigned number. unsigned int // Return zero (0) if the handle is valid and its type // is one of the types specified by the HandleType argument; // otherwise, the handle is invalid, and one (1) is returned. InvalidHandle ( // Check for an invalid handle. IN HANDLE_TYPE HandleType // Bitmap of one or more handle types to // be used in validating the handle. ); HANDLE_TYPE Type (HANDLE_TYPE BaseType) { #ifdef DEBUGRPC ASSERT( ObjectType ); #endif return (ObjectType & BaseType); } virtual void DoNothing(void) { } }; class NO_VTABLE REFERENCED_OBJECT : public GENERIC_OBJECT { public: inline REFERENCED_OBJECT ( ) : RefCount(1) {} virtual ~REFERENCED_OBJECT ( ) {} virtual void ProcessSendComplete ( IN RPC_STATUS EventStatus, IN BUFFER Buffer ) {ASSERT(0);} virtual void FreeObject ( ); int AddReference ( ); inline void SingleThreadedAddReference(void) { RefCount.SingleThreadedIncrement(); } inline void SingleThreadedAddMultipleReferences(long nReferences) { RefCount.SingleThreadedIncrement(nReferences); } virtual void RemoveReference ( ); void Delete ( ); void Destroy ( ); BOOL IsDeleted ( ); void SetNotDeleted(void) { ObjectType &= ~OBJECT_DELETED; } void SetReferenceCount ( IN int Count ) {RefCount.SetInteger(Count);} protected: BOOL SetDeletedFlag(void) { int savedObjectType = ObjectType; if (((savedObjectType & OBJECT_DELETED) == 0) && InterlockedCompareExchange((long *)&ObjectType, savedObjectType | OBJECT_DELETED, savedObjectType) == savedObjectType) { LogEvent(SU_REFOBJ, EV_DELETE, this, IntToPtr(savedObjectType), RefCount.GetInteger(), 1, 1); return TRUE; } return FALSE; } INTERLOCKED_INTEGER RefCount; }; inline void REFERENCED_OBJECT::FreeObject ( ) { delete this; } inline int REFERENCED_OBJECT::AddReference ( ) { int MyCount; MyCount = RefCount.Increment(); LogEvent(SU_REFOBJ, EV_INC, this, IntToPtr(ObjectType), MyCount, 1, 1); return MyCount; } inline void REFERENCED_OBJECT::RemoveReference ( ) { int MyCount; LogEvent(SU_REFOBJ, EV_DEC, this, IntToPtr(ObjectType), RefCount.GetInteger(), 1, 1); MyCount = RefCount.Decrement(); ASSERT(MyCount >= 0); if (0 == MyCount) { FreeObject(); } } inline void REFERENCED_OBJECT::Delete ( ) { int MyCount; if (SetDeletedFlag()) { MyCount = RefCount.Decrement(); ASSERT(MyCount); } } inline void REFERENCED_OBJECT::Destroy ( ) { int MyCount; if (SetDeletedFlag()) { RemoveReference(); } } inline BOOL REFERENCED_OBJECT::IsDeleted ( ) { return (ObjectType & OBJECT_DELETED); } class BINDING_HANDLE; // forward /* -------------------------------------------------------------------- MESSAGE_OBJECT : The MESSAGE_OBJECT class provides the common protocol for all handle types which can be used to send messages. The common protocol defined includes message routines, buffer management routines, and routines for querying calls and bindings. -------------------------------------------------------------------- */ class NO_VTABLE MESSAGE_OBJECT : public REFERENCED_OBJECT { public: virtual RPC_STATUS // Value to be returned by SendReceive API. SendReceive ( // Perform a send-receive operation in a handle specific // way. IN OUT PRPC_MESSAGE Message ) = 0; // Perform a send operationin a handle specific way // this API is used in conjunction with pipes virtual RPC_STATUS Send ( IN OUT PRPC_MESSAGE Message ) = 0; // Perform a receive in a handle specific way // this API is used in conjunction with pipes virtual RPC_STATUS Receive ( IN OUT PRPC_MESSAGE Message, IN unsigned int Size ) = 0; // Perform a send operationin a handle specific way // this API is used in conjunction with pipes virtual RPC_STATUS AsyncSend ( IN OUT PRPC_MESSAGE Message ) ; // Perform a receive in a handle specific way // this API is used in conjunction with pipes virtual RPC_STATUS AsyncReceive ( IN OUT PRPC_MESSAGE Message, IN unsigned int Size ) ; virtual RPC_STATUS SetAsyncHandle ( IN PRPC_ASYNC_STATE pAsync ) ; virtual RPC_STATUS AbortAsyncCall ( IN PRPC_ASYNC_STATE pAsync, IN unsigned long ExceptionCode ) ; virtual RPC_STATUS GetCallStatus ( ) ; // on the client side, Message->RpcInterfaceInformation // points to an RPC_CLIENT_INTERFACE structure. The // TransferSyntax member on in points to the transfer syntax preferred // by the stub, and on output is filled by the best estimate of the // runtime what transfer syntax will be optimal for the call. The // memory pointed by TransferSyntax on in is owned by the stub and // is guaranteed to be valid for the duration of the call. On out // this memory is owned by the runtime and should not be freed by the // stub. The runtime guarantees it is valid for the lifetime of the // call (i.e. until calling I_RpcFreeBuffer, or one of the I_Rpc // functions returns failure. // On the server side, Message->RpcInterfaceInformation points to // an RPC_SERVER_INTERFACE structure virtual RPC_STATUS NegotiateTransferSyntax ( IN OUT PRPC_MESSAGE Message ) = 0; virtual RPC_STATUS // Value to be returned by RpcGetBuffer API. GetBuffer ( // Perform a buffer allocation operation in a handle specific // way. IN OUT PRPC_MESSAGE Message, IN UUID *ObjectUuid ) = 0; virtual void FreeBuffer ( // Perform a buffer deallocation operation in a handle // specific way. IN PRPC_MESSAGE Message ) = 0; // deallocate a buffer associated with pipes, in a handle specific way virtual void FreePipeBuffer ( IN PRPC_MESSAGE Messsage ) ; // reallocate a buffer associated with pipes, in a handle specific way virtual RPC_STATUS ReallocPipeBuffer ( IN PRPC_MESSAGE Message, IN unsigned int NewSize ) ; virtual RPC_STATUS BindingCopy ( OUT BINDING_HANDLE * PAPI * DestinationBinding, IN unsigned int MaintainContext ); virtual BOOL IsSyncCall ( ) ; }; inline void MESSAGE_OBJECT::FreePipeBuffer ( IN PRPC_MESSAGE Messsage ) { ASSERT(0) ; return ; } inline BOOL MESSAGE_OBJECT::IsSyncCall ( ) { return 1; } inline RPC_STATUS MESSAGE_OBJECT::GetCallStatus ( ) { ASSERT(0 && "improper MESSAGE_OBJECT member called\n"); return (RPC_S_CANNOT_SUPPORT) ; } inline RPC_STATUS MESSAGE_OBJECT::AsyncSend ( IN OUT PRPC_MESSAGE Message ) { ASSERT(0 && "improper MESSAGE_OBJECT member called\n"); return (RPC_S_CANNOT_SUPPORT) ; } inline RPC_STATUS MESSAGE_OBJECT::SetAsyncHandle ( IN PRPC_ASYNC_STATE pAsync ) { ASSERT(0 && "improper MESSAGE_OBJECT member called\n"); return (RPC_S_CANNOT_SUPPORT) ; } inline RPC_STATUS MESSAGE_OBJECT::AbortAsyncCall ( IN PRPC_ASYNC_STATE pAsync, IN unsigned long ExceptionCode ) { ASSERT(0 && "improper MESSAGE_OBJECT member called\n"); return (RPC_S_CANNOT_SUPPORT) ; } // Perform a receive in a handle specific way // this API is used in conjunction with pipes inline RPC_STATUS MESSAGE_OBJECT::AsyncReceive ( IN OUT PRPC_MESSAGE Message, IN unsigned int Size ) { ASSERT(0 && "improper MESSAGE_OBJECT member called\n"); return (RPC_S_CANNOT_SUPPORT) ; } inline RPC_STATUS MESSAGE_OBJECT::ReallocPipeBuffer ( IN PRPC_MESSAGE Messsage, IN unsigned int NewSize ) { ASSERT(0 && "improper MESSAGE_OBJECT member called\n"); return (RPC_S_CANNOT_SUPPORT) ; } class SECURITY_CREDENTIALS; struct CLIENT_AUTH_INFO { unsigned long AuthenticationLevel; unsigned long AuthenticationService; RPC_CHAR * ServerPrincipalName; union { RPC_AUTH_IDENTITY_HANDLE AuthIdentity; // Client-side only RPC_AUTHZ_HANDLE PacHandle; // Server-side only }; unsigned long AuthorizationService; unsigned long IdentityTracking; unsigned long ImpersonationType; unsigned long Capabilities; unsigned long AdditionalTransportCredentialsType; void *AdditionalCredentials; LUID ModifiedId; BOOL DefaultLogonId; SECURITY_CREDENTIALS * Credentials; CLIENT_AUTH_INFO(); CLIENT_AUTH_INFO::CLIENT_AUTH_INFO( const CLIENT_AUTH_INFO * myAuthInfo, RPC_STATUS PAPI * pStatus ); ~CLIENT_AUTH_INFO(); BOOL IsSupportedAuthInfo( const CLIENT_AUTH_INFO * AuthInfo, BOOL fNamedPipe = 0 ) const; int CredentialsMatch( SECURITY_CREDENTIALS PAPI * Creds ) const; void ReferenceCredentials() const; // note that after this method is called, but before destruction of pTarget occurs, // PrepareForDestructionAfterShallowCopy must be called on target inline CLIENT_AUTH_INFO *ShallowCopyTo(CLIENT_AUTH_INFO *pTarget) { memcpy(pTarget, this, sizeof(CLIENT_AUTH_INFO)); return pTarget; } inline void PrepareForDestructionAfterShallowCopy(void) { ServerPrincipalName = NULL; AdditionalCredentials = NULL; AdditionalTransportCredentialsType = 0; } }; inline CLIENT_AUTH_INFO::CLIENT_AUTH_INFO( ) { AuthenticationLevel = RPC_C_AUTHN_LEVEL_NONE; AuthenticationService = RPC_C_AUTHN_NONE; AuthorizationService = RPC_C_AUTHZ_NONE; ServerPrincipalName = 0; AuthIdentity = 0; Credentials = 0; ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE; IdentityTracking = RPC_C_QOS_IDENTITY_STATIC; Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT; DefaultLogonId = 1; AdditionalTransportCredentialsType = 0; AdditionalCredentials = NULL; } #define LOW_BITS 0x0000007L #define NOT_MULTIPLE_OF_EIGHT(_x_) (_x_ & 0x00000007L) class NO_VTABLE CALL : public MESSAGE_OBJECT { public: CALL * NestingCall; PRPC_ASYNC_STATE pAsync ; long NotificationIssued; inline CALL( ) { } // Perform a send operationin a handle specific way // this API is used in conjunction with pipes virtual RPC_STATUS Send ( IN OUT PRPC_MESSAGE Message ) ; // Perform a receive in a handle specific way // this API is used in conjunction with pipes virtual RPC_STATUS Receive ( IN OUT PRPC_MESSAGE Message, IN unsigned int Size ) ; virtual RPC_STATUS AsyncSend ( IN OUT PRPC_MESSAGE Message ) ; virtual RPC_STATUS AsyncReceive ( IN OUT PRPC_MESSAGE Message, IN unsigned int Size ) ; virtual RPC_STATUS SetAsyncHandle ( IN PRPC_ASYNC_STATE pAsync ) ; virtual RPC_STATUS AbortAsyncCall ( IN PRPC_ASYNC_STATE pAsync, IN unsigned long ExceptionCode ) ; virtual RPC_STATUS GetCallStatus ( ) ; virtual void ProcessEvent ( ) ; virtual RPC_STATUS CancelAsyncCall ( IN BOOL fAbort ); virtual void ProcessResponse ( IN BOOL fDirectCall = 0 ) ; virtual RPC_STATUS Cancel( void * ThreadHandle ); virtual unsigned TestCancel( ); virtual void FreeAPCInfo ( IN RPC_APC_INFO *pAPCInfo ) ; virtual BOOL IssueNotification ( IN RPC_ASYNC_EVENT Event = RpcCallComplete ) ; virtual RPC_STATUS InqSecurityContext ( OUT void **SecurityContextHandle ) { return RPC_S_CANNOT_SUPPORT; } protected: RPC_STATUS AsyncStatus ; RPC_APC_INFO CachedAPCInfo ; BOOL CachedAPCInfoAvailable ; THREAD *CallingThread ; BOOL QueueAPC ( IN RPC_ASYNC_EVENT Event, IN void *Context = 0 ) ; // Validates parameters and check whether actual // notification is necessary. 0 if none is necessary // or non-zero if notification is necessary. The // function is non-idempotent, and if called, and // returns non-zero, the main notification function // MUST be called (state corruption will occur // otherwise) BOOL IssueNotificationEntry ( IN RPC_ASYNC_EVENT Event = RpcCallComplete ); // do the actual notification. Caller MUST have // called IssueNotificationEntry before that, and // call this only IssueNotificationEntry returns // non-zero BOOL IssueNotificationMain ( IN RPC_ASYNC_EVENT Event = RpcCallComplete ); }; inline RPC_STATUS CALL::GetCallStatus ( ) { return AsyncStatus ; } inline RPC_STATUS CALL::CancelAsyncCall ( IN BOOL fAbort ) { return RPC_S_OK; } inline RPC_STATUS CALL::SetAsyncHandle ( IN PRPC_ASYNC_STATE pAsync ) /*++ Routine Description: This method is called by the stubs to associate an async handle with this CCALL. Arguments: pAsync - The async handle to association with this CCALL. Return Value: RPC_S_OK - Function succeeded RPC_S_OUT_OF_MEMORY - we ran out of memory --*/ { if (pAsync->u.APC.hThread == 0) { pAsync->u.APC.hThread = RpcpGetThreadPointer()->ThreadHandle(); } this->pAsync = pAsync ; return RPC_S_OK ; } class NO_VTABLE CCALL : public CALL // // This class represents a call on the client side. It implements // the pure virtual fns from class CALL. // { public: BOOL UuidSpecified; UUID ObjectUuid; inline CCALL( CLIENT_AUTH_INFO * myAuthInfo, RPC_STATUS __RPC_FAR * pStatus ) { UuidSpecified = 0; } inline CCALL( ) { } protected: // utility function which sets the common debug information for a client call RPC_STATUS SetDebugClientCallInformation(OUT DebugClientCallInfo **ppClientCallInfo, OUT CellTag *ClientCallInfoCellTag, OUT DebugCallTargetInfo **ppCallTargetInfo, OUT CellTag *CallTargetInfoCellTag, IN OUT PRPC_MESSAGE Message, IN DebugThreadInfo *ThreadDebugCell, IN CellTag ThreadCellTag); }; RPC_STATUS DispatchCallback( IN PRPC_DISPATCH_TABLE DispatchTableCallback, IN OUT PRPC_MESSAGE Message, OUT RPC_STATUS PAPI * ExceptionCode ); class TRANS_INFO; // forward class DCE_BINDING; /* -------------------------------------------------------------------- BINDING_HANDLE : A BINDING_HANDLE is the binding handle used by clients to make remote procedure calls. We derive the BINDING_HANDLE class from the MESSAGE_OBJECT class because binding handles are used to send remote procedure calls. For some operating environments and transports we need to clean up the transports when the process ends. -------------------------------------------------------------------- */ class NO_VTABLE BINDING_HANDLE : public MESSAGE_OBJECT /*++ Class Description: Fields: Timeout - Contains the communications timeout for this binding handle. ObjectUuid - Contains the object uuid for this binding handle. The constructor will initialize this value to the null uuid. NullObjectUuidFlag - Contains a flag which indicates whether or not the object uuid for this binding handle is the null uuid. If this flag is non-zero, then this binding handle has the null uuid as its object uuid; otherwise, the object uuid is not the null uuid. EpLookupHandle - Contains the endpoint mapper lookup handle for this binding handle. This makes it possible to iterate through all of the endpoints in an endpoint mapper database by trying to make a remote procedure call, and then, when it fails, calling RpcBindingReset. BindingSetKey - Contains the key for this binding handle in the global set of binding handles. EntryNameSyntax - Contains the syntax of the entry name field of this object. This field will be zero if the binding handle was not imported or looked up. EntryName - Contains the entry name in the name service where this binding handle was imported or looked up from. This field will be zero if the binding handle was not imported or looked up. ClientAuthInfo - Contains the authentication and authorization information for this binding handle. --*/ { private: RPC_UUID ObjectUuid; unsigned int Timeout; unsigned int NullObjectUuidFlag; unsigned long EntryNameSyntax; RPC_CHAR * EntryName; void PAPI * EpLookupHandle; ULONG_PTR * OptionsVector; protected: CLIENT_AUTH_INFO ClientAuthInfo; MUTEX BindingMutex; public: // // This is an opaque area of memory set aside for the transport // to manage transport specific options: // void PAPI * pvTransportOptions; BINDING_HANDLE ( IN OUT RPC_STATUS *pStatus ); public: virtual ~BINDING_HANDLE ( ); virtual RPC_STATUS BindingFree ( ) = 0; RPC_STATUS Clone( IN BINDING_HANDLE * OriginalHandle ); void InquireObjectUuid ( OUT RPC_UUID PAPI * ObjectUuid ); void SetObjectUuid ( IN RPC_UUID PAPI * ObjectUuid ); virtual RPC_STATUS PrepareBindingHandle ( IN TRANS_INFO * TransInfo, IN DCE_BINDING * DceBinding ) = 0; virtual RPC_STATUS ToStringBinding ( OUT RPC_CHAR PAPI * PAPI * StringBinding ) = 0; unsigned int InqComTimeout ( ); RPC_STATUS SetComTimeout ( IN unsigned int Timeout ); RPC_UUID * InqPointerAtObjectUuid ( ); unsigned int InqIfNullObjectUuid ( ); virtual RPC_STATUS ResolveBinding ( IN PRPC_CLIENT_INTERFACE RpcClientInterface ) = 0; RPC_STATUS InquireEntryName ( IN unsigned long EntryNameSyntax, OUT RPC_CHAR PAPI * PAPI * EntryName ); RPC_STATUS SetEntryName ( IN unsigned long EntryNameSyntax, IN RPC_CHAR PAPI * EntryName ); virtual RPC_STATUS InquireDynamicEndpoint ( OUT RPC_CHAR PAPI * PAPI * DynamicEndpoint ); virtual RPC_STATUS BindingReset ( ) = 0; void PAPI * PAPI * InquireEpLookupHandle ( ); virtual CLIENT_AUTH_INFO * InquireAuthInformation ( ); virtual RPC_STATUS SetAuthInformation ( IN RPC_CHAR PAPI * ServerPrincipalName, OPTIONAL IN unsigned long AuthenticationLevel, IN unsigned long AuthenticationService, IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL IN unsigned long AuthorizationService, OPTIONAL IN SECURITY_CREDENTIALS PAPI * Credentials = 0, OPTIONAL IN unsigned long ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE,OPTIONAL IN unsigned long IdentityTracking = RPC_C_QOS_IDENTITY_STATIC, OPTIONAL IN unsigned long Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT, OPTIONAL IN BOOL bAcquireNewCredentials = FALSE, OPTIONAL IN ULONG AdditionalTransportCredentialsType = 0, OPTIONAL IN void *AdditionalCredentials = NULL OPTIONAL ); virtual int SetServerPrincipalName ( IN RPC_CHAR PAPI *ServerPrincipalName ); virtual unsigned long MapAuthenticationLevel ( IN unsigned long AuthenticationLevel ); virtual BOOL SetTransportAuthentication( IN unsigned long ulAuthenticationLevel, IN unsigned long ulAuthenticationService, OUT RPC_STATUS *pStatus ); virtual RPC_STATUS // Value to be returned by SendReceive API. SendReceive ( // Perform a send-receive operation in a handle specific // way. IN OUT PRPC_MESSAGE Message ); virtual RPC_STATUS Send ( IN OUT PRPC_MESSAGE Message ) ; virtual RPC_STATUS Receive ( IN OUT PRPC_MESSAGE Message, IN unsigned int Size ) ; virtual RPC_STATUS // Value to be returned by RpcGetBuffer API. GetBuffer ( // Perform a buffer allocation operation in a handle specific // way. IN OUT PRPC_MESSAGE Message, IN UUID *ObjectUuid ) = 0; virtual void FreeBuffer ( // Perform a buffer deallocation operation in a handle // specific way. IN PRPC_MESSAGE Message ); virtual RPC_STATUS InquireTransportType( OUT unsigned int PAPI * Type ) = 0; virtual RPC_STATUS ReAcquireCredentialsIfNecessary( void ); virtual RPC_STATUS SetTransportOption( unsigned long option, ULONG_PTR optionValue ); virtual RPC_STATUS InqTransportOption( unsigned long option, ULONG_PTR * pOptionValue ); }; inline unsigned int BINDING_HANDLE::InqComTimeout ( ) /*++ Routine Description: All we have got to do is to return the communications timeout for this binding handle. Return Value: The communications timeout in this binding handle will be returned. --*/ { return(Timeout); } inline RPC_UUID * BINDING_HANDLE::InqPointerAtObjectUuid ( ) /*++ Routine Description: This reader returns a pointer to the object uuid contained in this binding handle. Return Value: A pointer to the object uuid contained in this binding handle is always returned. --*/ { return(&ObjectUuid); } inline unsigned int BINDING_HANDLE::InqIfNullObjectUuid ( ) /*++ Routine Description: This method is used to inquire if the object uuid in this binding handle is null or not. Return Value: Zero will be returned if object uuid is not null, otherwise (the object uuid is null) zero will be returned. --*/ { return(NullObjectUuidFlag); } inline void PAPI * PAPI * BINDING_HANDLE::InquireEpLookupHandle ( ) /*++ Return Value: A pointer to the endpoint mapper lookup handle for this binding handle will be returned. --*/ { return(&EpLookupHandle); } inline CLIENT_AUTH_INFO * BINDING_HANDLE::InquireAuthInformation ( ) /*++ Return Value: If this binding handle is authenticated, then a pointer to its authentication and authorization information will be returned; otherwise, zero will be returned. --*/ { return(&ClientAuthInfo); } //////////////////////////////////////////////////////////////////// /// Stub interface information //////////////////////////////////////////////////////////////////// const int MaximumNumberOfTransferSyntaxes = 2; const int TransferSyntaxIsServerPreferredFlag = 1; const int TransferSyntaxListStartFlag = 2; class TRANSFER_SYNTAX_STUB_INFO { public: RPC_SYNTAX_IDENTIFIER TransferSyntax; PRPC_DISPATCH_TABLE DispatchTable; }; class TRANSFER_SYNTAX_INFO_ATOM : public TRANSFER_SYNTAX_STUB_INFO { public: void Init (TRANSFER_SYNTAX_STUB_INFO *TransferSyntaxInfo) { Flags = 0; RpcpMemoryCopy(this, TransferSyntaxInfo, sizeof(TRANSFER_SYNTAX_STUB_INFO)); } inline BOOL IsTransferSyntaxServerPreferred(void) { return (Flags & TransferSyntaxIsServerPreferredFlag); } inline void TransferSyntaxIsServerPreferred(void) { Flags |= TransferSyntaxIsServerPreferredFlag; } inline void TransferSyntaxIsNotServerPreferred(void) { Flags &= ~TransferSyntaxIsServerPreferredFlag; } inline BOOL IsTransferSyntaxListStart(void) { return (Flags & TransferSyntaxListStartFlag); } inline void TransferSyntaxIsListStart(void) { Flags |= TransferSyntaxListStartFlag; } private: // can be: // TransferSyntaxIsServerPreferredFlag // TransferSyntaxListStartFlag int Flags; }; // Interface can be both RPC_CLIENT_INTERFACE & RPC_SERVER_INTERFACE inline BOOL DoesInterfaceSupportMultipleTransferSyntaxes(void *Interface) { // the client and server interface have the same layout - we can just // use one of them RPC_CLIENT_INTERFACE *ClientInterface = (RPC_CLIENT_INTERFACE *)Interface; ASSERT ((ClientInterface->Length == sizeof(RPC_CLIENT_INTERFACE)) || (ClientInterface->Length == NT351_INTERFACE_SIZE)); ASSERT(sizeof(RPC_CLIENT_INTERFACE) == sizeof(RPC_SERVER_INTERFACE)); #if !defined(_WIN64) if (ClientInterface->Length == NT351_INTERFACE_SIZE) return FALSE; #else ASSERT(ClientInterface->Length == sizeof(RPC_CLIENT_INTERFACE)); #endif return (ClientInterface->Flags & RPCFLG_HAS_MULTI_SYNTAXES); } // And here we have a couple of inline operators for comparing GUIDs. // There is no particular reason that they should live here. inline int operator == ( IN GUID& guid1, IN GUID& guid2 ) {return(RpcpMemoryCompare(&guid1,&guid2,sizeof(GUID)) == 0);} inline int operator == ( IN GUID PAPI * guid1, IN GUID& guid2 ) {return(RpcpMemoryCompare(guid1,&guid2,sizeof(GUID)) == 0);} extern const RPC_SYNTAX_IDENTIFIER *NDR20TransferSyntax; extern const RPC_SYNTAX_IDENTIFIER *NDR64TransferSyntax; extern const RPC_SYNTAX_IDENTIFIER *NDRTestTransferSyntax; extern int InitializeClientDLL ( // This routine will be called at DLL load time. ); extern int InitializeLoadableTransportClient ( ); extern int InitializeRpcProtocolOfsClient ( ); extern int InitializeRpcProtocolDgClient ( ); START_C_EXTERN extern int InitializeWinExceptions ( ); END_C_EXTERN #define DEFAULT_MAX_DATAGRAM_LENGTH (0) extern unsigned DefaultMaxDatagramLength; #define DEFAULT_CONNECTION_BUFFER_LENGTH (0) extern unsigned DefaultConnectionBufferLength; typedef struct _RPC_RUNTIME_INFO { unsigned int Length ; unsigned long Flags ; void __RPC_FAR *OldBuffer ; } RPC_RUNTIME_INFO, __RPC_FAR *PRPC_RUNTIME_INFO ; void I_RpcAPCRoutine ( IN RPC_APC_INFO *pAPCInfo ); inline BOOL IsPartialMessage (RPC_MESSAGE *Message) { return (Message->RpcFlags & RPC_BUFFER_PARTIAL); } inline BOOL IsExtraMessage (RPC_MESSAGE *Message) { return (Message->RpcFlags & RPC_BUFFER_EXTRA); } inline BOOL IsAsyncMessage (RPC_MESSAGE *Message) { return (Message->RpcFlags & RPC_BUFFER_ASYNC); } inline BOOL IsCompleteMessage (RPC_MESSAGE *Message) { return (Message->RpcFlags & RPC_BUFFER_COMPLETE); } inline BOOL IsNotifyMessage (RPC_MESSAGE *Message) { return (!(Message->RpcFlags & RPC_BUFFER_NONOTIFY)); } inline BOOL IsNonsyncMessage (RPC_MESSAGE *Message) { return (Message->RpcFlags & (RPC_BUFFER_ASYNC | RPC_BUFFER_PARTIAL)); } #define PARTIAL(_Message) ((_Message)->RpcFlags & RPC_BUFFER_PARTIAL) #define EXTRA(_Message) ((_Message)->RpcFlags & RPC_BUFFER_EXTRA) #define ASYNC(_Message) ((_Message)->RpcFlags & RPC_BUFFER_ASYNC) #define COMPLETE(_Message) ((_Message)->RpcFlags & RPC_BUFFER_COMPLETE) #define NOTIFY(_Message) (!((_Message)->RpcFlags & RPC_BUFFER_NONOTIFY)) #define NONSYNC(_Message) ((_Message)->RpcFlags & \ (RPC_BUFFER_ASYNC | RPC_BUFFER_PARTIAL)) class RPC_SERVER; class LRPC_SERVER; extern int RpcHasBeenInitialized; extern RPC_SERVER * GlobalRpcServer; extern BOOL g_fClientSideDebugInfoEnabled; extern BOOL g_fServerSideDebugInfoEnabled; extern LRPC_SERVER *GlobalLrpcServer; extern HINSTANCE hInstanceDLL ; inline BOOL IsClientSideDebugInfoEnabled(void) { return g_fClientSideDebugInfoEnabled; } inline BOOL IsServerSideDebugInfoEnabled(void) { return g_fServerSideDebugInfoEnabled; } #endif // __HANDLE_HXX__