ReactOS 0.4.15-dev-6057-gd708c79
create.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/create.c
5 * PURPOSE: Local Procedure Call: Port/Queue/Message Creation
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/* PRIVATE FUNCTIONS *********************************************************/
16
20{
21 PLPCP_NONPAGED_PORT_QUEUE MessageQueue;
22
23 PAGED_CODE();
24
25 /* Allocate the queue */
27 sizeof(*MessageQueue),
28 'troP');
29 if (!MessageQueue) return STATUS_INSUFFICIENT_RESOURCES;
30
31 /* Set it up */
32 KeInitializeSemaphore(&MessageQueue->Semaphore, 0, MAXLONG);
33 MessageQueue->BackPointer = Port;
34
35 /* And link it with the Paged Pool part */
36 Port->MsgQueue.Semaphore = &MessageQueue->Semaphore;
37 InitializeListHead(&Port->MsgQueue.ReceiveHead);
38 return STATUS_SUCCESS;
39}
40
45 IN ULONG MaxConnectionInfoLength,
46 IN ULONG MaxMessageLength,
47 IN ULONG MaxPoolUsage,
48 IN BOOLEAN Waitable)
49{
52 UNICODE_STRING CapturedObjectName, *ObjectName;
53#if DBG
54 UNICODE_STRING CapturedPortName;
55#endif
58
59 PAGED_CODE();
60
61 RtlInitEmptyUnicodeString(&CapturedObjectName, NULL, 0);
62
63 /* Check if the call comes from user mode */
65 {
67 {
68 /* Probe the PortHandle */
69 ProbeForWriteHandle(PortHandle);
70
71 /* Probe the ObjectAttributes and its object name (not the buffer) */
73 ObjectName = ((volatile OBJECT_ATTRIBUTES*)ObjectAttributes)->ObjectName;
74 if (ObjectName)
75 CapturedObjectName = ProbeForReadUnicodeString(ObjectName);
76 }
78 {
79 /* Return the exception code */
81 }
83 }
84 else
85 {
86 if (ObjectAttributes->ObjectName)
87 CapturedObjectName = *(ObjectAttributes->ObjectName);
88 }
89
90 /* Normalize the buffer pointer in case we don't have
91 * a name, for initializing an unconnected port. */
92 if (CapturedObjectName.Length == 0)
93 CapturedObjectName.Buffer = NULL;
94
95#if DBG
96 /* Capture the port name for DPRINT only - ObCreateObject does its
97 * own capture. As it is used only for debugging, ignore any failure;
98 * the string is zeroed out in such case. */
99 ProbeAndCaptureUnicodeString(&CapturedPortName, PreviousMode, &CapturedObjectName);
100 LPCTRACE(LPC_CREATE_DEBUG, "Name: %wZ\n", &CapturedPortName);
101 ReleaseCapturedUnicodeString(&CapturedPortName, PreviousMode);
102#endif
103
104 /* Create the Object */
109 NULL,
110 sizeof(LPCP_PORT_OBJECT),
111 0,
112 0,
113 (PVOID*)&Port);
114 if (!NT_SUCCESS(Status)) return Status;
115
116 /* Set up the Object */
118 Port->ConnectionPort = Port;
119 Port->Creator = PsGetCurrentThread()->Cid;
120 InitializeListHead(&Port->LpcDataInfoChainHead);
121 InitializeListHead(&Port->LpcReplyChainHead);
122
123 /* Check if we don't have a name */
124 if (CapturedObjectName.Buffer == NULL)
125 {
126 /* Set up for an unconnected port */
128 Port->ConnectedPort = Port;
129 Port->ServerProcess = NULL;
130 }
131 else
132 {
133 /* Set up for a named connection port */
135 Port->ServerProcess = PsGetCurrentProcess();
136
137 /* Don't let the process die on us */
138 ObReferenceObject(Port->ServerProcess);
139 }
140
141 /* Check if this is a waitable port */
142 if (Waitable) Port->Flags |= LPCP_WAITABLE_PORT;
143
144 /* Setup the port queue */
146 if (!NT_SUCCESS(Status))
147 {
148 /* Fail */
150 return Status;
151 }
152
153 /* Check if this is a waitable port */
155 {
156 /* Setup the wait event */
158 }
159
160 /* Set the maximum message size allowed */
161 Port->MaxMessageLength = LpcpMaxMessageSize -
163
164 /* Now subtract the actual message structures and get the data size */
165 Port->MaxConnectionInfoLength = Port->MaxMessageLength -
166 sizeof(PORT_MESSAGE) -
168
169 /* Validate the sizes */
170 if (Port->MaxConnectionInfoLength < MaxConnectionInfoLength)
171 {
172 /* Not enough space for your request */
175 }
176 else if (Port->MaxMessageLength < MaxMessageLength)
177 {
178 /* Not enough space for your request */
181 }
182
183 /* Now set the custom setting */
184 Port->MaxMessageLength = MaxMessageLength;
185
186 /* Insert it now */
188 NULL,
190 0,
191 NULL,
192 &Handle);
193 if (NT_SUCCESS(Status))
194 {
196 {
197 /* Write back the handle, pointer was already probed */
198 *PortHandle = Handle;
199 }
201 {
202 /* An exception happened, close the opened handle */
205 }
206 _SEH2_END;
207 }
208
209 /* Return success or the error */
210 LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %p\n", Port, Handle);
211 return Status;
212}
213
214/* PUBLIC FUNCTIONS **********************************************************/
215
216/*
217 * @implemented
218 */
220NTAPI
223 IN ULONG MaxConnectInfoLength,
224 IN ULONG MaxDataLength,
225 IN ULONG MaxPoolUsage)
226{
227 PAGED_CODE();
228
229 /* Call the internal API */
230 return LpcpCreatePort(PortHandle,
232 MaxConnectInfoLength,
233 MaxDataLength,
234 MaxPoolUsage,
235 FALSE);
236}
237
238/*
239 * @implemented
240 */
242NTAPI
245 IN ULONG MaxConnectInfoLength,
246 IN ULONG MaxDataLength,
247 IN ULONG MaxPoolUsage)
248{
249 PAGED_CODE();
250
251 /* Call the internal API */
252 return LpcpCreatePort(PortHandle,
254 MaxConnectInfoLength,
255 MaxDataLength,
256 MaxPoolUsage,
257 TRUE);
258}
259
260/* EOF */
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#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
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
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
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
CPPORT Port[4]
Definition: headless.c:35
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _PORT_MESSAGE_HEADER PORT_MESSAGE
ULONG LpcpMaxMessageSize
Definition: port.c:18
#define LPC_CREATE_DEBUG
Definition: lpc.h:17
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
#define LPCTRACE(x, fmt,...)
Definition: lpc.h:49
#define LPCP_CONNECTION_PORT
Definition: lpctypes.h:54
#define LPCP_WAITABLE_PORT
Definition: lpctypes.h:60
#define PORT_ALL_ACCESS
Definition: lpctypes.h:47
#define LPCP_UNCONNECTED_PORT
Definition: lpctypes.h:55
#define KernelMode
Definition: asm.h:34
#define KeGetPreviousMode()
Definition: ketypes.h:1108
@ NotificationEvent
NTSTATUS NTAPI NtCreateWaitablePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:243
NTSTATUS NTAPI LpcpInitializePortQueue(IN PLPCP_PORT_OBJECT Port)
Definition: create.c:19
NTSTATUS NTAPI LpcpCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectionInfoLength, IN ULONG MaxMessageLength, IN ULONG MaxPoolUsage, IN BOOLEAN Waitable)
Definition: create.c:43
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:221
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:478
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
#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
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
#define STATUS_SUCCESS
Definition: shellext.h:65
USHORT Flags
Definition: cportlib.h:31
struct _LPCP_PORT_OBJECT * BackPointer
Definition: lpctypes.h:196
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MAXLONG
Definition: umtypes.h:116
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103