Leaked source code of windows server 2003
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.

384 lines
9.3 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. //#define _LPC_LOG_ERRORS
  20. //
  21. // Global Mutex to guard the following fields:
  22. //
  23. // ETHREAD.LpcReplyMsg
  24. // LPCP_PORT_QUEUE.ReceiveHead
  25. //
  26. // Mutex is never held longer than is necessary to modify or read the field.
  27. // Contains an additional field to track the owner of the mutex.
  28. //
  29. typedef struct _LPC_MUTEX {
  30. KGUARDED_MUTEX Lock;
  31. //
  32. // field that holds the thread that owns the lock
  33. //
  34. PETHREAD Owner;
  35. } LPC_MUTEX, *PLPC_MUTEX;
  36. extern LPC_MUTEX LpcpLock;
  37. extern ULONG LpcpMaxMessageSize;
  38. #define LpcpGetMaxMessageLength() (LpcpMaxMessageSize)
  39. extern ULONG LpcpNextMessageId;
  40. extern ULONG LpcpNextCallbackId;
  41. #define LpcpGenerateMessageId() \
  42. LpcpNextMessageId++; if (LpcpNextMessageId == 0) LpcpNextMessageId = 1;
  43. #define LpcpGenerateCallbackId() \
  44. LpcpNextCallbackId++; if (LpcpNextCallbackId == 0) LpcpNextCallbackId = 1;
  45. extern ULONG LpcpTotalNumberOfMessages;
  46. //
  47. // Global macrodefinitions to acquire and release the LPC_MUTEX
  48. // in order to track the owner and allow recursive calls
  49. //
  50. #define LpcpInitializeLpcpLock() \
  51. { \
  52. KeInitializeGuardedMutex( &LpcpLock.Lock ); \
  53. LpcpLock.Owner = NULL; \
  54. }
  55. #define LpcpAcquireLpcpLock() \
  56. { \
  57. ASSERT ( LpcpLock.Owner != PsGetCurrentThread() ); \
  58. \
  59. KeAcquireGuardedMutex( &LpcpLock.Lock ); \
  60. LpcpLock.Owner = PsGetCurrentThread(); \
  61. }
  62. #define LpcpAcquireLpcpLockByThread(Thread) \
  63. { \
  64. ASSERT ( LpcpLock.Owner != PsGetCurrentThread() ); \
  65. \
  66. KeAcquireGuardedMutex( &LpcpLock.Lock ); \
  67. LpcpLock.Owner = Thread; \
  68. }
  69. #define LpcpReleaseLpcpLock() \
  70. { \
  71. ASSERT( LpcpLock.Owner == PsGetCurrentThread() ); \
  72. \
  73. LpcpLock.Owner = NULL; \
  74. KeReleaseGuardedMutex( &LpcpLock.Lock ); \
  75. }
  76. //
  77. // Internal Entry Points defined in lpcclose.c
  78. //
  79. VOID
  80. LpcpClosePort (
  81. IN PEPROCESS Process OPTIONAL,
  82. IN PVOID Object,
  83. IN ACCESS_MASK GrantedAccess,
  84. IN ULONG_PTR ProcessHandleCount,
  85. IN ULONG_PTR SystemHandleCount
  86. );
  87. VOID
  88. LpcpDeletePort (
  89. IN PVOID Object
  90. );
  91. //
  92. // Entry points defined in lpcqueue.c
  93. //
  94. NTSTATUS
  95. LpcpInitializePortQueue (
  96. IN PLPCP_PORT_OBJECT Port
  97. );
  98. VOID
  99. LpcpDestroyPortQueue (
  100. IN PLPCP_PORT_OBJECT Port,
  101. IN BOOLEAN CleanupAndDestroy
  102. );
  103. VOID
  104. LpcpInitializePortZone (
  105. IN ULONG MaxEntrySize
  106. );
  107. NTSTATUS
  108. LpcpExtendPortZone (
  109. VOID
  110. );
  111. VOID
  112. LpcpSaveDataInfoMessage (
  113. IN PLPCP_PORT_OBJECT Port,
  114. IN PLPCP_MESSAGE Msg,
  115. IN ULONG MutexFlags
  116. );
  117. VOID
  118. LpcpFreeDataInfoMessage (
  119. IN PLPCP_PORT_OBJECT Port,
  120. IN ULONG MessageId,
  121. IN ULONG CallbackId,
  122. IN LPC_CLIENT_ID ClientId
  123. );
  124. PLPCP_MESSAGE
  125. LpcpFindDataInfoMessage (
  126. IN PLPCP_PORT_OBJECT Port,
  127. IN ULONG MessageId,
  128. IN ULONG CallbackId,
  129. IN LPC_CLIENT_ID ClientId
  130. );
  131. //
  132. // Entry points defined in lpcquery.c
  133. //
  134. //
  135. // Entry points defined in lpcmove.s and lpcmove.asm
  136. //
  137. VOID
  138. LpcpMoveMessage (
  139. OUT PPORT_MESSAGE DstMsg,
  140. IN PPORT_MESSAGE SrcMsg,
  141. IN PVOID SrcMsgData,
  142. IN ULONG MsgType OPTIONAL,
  143. IN PCLIENT_ID ClientId OPTIONAL
  144. );
  145. //
  146. // Internal Entry Points defined in lpcpriv.c
  147. //
  148. VOID
  149. LpcpFreePortClientSecurity (
  150. IN PLPCP_PORT_OBJECT Port
  151. );
  152. //
  153. // Macro Procedures used by RequestWaitReply, Reply, ReplyWaitReceive,
  154. // and ReplyWaitReply services
  155. //
  156. #define LpcpGetDynamicClientSecurity(Thread,Port,DynamicSecurity) \
  157. SeCreateClientSecurity((Thread),&(Port)->SecurityQos,FALSE,(DynamicSecurity))
  158. #define LpcpFreeDynamicClientSecurity(DynamicSecurity) \
  159. SeDeleteClientSecurity( DynamicSecurity )
  160. #define LpcpReferencePortObject(PortHandle,PortAccess,PreviousMode,PortObject) \
  161. ObReferenceObjectByHandle((PortHandle),(PortAccess),LpcPortObjectType,(PreviousMode),(PVOID *)(PortObject),NULL)
  162. #define LPCP_PORT_BIT 1
  163. #define LPCP_NO_IMPERSONATION 2
  164. #define LPCP_THREAD_ATTRIBUTES (LPCP_PORT_BIT | LPCP_NO_IMPERSONATION)
  165. #define LpcpGetThreadMessage(T) \
  166. ( \
  167. (((ULONG_PTR)(T)->LpcReplyMessage) & LPCP_PORT_BIT) ? NULL : \
  168. (PLPCP_MESSAGE)((ULONG_PTR)(T)->LpcReplyMessage & ~LPCP_THREAD_ATTRIBUTES) \
  169. )
  170. #define LpcpGetThreadPort(T) \
  171. ( \
  172. (((ULONG_PTR)(T)->LpcReplyMessage) & LPCP_PORT_BIT) ? \
  173. (PLPCP_PORT_OBJECT)(((ULONG_PTR)(T)->LpcWaitingOnPort) & ~LPCP_THREAD_ATTRIBUTES): \
  174. NULL \
  175. )
  176. #define LpcpGetThreadAttributes(T) \
  177. (((ULONG_PTR)(T)->LpcWaitingOnPort) & LPCP_THREAD_ATTRIBUTES)
  178. #define LpcpSetThreadAttributes(T,A) \
  179. (T)->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)(T)->LpcWaitingOnPort) | (A));
  180. #define LpcpSetPortToThread(T,P) \
  181. (T)->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)P) | LPCP_PORT_BIT);
  182. #define LPCP_VALIDATE_REASON_IMPERSONATION 1
  183. #define LPCP_VALIDATE_REASON_REPLY 2
  184. #define LPCP_VALIDATE_REASON_WRONG_DATA 3
  185. BOOLEAN
  186. FASTCALL
  187. LpcpValidateClientPort(
  188. IN PETHREAD Thread,
  189. IN PLPCP_PORT_OBJECT ReplyPort,
  190. IN ULONG Reason
  191. );
  192. //
  193. // Entry Points defined in lpcinit.c
  194. //
  195. #if DBG
  196. #define ENABLE_LPC_TRACING 1
  197. #else
  198. #define ENABLE_LPC_TRACING 0
  199. #endif
  200. #if ENABLE_LPC_TRACING
  201. BOOLEAN LpcpStopOnReplyMismatch;
  202. BOOLEAN LpcpTraceMessages;
  203. char *LpcpMessageTypeName[];
  204. char *
  205. LpcpGetCreatorName (
  206. PLPCP_PORT_OBJECT PortObject
  207. );
  208. #define LpcpPrint( _x_ ) { \
  209. DbgPrint( "LPC[ %02x.%02x ]: ", \
  210. PsGetCurrentThread()->Cid.UniqueProcess, \
  211. PsGetCurrentThread()->Cid.UniqueThread ); \
  212. DbgPrint _x_ ; \
  213. }
  214. #define LpcpTrace( _x_ ) if (LpcpTraceMessages) { LpcpPrint( _x_ ); }
  215. #else
  216. #define LpcpPrint( _x_ )
  217. #define LpcpTrace( _x_ )
  218. #endif // ENABLE_LPC_TRACING
  219. extern PAGED_LOOKASIDE_LIST LpcpMessagesLookaside;
  220. __forceinline
  221. PLPCP_MESSAGE
  222. LpcpAllocateFromPortZone (
  223. ULONG Size
  224. )
  225. {
  226. PLPCP_MESSAGE Msg;
  227. PAGED_CODE();
  228. UNREFERENCED_PARAMETER (Size);
  229. Msg = ExAllocateFromPagedLookasideList( &LpcpMessagesLookaside );
  230. if (Msg != NULL) {
  231. LpcpTrace(( "Allocate Msg %lx\n", Msg ));
  232. InitializeListHead( &Msg->Entry );
  233. Msg->RepliedToThread = NULL;
  234. //
  235. // Clear the message type field. In some failure paths this message get freed
  236. // w/o having it initialized.
  237. //
  238. Msg->Request.u2.s2.Type = 0;
  239. return Msg;
  240. }
  241. return NULL;
  242. }
  243. #define LPCP_MUTEX_OWNED 0x1
  244. #define LPCP_MUTEX_RELEASE_ON_RETURN 0x2
  245. VOID
  246. FASTCALL
  247. LpcpFreeToPortZone (
  248. IN PLPCP_MESSAGE Msg,
  249. IN ULONG MutexFlags
  250. );
  251. #ifdef _LPC_LOG_ERRORS
  252. extern NTSTATUS LpcpLogErrorFilter;
  253. VOID
  254. LpcpInitilizeLogging();
  255. VOID
  256. LpcpLogEntry (
  257. NTSTATUS Status,
  258. CLIENT_ID ClientId,
  259. PPORT_MESSAGE PortMessage
  260. );
  261. __forceinline
  262. VOID
  263. LpcpTraceError (
  264. NTSTATUS Status,
  265. CLIENT_ID ClientId,
  266. PPORT_MESSAGE PortMessage
  267. )
  268. {
  269. if ((LpcpLogErrorFilter == 0)
  270. ||
  271. (LpcpLogErrorFilter == Status)) {
  272. LpcpLogEntry( Status, ClientId, PortMessage);
  273. }
  274. }
  275. #else // _LPC_LOG_ERRORS
  276. #define LpcpInitilizeLogging()
  277. #define LpcpLogEntry(_Status_,_ClientId_,_PortMessage_)
  278. #define LpcpTraceError(_Status_,_ClientId_,_PortMessage_)
  279. #endif // _LPC_LOG_ERRORS