windows-nt/Source/XPSP1/NT/base/ntos/lpc/lpcp.h
2020-09-26 16:20:57 +08:00

333 lines
7.8 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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
);