333 lines
7.8 KiB
C
333 lines
7.8 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
lpcp.h
|
||
|
||
Abstract:
|
||
|
||
Private include file for the LPC subcomponent of the NTOS project
|
||
|
||
Author:
|
||
|
||
Steve Wood (stevewo) 15-May-1989
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#pragma warning(disable:4214) // bit field types other than int
|
||
#pragma warning(disable:4201) // nameless struct/union
|
||
#pragma warning(disable:4324) // alignment sensitive to declspec
|
||
#pragma warning(disable:4127) // condition expression is constant
|
||
#pragma warning(disable:4115) // named type definition in parentheses
|
||
#pragma warning(disable:4310) // cast truncates constant value
|
||
|
||
#include "ntos.h"
|
||
#include <zwapi.h>
|
||
|
||
|
||
//
|
||
// Global Mutex to guard the following fields:
|
||
//
|
||
// ETHREAD.LpcReplyMsg
|
||
// LPCP_PORT_QUEUE.ReceiveHead
|
||
//
|
||
// Mutex is never held longer than is necessary to modify or read the field.
|
||
// Contains an additional field to track the owner of the mutex.
|
||
//
|
||
|
||
typedef struct _LPC_MUTEX {
|
||
|
||
FAST_MUTEX Lock;
|
||
|
||
//
|
||
// field that holds the thread that owns the lock
|
||
//
|
||
|
||
PETHREAD Owner;
|
||
|
||
} LPC_MUTEX, *PLPC_MUTEX;
|
||
|
||
|
||
extern LPC_MUTEX LpcpLock;
|
||
|
||
extern ULONG LpcpMaxMessageSize;
|
||
|
||
#define LpcpGetMaxMessageLength() (LpcpMaxMessageSize)
|
||
|
||
extern ULONG LpcpNextMessageId;
|
||
|
||
extern ULONG LpcpNextCallbackId;
|
||
|
||
#define LpcpGenerateMessageId() \
|
||
LpcpNextMessageId++; if (LpcpNextMessageId == 0) LpcpNextMessageId = 1;
|
||
|
||
#define LpcpGenerateCallbackId() \
|
||
LpcpNextCallbackId++; if (LpcpNextCallbackId == 0) LpcpNextCallbackId = 1;
|
||
|
||
extern ULONG LpcpTotalNumberOfMessages;
|
||
|
||
//
|
||
// Global macrodefinitions to acquire and release the LPC_MUTEX
|
||
// in order to track the owner and allow recursive calls
|
||
//
|
||
|
||
#define LpcpInitializeLpcpLock() \
|
||
{ \
|
||
ExInitializeFastMutex( &LpcpLock.Lock ); \
|
||
LpcpLock.Owner = NULL; \
|
||
}
|
||
|
||
#define LpcpAcquireLpcpLock() \
|
||
{ \
|
||
ASSERT ( LpcpLock.Owner != PsGetCurrentThread() ); \
|
||
\
|
||
ExAcquireFastMutex( &LpcpLock.Lock ); \
|
||
LpcpLock.Owner = PsGetCurrentThread(); \
|
||
}
|
||
|
||
#define LpcpAcquireLpcpLockByThread(Thread) \
|
||
{ \
|
||
ASSERT ( LpcpLock.Owner != PsGetCurrentThread() ); \
|
||
\
|
||
ExAcquireFastMutex( &LpcpLock.Lock ); \
|
||
LpcpLock.Owner = Thread; \
|
||
}
|
||
|
||
#define LpcpReleaseLpcpLock() \
|
||
{ \
|
||
ASSERT( LpcpLock.Owner == PsGetCurrentThread() ); \
|
||
\
|
||
LpcpLock.Owner = NULL; \
|
||
ExReleaseFastMutex( &LpcpLock.Lock ); \
|
||
}
|
||
|
||
|
||
//
|
||
// Internal Entry Points defined in lpcclose.c
|
||
//
|
||
|
||
VOID
|
||
LpcpClosePort (
|
||
IN PEPROCESS Process OPTIONAL,
|
||
IN PVOID Object,
|
||
IN ACCESS_MASK GrantedAccess,
|
||
IN ULONG ProcessHandleCount,
|
||
IN ULONG SystemHandleCount
|
||
);
|
||
|
||
VOID
|
||
LpcpDeletePort (
|
||
IN PVOID Object
|
||
);
|
||
|
||
|
||
//
|
||
// Entry points defined in lpcqueue.c
|
||
//
|
||
|
||
NTSTATUS
|
||
LpcpInitializePortQueue (
|
||
IN PLPCP_PORT_OBJECT Port
|
||
);
|
||
|
||
VOID
|
||
LpcpDestroyPortQueue (
|
||
IN PLPCP_PORT_OBJECT Port,
|
||
IN BOOLEAN CleanupAndDestroy
|
||
);
|
||
|
||
VOID
|
||
LpcpInitializePortZone (
|
||
IN ULONG MaxEntrySize
|
||
);
|
||
|
||
NTSTATUS
|
||
LpcpExtendPortZone (
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
LpcpSaveDataInfoMessage (
|
||
IN PLPCP_PORT_OBJECT Port,
|
||
IN PLPCP_MESSAGE Msg,
|
||
IN ULONG MutexFlags
|
||
);
|
||
|
||
VOID
|
||
LpcpFreeDataInfoMessage (
|
||
IN PLPCP_PORT_OBJECT Port,
|
||
IN ULONG MessageId,
|
||
IN ULONG CallbackId
|
||
);
|
||
|
||
PLPCP_MESSAGE
|
||
LpcpFindDataInfoMessage (
|
||
IN PLPCP_PORT_OBJECT Port,
|
||
IN ULONG MessageId,
|
||
IN ULONG CallbackId
|
||
);
|
||
|
||
|
||
//
|
||
// Entry points defined in lpcquery.c
|
||
//
|
||
|
||
|
||
//
|
||
// Entry points defined in lpcmove.s and lpcmove.asm
|
||
//
|
||
|
||
VOID
|
||
LpcpMoveMessage (
|
||
OUT PPORT_MESSAGE DstMsg,
|
||
IN PPORT_MESSAGE SrcMsg,
|
||
IN PVOID SrcMsgData,
|
||
IN ULONG MsgType OPTIONAL,
|
||
IN PCLIENT_ID ClientId OPTIONAL
|
||
);
|
||
|
||
|
||
//
|
||
// Internal Entry Points defined in lpcpriv.c
|
||
//
|
||
|
||
VOID
|
||
LpcpFreePortClientSecurity (
|
||
IN PLPCP_PORT_OBJECT Port
|
||
);
|
||
|
||
|
||
//
|
||
// Macro Procedures used by RequestWaitReply, Reply, ReplyWaitReceive,
|
||
// and ReplyWaitReply services
|
||
//
|
||
|
||
#define LpcpGetDynamicClientSecurity(Thread,Port,DynamicSecurity) \
|
||
SeCreateClientSecurity((Thread),&(Port)->SecurityQos,FALSE,(DynamicSecurity))
|
||
|
||
#define LpcpFreeDynamicClientSecurity(DynamicSecurity) \
|
||
SeDeleteClientSecurity( DynamicSecurity )
|
||
|
||
#define LpcpReferencePortObject(PortHandle,PortAccess,PreviousMode,PortObject) \
|
||
ObReferenceObjectByHandle((PortHandle),(PortAccess),LpcPortObjectType,(PreviousMode),(PVOID *)(PortObject),NULL)
|
||
|
||
#define LPC_PORT_MASK_BIT 1
|
||
|
||
#define LpcpGetThreadMessage(T) \
|
||
( \
|
||
(((ULONG_PTR)(T)->LpcReplyMessage) & LPC_PORT_MASK_BIT) ? NULL : (PLPCP_MESSAGE)(T)->LpcReplyMessage \
|
||
)
|
||
|
||
#define LpcpGetThreadPort(T) \
|
||
( \
|
||
(((ULONG_PTR)(T)->LpcReplyMessage) & LPC_PORT_MASK_BIT) ? \
|
||
(PLPCP_PORT_OBJECT)(((ULONG_PTR)(T)->LpcWaitingOnPort) & ~LPC_PORT_MASK_BIT): \
|
||
NULL \
|
||
)
|
||
|
||
#define LpcpSetPortToThread(T,P) \
|
||
(T)->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)P) | LPC_PORT_MASK_BIT);
|
||
|
||
#define LPCP_VALIDATE_REASON_IMPERSONATION 1
|
||
#define LPCP_VALIDATE_REASON_REPLY 2
|
||
#define LPCP_VALIDATE_REASON_WRONG_DATA 3
|
||
|
||
BOOLEAN
|
||
FASTCALL
|
||
LpcpValidateClientPort(
|
||
IN PETHREAD Thread,
|
||
IN PLPCP_PORT_OBJECT ReplyPort,
|
||
IN ULONG Reason
|
||
);
|
||
|
||
|
||
//
|
||
// Entry Points defined in lpcinit.c
|
||
//
|
||
|
||
#if DBG
|
||
#define ENABLE_LPC_TRACING 1
|
||
#else
|
||
#define ENABLE_LPC_TRACING 0
|
||
#endif
|
||
|
||
#if ENABLE_LPC_TRACING
|
||
BOOLEAN LpcpStopOnReplyMismatch;
|
||
BOOLEAN LpcpTraceMessages;
|
||
|
||
char *LpcpMessageTypeName[];
|
||
|
||
char *
|
||
LpcpGetCreatorName (
|
||
PLPCP_PORT_OBJECT PortObject
|
||
);
|
||
|
||
#define LpcpPrint( _x_ ) { \
|
||
DbgPrint( "LPC[ %02x.%02x ]: ", \
|
||
PsGetCurrentThread()->Cid.UniqueProcess, \
|
||
PsGetCurrentThread()->Cid.UniqueThread ); \
|
||
DbgPrint _x_ ; \
|
||
}
|
||
|
||
#define LpcpTrace( _x_ ) if (LpcpTraceMessages) { LpcpPrint( _x_ ); }
|
||
|
||
#else
|
||
|
||
#define LpcpPrint( _x_ )
|
||
#define LpcpTrace( _x_ )
|
||
|
||
#endif // ENABLE_LPC_TRACING
|
||
|
||
extern PAGED_LOOKASIDE_LIST LpcpMessagesLookaside;
|
||
|
||
__forceinline
|
||
PLPCP_MESSAGE
|
||
LpcpAllocateFromPortZone (
|
||
ULONG Size
|
||
)
|
||
{
|
||
PLPCP_MESSAGE Msg;
|
||
|
||
PAGED_CODE();
|
||
|
||
UNREFERENCED_PARAMETER (Size);
|
||
|
||
Msg = ExAllocateFromPagedLookasideList( &LpcpMessagesLookaside );
|
||
|
||
if (Msg != NULL) {
|
||
|
||
LpcpTrace(( "Allocate Msg %lx\n", Msg ));
|
||
|
||
InitializeListHead( &Msg->Entry );
|
||
|
||
Msg->RepliedToThread = NULL;
|
||
|
||
//
|
||
// Clear the message type field. In some failure paths this message get freed
|
||
// w/o having it initialized.
|
||
//
|
||
|
||
Msg->Request.u2.s2.Type = 0;
|
||
|
||
return Msg;
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
|
||
#define LPCP_MUTEX_OWNED 0x1
|
||
#define LPCP_MUTEX_RELEASE_ON_RETURN 0x2
|
||
|
||
VOID
|
||
FASTCALL
|
||
LpcpFreeToPortZone (
|
||
IN PLPCP_MESSAGE Msg,
|
||
IN ULONG MutexFlags
|
||
);
|
||
|