Source code of Windows XP (NT5)
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.

332 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. lpcp.h
  5. Abstract:
  6. Private include file for the LPC subcomponent of the NTOS project
  7. Author:
  8. Steve Wood (stevewo) 15-May-1989
  9. Revision History:
  10. --*/
  11. #pragma warning(disable:4214) // bit field types other than int
  12. #pragma warning(disable:4201) // nameless struct/union
  13. #pragma warning(disable:4324) // alignment sensitive to declspec
  14. #pragma warning(disable:4127) // condition expression is constant
  15. #pragma warning(disable:4115) // named type definition in parentheses
  16. #pragma warning(disable:4310) // cast truncates constant value
  17. #include "ntos.h"
  18. #include <zwapi.h>
  19. //
  20. // Global Mutex to guard the following fields:
  21. //
  22. // ETHREAD.LpcReplyMsg
  23. // LPCP_PORT_QUEUE.ReceiveHead
  24. //
  25. // Mutex is never held longer than is necessary to modify or read the field.
  26. // Contains an additional field to track the owner of the mutex.
  27. //
  28. typedef struct _LPC_MUTEX {
  29. FAST_MUTEX Lock;
  30. //
  31. // field that holds the thread that owns the lock
  32. //
  33. PETHREAD Owner;
  34. } LPC_MUTEX, *PLPC_MUTEX;
  35. extern LPC_MUTEX LpcpLock;
  36. extern ULONG LpcpMaxMessageSize;
  37. #define LpcpGetMaxMessageLength() (LpcpMaxMessageSize)
  38. extern ULONG LpcpNextMessageId;
  39. extern ULONG LpcpNextCallbackId;
  40. #define LpcpGenerateMessageId() \
  41. LpcpNextMessageId++; if (LpcpNextMessageId == 0) LpcpNextMessageId = 1;
  42. #define LpcpGenerateCallbackId() \
  43. LpcpNextCallbackId++; if (LpcpNextCallbackId == 0) LpcpNextCallbackId = 1;
  44. extern ULONG LpcpTotalNumberOfMessages;
  45. //
  46. // Global macrodefinitions to acquire and release the LPC_MUTEX
  47. // in order to track the owner and allow recursive calls
  48. //
  49. #define LpcpInitializeLpcpLock() \
  50. { \
  51. ExInitializeFastMutex( &LpcpLock.Lock ); \
  52. LpcpLock.Owner = NULL; \
  53. }
  54. #define LpcpAcquireLpcpLock() \
  55. { \
  56. ASSERT ( LpcpLock.Owner != PsGetCurrentThread() ); \
  57. \
  58. ExAcquireFastMutex( &LpcpLock.Lock ); \
  59. LpcpLock.Owner = PsGetCurrentThread(); \
  60. }
  61. #define LpcpAcquireLpcpLockByThread(Thread) \
  62. { \
  63. ASSERT ( LpcpLock.Owner != PsGetCurrentThread() ); \
  64. \
  65. ExAcquireFastMutex( &LpcpLock.Lock ); \
  66. LpcpLock.Owner = Thread; \
  67. }
  68. #define LpcpReleaseLpcpLock() \
  69. { \
  70. ASSERT( LpcpLock.Owner == PsGetCurrentThread() ); \
  71. \
  72. LpcpLock.Owner = NULL; \
  73. ExReleaseFastMutex( &LpcpLock.Lock ); \
  74. }
  75. //
  76. // Internal Entry Points defined in lpcclose.c
  77. //
  78. VOID
  79. LpcpClosePort (
  80. IN PEPROCESS Process OPTIONAL,
  81. IN PVOID Object,
  82. IN ACCESS_MASK GrantedAccess,
  83. IN ULONG ProcessHandleCount,
  84. IN ULONG SystemHandleCount
  85. );
  86. VOID
  87. LpcpDeletePort (
  88. IN PVOID Object
  89. );
  90. //
  91. // Entry points defined in lpcqueue.c
  92. //
  93. NTSTATUS
  94. LpcpInitializePortQueue (
  95. IN PLPCP_PORT_OBJECT Port
  96. );
  97. VOID
  98. LpcpDestroyPortQueue (
  99. IN PLPCP_PORT_OBJECT Port,
  100. IN BOOLEAN CleanupAndDestroy
  101. );
  102. VOID
  103. LpcpInitializePortZone (
  104. IN ULONG MaxEntrySize
  105. );
  106. NTSTATUS
  107. LpcpExtendPortZone (
  108. VOID
  109. );
  110. VOID
  111. LpcpSaveDataInfoMessage (
  112. IN PLPCP_PORT_OBJECT Port,
  113. IN PLPCP_MESSAGE Msg,
  114. IN ULONG MutexFlags
  115. );
  116. VOID
  117. LpcpFreeDataInfoMessage (
  118. IN PLPCP_PORT_OBJECT Port,
  119. IN ULONG MessageId,
  120. IN ULONG CallbackId
  121. );
  122. PLPCP_MESSAGE
  123. LpcpFindDataInfoMessage (
  124. IN PLPCP_PORT_OBJECT Port,
  125. IN ULONG MessageId,
  126. IN ULONG CallbackId
  127. );
  128. //
  129. // Entry points defined in lpcquery.c
  130. //
  131. //
  132. // Entry points defined in lpcmove.s and lpcmove.asm
  133. //
  134. VOID
  135. LpcpMoveMessage (
  136. OUT PPORT_MESSAGE DstMsg,
  137. IN PPORT_MESSAGE SrcMsg,
  138. IN PVOID SrcMsgData,
  139. IN ULONG MsgType OPTIONAL,
  140. IN PCLIENT_ID ClientId OPTIONAL
  141. );
  142. //
  143. // Internal Entry Points defined in lpcpriv.c
  144. //
  145. VOID
  146. LpcpFreePortClientSecurity (
  147. IN PLPCP_PORT_OBJECT Port
  148. );
  149. //
  150. // Macro Procedures used by RequestWaitReply, Reply, ReplyWaitReceive,
  151. // and ReplyWaitReply services
  152. //
  153. #define LpcpGetDynamicClientSecurity(Thread,Port,DynamicSecurity) \
  154. SeCreateClientSecurity((Thread),&(Port)->SecurityQos,FALSE,(DynamicSecurity))
  155. #define LpcpFreeDynamicClientSecurity(DynamicSecurity) \
  156. SeDeleteClientSecurity( DynamicSecurity )
  157. #define LpcpReferencePortObject(PortHandle,PortAccess,PreviousMode,PortObject) \
  158. ObReferenceObjectByHandle((PortHandle),(PortAccess),LpcPortObjectType,(PreviousMode),(PVOID *)(PortObject),NULL)
  159. #define LPC_PORT_MASK_BIT 1
  160. #define LpcpGetThreadMessage(T) \
  161. ( \
  162. (((ULONG_PTR)(T)->LpcReplyMessage) & LPC_PORT_MASK_BIT) ? NULL : (PLPCP_MESSAGE)(T)->LpcReplyMessage \
  163. )
  164. #define LpcpGetThreadPort(T) \
  165. ( \
  166. (((ULONG_PTR)(T)->LpcReplyMessage) & LPC_PORT_MASK_BIT) ? \
  167. (PLPCP_PORT_OBJECT)(((ULONG_PTR)(T)->LpcWaitingOnPort) & ~LPC_PORT_MASK_BIT): \
  168. NULL \
  169. )
  170. #define LpcpSetPortToThread(T,P) \
  171. (T)->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)P) | LPC_PORT_MASK_BIT);
  172. #define LPCP_VALIDATE_REASON_IMPERSONATION 1
  173. #define LPCP_VALIDATE_REASON_REPLY 2
  174. #define LPCP_VALIDATE_REASON_WRONG_DATA 3
  175. BOOLEAN
  176. FASTCALL
  177. LpcpValidateClientPort(
  178. IN PETHREAD Thread,
  179. IN PLPCP_PORT_OBJECT ReplyPort,
  180. IN ULONG Reason
  181. );
  182. //
  183. // Entry Points defined in lpcinit.c
  184. //
  185. #if DBG
  186. #define ENABLE_LPC_TRACING 1
  187. #else
  188. #define ENABLE_LPC_TRACING 0
  189. #endif
  190. #if ENABLE_LPC_TRACING
  191. BOOLEAN LpcpStopOnReplyMismatch;
  192. BOOLEAN LpcpTraceMessages;
  193. char *LpcpMessageTypeName[];
  194. char *
  195. LpcpGetCreatorName (
  196. PLPCP_PORT_OBJECT PortObject
  197. );
  198. #define LpcpPrint( _x_ ) { \
  199. DbgPrint( "LPC[ %02x.%02x ]: ", \
  200. PsGetCurrentThread()->Cid.UniqueProcess, \
  201. PsGetCurrentThread()->Cid.UniqueThread ); \
  202. DbgPrint _x_ ; \
  203. }
  204. #define LpcpTrace( _x_ ) if (LpcpTraceMessages) { LpcpPrint( _x_ ); }
  205. #else
  206. #define LpcpPrint( _x_ )
  207. #define LpcpTrace( _x_ )
  208. #endif // ENABLE_LPC_TRACING
  209. extern PAGED_LOOKASIDE_LIST LpcpMessagesLookaside;
  210. __forceinline
  211. PLPCP_MESSAGE
  212. LpcpAllocateFromPortZone (
  213. ULONG Size
  214. )
  215. {
  216. PLPCP_MESSAGE Msg;
  217. PAGED_CODE();
  218. UNREFERENCED_PARAMETER (Size);
  219. Msg = ExAllocateFromPagedLookasideList( &LpcpMessagesLookaside );
  220. if (Msg != NULL) {
  221. LpcpTrace(( "Allocate Msg %lx\n", Msg ));
  222. InitializeListHead( &Msg->Entry );
  223. Msg->RepliedToThread = NULL;
  224. //
  225. // Clear the message type field. In some failure paths this message get freed
  226. // w/o having it initialized.
  227. //
  228. Msg->Request.u2.s2.Type = 0;
  229. return Msg;
  230. }
  231. return NULL;
  232. }
  233. #define LPCP_MUTEX_OWNED 0x1
  234. #define LPCP_MUTEX_RELEASE_ON_RETURN 0x2
  235. VOID
  236. FASTCALL
  237. LpcpFreeToPortZone (
  238. IN PLPCP_MESSAGE Msg,
  239. IN ULONG MutexFlags
  240. );