;       SCCSID = @(#)smrapsrv.asm	6.1 90/11/18
;	SCCSID @(#)smrapsrv.asm	6.5 90/05/18
PAGE 60,132    ;
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************

;************************************************************************
;
; Source File Name:	SMRAPSRV.ASM
;
; Subroutine Name:	DOSSMSERVEAPPREQ
;
; Descriptive Name:	Service Application Session Requests
;
; Function:	Services an application request to start, switch,
;		terminate, or set a session.
;
; Notes:
;	Dependencies:	None
;
;	Restrictions:	Only the Shell can call this procedure.
;			Once this call is issued by the Shell,
;			DOSSMGETAPPREQ and DOSSMDOAPPREQ are
;			invalid calls.
;
;	Change History:
;
; Entry Point:
;	Linkage:  EXTRN DOSSMSERVEAPPREQ:FAR
;			CALL	DOSSMSERVEAPPREQ
; Inputs:
;	None
;
; Exit Normal:
;	None
;
; Exit Errors:
;	AX	ReturnCode error_smg_bad_action
;			   error_smg_bad_reserve
;			   error_smg_bad_statusreq
;			   error_smg_invalid_call
;			   error_smg_invalid_session_id
;			   error_smg_invalid_start_mode
;			   error_smg_no_sessions
;			   error_smg_not_baseshell
;			   error_smg_session_not_bound
;			   error_smg_session_not_foregrnd
;			   error_smg_session_not_found
;			   error_smg_session_not_parent
;
;			   DOSSMGETAPPREQ errors
;			   DOSSMDOAPPREQ  errors
;
; Effects:	All other registers preserved.
;
; Internal References:
;	   Data:	RDATA - common data segment
;				ShellPid - Shell process ID (DOSSMINITIALIZE)
;				serviceappthd - 1st thread to call SERVEAPPREQ
;	   Routines:	DOSSMDOAPPREQ
;			DOSSMGETAPPREQ
;
; External References:
;	   Data:	Local information segment (LIS_CurProcID,
;			LIS_CurThrdID)
;	   Routines:
;
;************************************************************************
ifdef I1
;
;   IF (Caller is Shell)
;      IF (serviceappthd e 0)
;	  serviceappthd = LIS_CurThrdID
;	  REPEAT
;	     DOSSMGETAPPREQ (Get application request block)
;	     IF (No_Error)
;		DOSSMDOAPPREQ (Process application request block)
;	     ELSE
;	       IF (Process_Terminated)
;		 LEAVE
;	       ENDIF
;	     ENDIF
;	  UNTIL (forever)
;	  serviceappthd = 0
;      ELSE
;	  RC = Error_SMG_Invalid_Call
;      ENDIF
;   ELSE
;      RC = Error_SMG_Not_BaseShell
;   ENDIF
;
;************************************************************************
else

.386C
    EXTRN LocalSelector    : WORD	; Selector to LDT
    EXTRN ServiceAppThd    : WORD	; Service app req. thread ID
    EXTRN ShellPID	   : WORD	; Shell ID
    EXTRN ReqBlock	   : DWORD	; Application request block addr

    EXTRN DOSSMDOAPPREQ    : FAR	; Process application request
    EXTRN DOSSMGETAPPREQ   : FAR	; Get application request block
.xlist
    INCLUDE SMRREQB.INC 		; Request block definitions
.xcref
    INCLUDE ERROR2.INC			; Error code equates
    INCLUDE INFOSEG.INC 		; Information segment definitions
    INCLUDE SMRRDATA.INC		; Router data declarations
    INCLUDE STRUC.INC
.cref
.list


CODE SEGMENT WORD PUBLIC 'CODE' USE16
    ASSUME CS:CODE,DS:NOTHING,SS:NOTHING,ES:NOTHING

    PUBLIC DOSSMSERVEAPPREQ
DOSSMSERVEAPPREQ PROC FAR

    ENTER 0,0
    PUSH ES
    PUSH DS
;   PUSH DI								;CJ10

;   **********************************************************
;   *  Retrieve and save threadid. DOSSMGETAPPREQ calls are  *
;   *  disallowed from all other shell threads from now on.  *
;   **********************************************************
    MOV  AX, RDATA			; Addressability to global data
    MOV  DS, AX

    MOV  AX, LocalSelector		; @ of LDT
    MOV  ES, AX

    MOV  AX, ShellPid
    .IF  < ES:LIS_CurProcID eq AX > NEAR

      .IF  < DS:ServiceAppThd eq No >	; DOSSMSERVEAPPREQ not called yet
;	**********************************************
;	*  Save Current Thread ID for future use so  *
;	*  that only THIS thread can service apps.   *
;	**********************************************
	MOV  AX, ES:LIS_CurThrdID	; Get service app thread id
	MOV  DS:ServiceAppThd, AX	; No other thread can call get app

;	***********************************
;	*  Get application request block  *
;	***********************************
	.REPEAT 			; Repeat forever, unless error occurs
	  PUSH DS
	  PUSH OFFSET ReqBlock		; Address of the request block with
	  CALL DOSSMGETAPPREQ		; which we are working
	  .IF  < zero AX >						;CJ10
;	    ***************************************
;	    *  Process application request block  *
;	    ***************************************
	    PUSH DWORD PTR DS:ReqBlock					;CJ10
;CJ10	    PUSH ES
;CJ10	    PUSH DI
	    CALL DOSSMDOAPPREQ

	  .ELSE 			; Some error occured
;	    **********************************************************
;	    *  DOSSMDOAPPREQ will check a termination flag in the    *
;	    *  request block, and set AX = DEAD if it is set.  If    *
;	    *  this occurs, just ignore the request block, and read  *
;	    *  the next one.					     *
;	    **********************************************************
	    .IF  < AX ne 0DEADH >	; See if error caused by dead process
	    .LEAVE			; If not, then leave & go home
	    .ENDIF
	  .ENDIF			; End Error check
	.UNTIL				; Until loop ends because of error

;	******************************************
;	*  Notify the shell that a severe error  *
;	*  occurred during DOSSMGETAPPREQ	 *
;	******************************************
	MOV  DS:ServiceAppThd, No	; Allow other threads to call get app

      .ELSE				; SMRAPSRV already started
	MOV  AX, Error_SMG_Invalid_Call ; Thread not allowed
      .ENDIF				; SMRAPSRV started test
    .ELSE				; Not shell thread
      MOV  AX, Error_SMG_Not_Baseshell	; Not base shell calling
    .ENDIF				; Check for shell

;   POP  DI								;CJ10
    POP  DS				; Restore registers
    POP  ES

    LEAVE
    RET

DOSSMSERVEAPPREQ ENDP

CODE ENDS
endif
    END
