Merge 13159:13510 from trunk
[reactos.git] / reactos / ntoskrnl / lpc / connect.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/lpc/connect.c
6 * PURPOSE: Communication mechanism
7 *
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* GLOBALS *******************************************************************/
18
19 #define TAG_LPC_CONNECT_MESSAGE TAG('L', 'P', 'C', 'C')
20
21 /* FUNCTIONS *****************************************************************/
22
23 /**********************************************************************
24 * NAME EXPORTED
25 * EiConnectPort/12
26 *
27 * DESCRIPTION
28 *
29 * ARGUMENTS
30 *
31 * RETURN VALUE
32 */
33 NTSTATUS STDCALL
34 EiConnectPort(IN PEPORT* ConnectedPort,
35 IN PEPORT NamedPort,
36 IN PSECTION_OBJECT Section,
37 IN LARGE_INTEGER SectionOffset,
38 IN ULONG ViewSize,
39 OUT PVOID* ClientSendViewBase,
40 OUT PVOID* ServerSendViewBase,
41 OUT PULONG ReceiveViewSize,
42 OUT PVOID* ReceiveViewBase,
43 OUT PULONG MaximumMessageSize,
44 IN OUT PVOID ConnectData,
45 IN OUT PULONG ConnectDataLength)
46 {
47 PEPORT_CONNECT_REQUEST_MESSAGE RequestMessage;
48 ULONG RequestConnectDataLength;
49 PEPORT OurPort;
50 PQUEUEDMESSAGE Reply;
51 PEPORT_CONNECT_REPLY_MESSAGE CReply;
52 NTSTATUS Status;
53 KIRQL oldIrql;
54
55 if (ConnectDataLength == NULL)
56 {
57 RequestConnectDataLength = 0;
58 }
59 else
60 {
61 RequestConnectDataLength = *ConnectDataLength;
62 }
63
64 /*
65 * Create a port to represent our side of the connection
66 */
67 Status = ObCreateObject (KernelMode,
68 LpcPortObjectType,
69 NULL,
70 KernelMode,
71 NULL,
72 sizeof(EPORT),
73 0,
74 0,
75 (PVOID*)&OurPort);
76 if (!NT_SUCCESS(Status))
77 {
78 return (Status);
79 }
80 LpcpInitializePort(OurPort, EPORT_TYPE_CLIENT_COMM_PORT, NamedPort);
81
82 /*
83 * Allocate a request message.
84 */
85 RequestMessage = ExAllocatePool(NonPagedPool,
86 sizeof(EPORT_CONNECT_REQUEST_MESSAGE) +
87 RequestConnectDataLength);
88 if (RequestMessage == NULL)
89 {
90 ObDereferenceObject(OurPort);
91 return(STATUS_NO_MEMORY);
92 }
93
94 /*
95 * Initialize the request message.
96 */
97 RequestMessage->MessageHeader.DataSize =
98 sizeof(EPORT_CONNECT_REQUEST_MESSAGE) + RequestConnectDataLength -
99 sizeof(LPC_MESSAGE);
100 RequestMessage->MessageHeader.MessageSize =
101 sizeof(EPORT_CONNECT_REQUEST_MESSAGE) + RequestConnectDataLength;
102 DPRINT("RequestMessageSize %d\n",
103 RequestMessage->MessageHeader.MessageSize);
104 RequestMessage->MessageHeader.SectionSize = 0;
105 RequestMessage->ConnectingProcess = PsGetCurrentProcess();
106 ObReferenceObjectByPointer(RequestMessage->ConnectingProcess,
107 PROCESS_VM_OPERATION,
108 NULL,
109 KernelMode);
110 RequestMessage->SendSectionObject = (struct _SECTION_OBJECT*)Section;
111 RequestMessage->SendSectionOffset = SectionOffset;
112 RequestMessage->SendViewSize = ViewSize;
113 RequestMessage->ConnectDataLength = RequestConnectDataLength;
114 if (RequestConnectDataLength > 0)
115 {
116 memcpy(RequestMessage->ConnectData, ConnectData,
117 RequestConnectDataLength);
118 }
119
120 /*
121 * Queue the message to the named port
122 */
123 EiReplyOrRequestPort(NamedPort,
124 &RequestMessage->MessageHeader,
125 LPC_CONNECTION_REQUEST,
126 OurPort);
127 KeReleaseSemaphore(&NamedPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
128 ExFreePool(RequestMessage);
129
130 /*
131 * Wait for them to accept our connection
132 */
133 KeWaitForSingleObject(&OurPort->Semaphore,
134 UserRequest,
135 UserMode,
136 FALSE,
137 NULL);
138
139 /*
140 * Dequeue the response
141 */
142 KeAcquireSpinLock (&OurPort->Lock, &oldIrql);
143 Reply = EiDequeueMessagePort (OurPort);
144 KeReleaseSpinLock (&OurPort->Lock, oldIrql);
145 CReply = (PEPORT_CONNECT_REPLY_MESSAGE)&Reply->Message;
146
147 /*
148 * Do some initial cleanup.
149 */
150 ObDereferenceObject(PsGetCurrentProcess());
151
152 /*
153 * Check for connection refusal.
154 */
155 if (CReply->MessageHeader.MessageType == LPC_CONNECTION_REFUSED)
156 {
157 ObDereferenceObject(OurPort);
158 ExFreePool(Reply);
159 /*
160 * FIXME: Check what NT does here. Giving the user data back on
161 * connect failure sounds reasonable; it probably wouldn't break
162 * anything anyway.
163 */
164 if (ConnectDataLength != NULL)
165 {
166 *ConnectDataLength = CReply->ConnectDataLength;
167 memcpy(ConnectData, CReply->ConnectData, CReply->ConnectDataLength);
168 }
169 return(STATUS_PORT_CONNECTION_REFUSED);
170 }
171
172 /*
173 * Otherwise we are connected. Copy data back to the client.
174 */
175 *ServerSendViewBase = CReply->SendServerViewBase;
176 *ReceiveViewSize = CReply->ReceiveClientViewSize;
177 *ReceiveViewBase = CReply->ReceiveClientViewBase;
178 *MaximumMessageSize = CReply->MaximumMessageSize;
179 if (ConnectDataLength != NULL)
180 {
181 *ConnectDataLength = CReply->ConnectDataLength;
182 memcpy(ConnectData, CReply->ConnectData, CReply->ConnectDataLength);
183 }
184
185 /*
186 * Create our view of the send section object.
187 */
188 if (Section != NULL)
189 {
190 *ClientSendViewBase = 0;
191 Status = MmMapViewOfSection(Section,
192 PsGetCurrentProcess(),
193 ClientSendViewBase,
194 0,
195 ViewSize,
196 &SectionOffset,
197 &ViewSize,
198 ViewUnmap,
199 0 /* MEM_TOP_DOWN? */,
200 PAGE_READWRITE);
201 if (!NT_SUCCESS(Status))
202 {
203 /* FIXME: Cleanup here. */
204 return(Status);
205 }
206 }
207
208 /*
209 * Do the final initialization of our port.
210 */
211 OurPort->State = EPORT_CONNECTED_CLIENT;
212
213 /*
214 * Cleanup.
215 */
216 ExFreePool(Reply);
217 *ConnectedPort = OurPort;
218 return(STATUS_SUCCESS);
219 }
220
221 /**********************************************************************
222 * NAME EXPORTED
223 * NtConnectPort/8
224 *
225 * DESCRIPTION
226 * Connect to a named port and wait for the other side to
227 * accept or reject the connection request.
228 *
229 * ARGUMENTS
230 * ConnectedPort
231 * PortName
232 * Qos
233 * WriteMap
234 * ReadMap
235 * MaxMessageSize
236 * ConnectInfo
237 * UserConnectInfoLength
238 *
239 * RETURN VALUE
240 *
241 * @unimplemented
242 */
243 NTSTATUS STDCALL
244 NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
245 PUNICODE_STRING PortName,
246 PSECURITY_QUALITY_OF_SERVICE Qos,
247 PLPC_SECTION_WRITE UnsafeWriteMap,
248 PLPC_SECTION_READ UnsafeReadMap,
249 PULONG UnsafeMaximumMessageSize,
250 PVOID UnsafeConnectData,
251 PULONG UnsafeConnectDataLength)
252 {
253 HANDLE ConnectedPortHandle;
254 LPC_SECTION_WRITE WriteMap;
255 LPC_SECTION_READ ReadMap;
256 ULONG MaximumMessageSize;
257 PVOID ConnectData;
258 ULONG ConnectDataLength;
259 PSECTION_OBJECT SectionObject;
260 LARGE_INTEGER SectionOffset;
261 PEPORT ConnectedPort;
262 NTSTATUS Status;
263 PEPORT NamedPort;
264
265 /*
266 * Copy in write map and partially validate.
267 */
268 if (UnsafeWriteMap != NULL)
269 {
270 Status = MmCopyFromCaller(&WriteMap,
271 UnsafeWriteMap,
272 sizeof(LPC_SECTION_WRITE));
273 if (!NT_SUCCESS(Status))
274 {
275 return(Status);
276 }
277 if (WriteMap.Length != sizeof(LPC_SECTION_WRITE))
278 {
279 return(STATUS_INVALID_PARAMETER_4);
280 }
281 SectionOffset.QuadPart = WriteMap.SectionOffset;
282 }
283 else
284 {
285 WriteMap.SectionHandle = INVALID_HANDLE_VALUE;
286 }
287
288 /*
289 * Handle connection data.
290 */
291 if (UnsafeConnectData == NULL)
292 {
293 ConnectDataLength = 0;
294 ConnectData = NULL;
295 }
296 else
297 {
298 if (ExGetPreviousMode() == KernelMode)
299 {
300 ConnectDataLength = *UnsafeConnectDataLength;
301 ConnectData = UnsafeConnectData;
302 }
303 else
304 {
305 Status = MmCopyFromCaller(&ConnectDataLength,
306 UnsafeConnectDataLength,
307 sizeof(ULONG));
308 if (!NT_SUCCESS(Status))
309 {
310 return(Status);
311 }
312 ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength);
313 if (ConnectData == NULL && ConnectDataLength != 0)
314 {
315 return(STATUS_NO_MEMORY);
316 }
317 Status = MmCopyFromCaller(ConnectData,
318 UnsafeConnectData,
319 ConnectDataLength);
320 if (!NT_SUCCESS(Status))
321 {
322 ExFreePool(ConnectData);
323 return(Status);
324 }
325 }
326 }
327
328 /*
329 * Reference the named port.
330 */
331 Status = ObReferenceObjectByName (PortName,
332 0,
333 NULL,
334 PORT_ALL_ACCESS, /* DesiredAccess */
335 LpcPortObjectType,
336 UserMode,
337 NULL,
338 (PVOID*)&NamedPort);
339 if (!NT_SUCCESS(Status))
340 {
341 if (KeGetPreviousMode() != KernelMode)
342 {
343 ExFreePool(ConnectData);
344 }
345 return(Status);
346 }
347
348 /*
349 * Reference the send section object.
350 */
351 if (WriteMap.SectionHandle != INVALID_HANDLE_VALUE)
352 {
353 Status = ObReferenceObjectByHandle(WriteMap.SectionHandle,
354 SECTION_MAP_READ | SECTION_MAP_WRITE,
355 MmSectionObjectType,
356 UserMode,
357 (PVOID*)&SectionObject,
358 NULL);
359 if (!NT_SUCCESS(Status))
360 {
361 ObDereferenceObject(NamedPort);
362 if (KeGetPreviousMode() != KernelMode)
363 {
364 ExFreePool(ConnectData);
365 }
366 return(Status);
367 }
368 }
369 else
370 {
371 SectionObject = NULL;
372 }
373
374 /*
375 * Do the connection establishment.
376 */
377 Status = EiConnectPort(&ConnectedPort,
378 NamedPort,
379 SectionObject,
380 SectionOffset,
381 WriteMap.ViewSize,
382 &WriteMap.ViewBase,
383 &WriteMap.TargetViewBase,
384 &ReadMap.ViewSize,
385 &ReadMap.ViewBase,
386 &MaximumMessageSize,
387 ConnectData,
388 &ConnectDataLength);
389 if (!NT_SUCCESS(Status))
390 {
391 /* FIXME: Again, check what NT does here. */
392 if (UnsafeConnectDataLength != NULL)
393 {
394 if (ExGetPreviousMode() != KernelMode)
395 {
396 MmCopyToCaller(UnsafeConnectData,
397 ConnectData,
398 ConnectDataLength);
399 ExFreePool(ConnectData);
400 }
401 MmCopyToCaller(UnsafeConnectDataLength,
402 &ConnectDataLength,
403 sizeof(ULONG));
404 }
405 return(Status);
406 }
407
408 /*
409 * Do some initial cleanup.
410 */
411 if (SectionObject != NULL)
412 {
413 ObDereferenceObject(SectionObject);
414 SectionObject = NULL;
415 }
416 ObDereferenceObject(NamedPort);
417 NamedPort = NULL;
418
419 /*
420 * Copy the data back to the caller.
421 */
422 if (ExGetPreviousMode() != KernelMode)
423 {
424 if (UnsafeConnectDataLength != NULL)
425 {
426 Status = MmCopyToCaller(UnsafeConnectDataLength,
427 &ConnectDataLength,
428 sizeof(ULONG));
429 if (!NT_SUCCESS(Status))
430 {
431 return(Status);
432 }
433 }
434 if (UnsafeConnectData != NULL && ConnectData != NULL)
435 {
436 Status = MmCopyToCaller(UnsafeConnectData,
437 ConnectData,
438 ConnectDataLength);
439 ExFreePool(ConnectData);
440 if (!NT_SUCCESS(Status))
441 {
442 return(Status);
443 }
444 }
445 }
446 Status = ObInsertObject(ConnectedPort,
447 NULL,
448 PORT_ALL_ACCESS,
449 0,
450 NULL,
451 &ConnectedPortHandle);
452 if (!NT_SUCCESS(Status))
453 {
454 return(Status);
455 }
456 Status = MmCopyToCaller(UnsafeConnectedPortHandle,
457 &ConnectedPortHandle,
458 sizeof(HANDLE));
459 if (!NT_SUCCESS(Status))
460 {
461 return(Status);
462 }
463 if (UnsafeWriteMap != NULL)
464 {
465 Status = MmCopyToCaller(UnsafeWriteMap,
466 &WriteMap,
467 sizeof(LPC_SECTION_WRITE));
468 if (!NT_SUCCESS(Status))
469 {
470 return(Status);
471 }
472 }
473 if (UnsafeReadMap != NULL)
474 {
475 Status = MmCopyToCaller(UnsafeReadMap,
476 &ReadMap,
477 sizeof(LPC_SECTION_READ));
478 if (!NT_SUCCESS(Status))
479 {
480 return(Status);
481 }
482 }
483 if (UnsafeMaximumMessageSize != NULL)
484 {
485 Status = MmCopyToCaller(UnsafeMaximumMessageSize,
486 &MaximumMessageSize,
487 sizeof(ULONG));
488 if (!NT_SUCCESS(Status))
489 {
490 return(Status);
491 }
492 }
493
494 /*
495 * All done.
496 */
497
498 return(STATUS_SUCCESS);
499 }
500
501
502 /**********************************************************************
503 * NAME EXPORTED
504 * NtAcceptConnectPort/6
505 *
506 * DESCRIPTION
507 *
508 * ARGUMENTS
509 * ServerPortHandle
510 * NamedPortHandle
511 * LpcMessage
512 * AcceptIt
513 * WriteMap
514 * ReadMap
515 *
516 * RETURN VALUE
517 */
518 /*EXPORTED*/ NTSTATUS STDCALL
519 NtAcceptConnectPort (PHANDLE ServerPortHandle,
520 HANDLE NamedPortHandle,
521 PLPC_MESSAGE LpcMessage,
522 BOOLEAN AcceptIt,
523 PLPC_SECTION_WRITE WriteMap,
524 PLPC_SECTION_READ ReadMap)
525 {
526 NTSTATUS Status;
527 PEPORT NamedPort;
528 PEPORT OurPort = NULL;
529 PQUEUEDMESSAGE ConnectionRequest;
530 KIRQL oldIrql;
531 PEPORT_CONNECT_REQUEST_MESSAGE CRequest;
532 PEPORT_CONNECT_REPLY_MESSAGE CReply;
533 ULONG Size;
534
535 Size = sizeof(EPORT_CONNECT_REPLY_MESSAGE);
536 if (LpcMessage)
537 {
538 Size += LpcMessage->DataSize;
539 }
540
541 CReply = ExAllocatePool(NonPagedPool, Size);
542 if (CReply == NULL)
543 {
544 return(STATUS_NO_MEMORY);
545 }
546
547 Status = ObReferenceObjectByHandle(NamedPortHandle,
548 PORT_ALL_ACCESS,
549 LpcPortObjectType,
550 UserMode,
551 (PVOID*)&NamedPort,
552 NULL);
553 if (!NT_SUCCESS(Status))
554 {
555 ExFreePool(CReply);
556 return (Status);
557 }
558
559 /*
560 * Create a port object for our side of the connection
561 */
562 if (AcceptIt)
563 {
564 Status = ObCreateObject(ExGetPreviousMode(),
565 LpcPortObjectType,
566 NULL,
567 ExGetPreviousMode(),
568 NULL,
569 sizeof(EPORT),
570 0,
571 0,
572 (PVOID*)&OurPort);
573 if (!NT_SUCCESS(Status))
574 {
575 ExFreePool(CReply);
576 ObDereferenceObject(NamedPort);
577 return(Status);
578 }
579
580 Status = ObInsertObject ((PVOID)OurPort,
581 NULL,
582 PORT_ALL_ACCESS,
583 0,
584 NULL,
585 ServerPortHandle);
586 if (!NT_SUCCESS(Status))
587 {
588 ObDereferenceObject(OurPort);
589 ExFreePool(CReply);
590 ObDereferenceObject(NamedPort);
591 return(Status);
592 }
593
594 LpcpInitializePort(OurPort, EPORT_TYPE_SERVER_COMM_PORT, NamedPort);
595 }
596
597 /*
598 * Dequeue the connection request
599 */
600 KeAcquireSpinLock(&NamedPort->Lock, &oldIrql);
601 ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
602 KeReleaseSpinLock(&NamedPort->Lock, oldIrql);
603 CRequest = (PEPORT_CONNECT_REQUEST_MESSAGE)(&ConnectionRequest->Message);
604
605 /*
606 * Prepare the reply.
607 */
608 if (LpcMessage != NULL)
609 {
610 memcpy(&CReply->MessageHeader, LpcMessage, sizeof(LPC_MESSAGE));
611 memcpy(&CReply->ConnectData, (PVOID)(LpcMessage + 1),
612 LpcMessage->DataSize);
613 CReply->MessageHeader.MessageSize =
614 sizeof(EPORT_CONNECT_REPLY_MESSAGE) + LpcMessage->DataSize;
615 CReply->MessageHeader.DataSize = CReply->MessageHeader.MessageSize -
616 sizeof(LPC_MESSAGE);
617 CReply->ConnectDataLength = LpcMessage->DataSize;
618 }
619 else
620 {
621 CReply->MessageHeader.MessageSize = sizeof(EPORT_CONNECT_REPLY_MESSAGE);
622 CReply->MessageHeader.DataSize = sizeof(EPORT_CONNECT_REPLY_MESSAGE) -
623 sizeof(LPC_MESSAGE);
624 CReply->ConnectDataLength = 0;
625 }
626 if (!AcceptIt)
627 {
628 EiReplyOrRequestPort(ConnectionRequest->Sender,
629 &CReply->MessageHeader,
630 LPC_CONNECTION_REFUSED,
631 NamedPort);
632 KeReleaseSemaphore(&ConnectionRequest->Sender->Semaphore,
633 IO_NO_INCREMENT,
634 1,
635 FALSE);
636 ObDereferenceObject(ConnectionRequest->Sender);
637 ExFreePool(ConnectionRequest);
638 ExFreePool(CReply);
639 ObDereferenceObject(NamedPort);
640 return (STATUS_SUCCESS);
641 }
642
643 /*
644 * Prepare the connection.
645 */
646 if (WriteMap != NULL)
647 {
648 PSECTION_OBJECT SectionObject;
649 LARGE_INTEGER SectionOffset;
650
651 Status = ObReferenceObjectByHandle(WriteMap->SectionHandle,
652 SECTION_MAP_READ | SECTION_MAP_WRITE,
653 MmSectionObjectType,
654 UserMode,
655 (PVOID*)&SectionObject,
656 NULL);
657 if (!NT_SUCCESS(Status))
658 {
659 return(Status);
660 }
661
662 SectionOffset.QuadPart = WriteMap->SectionOffset;
663 WriteMap->TargetViewBase = 0;
664 CReply->ReceiveClientViewSize = WriteMap->ViewSize;
665 Status = MmMapViewOfSection(SectionObject,
666 CRequest->ConnectingProcess,
667 &WriteMap->TargetViewBase,
668 0,
669 CReply->ReceiveClientViewSize,
670 &SectionOffset,
671 &CReply->ReceiveClientViewSize,
672 ViewUnmap,
673 0 /* MEM_TOP_DOWN? */,
674 PAGE_READWRITE);
675 if (!NT_SUCCESS(Status))
676 {
677 return(Status);
678 }
679
680 WriteMap->ViewBase = 0;
681 Status = MmMapViewOfSection(SectionObject,
682 PsGetCurrentProcess(),
683 &WriteMap->ViewBase,
684 0,
685 WriteMap->ViewSize,
686 &SectionOffset,
687 &WriteMap->ViewSize,
688 ViewUnmap,
689 0 /* MEM_TOP_DOWN? */,
690 PAGE_READWRITE);
691 if (!NT_SUCCESS(Status))
692 {
693 return(Status);
694 }
695
696 ObDereferenceObject(SectionObject);
697 }
698 if (ReadMap != NULL && CRequest->SendSectionObject != NULL)
699 {
700 LARGE_INTEGER SectionOffset;
701
702 SectionOffset = CRequest->SendSectionOffset;
703 ReadMap->ViewSize = CRequest->SendViewSize;
704 ReadMap->ViewBase = 0;
705 Status = MmMapViewOfSection(CRequest->SendSectionObject,
706 PsGetCurrentProcess(),
707 &ReadMap->ViewBase,
708 0,
709 CRequest->SendViewSize,
710 &SectionOffset,
711 &CRequest->SendViewSize,
712 ViewUnmap,
713 0 /* MEM_TOP_DOWN? */,
714 PAGE_READWRITE);
715 if (!NT_SUCCESS(Status))
716 {
717 return(Status);
718 }
719 }
720
721 /*
722 * Finish the reply.
723 */
724 if (ReadMap != NULL)
725 {
726 CReply->SendServerViewBase = ReadMap->ViewBase;
727 }
728 else
729 {
730 CReply->SendServerViewBase = 0;
731 }
732 if (WriteMap != NULL)
733 {
734 CReply->ReceiveClientViewBase = WriteMap->TargetViewBase;
735 }
736 CReply->MaximumMessageSize = PORT_MAX_MESSAGE_LENGTH;
737
738
739 /*
740 * Connect the two ports
741 */
742 OurPort->OtherPort = ConnectionRequest->Sender;
743 OurPort->OtherPort->OtherPort = OurPort;
744 EiReplyOrRequestPort(ConnectionRequest->Sender,
745 (PLPC_MESSAGE)CReply,
746 LPC_REPLY,
747 OurPort);
748 ExFreePool(ConnectionRequest);
749 ExFreePool(CReply);
750
751 ObDereferenceObject(OurPort);
752 ObDereferenceObject(NamedPort);
753
754 return (STATUS_SUCCESS);
755 }
756
757 /**********************************************************************
758 * NAME EXPORTED
759 * NtSecureConnectPort/9
760 *
761 * DESCRIPTION
762 * Connect to a named port and wait for the other side to
763 * accept the connection. Possibly verify that the server
764 * matches the ServerSid (trusted server).
765 * Present in w2k+.
766 *
767 * ARGUMENTS
768 * ConnectedPort
769 * PortName: fully qualified name in the Ob name space;
770 * Qos
771 * WriteMap
772 * ServerSid
773 * ReadMap
774 * MaxMessageSize
775 * ConnectInfo
776 * UserConnectInfoLength
777 *
778 * RETURN VALUE
779 */
780 NTSTATUS STDCALL
781 NtSecureConnectPort (OUT PHANDLE ConnectedPort,
782 IN PUNICODE_STRING PortName,
783 IN PSECURITY_QUALITY_OF_SERVICE Qos,
784 IN OUT PLPC_SECTION_WRITE WriteMap OPTIONAL,
785 IN PSID ServerSid OPTIONAL,
786 IN OUT PLPC_SECTION_READ ReadMap OPTIONAL,
787 OUT PULONG MaxMessageSize OPTIONAL,
788 IN OUT PVOID ConnectInfo OPTIONAL,
789 IN OUT PULONG UserConnectInfoLength OPTIONAL)
790 {
791 /* TODO: implement a new object type: WaitablePort */
792 /* TODO: verify the process' SID that hosts the rendez-vous port equals ServerSid */
793 return NtConnectPort (ConnectedPort,
794 PortName,
795 Qos,
796 WriteMap,
797 ReadMap,
798 MaxMessageSize,
799 ConnectInfo,
800 UserConnectInfoLength);
801 }
802
803 /* EOF */