示例#1
0
文件: smloop.c 项目: mingpen/OpenNT
NTSTATUS
SmpApiLoop (
    IN PVOID ThreadParameter
    )

/*++

Routine Description:

    This is the main Session Manager API Loop. It
    services session manager API requests.

Arguments:

    ThreadParameter - Supplies a handle to the API port used
        to receive session manager API requests.

Return Value:

    None.

--*/

{
    PSMAPIMSG SmApiReplyMsg;
    SMMESSAGE_SIZE MsgBuf;

    PSMAPIMSG SmApiMsg;
    NTSTATUS Status;
    HANDLE ConnectionPort;
    PSMP_CLIENT_CONTEXT ClientContext;
    PSMPKNOWNSUBSYS KnownSubSys;


    ConnectionPort = (HANDLE) ThreadParameter;

    SmApiMsg = (PSMAPIMSG)&MsgBuf;
    SmApiReplyMsg = NULL;
    try {
        for(;;) {

            Status = NtReplyWaitReceivePort(
                        ConnectionPort,
                        (PVOID *) &ClientContext,
                        (PPORT_MESSAGE) SmApiReplyMsg,
                        (PPORT_MESSAGE) SmApiMsg
                        );
            if ( !NT_SUCCESS(Status) ) {
                SmApiReplyMsg = NULL;
                continue;
            } else if ( SmApiMsg->h.u2.s2.Type == LPC_CONNECTION_REQUEST ) {
                SmpHandleConnectionRequest( ConnectionPort,
                                            (PSBAPIMSG) SmApiMsg
                                          );
                SmApiReplyMsg = NULL;
            } else if ( SmApiMsg->h.u2.s2.Type == LPC_DEBUG_EVENT ) {
                ASSERT(SmpDbgSsLoaded);
                DbgSsHandleKmApiMsg((PDBGKM_APIMSG)SmApiMsg,NULL);
                SmApiReplyMsg = NULL;
            } else if ( SmApiMsg->h.u2.s2.Type == LPC_PORT_CLOSED ) {
                SmApiReplyMsg = NULL;
            } else {
                KnownSubSys = ClientContext->KnownSubSys;

                SmApiMsg->ReturnedStatus = STATUS_PENDING;

#if DBG && 0
                if (SmApiMsg->ApiNumber >= SmMaxApiNumber ) {
                    SmApiMsg->ApiNumber = SmMaxApiNumber;
                }
                KdPrint(( "SMSS: %s Api Request received from %lx.%lx\n",
                          SmpApiName[ SmApiMsg->ApiNumber ],
                          SmApiMsg->h.ClientId.UniqueProcess,
                          SmApiMsg->h.ClientId.UniqueThread
                       ));
#endif // DBG

                if (SmApiMsg->ApiNumber >= SmMaxApiNumber ) {

                    Status = STATUS_NOT_IMPLEMENTED;

                } else {

                    switch (SmApiMsg->ApiNumber) {
                        case SmExecPgmApi :
                            Status = (SmpApiDispatch[SmApiMsg->ApiNumber])(
                                          SmApiMsg,
                                          ClientContext,
                                          ConnectionPort);
                            break;

                        case SmLoadDeferedSubsystemApi :
                            Status = (SmpApiDispatch[SmApiMsg->ApiNumber])(
                                          SmApiMsg,
                                          ClientContext,
                                          ConnectionPort);
                            break;


                        case SmCreateForeignSessionApi :
                        case SmSessionCompleteApi :
                        case SmTerminateForeignSessionApi :
                            if (!KnownSubSys) {
                                Status = STATUS_INVALID_PARAMETER;
                            } else {

                                Status =
                                    (SmpApiDispatch[SmApiMsg->ApiNumber])(
                                         SmApiMsg,
                                         ClientContext,
                                         ConnectionPort);
                            }
                            break;

                    }

                }

                SmApiMsg->ReturnedStatus = Status;
                SmApiReplyMsg = SmApiMsg;
            }
        }
    } except (DbgpUnhandledExceptionFilter( GetExceptionInformation() )) {
        ;
    }

    //
    // Make the compiler happy
    //

    return STATUS_UNSUCCESSFUL;
}
示例#2
0
文件: smloop.c 项目: Strongc/reactos
ULONG
NTAPI
SmpApiLoop(IN PVOID Parameter)
{
    HANDLE SmApiPort = (HANDLE)Parameter;
    NTSTATUS Status;
    PSMP_CLIENT_CONTEXT ClientContext;
    PSM_API_MSG ReplyMsg = NULL;
    SM_API_MSG RequestMsg;
    PROCESS_BASIC_INFORMATION ProcessInformation;
    LARGE_INTEGER Timeout;

    /* Increase the number of API threads for throttling code for later */
    _InterlockedExchangeAdd(&SmTotalApiThreads, 1);

    /* Mark us critical */
    RtlSetThreadIsCritical(TRUE, NULL, TRUE);

    /* Set the PID of the SM process itself for later checking */
    NtQueryInformationProcess(NtCurrentProcess(),
                              ProcessBasicInformation,
                              &ProcessInformation,
                              sizeof(ProcessInformation),
                              NULL);
    SmUniqueProcessId = (HANDLE)ProcessInformation.UniqueProcessId;

    /* Now process incoming messages */
    while (TRUE)
    {
        /* Begin waiting on a request */
        Status = NtReplyWaitReceivePort(SmApiPort,
                                        (PVOID*)&ClientContext,
                                        &ReplyMsg->h,
                                        &RequestMsg.h);
        if (Status == STATUS_NO_MEMORY)
        {
            /* Ran out of memory, so do a little timeout and try again */
            if (ReplyMsg) DPRINT1("SMSS: Failed to reply to calling thread, retrying.\n");
            Timeout.QuadPart = -50000000;
            NtDelayExecution(FALSE, &Timeout);
            continue;
        }

        /* Check what kind of request we received */
        switch (RequestMsg.h.u2.s2.Type)
        {
            /* A new connection */
            case LPC_CONNECTION_REQUEST:
                /* Create the right structures for it */
                SmpHandleConnectionRequest(SmApiPort, (PSB_API_MSG)&RequestMsg);
                ReplyMsg =  NULL;
                break;

            /* A closed connection */
            case LPC_PORT_CLOSED:
                /* Destroy any state we had for this client */
                DPRINT1("Port closed\n");
                //if (ClientContext) SmpPushDeferredClientContext(ClientContext);
                ReplyMsg = NULL;
                break;

            /* An actual API message */
            default:
                if (!ClientContext)
                {
                    ReplyMsg = NULL;
                    break;
                }

                RequestMsg.ReturnValue = STATUS_PENDING;

                /* Check if the API is valid */
                if (RequestMsg.ApiNumber >= SmpMaxApiNumber)
                {
                    /* It isn't, fail */
                    DPRINT1("Invalid API: %lx\n", RequestMsg.ApiNumber);
                    Status = STATUS_NOT_IMPLEMENTED;
                }
                else if ((RequestMsg.ApiNumber <= SmpTerminateForeignSessionApi) &&
                         !(ClientContext->Subsystem))
                {
                    /* It's valid, but doesn't have a subsystem with it */
                    DPRINT1("Invalid session API\n");
                    Status = STATUS_INVALID_PARAMETER;
                }
                else
                {
                    /* It's totally okay, so call the dispatcher for it */
                    Status = SmpApiDispatch[RequestMsg.ApiNumber](&RequestMsg,
                                                                  ClientContext,
                                                                  SmApiPort);
                }

                /* Write the result valud and return the message back */
                RequestMsg.ReturnValue = Status;
                ReplyMsg = &RequestMsg;
                break;
        }
    }
    return STATUS_SUCCESS;
}