ReactOS 0.4.15-dev-7842-g558ab78
port.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/lpc/port.c
5 * PURPOSE: Local Procedure Call: Port Management
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS *******************************************************************/
16
23
25{
28 0,
30};
31
32/* PRIVATE FUNCTIONS *********************************************************/
33
34CODE_SEG("INIT")
38{
39 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
41
42 /* Setup the LPC Lock */
44
45 /* Create the Port Object Type */
46 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
48 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
49 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(LPCP_NONPAGED_PORT_QUEUE);
50 ObjectTypeInitializer.DefaultPagedPoolCharge = FIELD_OFFSET(LPCP_PORT_OBJECT, WaitEvent);
51 ObjectTypeInitializer.GenericMapping = LpcpPortMapping;
52 ObjectTypeInitializer.PoolType = PagedPool;
53 ObjectTypeInitializer.UseDefaultObject = TRUE;
54 ObjectTypeInitializer.CloseProcedure = LpcpClosePort;
55 ObjectTypeInitializer.DeleteProcedure = LpcpDeletePort;
56 ObjectTypeInitializer.ValidAccessMask = PORT_ALL_ACCESS;
57 ObjectTypeInitializer.InvalidAttributes = OBJ_VALID_ATTRIBUTES & ~OBJ_CASE_INSENSITIVE;
59 &ObjectTypeInitializer,
60 NULL,
62
63 /* Create the Waitable Port Object Type */
64 RtlInitUnicodeString(&Name, L"WaitablePort");
65 ObjectTypeInitializer.PoolType = NonPagedPool;
66 ObjectTypeInitializer.DefaultNonPagedPoolCharge += sizeof(LPCP_PORT_OBJECT);
67 ObjectTypeInitializer.DefaultPagedPoolCharge = 0;
68 ObjectTypeInitializer.UseDefaultObject = FALSE;
70 &ObjectTypeInitializer,
71 NULL,
73
74 /* Allocate the LPC lookaside list */
77 NULL,
78 NULL,
79 0,
81 'McpL',
82 32);
83
84 /* We're done */
85 return TRUE;
86}
87
93{
94 PLPCP_PORT_OBJECT ThreadPort;
95
96 /* Get the thread's port */
98 if (ThreadPort == NULL)
99 {
100 return FALSE;
101 }
102
103 /* Check if the port matches directly */
104 if ((Port == ThreadPort) ||
105 (Port == ThreadPort->ConnectionPort) ||
106 (Port == ThreadPort->ConnectedPort))
107 {
108 return TRUE;
109 }
110
111 /* Check if this is a communication port and the connection port matches */
113 (Port->ConnectionPort == ThreadPort))
114 {
115 return TRUE;
116 }
117
118 return FALSE;
119}
120
121
122/* PUBLIC FUNCTIONS **********************************************************/
123
125NTAPI
127 IN PPORT_MESSAGE ClientMessage)
128{
132 ULONG MessageId;
133 PLPCP_PORT_OBJECT Port = NULL, ConnectedPort = NULL;
136
137 PAGED_CODE();
138
139 /* Check if the call comes from user mode */
141 {
143 {
144 ProbeForRead(ClientMessage, sizeof(*ClientMessage), sizeof(PVOID));
145 ClientId = ((volatile PORT_MESSAGE*)ClientMessage)->ClientId;
146 MessageId = ((volatile PORT_MESSAGE*)ClientMessage)->MessageId;
147 }
149 {
151 }
152 _SEH2_END;
153 }
154 else
155 {
156 ClientId = ClientMessage->ClientId;
157 MessageId = ClientMessage->MessageId;
158 }
159
160 /* Reference the port handle */
165 (PVOID*)&Port,
166 NULL);
167 if (!NT_SUCCESS(Status))
168 {
169 DPRINT1("Failed to reference port handle: 0x%ls\n", Status);
170 return Status;
171 }
172
173 /* Make sure this is a connection port */
175 {
176 /* It isn't, fail */
177 DPRINT1("Port is not a communication port\n");
179 goto Cleanup;
180 }
181
182 /* Look up the client thread */
184 if (!NT_SUCCESS(Status))
185 {
186 DPRINT1("Failed to lookup client thread: 0x%ls\n", Status);
187 goto Cleanup;
188 }
189
190 /* Acquire the lock */
192
193 /* Get the connected port and try to reference it */
194 ConnectedPort = Port->ConnectedPort;
195 if ((ConnectedPort == NULL) || !ObReferenceObjectSafe(ConnectedPort))
196 {
197 DPRINT1("Failed to reference the connected port\n");
198 ConnectedPort = NULL;
200 goto CleanupWithLock;
201 }
202
203 /* Check for no-impersonation flag */
205 {
206 DPRINT1("Reply message has no impersonation flag set\n");
208 goto CleanupWithLock;
209 }
210
211 /* Check for message id mismatch */
212 if ((ClientThread->LpcReplyMessageId != MessageId) || (MessageId == 0))
213 {
214 DPRINT1("LpcReplyMessageId mismatch: 0x%lx/0x%lx.\n",
215 ClientThread->LpcReplyMessageId, MessageId);
217 goto CleanupWithLock;
218 }
219
220 /* Validate the port */
222 {
223 DPRINT1("LpcpValidateClientPort failed\n");
225 goto CleanupWithLock;
226 }
227
228 /* Release the lock */
230
231 /* Check if security is static */
232 if (!(ConnectedPort->Flags & LPCP_SECURITY_DYNAMIC))
233 {
234 /* Use the static security for impersonation */
235 Status = SeImpersonateClientEx(&ConnectedPort->StaticSecurity, NULL);
236 goto Cleanup;
237 }
238
239 /* Create new dynamic security */
241 &ConnectedPort->SecurityQos,
242 FALSE,
244 if (!NT_SUCCESS(Status))
245 {
246 DPRINT1("SeCreateClientSecurity failed\n");
247 goto Cleanup;
248 }
249
250 /* Use dynamic security for impersonation */
252
253 /* Get rid of the security context */
255
256Cleanup:
257
258 if (ConnectedPort != NULL)
259 ObDereferenceObject(ConnectedPort);
260
261 if (ClientThread != NULL)
263
265
266 return Status;
267
268CleanupWithLock:
269
270 /* Release the lock */
272 goto Cleanup;
273}
274
276NTAPI
278{
279 /* This is all this function does */
280 return STATUS_UNSUCCESSFUL;
281}
282
284NTAPI
290{
293}
294
295/* EOF */
#define PAGED_CODE()
UINT CALLBACK ClientThread(_Inout_ PVOID Parameter)
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:115
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR Cleanup[]
Definition: register.c:80
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
IN CINT OUT PVOID IN ULONG PortInformationLength
Definition: dumpinfo.c:41
IN CINT OUT PVOID PortInformation
Definition: dumpinfo.c:40
IN CINT PortInformationClass
Definition: dumpinfo.c:39
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
CPPORT Port[4]
Definition: headless.c:35
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define OBJ_VALID_ATTRIBUTES
Definition: winternl.h:233
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
VOID NTAPI ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:270
VOID NTAPI LpcpDeletePort(IN PVOID ObjectBody)
Definition: close.c:302
#define LPCP_THREAD_FLAG_NO_IMPERSONATION
Definition: lpc.h:56
VOID NTAPI LpcpClosePort(IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
Definition: close.c:244
FORCEINLINE PLPCP_PORT_OBJECT LpcpGetPortFromThread(IN PETHREAD Thread)
Definition: lpc_x.h:144
#define LPCP_SECURITY_DYNAMIC
Definition: lpctypes.h:62
#define LPCP_COMMUNICATION_PORT
Definition: lpctypes.h:56
#define PORT_ALL_ACCESS
Definition: lpctypes.h:47
#define LPCP_PORT_TYPE_MASK
Definition: lpctypes.h:58
struct _LPCP_NONPAGED_PORT_QUEUE LPCP_NONPAGED_PORT_QUEUE
struct _LPCP_PORT_OBJECT LPCP_PORT_OBJECT
#define LPCP_MAX_MESSAGE_SIZE
Definition: lpctypes.h:276
#define PORT_CONNECT
Definition: lpctypes.h:46
enum _PORT_INFORMATION_CLASS PORT_INFORMATION_CLASS
#define SeDeleteClientSecurity(C)
Definition: imports.h:320
NTKERNELAPI NTSTATUS NTAPI SeCreateClientSecurity(IN PETHREAD Thread, IN PSECURITY_QUALITY_OF_SERVICE QualityOfService, IN BOOLEAN RemoteClient, OUT PSECURITY_CLIENT_CONTEXT ClientContext)
#define KernelMode
Definition: asm.h:34
#define KeGetPreviousMode()
Definition: ketypes.h:1115
_In_ PVOID ClientContext
Definition: netioddk.h:55
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
ULONG LpcpMaxMessageSize
Definition: port.c:18
KGUARDED_MUTEX LpcpLock
Definition: port.c:20
ULONG LpcpNextCallbackId
Definition: port.c:22
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
ULONG LpcpTraceLevel
Definition: port.c:21
NTSTATUS NTAPI NtQueryInformationPort(IN HANDLE PortHandle, IN PORT_INFORMATION_CLASS PortInformationClass, OUT PVOID PortInformation, IN ULONG PortInformationLength, OUT PULONG ReturnLength)
Definition: port.c:285
PAGED_LOOKASIDE_LIST LpcpMessagesLookaside
Definition: port.c:19
NTSTATUS NTAPI NtImpersonateClientOfPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ClientMessage)
Definition: port.c:126
POBJECT_TYPE LpcWaitablePortObjectType
Definition: port.c:17
static GENERIC_MAPPING LpcpPortMapping
Definition: port.c:24
BOOLEAN NTAPI LpcpValidateClientPort(PETHREAD ClientThread, PLPCP_PORT_OBJECT Port)
Definition: port.c:90
NTSTATUS NTAPI NtQueryPortInformationProcess(VOID)
Definition: port.c:277
BOOLEAN NTAPI LpcInitSystem(VOID)
Definition: port.c:37
ULONG LpcpNextMessageId
Definition: port.c:22
NTSTATUS NTAPI PsLookupProcessThreadByCid(IN PCLIENT_ID Cid, OUT PEPROCESS *Process OPTIONAL, OUT PETHREAD *Thread)
Definition: process.c:961
NTSTATUS NTAPI SeImpersonateClientEx(_In_ PSECURITY_CLIENT_CONTEXT ClientContext, _In_opt_ PETHREAD ServerThread)
Extended function that impersonates a client.
Definition: client.c:276
#define STATUS_INVALID_PORT_HANDLE
Definition: ntstatus.h:302
#define STATUS_REPLY_MESSAGE_MISMATCH
Definition: ntstatus.h:675
#define STATUS_PORT_DISCONNECTED
Definition: ntstatus.h:291
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
USHORT Flags
Definition: cportlib.h:31
struct _LPCP_PORT_OBJECT * ConnectedPort
Definition: lpctypes.h:212
struct _LPCP_PORT_OBJECT * ConnectionPort
Definition: lpctypes.h:211
OB_CLOSE_METHOD CloseProcedure
Definition: obtypes.h:368
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103