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