ReactOS 0.4.15-dev-7953-g1f49173
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 ObjectName = ObjectAttributes->ObjectName;
87 if (ObjectName)
88 CapturedObjectName = *ObjectName;
89 }
90
91 /* Normalize the buffer pointer in case we don't have
92 * a name, for initializing an unconnected port. */
93 if (CapturedObjectName.Length == 0)
94 CapturedObjectName.Buffer = NULL;
95
96#if DBG
97 /* Capture the port name for DPRINT only - ObCreateObject does its
98 * own capture. As it is used only for debugging, ignore any failure;
99 * the string is zeroed out in such case. */
101 LPCTRACE(LPC_CREATE_DEBUG, "Name: %wZ\n", &CapturedPortName);
102 ReleaseCapturedUnicodeString(&CapturedPortName, PreviousMode);
103#endif
104
105 /* Create the Object */
110 NULL,
111 sizeof(LPCP_PORT_OBJECT),
112 0,
113 0,
114 (PVOID*)&Port);
115 if (!NT_SUCCESS(Status)) return Status;
116
117 /* Set up the Object */
119 Port->ConnectionPort = Port;
120 Port->Creator = PsGetCurrentThread()->Cid;
121 InitializeListHead(&Port->LpcDataInfoChainHead);
122 InitializeListHead(&Port->LpcReplyChainHead);
123
124 /* Check if we don't have a name */
125 if (CapturedObjectName.Buffer == NULL)
126 {
127 /* Set up for an unconnected port */
129 Port->ConnectedPort = Port;
130 Port->ServerProcess = NULL;
131 }
132 else
133 {
134 /* Set up for a named connection port */
136 Port->ServerProcess = PsGetCurrentProcess();
137
138 /* Don't let the process die on us */
139 ObReferenceObject(Port->ServerProcess);
140 }
141
142 /* Check if this is a waitable port */
143 if (Waitable) Port->Flags |= LPCP_WAITABLE_PORT;
144
145 /* Setup the port queue */
147 if (!NT_SUCCESS(Status))
148 {
149 /* Fail */
151 return Status;
152 }
153
154 /* Check if this is a waitable port */
156 {
157 /* Setup the wait event */
159 }
160
161 /* Set the maximum message size allowed */
162 Port->MaxMessageLength = LpcpMaxMessageSize -
164
165 /* Now subtract the actual message structures and get the data size */
166 Port->MaxConnectionInfoLength = Port->MaxMessageLength -
167 sizeof(PORT_MESSAGE) -
169
170 /* Validate the sizes */
171 if (Port->MaxConnectionInfoLength < MaxConnectionInfoLength)
172 {
173 /* Not enough space for your request */
176 }
177 else if (Port->MaxMessageLength < MaxMessageLength)
178 {
179 /* Not enough space for your request */
182 }
183
184 /* Now set the custom setting */
185 Port->MaxMessageLength = MaxMessageLength;
186
187 /* Insert it now */
189 NULL,
191 0,
192 NULL,
193 &Handle);
194 if (NT_SUCCESS(Status))
195 {
197 {
198 /* Write back the handle, pointer was already probed */
199 *PortHandle = Handle;
200 }
202 {
203 /* An exception happened, close the opened handle */
206 }
207 _SEH2_END;
208 }
209
210 /* Return success or the error */
211 LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %p\n", Port, Handle);
212 return Status;
213}
214
215/* PUBLIC FUNCTIONS **********************************************************/
216
217/*
218 * @implemented
219 */
221NTAPI
224 IN ULONG MaxConnectInfoLength,
225 IN ULONG MaxDataLength,
226 IN ULONG MaxPoolUsage)
227{
228 PAGED_CODE();
229
230 /* Call the internal API */
231 return LpcpCreatePort(PortHandle,
233 MaxConnectInfoLength,
234 MaxDataLength,
235 MaxPoolUsage,
236 FALSE);
237}
238
239/*
240 * @implemented
241 */
243NTAPI
246 IN ULONG MaxConnectInfoLength,
247 IN ULONG MaxDataLength,
248 IN ULONG MaxPoolUsage)
249{
250 PAGED_CODE();
251
252 /* Call the internal API */
253 return LpcpCreatePort(PortHandle,
255 MaxConnectInfoLength,
256 MaxDataLength,
257 MaxPoolUsage,
258 TRUE);
259}
260
261/* 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:1115
@ NotificationEvent
NTSTATUS NTAPI NtCreateWaitablePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:244
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:222
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