/*++ * @name CsrSbApiRequestThread * * The CsrSbApiRequestThread routine handles incoming messages or connection * requests on the SM API LPC Port. * * @param Parameter * System-default user-defined parameter. Unused. * * @return The thread exit code, if the thread is terminated. * * @remarks Before listening on the port, the routine will first attempt * to connect to the user subsystem. * *--*/ VOID NTAPI CsrSbApiRequestThread(IN PVOID Parameter) { NTSTATUS Status; SB_API_MSG ReceiveMsg; PSB_API_MSG ReplyMsg = NULL; PVOID PortContext; ULONG MessageType; /* Start the loop */ while (TRUE) { /* Wait for a message to come in */ Status = NtReplyWaitReceivePort(CsrSbApiPort, &PortContext, &ReplyMsg->h, &ReceiveMsg.h); /* Check if we didn't get success */ if (Status != STATUS_SUCCESS) { /* If we only got a warning, keep going */ if (NT_SUCCESS(Status)) continue; /* We failed big time, so start out fresh */ ReplyMsg = NULL; DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status); continue; } /* Save the message type */ MessageType = ReceiveMsg.h.u2.s2.Type; /* Check if this is a connection request */ if (MessageType == LPC_CONNECTION_REQUEST) { /* Handle connection request */ CsrSbApiHandleConnectionRequest(&ReceiveMsg); /* Start over */ ReplyMsg = NULL; continue; } /* Check if the port died */ if (MessageType == LPC_PORT_CLOSED) { /* Close the handle if we have one */ if (PortContext) NtClose((HANDLE)PortContext); /* Client died, start over */ ReplyMsg = NULL; continue; } else if (MessageType == LPC_CLIENT_DIED) { /* Client died, start over */ ReplyMsg = NULL; continue; } /* * It's an API Message, check if it's within limits. If it's not, the * NT Behaviour is to set this to the Maximum API. */ if (ReceiveMsg.ApiNumber > SbpMaxApiNumber) { ReceiveMsg.ApiNumber = SbpMaxApiNumber; DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber); } /* Reuse the message */ ReplyMsg = &ReceiveMsg; /* Make sure that the message is supported */ if (ReceiveMsg.ApiNumber < SbpMaxApiNumber) { /* Call the API */ if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg)) { /* It failed, so return nothing */ ReplyMsg = NULL; } } else { /* We don't support this API Number */ ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED; } } }
NTSTATUS CsrSbApiRequestThread( IN PVOID Parameter ) { NTSTATUS Status; SBAPIMSG ReceiveMsg; PSBAPIMSG ReplyMsg; ReplyMsg = NULL; while (TRUE) { IF_CSR_DEBUG( LPC ) { DbgPrint( "CSRSS: Sb Api Request Thread waiting...\n" ); } Status = NtReplyWaitReceivePort( CsrSbApiPort, NULL, (PPORT_MESSAGE)ReplyMsg, (PPORT_MESSAGE)&ReceiveMsg ); if (Status != 0) { if (NT_SUCCESS( Status )) { continue; // Try again if alerted or a failure } else { IF_DEBUG { DbgPrint( "CSRSS: ReceivePort failed - Status == %X\n", Status ); } break; } } // // Check to see if this is a connection request and handle // if (ReceiveMsg.h.u2.s2.Type == LPC_CONNECTION_REQUEST) { CsrSbApiHandleConnectionRequest( &ReceiveMsg ); ReplyMsg = NULL; continue; } if ((ULONG)ReceiveMsg.ApiNumber >= SbMaxApiNumber) { IF_DEBUG { DbgPrint( "CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber ); } ReceiveMsg.ApiNumber = SbMaxApiNumber; } #if DBG IF_CSR_DEBUG( LPC ) { DbgPrint( "CSRSS: %s Sb Api Request received from %lx.%lx\n", CsrServerSbApiName[ ReceiveMsg.ApiNumber ], ReceiveMsg.h.ClientId.UniqueProcess, ReceiveMsg.h.ClientId.UniqueThread ); } #endif // DBG ReplyMsg = &ReceiveMsg; if (ReceiveMsg.ApiNumber < SbMaxApiNumber) { if (!(*CsrServerSbApiDispatch[ ReceiveMsg.ApiNumber ])( &ReceiveMsg )) { ReplyMsg = NULL; } } else { ReplyMsg->ReturnedStatus = STATUS_NOT_IMPLEMENTED; } #if DBG IF_CSR_DEBUG( LPC ) { if (ReplyMsg != NULL) { DbgPrint( "CSRSS: %s Sb Api sending %lx status reply to %lx.%lx\n", CsrServerSbApiName[ ReceiveMsg.ApiNumber ], ReplyMsg->ReturnedStatus, ReplyMsg->h.ClientId.UniqueProcess, ReplyMsg->h.ClientId.UniqueThread ); } } #endif // DBG }