Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

910 lines
20 KiB

/* --------------------------------------------------------------------
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.
-------------------------------------------------------------------- */
#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 SERVER_HANDLE_TYPE 0x0001
#define ADDRESS_HANDLE_TYPE 0x0002
#define INTERFACE_HANDLE_TYPE 0x0004
#define SCONNECTION_TYPE 0x0008
#define CCONNECTION_TYPE 0x0010
#define BINDING_HANDLE_TYPE 0x0040
typedef unsigned short HANDLE_TYPE;
/* --------------------------------------------------------------------
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
#ifdef NTENV
extern RPC_STATUS CaptureLogonid( LUID * LogonId );
#endif
class GENERIC_OBJECT
{
// This instance variable contains a magic value which is used to
// validate handles.
unsigned long MagicLong;
protected:
GENERIC_OBJECT ( // Constructor.
) {MagicLong = MAGICLONG;}
~GENERIC_OBJECT ( // Destructor.
) {MagicLong = MAGICLONGDEAD;}
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.
);
virtual HANDLE_TYPE // Return the type of the handle.
Type ( // This is a virtual method, so each user visible handle type
// will specify a Type method which returns its actual type.
) = 0;
};
/* --------------------------------------------------------------------
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 MESSAGE_OBJECT : public GENERIC_OBJECT
{
public:
virtual HANDLE_TYPE // Return the type of the handle.
Type ( // This is a virtual method, so each user visible handle type
// will specify a Type method which returns its actual type.
) = 0;
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;
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
) = 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
) ;
#if defined(WIN32) && !defined(DOSWIN32RPC)
virtual RPC_STATUS
AsyncSendReceive(
IN OUT PRPC_MESSAGE Message,
IN OPTIONAL void *Context,
IN HWND hWnd
) ;
#endif
virtual RPC_STATUS
BindingCopy (
OUT BINDING_HANDLE * PAPI * DestinationBinding,
IN unsigned int MaintainContext
);
};
inline void
MESSAGE_OBJECT::FreePipeBuffer (
IN PRPC_MESSAGE Messsage
)
{
ASSERT(0) ;
return ;
}
inline RPC_STATUS
MESSAGE_OBJECT::ReallocPipeBuffer (
IN PRPC_MESSAGE Messsage,
IN unsigned int NewSize
)
{
ASSERT(0) ;
return (RPC_S_CANNOT_SUPPORT) ;
}
#if defined(WIN32) && !defined(DOSWIN32RPC)
inline RPC_STATUS
MESSAGE_OBJECT::AsyncSendReceive(
IN OUT PRPC_MESSAGE Message,
IN OPTIONAL void *Context,
IN HWND hWnd
)
{
UNUSED(Message) ;
return (RPC_S_CANNOT_SUPPORT) ;
}
#endif
class SECURITY_CREDENTIALS;
struct CLIENT_AUTH_INFO
{
RPC_CHAR * ServerPrincipalName;
unsigned long AuthenticationLevel;
unsigned long AuthenticationService;
RPC_AUTH_IDENTITY_HANDLE AuthIdentity;
unsigned long AuthorizationService;
#ifdef NTENV
unsigned long IdentityTracking;
unsigned long ImpersonationType;
unsigned long Capabilities;
LUID LogonId;
unsigned long DefaultLogonId;
#endif
SECURITY_CREDENTIALS * Credentials;
CLIENT_AUTH_INFO(
);
CLIENT_AUTH_INFO::CLIENT_AUTH_INFO(
CLIENT_AUTH_INFO * myAuthInfo,
RPC_STATUS PAPI * pStatus
);
~CLIENT_AUTH_INFO(
);
IsSupportedAuthInfo(
CLIENT_AUTH_INFO * AuthInfo
);
int
CredentialsMatch(
SECURITY_CREDENTIALS PAPI * Creds
);
void
ReferenceCredentials(
);
};
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;
#ifdef NTENV
ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
DefaultLogonId = 1;
#endif
}
/* --------------------------------------------------------------------
CCONNECTION :
This class provides one method: Type, used to obtain the type of a
handle.
-------------------------------------------------------------------- */
#define LOW_BITS 0x0000007L
#define NOT_MULTIPLE_OF_EIGHT(_x_) (_x_ & 0x00000007L)
class CONNECTION : public MESSAGE_OBJECT
{
public:
CLIENT_AUTH_INFO AuthInfo;
CONNECTION * NestingCall;
inline
CONNECTION(
CLIENT_AUTH_INFO * myAuthInfo,
RPC_STATUS __RPC_FAR * pStatus
)
: AuthInfo(myAuthInfo, pStatus)
{
RemainingData[0] = 0 ;
}
inline
CONNECTION(
)
{
RemainingData[0] = 0 ;
}
virtual HANDLE_TYPE
Type (
) = 0;
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
) ;
// 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 // Value to be returned by RpcGetBuffer API.
GetBuffer ( // Perform a buffer allocation operation in a handle specific
// way.
IN OUT PRPC_MESSAGE Message
) = 0;
virtual void
FreeBuffer ( // Perform a buffer deallocation operation in a handle
// specific way.
IN PRPC_MESSAGE Message
) = 0;
#if defined(NTENV) || defined(DOSWIN32RPC)
virtual RPC_STATUS
Cancel(
void * ThreadHandle
);
virtual unsigned
TestCancel(
);
#endif
protected:
char RemainingData[8] ;
void
SaveRemainingData (
IN OUT PRPC_MESSAGE Message
) ;
};
inline void
CONNECTION::SaveRemainingData (
IN OUT PRPC_MESSAGE Message
)
{
RemainingData[0] = Message->BufferLength & LOW_BITS ;
Message->BufferLength &= ~LOW_BITS ;
RpcpMemoryCopy(&RemainingData[1],
(char PAPI *) Message->Buffer+Message->BufferLength, RemainingData[0]) ;
}
class CCONNECTION : public CONNECTION
//
// This class represents a call on the client side. It implements
// the pure virtual fns from class CONNECTION.
//
{
public:
inline
CCONNECTION(
CLIENT_AUTH_INFO * myAuthInfo,
RPC_STATUS __RPC_FAR * pStatus
)
: CONNECTION(myAuthInfo, pStatus)
{
}
inline
CCONNECTION(
)
{
}
HANDLE_TYPE
Type (
);
#if defined(WIN32) && !defined(DOSWIN32RPC)
virtual RPC_STATUS
AsyncSendReceive(
IN OUT PRPC_MESSAGE Message,
IN OPTIONAL void *Context,
IN HWND hWnd
) ;
#endif
};
#if defined(WIN32) && !defined(DOSWIN32RPC)
inline RPC_STATUS
CCONNECTION::AsyncSendReceive(
IN OUT PRPC_MESSAGE Message,
IN void *Context,
IN HWND hWnd
)
{
UNUSED(Message) ;
return (RPC_S_CANNOT_SUPPORT) ;
}
#endif
RPC_STATUS
DispatchCallback(
IN PRPC_DISPATCH_TABLE DispatchTableCallback,
IN OUT PRPC_MESSAGE Message,
OUT RPC_STATUS PAPI * ExceptionCode
);
/* --------------------------------------------------------------------
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 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:
unsigned int Timeout;
RPC_UUID ObjectUuid;
unsigned int NullObjectUuidFlag;
unsigned long EntryNameSyntax;
RPC_CHAR * EntryName;
void PAPI * EpLookupHandle;
#if defined(WIN) || defined(MAC)
unsigned int BindingSetKey;
#endif // WIN || MAC
protected:
CLIENT_AUTH_INFO ClientAuthInfo;
BINDING_HANDLE (
);
public:
#ifdef WIN
unsigned int TaskId;
#endif // WIN
virtual
~BINDING_HANDLE (
);
virtual RPC_STATUS
BindingFree (
) = 0;
void
InquireObjectUuid (
OUT RPC_UUID PAPI * ObjectUuid
);
void
SetObjectUuid (
IN RPC_UUID PAPI * ObjectUuid
);
virtual void
PrepareBindingHandle (
IN void * TransportInterface,
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
#ifndef NTENV
IN SECURITY_CREDENTIALS * Credentials
#else
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
#endif
);
virtual int
SetServerPrincipalName (
IN RPC_CHAR PAPI * ServerPrincipalName
);
virtual unsigned long
MapAuthenticationLevel (
IN unsigned long AuthenticationLevel
);
virtual HANDLE_TYPE
Type (
);
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
) = 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
SetConnectionParameter (
IN unsigned Parameter,
IN unsigned long Value
);
virtual RPC_STATUS
InqConnectionParameter (
IN unsigned Parameter,
IN unsigned long __RPC_FAR * pValue
);
#if defined(WIN32) && !defined(DOSWIN32RPC)
virtual
RPC_STATUS
SetAsync(
IN RPC_BLOCKING_FN BlockingFn
) ;
#endif
#ifdef NTENV
virtual RPC_STATUS
ReAcquireCredentialsIfNecessary(
);
#endif
};
#if defined(WIN32) && !defined(DOSWIN32RPC)
inline RPC_STATUS
BINDING_HANDLE::SetAsync(
IN RPC_BLOCKING_FN BlockingFn
)
{
return (RPC_S_CANNOT_SUPPORT) ;
}
#endif
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.AuthenticationLevel == RPC_C_AUTHN_LEVEL_NONE)
? 0 : &ClientAuthInfo));
}
// 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);}
#ifdef WIN
START_C_EXTERN
#endif
extern
#ifdef WIN
int pascal far
#else // WIN
int
#endif // WIN
InitializeClientDLL ( // This routine will be called at DLL load time.
);
#ifdef WIN
END_C_EXTERN
#endif
extern int
InitializeLoadableTransportClient (
);
extern int
InitializeRpcProtocolOfsClient (
);
extern int
InitializeRpcProtocolDgClient (
);
START_C_EXTERN
extern int
InitializeWinExceptions (
);
END_C_EXTERN
extern void
OsfDeleteIdleConnections (
void
);
#ifdef WIN
extern void
CleanupDgTransports(
);
#endif
#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 ;
#endif // __HANDLE_HXX__