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

;************************************************************************
;
; Source File Name:	SMRSELSE.ASM
;
; Subroutine Name:	DOSSELECTSESSION
;
; Descriptive Name:	Application switch API
;
; Function:	Allow an application to switch a child session to the
;		foreground.
;
; Notes:
;	Dependencies:	None
;
;	Restrictions:	None
;
;     Change History:
;	@TL7 - 04/05/90 - PTR B712376 - Enable for MMIO
;	@MHW - 09/13/90 - PTR B715818 - In-line performance (MMIO) hooks
;
; Entry Point:
;	Linkage:  EXTRN DOSSELECTSESSION:FAR
;			PUSH	WORD   SessionID  ; Session Number
;			PUSH	DWORD  Reserved	  ; Reserved
;			CALL	DOSSELECTSESSION
; Inputs:
;	WORD	SessionID  Session Number
;	DWORD	Reserved   Reserve a double word on stack for
;			   future use
;
; Exit Normal:
;	AX	ReturnCode Value = 0, Session switch successful
;
; Exit Errors:
;	AX	ReturnCode error_smg_bad_reserve
;			   error_smg_invalid_call
;			   error_smg_invalid_session_id
;			   error_smg_process_not_parent
;			   error_smg_retry_sub_alloc
;
;			   REQUESTBLOCKALOC errors
;			   APPSENDREQUEST   errors
;
; Effects:	All other registers preserved.
;
; Internal References:
;	   Data:	reqblock (SMRREQB.INC)
;	   Routines:	REQUESTBLOCKALOC
;			APPSENDREQUEST
;
; External References:
;	   Routines:
;
;************************************************************************
ifdef I1
;
;   IF (selreserved e 0)
;      IF (request session ID ne current sgid)
;	  REQUESTBLOCKALOC (Allocate req. block and init header)
;	  IF (No_Error)
;	     IF (SessionID from stack e 0)
;		SessionID = reqsessionid
;	     ENDIF
;	     Move select request type into request block header
;	     Move user supplied parms into queue element
;	     APPSENDREQUEST (Write the queue element)
;	  ENDIF
;      ELSE
;	  RC = Error_SMG_Invalid_Session_ID
;      ENDIF
;   ELSE
;     RC = Error_SMG_Bad_Reserve
;   ENDIF
;
;************************************************************************
else

.386C
    EXTRN LocalSelector	   : WORD	; @ of Local Selector

    EXTRN APPSENDREQUEST   : NEAR	; Send Shell application request
    EXTRN REQUESTBLOCKALOC : NEAR	; Allocate app request block
.xlist
    INCLUDE SMRREQB.INC
    INCLUDE SMRSELSE.INC
    INCLUDE SMMMPHA.INC			; Performance hook macros	;MHW
.xcref
    INCLUDE ERROR2.INC
    INCLUDE INFOSEG.INC
    INCLUDE SMRRDATA.INC
    INCLUDE STRUC.INC
.cref
.list

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

    PUBLIC DOSSELECTSESSION
    PUBLIC DOSSELECTSESSION_POSTDT	; Dynamic Trace Label
DOSSELECTSESSION PROC FAR

    Local_Bytes	 EQU  0

    ENTER Local_Bytes,0
    PUSHA
    PUSH DS
    PUSH ES
    PUSH FS
    PUSH GS

    MMPHPreDOSSelectSession		; Performance Hook (800Ch)	;MHW

    .IF	 < <WORD PTR SS:[BP].SelReserved[0]> eq Null > AND NEAR ; Check reserved
    .IF	 < <WORD PTR SS:[BP].SelReserved[2]> eq Null >	NEAR ; Check reserved
      MOV  AX, RDATA
      MOV  DS, AX
      MOV  GS, DS:LocalSelector

      MOV  AX, SS:[BP].SelSessionID
      XOR  AH, AH			    ; Use only session id
      .IF  < AX ne GS:LIS_CurScrnGrp > NEAR ; Cannot sel self explicitly

;	**************************************************************
;	* Sub-allocate the request block in the queue request seg.   *
;	* Inputs:						     *
;	*	AX - Start Related Child Request Flag = 0.	     *
;	*	BX - Reqbsize	Size of request block to allocate    *
;	* Exit Normal:						     *
;	*	AX - ReturnCode Value = 0, Request block allocated   *
;	*	GS - LocalSel	Local information selector	     *
;	*	FS - INSTANCE	Instance Data Segment		     *
;	*	GS - LocalSel	Local information selector	     *
;	*	ES:DI - ReqBlock   Offset to the request block	     *
;	**************************************************************
	XOR  AX, AX			; Specify this is not a start related
	MOV  BX, SelectReqBSize		; # of bytes to sub-allocate
	CALL REQUESTBLOCKALOC		; DS:DI --> New Request Block
					; GS	--> LDT

	.IF  < zero AX >						;CJ10
;	  ***************************************************
;	  *  Fill in request block with user supplied data  *
;	  ***************************************************
	  MOV  AX, SS:[BP].SelSessionID

;	  *************************************
;	  *  If session id = 0, then make it  *
;	  *  the requesting session's id.     *
;	  *************************************
	  .IF  < zero AX >						;CJ10
	    MOV	 AX, ES:[DI].ReqSessionID ; Get requesting SID from Req Blk hdr
	  .ENDIF			  ; End selsessionid test

	  MOV  ES:[DI].RqSwtSessionID, AX
	  MOV  ES:[DI].RqSwtLength, SelectReqBSize - RB_Head_Len_Equ
	  MOV  ES:[DI].ReqType, App_Select ; Specify Select Session
	  CALL APPSENDREQUEST
	.ENDIF				; End error check from REQUESTBLOCKALOC
      .ELSE				; Trying to sel. self explicitly
	MOV  AX, Error_SMG_Invalid_Session_ID
      .ENDIF
    .ELSE				; Bad reserved DWORD
      MOV  AX, Error_SMG_Bad_Reserve
    .ENDIF

    MOV	 AX_Reg[-Local_Bytes], AX	; Save AX on stack for RASTRACE

    MMPHPostDOSSelectSession		; Performance Hook (808Ch)	;MHW

    POP	 GS
    POP	 FS
    POP	 ES
    POP	 DS
    POPA

    LEAVE
    DOSSELECTSESSION_POSTDT LABEL FAR  ; Dynamic Trace Label
    RET	 selseslen

DOSSELECTSESSION ENDP

CODE ENDS
endif
    END
