ANSC_STATUS
ScliShoBufferCmd
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hSrvSession,
        ULONG                       ulCmdCode,
        PUCHAR                      pCmd
    )
{
    PSCLI_SHELL_OBJECT              pMyObject           = (PSCLI_SHELL_OBJECT  )hThisObject;
    PSCLI_SHELL_PROPERTY            pProperty           = (PSCLI_SHELL_PROPERTY)&pMyObject->Property;
    PSCLI_SHELL_BUFFERED_CMD_LIST   pBufferedCmdArray;
    PSCLI_SHELL_SESSION_EXEC        pSession;

    /* we allow empty string to be cached to support cases like user just 
     * hits ENTER to accept default value and so on 
     */
    /*
    if ( !pCmd || AnscSizeOfString( pCmd ) == 0 )
    {
        return ANSC_STATUS_SUCCESS;
    }
    */

    pSession    = (PSCLI_SHELL_SESSION_EXEC)pMyObject->GetSession((ANSC_HANDLE)pMyObject, (ULONG)hSrvSession);

    pBufferedCmdArray   = &pSession->BufferedCmd;

    if ( pBufferedCmdArray->ulCount >= pBufferedCmdArray->ulSize )
    {
        AnscReleaseLock(&pSession->AccessLock);
        return ANSC_STATUS_RESOURCES;
    }

    pBufferedCmdArray->pCmds[pBufferedCmdArray->ulCount].pCmd      = pCmd ? AnscCloneString(pCmd) : NULL;
    pBufferedCmdArray->pCmds[pBufferedCmdArray->ulCount].ulCmdCode = ulCmdCode;

    pBufferedCmdArray->ulCount ++;

    if ( pSession->hActiveTextBox || pSession->bWaitInput )
    {
        AnscSetEvent(&pSession->InputEvent);
    }

    return ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
ScliShoCenNotify
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hExecEnv,
        ULONG                       CenEvent
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PSCLI_SHELL_OBJECT              pMyObject    = (PSCLI_SHELL_OBJECT       )hThisObject;
    PSCLI_SHELL_EXEC_ENV            pScliExecEnv = (PSCLI_SHELL_EXEC_ENV     )hExecEnv;
    PTELNET_CMD_EXECUTION_ENV       pTelnetEnv   = (PTELNET_CMD_EXECUTION_ENV)pScliExecEnv->hTelnetEnv;
    PTELNET_TSC_INTERFACE           pTscIf       = (PTELNET_TSC_INTERFACE    )pTelnetEnv->hTscIf;
    ANSC_HANDLE                     hSrvSession  = pScliExecEnv->hSession;
    PSCLI_SHELL_SESSION_EXEC        pSession;

    pSession    = (PSCLI_SHELL_SESSION_EXEC)pMyObject->GetSession((ANSC_HANDLE)pMyObject, (ULONG)hSrvSession);

    switch ( CenEvent )
    {
        case    SCLI_SHELL_CEN_EVENT_CmdBegin:

                pSession->bServing  = TRUE;

                pTscIf->Notify
                    (
                        pTscIf->hOwnerContext,
                        hSrvSession,
                        TELNET_TSC_EVENT_CmdBegin,
                        (ANSC_HANDLE)NULL
                    );

                break;

        case    SCLI_SHELL_CEN_EVENT_CmdEnd:

                if ( pSession->SessionState == SCLI_SHELL_STATE_LOGGED_IN && !pSession->bWillExit )
                {
                    pTscIf->SendShellPrompt
                        (
                            pTscIf->hOwnerContext,
                            hSrvSession,
                            TRUE
                        );
                }

                pTscIf->Notify
                    (
                        pTscIf->hOwnerContext,
                        hSrvSession,
                        TELNET_TSC_EVENT_CmdEnd,
                        (ANSC_HANDLE)NULL
                    );

                pSession->bServing  = FALSE;

                if ( pSession->bWillExit )
                {
                    returnStatus =
                        pMyObject->RunBuiltInCmd
                            (
                                (ANSC_HANDLE)pMyObject,
                                hSrvSession,
                                (ANSC_HANDLE)pTelnetEnv,
                                SCLI_SHELL_BICODE_Exit
                            );
                }
                else
                {
                    returnStatus =
                        pMyObject->DoBufferedCommands
                            (
                                (ANSC_HANDLE)pMyObject,
                                hSrvSession,
                                hExecEnv
                            );
                }

                break;
    }

    return returnStatus;
}
ANSC_STATUS
ScliShoDoBufferedCommands
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hSrvSession,
        ANSC_HANDLE                 hExecEnv
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PSCLI_SHELL_OBJECT              pMyObject    = (PSCLI_SHELL_OBJECT       )hThisObject;
    PSCLI_SHELL_PROPERTY            pProperty    = (PSCLI_SHELL_PROPERTY     )&pMyObject->Property;
    PSCLI_SHELL_EXEC_ENV            pScliExecEnv = (PSCLI_SHELL_EXEC_ENV     )hExecEnv;
    PTELNET_CMD_EXECUTION_ENV       pTelnetEnv   = (PTELNET_CMD_EXECUTION_ENV)pScliExecEnv->hTelnetEnv;
    PTELNET_TSC_INTERFACE           pTscIf       = (PTELNET_TSC_INTERFACE    )pTelnetEnv->hTscIf;
    PSCLI_SHELL_SESSION_EXEC        pSession;
    BOOL                            bCmdAvailable;
    PSCLI_SHELL_BUFFERED_CMD_LIST   pBufferedCmdArray; 

    pSession    = (PSCLI_SHELL_SESSION_EXEC)pMyObject->GetSession((ANSC_HANDLE)pMyObject, (ULONG)hSrvSession);
    
    if ( !pSession )
    {
        return ANSC_STATUS_RESOURCES;
    }

    pBufferedCmdArray   = &pSession->BufferedCmd;

    if ( TRUE )
    {
        AnscAcquireLock(&pSession->AccessLock);
        bCmdAvailable   = ( pBufferedCmdArray->ulCount != 0 );
        AnscReleaseLock(&pSession->AccessLock);

        if ( bCmdAvailable )
        {
            returnStatus =
                pMyObject->RunCmd
                    (
                        (ANSC_HANDLE)pMyObject,
                        hSrvSession,
                        (ANSC_HANDLE)pTelnetEnv
                    );
        }
        else
        {
            AnscAcquireLock(&pSession->AccessLock);
            
            if ( pSession->CommandLen != 0 )
            {
                returnStatus = 
                    pTscIf->Output
                        (
                            pTscIf->hOwnerContext,
                            hSrvSession,
                            pSession->Command,
                            pSession->CommandLen
                        );
            }

            AnscReleaseLock(&pSession->AccessLock);
        }
    }

    return ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
ScliShoGetBufferedCmd
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hSrvSession,
        PULONG                      pulCmdCode,
        PUCHAR                      *ppCmd
    )
{
    ANSC_STATUS                     returnStatus        = ANSC_STATUS_SUCCESS;
    PSCLI_SHELL_OBJECT              pMyObject           = (PSCLI_SHELL_OBJECT  )hThisObject;
    PSCLI_SHELL_PROPERTY            pProperty           = (PSCLI_SHELL_PROPERTY)&pMyObject->Property;
    PSCLI_SHELL_BUFFERED_CMD_LIST   pBufferedCmdArray;
    PSCLI_SHELL_SESSION_EXEC        pSession;
    PSCLI_SHELL_BUFFERED_CMD        pCmd                = NULL;
    ULONG                           i;

    pSession    = (PSCLI_SHELL_SESSION_EXEC)pMyObject->GetSession((ANSC_HANDLE)pMyObject, (ULONG)hSrvSession);

    AnscAcquireLock(&pSession->AccessLock);

    pBufferedCmdArray   = &pSession->BufferedCmd;

    if ( pulCmdCode )
    {
        *pulCmdCode = pCmd ? pCmd->ulCmdCode : SCLI_SHELL_BICODE_Unrecognized;
    }

    if ( ppCmd )
    {
        *ppCmd  = NULL;
    }

    if ( pBufferedCmdArray->ulCount != 0 )
    {
        pCmd    = &pBufferedCmdArray->pCmds[0];

		if ( pulCmdCode )
		{
			*pulCmdCode = pCmd->ulCmdCode;
		}

		if ( ppCmd )
		{
			*ppCmd  = pCmd->pCmd;
		}

        for (i = 1; i < pBufferedCmdArray->ulCount; i ++)
        {
            pBufferedCmdArray->pCmds[i - 1] = pBufferedCmdArray->pCmds[i];
        }

        pBufferedCmdArray->ulCount --;
    }
    else
    {
        returnStatus = ANSC_STATUS_PENDING;
    }

    AnscReleaseLock(&pSession->AccessLock);

    return returnStatus;
}