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)
9 /* INCLUDES ******************************************************************/
15 /* PRIVATE FUNCTIONS *********************************************************/
19 LpcpInitializePortQueue(IN PLPCP_PORT_OBJECT Port
)
21 PLPCP_NONPAGED_PORT_QUEUE MessageQueue
;
24 /* Allocate the queue */
25 MessageQueue
= ExAllocatePoolWithTag(NonPagedPool
,
26 sizeof(LPCP_NONPAGED_PORT_QUEUE
),
28 if (!MessageQueue
) return STATUS_INSUFFICIENT_RESOURCES
;
31 KeInitializeSemaphore(&MessageQueue
->Semaphore
, 0, MAXLONG
);
32 MessageQueue
->BackPointer
= Port
;
34 /* And link it with the Paged Pool part */
35 Port
->MsgQueue
.Semaphore
= &MessageQueue
->Semaphore
;
36 InitializeListHead(&Port
->MsgQueue
.ReceiveHead
);
37 return STATUS_SUCCESS
;
42 LpcpCreatePort(OUT PHANDLE PortHandle
,
43 IN POBJECT_ATTRIBUTES ObjectAttributes
,
44 IN ULONG MaxConnectionInfoLength
,
45 IN ULONG MaxMessageLength
,
46 IN ULONG MaxPoolUsage
,
49 KPROCESSOR_MODE PreviousMode
= KeGetPreviousMode();
51 PLPCP_PORT_OBJECT Port
;
53 LPCTRACE(LPC_CREATE_DEBUG
, "Name: %wZ\n", ObjectAttributes
->ObjectName
);
55 /* Create the Object */
56 Status
= ObCreateObject(PreviousMode
,
61 sizeof(LPCP_PORT_OBJECT
),
65 if (!NT_SUCCESS(Status
)) return Status
;
67 /* Set up the Object */
68 RtlZeroMemory(Port
, sizeof(LPCP_PORT_OBJECT
));
69 Port
->ConnectionPort
= Port
;
70 Port
->Creator
= PsGetCurrentThread()->Cid
;
71 InitializeListHead(&Port
->LpcDataInfoChainHead
);
72 InitializeListHead(&Port
->LpcReplyChainHead
);
74 /* Check if we don't have a name */
75 if (!ObjectAttributes
->ObjectName
->Buffer
)
77 /* Set up for an unconnected port */
78 Port
->Flags
= LPCP_UNCONNECTED_PORT
;
79 Port
->ConnectedPort
= Port
;
80 Port
->ServerProcess
= NULL
;
84 /* Set up for a named connection port */
85 Port
->Flags
= LPCP_CONNECTION_PORT
;
86 Port
->ServerProcess
= PsGetCurrentProcess();
88 /* Don't let the process die on us */
89 ObReferenceObject(Port
->ServerProcess
);
92 /* Check if this is a waitable port */
93 if (Waitable
) Port
->Flags
|= LPCP_WAITABLE_PORT
;
95 /* Setup the port queue */
96 Status
= LpcpInitializePortQueue(Port
);
97 if (!NT_SUCCESS(Status
))
100 ObDereferenceObject(Port
);
104 /* Check if this is a waitable port */
105 if (Port
->Flags
& LPCP_WAITABLE_PORT
)
107 /* Setup the wait event */
108 KeInitializeEvent(&Port
->WaitEvent
, NotificationEvent
, FALSE
);
111 /* Set the maximum message size allowed */
112 Port
->MaxMessageLength
= LpcpMaxMessageSize
-
113 FIELD_OFFSET(LPCP_MESSAGE
, Request
);
115 /* Now subtract the actual message structures and get the data size */
116 Port
->MaxConnectionInfoLength
= Port
->MaxMessageLength
-
117 sizeof(PORT_MESSAGE
) -
118 sizeof(LPCP_CONNECTION_MESSAGE
);
120 /* Validate the sizes */
121 if (Port
->MaxConnectionInfoLength
< MaxConnectionInfoLength
)
123 /* Not enough space for your request */
124 ObDereferenceObject(Port
);
125 return STATUS_INVALID_PARAMETER_3
;
127 else if (Port
->MaxMessageLength
< MaxMessageLength
)
129 /* Not enough space for your request */
130 ObDereferenceObject(Port
);
131 return STATUS_INVALID_PARAMETER_4
;
134 /* Now set the custom setting */
135 Port
->MaxMessageLength
= MaxMessageLength
;
138 Status
= ObInsertObject((PVOID
)Port
,
145 /* Return success or the error */
146 LPCTRACE(LPC_CREATE_DEBUG
, "Port: %p. Handle: %p\n", Port
, *PortHandle
);
150 /* PUBLIC FUNCTIONS **********************************************************/
157 NtCreatePort(OUT PHANDLE PortHandle
,
158 IN POBJECT_ATTRIBUTES ObjectAttributes
,
159 IN ULONG MaxConnectInfoLength
,
160 IN ULONG MaxDataLength
,
161 IN ULONG MaxPoolUsage
)
165 /* Call the internal API */
166 return LpcpCreatePort(PortHandle
,
168 MaxConnectInfoLength
,
179 NtCreateWaitablePort(OUT PHANDLE PortHandle
,
180 IN POBJECT_ATTRIBUTES ObjectAttributes
,
181 IN ULONG MaxConnectInfoLength
,
182 IN ULONG MaxDataLength
,
183 IN ULONG MaxPoolUsage
)
187 /* Call the internal API */
188 return LpcpCreatePort(PortHandle
,
190 MaxConnectInfoLength
,