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