ReactOS  0.4.13-dev-563-g0561610
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 
18 NTAPI
20 {
21  PLPCP_NONPAGED_PORT_QUEUE MessageQueue;
22 
23  PAGED_CODE();
24 
25  /* Allocate the queue */
26  MessageQueue = ExAllocatePoolWithTag(NonPagedPool,
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 
42 NTAPI
45  IN ULONG MaxConnectionInfoLength,
46  IN ULONG MaxMessageLength,
47  IN ULONG MaxPoolUsage,
48  IN BOOLEAN Waitable)
49 {
52  UNICODE_STRING CapturedObjectName, *ObjectName;
54  HANDLE Handle;
55 
56  PAGED_CODE();
57  LPCTRACE(LPC_CREATE_DEBUG, "Name: %wZ\n", ObjectAttributes->ObjectName);
58 
59  RtlInitEmptyUnicodeString(&CapturedObjectName, NULL, 0);
60 
61  /* Check if the call comes from user mode */
62  if (PreviousMode != KernelMode)
63  {
64  _SEH2_TRY
65  {
66  /* Probe the PortHandle */
67  ProbeForWriteHandle(PortHandle);
68 
69  /* Probe the ObjectAttributes and its object name (not the buffer) */
71  ObjectName = ((volatile OBJECT_ATTRIBUTES*)ObjectAttributes)->ObjectName;
72  if (ObjectName)
73  {
74  ProbeForRead(ObjectName, sizeof(*ObjectName), 1);
75  CapturedObjectName = *(volatile UNICODE_STRING*)ObjectName;
76  }
77  }
79  {
80  /* Return the exception code */
82  }
83  _SEH2_END;
84  }
85  else
86  {
87  if (ObjectAttributes->ObjectName)
88  CapturedObjectName = *(ObjectAttributes->ObjectName);
89  }
90 
91  /* Normalize the buffer pointer in case we don't have a name */
92  if (CapturedObjectName.Length == 0)
93  CapturedObjectName.Buffer = NULL;
94 
95  /* Create the Object */
100  NULL,
101  sizeof(LPCP_PORT_OBJECT),
102  0,
103  0,
104  (PVOID*)&Port);
105  if (!NT_SUCCESS(Status)) return Status;
106 
107  /* Set up the Object */
109  Port->ConnectionPort = Port;
110  Port->Creator = PsGetCurrentThread()->Cid;
111  InitializeListHead(&Port->LpcDataInfoChainHead);
112  InitializeListHead(&Port->LpcReplyChainHead);
113 
114  /* Check if we don't have a name */
115  if (CapturedObjectName.Buffer == NULL)
116  {
117  /* Set up for an unconnected port */
119  Port->ConnectedPort = Port;
120  Port->ServerProcess = NULL;
121  }
122  else
123  {
124  /* Set up for a named connection port */
126  Port->ServerProcess = PsGetCurrentProcess();
127 
128  /* Don't let the process die on us */
129  ObReferenceObject(Port->ServerProcess);
130  }
131 
132  /* Check if this is a waitable port */
133  if (Waitable) Port->Flags |= LPCP_WAITABLE_PORT;
134 
135  /* Setup the port queue */
137  if (!NT_SUCCESS(Status))
138  {
139  /* Fail */
141  return Status;
142  }
143 
144  /* Check if this is a waitable port */
146  {
147  /* Setup the wait event */
149  }
150 
151  /* Set the maximum message size allowed */
152  Port->MaxMessageLength = LpcpMaxMessageSize -
154 
155  /* Now subtract the actual message structures and get the data size */
156  Port->MaxConnectionInfoLength = Port->MaxMessageLength -
157  sizeof(PORT_MESSAGE) -
158  sizeof(LPCP_CONNECTION_MESSAGE);
159 
160  /* Validate the sizes */
161  if (Port->MaxConnectionInfoLength < MaxConnectionInfoLength)
162  {
163  /* Not enough space for your request */
166  }
167  else if (Port->MaxMessageLength < MaxMessageLength)
168  {
169  /* Not enough space for your request */
172  }
173 
174  /* Now set the custom setting */
175  Port->MaxMessageLength = MaxMessageLength;
176 
177  /* Insert it now */
179  NULL,
181  0,
182  NULL,
183  &Handle);
184  if (NT_SUCCESS(Status))
185  {
186  _SEH2_TRY
187  {
188  /* Write back the handle, pointer was already probed */
189  *PortHandle = Handle;
190  }
192  {
193  /* An exception happened, close the opened handle */
196  }
197  _SEH2_END;
198  }
199 
200  /* Return success or the error */
201  LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %p\n", Port, Handle);
202  return Status;
203 }
204 
205 /* PUBLIC FUNCTIONS **********************************************************/
206 
207 /*
208  * @implemented
209  */
210 NTSTATUS
211 NTAPI
214  IN ULONG MaxConnectInfoLength,
215  IN ULONG MaxDataLength,
216  IN ULONG MaxPoolUsage)
217 {
218  PAGED_CODE();
219 
220  /* Call the internal API */
221  return LpcpCreatePort(PortHandle,
223  MaxConnectInfoLength,
224  MaxDataLength,
225  MaxPoolUsage,
226  FALSE);
227 }
228 
229 /*
230  * @implemented
231  */
232 NTSTATUS
233 NTAPI
236  IN ULONG MaxConnectInfoLength,
237  IN ULONG MaxDataLength,
238  IN ULONG MaxPoolUsage)
239 {
240  PAGED_CODE();
241 
242  /* Call the internal API */
243  return LpcpCreatePort(PortHandle,
245  MaxConnectInfoLength,
246  MaxDataLength,
247  MaxPoolUsage,
248  TRUE);
249 }
250 
251 /* EOF */
NTSTATUS NTAPI NtCreateWaitablePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:234
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
CPPORT Port[4]
Definition: headless.c:34
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define MAXLONG
Definition: umtypes.h:116
Iosb Status
Definition: create.c:4311
#define KeGetPreviousMode()
Definition: ketypes.h:1081
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
_SEH2_TRY
Definition: create.c:4250
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
struct _PORT_MESSAGE_HEADER PORT_MESSAGE
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:463
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define LPCP_CONNECTION_PORT
Definition: lpctypes.h:54
USHORT Flags
Definition: cportlib.h:31
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define LPCP_UNCONNECTED_PORT
Definition: lpctypes.h:55
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _LPCP_PORT_OBJECT * BackPointer
Definition: lpctypes.h:196
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:952
PAGED_CODE()
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
_In_ HANDLE Handle
Definition: extypes.h:390
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:212
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ULONG LpcpMaxMessageSize
Definition: port.c:18
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
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
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define LPCP_WAITABLE_PORT
Definition: lpctypes.h:60
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
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:2932
NTSTATUS NTAPI LpcpInitializePortQueue(IN PLPCP_PORT_OBJECT Port)
Definition: create.c:19
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define PORT_ALL_ACCESS
Definition: lpctypes.h:47
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
#define LPC_CREATE_DEBUG
Definition: lpc.h:17
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:464
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define LPCTRACE(x, fmt,...)
Definition: lpc.h:49