Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlpc_x.h
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/include/internal/lpc_x.h 00005 * PURPOSE: Internal Inlined Functions for Local Procedure Call 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 // 00010 // Gets the message type, removing the kernel-mode flag 00011 // 00012 #define LpcpGetMessageType(x) \ 00013 ((x)->u2.s2.Type &~ LPC_KERNELMODE_MESSAGE) 00014 00015 // 00016 // Waits on an LPC semaphore for a receive operation 00017 // 00018 #define LpcpReceiveWait(s, w) \ 00019 { \ 00020 LPCTRACE(LPC_REPLY_DEBUG, "Wait: %p\n", s); \ 00021 Status = KeWaitForSingleObject(s, \ 00022 WrLpcReceive, \ 00023 w, \ 00024 FALSE, \ 00025 NULL); \ 00026 LPCTRACE(LPC_REPLY_DEBUG, "Wait done: %lx\n", Status); \ 00027 } 00028 00029 // 00030 // Waits on an LPC semaphore for a reply operation 00031 // 00032 #define LpcpReplyWait(s, w) \ 00033 { \ 00034 LPCTRACE(LPC_SEND_DEBUG, "Wait: %p\n", s); \ 00035 Status = KeWaitForSingleObject(s, \ 00036 WrLpcReply, \ 00037 w, \ 00038 FALSE, \ 00039 NULL); \ 00040 LPCTRACE(LPC_SEND_DEBUG, "Wait done: %lx\n", Status); \ 00041 if (Status == STATUS_USER_APC) \ 00042 { \ 00043 /* We were preempted by an APC */ \ 00044 if (KeReadStateSemaphore(s)) \ 00045 { \ 00046 /* It's still signaled, so wait on it */ \ 00047 KeWaitForSingleObject(s, \ 00048 WrExecutive, \ 00049 KernelMode, \ 00050 FALSE, \ 00051 NULL); \ 00052 Status = STATUS_SUCCESS; \ 00053 } \ 00054 } \ 00055 } 00056 00057 // 00058 // Waits on an LPC semaphore for a connect operation 00059 // 00060 #define LpcpConnectWait(s, w) \ 00061 { \ 00062 LPCTRACE(LPC_CONNECT_DEBUG, "Wait: %p\n", s); \ 00063 Status = KeWaitForSingleObject(s, \ 00064 Executive, \ 00065 w, \ 00066 FALSE, \ 00067 NULL); \ 00068 LPCTRACE(LPC_CONNECT_DEBUG, "Wait done: %lx\n", Status);\ 00069 if (Status == STATUS_USER_APC) \ 00070 { \ 00071 /* We were preempted by an APC */ \ 00072 if (KeReadStateSemaphore(s)) \ 00073 { \ 00074 /* It's still signaled, so wait on it */ \ 00075 KeWaitForSingleObject(s, \ 00076 WrExecutive, \ 00077 KernelMode, \ 00078 FALSE, \ 00079 NULL); \ 00080 Status = STATUS_SUCCESS; \ 00081 } \ 00082 } \ 00083 } 00084 00085 // 00086 // Releases an LPC Semaphore to complete a wait 00087 // 00088 #define LpcpCompleteWait(s) \ 00089 { \ 00090 /* Release the semaphore */ \ 00091 LPCTRACE(LPC_SEND_DEBUG, "Release: %p\n", s); \ 00092 KeReleaseSemaphore(s, 1, 1, FALSE); \ 00093 } 00094 00095 // 00096 // Allocates a new message 00097 // 00098 static __inline 00099 PLPCP_MESSAGE 00100 LpcpAllocateFromPortZone(VOID) 00101 { 00102 PLPCP_MESSAGE Message; 00103 00104 /* Allocate a message from the port zone while holding the lock */ 00105 KeAcquireGuardedMutex(&LpcpLock); 00106 Message = (PLPCP_MESSAGE)ExAllocateFromPagedLookasideList(&LpcpMessagesLookaside); 00107 if (!Message) 00108 { 00109 /* Fail, and let caller cleanup */ 00110 KeReleaseGuardedMutex(&LpcpLock); 00111 return NULL; 00112 } 00113 00114 /* Initialize it */ 00115 InitializeListHead(&Message->Entry); 00116 Message->RepliedToThread = NULL; 00117 Message->Request.u2.ZeroInit = 0; 00118 00119 /* Release the lock */ 00120 KeReleaseGuardedMutex(&LpcpLock); 00121 return Message; 00122 } 00123 00124 // 00125 // Get the LPC Message associated to the Thread 00126 // 00127 FORCEINLINE 00128 PLPCP_MESSAGE 00129 LpcpGetMessageFromThread(IN PETHREAD Thread) 00130 { 00131 /* Check if the port flag is set */ 00132 if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT) 00133 { 00134 /* The pointer is actually a port, not a message, so return NULL */ 00135 return NULL; 00136 } 00137 00138 /* Otherwise, this is a message. Return the pointer */ 00139 return (PLPCP_MESSAGE)((ULONG_PTR)Thread->LpcReplyMessage & ~LPCP_THREAD_FLAGS); 00140 } 00141 00142 FORCEINLINE 00143 PLPCP_PORT_OBJECT 00144 LpcpGetPortFromThread(IN PETHREAD Thread) 00145 { 00146 /* Check if the port flag is set */ 00147 if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT) 00148 { 00149 /* The pointer is actually a port, return it */ 00150 return (PLPCP_PORT_OBJECT)((ULONG_PTR)Thread->LpcWaitingOnPort & 00151 ~LPCP_THREAD_FLAGS); 00152 } 00153 00154 /* Otherwise, this is a message. There is nothing to return */ 00155 return NULL; 00156 } 00157 00158 FORCEINLINE 00159 VOID 00160 LpcpSetPortToThread(IN PETHREAD Thread, 00161 IN PLPCP_PORT_OBJECT Port) 00162 { 00163 /* Set the port object */ 00164 Thread->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)Port) | 00165 LPCP_THREAD_FLAG_IS_PORT); 00166 } Generated on Sat May 26 2012 04:36:07 for ReactOS by
1.7.6.1
|