Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
5.4 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. conthrds.c
  5. Abstract:
  6. This module contains the Server Listen&Request threads
  7. procedures for the Console Session.
  8. Author:
  9. Avi Nathan (avin) 17-Jul-1991
  10. Revision History:
  11. Ellen Aycock-Wright (ellena) 15-Sept-1991 Modified for POSIX
  12. --*/
  13. #include <stdio.h>
  14. #include "psxsrv.h"
  15. #define NTPSX_ONLY
  16. #include "sesport.h"
  17. NTSTATUS
  18. PsxSessionHandleConnectionRequest(
  19. IN PPSXSESREQUESTMSG Message
  20. )
  21. {
  22. NTSTATUS Status;
  23. PPSXSESCONNECTINFO ConnectionInfoIn = &Message->ConnectionRequest;
  24. SCCONNECTINFO ConnectionInfoOut;
  25. ULONG ConnectionInfoOutLength;
  26. STRING SessionPortName;
  27. UNICODE_STRING SessionPortName_U;
  28. SECURITY_QUALITY_OF_SERVICE DynamicQos;
  29. CHAR SessionName[PSX_SES_BASE_PORT_NAME_LENGTH];
  30. HANDLE SessionPort;
  31. HANDLE PsxSessionCommPort;
  32. int Id;
  33. ConnectionInfoOutLength = sizeof(ConnectionInfoOut);
  34. Id = ConnectionInfoIn->In.SessionUniqueId;
  35. PSX_GET_SESSION_PORT_NAME(SessionName, Id);
  36. RtlInitAnsiString(&SessionPortName, SessionName);
  37. Status = RtlAnsiStringToUnicodeString(&SessionPortName_U,
  38. &SessionPortName, TRUE);
  39. if (!NT_SUCCESS(Status)) {
  40. return Status;
  41. }
  42. DynamicQos.ImpersonationLevel = SecurityImpersonation;
  43. DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  44. DynamicQos.EffectiveOnly = TRUE;
  45. //
  46. // Get the session communication port handle. This handle will
  47. // be used to send session requests to psxses.exe for this
  48. // session.
  49. //
  50. Status = NtConnectPort(&SessionPort, &SessionPortName_U,
  51. &DynamicQos, NULL, NULL, NULL,
  52. (PVOID)&ConnectionInfoOut, &ConnectionInfoOutLength);
  53. RtlFreeUnicodeString(&SessionPortName_U);
  54. if (!NT_SUCCESS(Status)) {
  55. NTSTATUS st2;
  56. // Reject
  57. st2 = NtAcceptConnectPort(&PsxSessionCommPort, NULL,
  58. (PPORT_MESSAGE)Message, FALSE, NULL, NULL);
  59. if (NT_SUCCESS(st2)) {
  60. NtClose(PsxSessionCommPort);
  61. }
  62. return Status;
  63. }
  64. // Accept the connection
  65. ConnectionInfoIn->Out.SessionPortHandle = SessionPort;
  66. //
  67. // PsxSessionCommPort is not used for Reply. Instead,
  68. // the port is created with ReceiveAny==TRUE and we wait
  69. // on the connection port.
  70. //
  71. Status = NtAcceptConnectPort(&PsxSessionCommPort, NULL,
  72. (PPORT_MESSAGE)Message, TRUE, NULL, NULL);
  73. ASSERT(NT_SUCCESS(Status));
  74. //
  75. // Add an entry to the ConnectingSessions list, saying
  76. // that the session exists but has not yet asked to have
  77. // a process created to be the session leader.
  78. //
  79. Status = AddConnectingTerminal(Id, PsxSessionCommPort, SessionPort);
  80. if (!NT_SUCCESS(Status)) {
  81. return Status;
  82. }
  83. Status = NtCompleteConnectPort(PsxSessionCommPort);
  84. ASSERT(NT_SUCCESS(Status));
  85. return Status;
  86. }
  87. // for debug
  88. int DbgBadRQ;
  89. NTSTATUS
  90. PsxSessionRequestThread(
  91. PVOID Parameter
  92. )
  93. {
  94. NTSTATUS Status;
  95. PSXSESREQUESTMSG ReceiveMsg, *pReplyMsg;
  96. int MessageType;
  97. pReplyMsg = NULL;
  98. for (;;) {
  99. Status = NtReplyWaitReceivePort(PsxSessionPort, NULL,
  100. (PPORT_MESSAGE)pReplyMsg, (PPORT_MESSAGE)&ReceiveMsg);
  101. if (!NT_SUCCESS(Status)) {
  102. KdPrint(("PSXSS: NtReplyWaitReceivePort: 0x%x\n",
  103. Status));
  104. if (STATUS_INVALID_HANDLE == Status ||
  105. STATUS_OBJECT_TYPE_MISMATCH == Status) {
  106. DbgBadRQ = ReceiveMsg.Request;
  107. KdPrint(("PSXSS: SessionRequestThread exits, "
  108. "rq was %d.\n", ReceiveMsg.Request));
  109. break;
  110. }
  111. pReplyMsg = NULL;
  112. continue;
  113. }
  114. MessageType = ReceiveMsg.h.u2.s2.Type;
  115. if (MessageType == LPC_CONNECTION_REQUEST) {
  116. PsxSessionHandleConnectionRequest( &ReceiveMsg );
  117. pReplyMsg = NULL;
  118. continue;
  119. }
  120. if (MessageType == LPC_CLIENT_DIED ||
  121. MessageType == LPC_PORT_CLOSED
  122. ) {
  123. pReplyMsg = NULL;
  124. continue;
  125. }
  126. if (MessageType == LPC_DEBUG_EVENT ||
  127. MessageType == LPC_ERROR_EVENT ||
  128. MessageType == LPC_EXCEPTION
  129. ) {
  130. pReplyMsg = NULL;
  131. continue;
  132. }
  133. if (MessageType != LPC_REQUEST) {
  134. KdPrint(("PSXSS: SesRqThread got type %d\n",
  135. MessageType));
  136. pReplyMsg = NULL;
  137. continue;
  138. } else {
  139. switch (ReceiveMsg.Request) {
  140. case SesConCreate:
  141. Status = PsxCreateConSession(&ReceiveMsg);
  142. break;
  143. case SesConSignal:
  144. Status = PsxCtrlSignalHandler(&ReceiveMsg);
  145. break;
  146. default:
  147. Status = 0;
  148. KdPrint(("PSXSS: Unknown Session request: %d\n",
  149. ReceiveMsg.Request));
  150. }
  151. pReplyMsg = &ReceiveMsg;
  152. pReplyMsg->Status = Status;
  153. }
  154. }
  155. return Status;
  156. }