;       SCCSID = @(#)smrapdor.asm       6.3 91/12/06
PAGE 60,132    ;
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************

;************************************************************************
;
; Source File Name:     SMRAPDOR.ASM
;
; Subroutine Name:      DOSSMDOAPPREQ
;
; Descriptive Name:     Process an Application Session Request
;
; Function:     Verify the application request is valid and that the
;               requesting process is the parent of the target session.
;               When the above conditions are met, call the appropriate
;               procedure to process the start, select, stop, or set
;               request block. If a start or set request made with the
;               Shell in the foreground, notify the Shell to redraw the
;               switch list.
;
; Notes:
;       Dependencies:   None
;
;       Restrictions:   None
;
;     Change History:
;       @TL7 - 04/05/90 - PTR B712376 - Enable for MMIO
;       @D998  06/21/90 - DCR 998 - Swaptuning, moved DosSMBaseShell from
;                         smrapdor.asm to smgsgswt.asm.
;       @MHW   09/13/90   PTR B715818 - In-line performance (MMIO) hooks
;       @GDW   08/26/91   PTR B725436 Fix to allow semaphore loop on INTERUPT
;       CJ47   12/06/91  PTR B730582  Co-req for PM20 SM05650.
;       MDLL   01/10/94  BJN Page Tune segments for Merged DLL.
;
; Entry Point:
;       Linkage:  EXTRN DOSSMDOAPPREQ:FAR
;                       PUSH    DWORD  ReqBlock   ; Request Block Addr.
;                       CALL    DOSSMDOAPPREQ
; Inputs:
;       DWORD   ReqBlock   Address to an application request block.
;
; Exit Normal:
;       AX      ReturnCode Value=0, application request successful
;
; Exit Errors:
;       AX      ReturnCode error_smg_bad_action
;                          error_smg_bad_reserve
;                          error_smg_bad_statusreq
;                          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
;
;                          APPSELECTSESSION errors
;                          APPSETSESSION    errors
;                          APPSTARTSESSION  errors
;                          APPSTOPSESSION   errors
;                          DOSSEMREQUEST    errors
;                          SESSIONRELATED   errors
;
; Effects:      All other registers preserved.
;
; Internal References:
;          Data:        RDATA - Common data segment
;                               smroutsem - Shell/Application synchronization
;                               shellredrawsem - Redraw notify semaphore
;                               statusindex table (See SMRQSTAT.ASM)
;                       SESDATA - Commom segment with active session data
;                                 returned from DOSSMGETSTATUS (GETQSTATUS)
;                       QDATA - Common data segment
;                                reqblock (SMRREQB.INC)
;          Routines:    GETQSTATUS
;                       SESSIONRELATED
;                       APPSTARTSESSION
;                       APPSELECTSESSION
;                       APPSTOPSESSION
;                       APPSETSESSION
;
; External References:
;          Data:        Local information segment (LIS_CurProcID, LIS_CurThrdID)
;          Routines:    DOSSEMREQUEST
;                       DOSSEMCLEAR
;                       DOSSEMSET
;
;************************************************************************
ifdef I1
;
;  IF (Caller is Shell)
;    DOSFSRAMSEMREQUEST (Wait for SMG router semaphore)
;    IF (No_Error)
;      IF (Valid request)
;        IF (Not a start request)
;          IF (Child session e 1) OR
;          IF (Child session ae first available session) AND
;          IF (Child session b maxsessions)
;            SESSIONRELATED (Check for relatedness)
;          ELSE
;            RC = Error_SMG_Invalid_Session_ID
;          ENDIF
;        ENDIF
;        IF (No_Error)
;          IF (Start session request)
;            APPSTARTSESSION (Spawn new session)
;          ELSEIF (Switch request)
;            APPSELECTSESSION (Switch session)
;          ELSEIF (Set request)
;            APPSETSESSION (Set session)
;          ELSEIF (Terminate request)
;            APPSTOPSESSION (Terminate session)
;          ENDIF
;          IF (Shell is foreground)   AND
;          IF (Start session request) OR
;          IF (Set session request)   AND
;          IF (Selectibility changed)
;             DOSSEMCLEAR (Release redraw semaphore)
;             DOSSEMSET (Set redraw semaphore)
;          ENDIF
;        ENDIF
;        DOSSEMCLEAR (Release req_synchrosem for parent exit)
;        DOSSEMCLEAR (Release request block semaphore)
;      ELSE
;        RC = Error_SMG_Bad_Action
;      ENDIF
;    ENDIF
;     DOSFSRAMSEMCLEAR (Release SMG router semaphore)
;  ELSE
;     RC = Error_SMG_Bot_BaseShell
;  ENDIF
;
;************************************************************************
else

.386C
    EXTRN LocalSelector      : WORD     ; Selector to LDT
    EXTRN DetSession         : BYTE     ; Detach screen group number
    EXTRN ShellRedrawSem     : WORD     ; Shell redraw notify semaphore
    EXTRN ShellPID           : WORD     ; Shell ID
    EXTRN SMRoutSem          : BYTE     ; Shell/application synchronization sem
    EXTRN TopMost            : DWORD
    EXTRN BaseShell          : DWORD
    EXTRN SGCB_ArraySize     : DWORD    ; Maximum # of Sessions

    EXTRN APPSETSESSION      : NEAR     ; Process app. set request
    EXTRN APPSELECTSESSION   : NEAR     ; Process app. select request
    EXTRN APPSTARTSESSION    : NEAR     ; Process app. start request
    EXTRN APPSTOPSESSION     : NEAR     ; Process app. stop request
    EXTRN SESSIONRELATED     : NEAR     ; Verify sessions related
    EXTRN DOSSEMCLEAR        : FAR      ; App. request processed
    EXTRN DOSSEMSET          : FAR      ; Reset notify semaphore
    EXTRN DOSSEMREQUEST      : FAR      ; Synchronize shell/API calls
    EXTRN DOSFSRAMSEMREQUEST : FAR      ; Synchronize shell/API calls
    EXTRN DOSFSRAMSEMCLEAR   : FAR      ; Synchronize shell/API calls
.xlist
    INCLUDE SMRAPGET.INC                ; Stack fram definition
    INCLUDE SMRREQB.INC                 ; Application request block definitions
    INCLUDE SMMMPHA.INC                 ; Performance hook macros       ;MHW
.xcref
    INCLUDE INFOSEG.INC                 ; GDT & LDT structures
    INCLUDE SMRRDATA.INC                ; Router common data segment
    INCLUDE STRUC.INC
    INCLUDE ERROR2.INC                  ; Error code equates
.cref
.list


CODE_TUNE1 SEGMENT WORD PUBLIC 'CODE' USE16                             ;MDLL
    ASSUME CS:CODE_TUNE1,DS:RDATA,SS:NOTHING,ES:NOTHING                 ;MDLL

    PUBLIC DOSSMDOAPPREQ
    PUBLIC DOSSMDOAPPREQ_POSTDT
DOSSMDOAPPREQ PROC FAR

    Local_Bytes  EQU  0

    ENTER Local_Bytes,0
    PUSHA                               ; Save registers
    PUSH DS
    PUSH ES
    PUSH FS
    PUSH GS

    MMPHPreDOSSMDoAppReq                ; Performance Hook (8011h)      ;MHW

    MOV  AX, RDATA                      ; Addressability to global data
    MOV  DS, AX

    MOV  ES, LocalSelector              ; @ of LDT

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

;     **********************************************************
;     * Sychronize Shell/Application Session Manager API calls *
;     **********************************************************
      .repeat                                                           ;@GDW
        PUSH DS                         ; SMG router RAM semaphore
        PUSH OFFSET SMRoutSem
        PUSH DWORD PTR -1               ; Wait Forever                  ;CJ10
;CJ10   PUSH -1
        CALL DOSFSRAMSEMREQUEST
      .until  <ax ne ERROR_INTERRUPT>                                   ;@GDW

      .IF  < zero AX > NEAR                                             ;CJ10
;       ******************************************************
;       *  Make ES:DI point to request block                 *
;       ******************************************************
        LES  DI, SS:[BP].GetReqBlock
        MOV  DX, ES:[DI].ReqType
        .IF  < DX be Last_Request > NEAR ; Check for valid request
          .IF  < DX a App_Start >        ; If not start request
;           *************************************************
;           *  Verify requesting application is the parent  *
;           *  of the child session.                        *
;           *************************************************
            LFS  SI, SGCB_ArraySize         ; FS:[SI] --> Max # of Sessions
            MOV  BX, ES:[DI].ReqSessionID   ; Parent session
            MOV  CX, ES:[DI].RQSwtSessionID ; Child session
            .IF  < CL e 1 > OR
            .IF  < CL ae First_Available_Session > AND ; Above the reserved scrn grp #'s ?
            .IF  < CL b FS:[SI] >                      ; Below last session
              CALL SESSIONRELATED                      ; Check relation

;             ********************************************************* ;CJ47
;             *  Check for special StopSession from WinTerminateApp.  * ;CJ47
;             ********************************************************* ;CJ47
              .IF  < DX eq App_Stop > AND       ;If Stop and not related;CJ47
              .IF  < nonzero AX >                                       ;CJ47
                 PUSH  EBX                                              ;CJ47
                 MOV   EBX, ES:[DI].RqTrmReserved  ;Check for special   ;CJ47
                 .IF   < EBX eq WinTerminateApp >  ;reserved value      ;CJ47
                    XOR AX, AX                     ;allow to do Stop    ;CJ47
                 .ENDIF                                                 ;CJ47
                 POP   EBX                                              ;CJ47
              .ENDIF                                                    ;CJ47

            .ELSE                                      ; illegal session ID
              MOV  AX, Error_SMG_Invalid_Session_ID
            .ENDIF
          .ENDIF                        ; End if not start request

          .IF  < zero AX >                                              ;CJ10
;           **************************************************
;           *  Convert the request block into a Session      *
;           *  Manager call, and call the Session Manager    *
;           *  to process the request.                       *
;           **************************************************
            .IF  < DX eq App_Start >     ; Start session request
              CALL APPSTARTSESSION
            .ELSEIF < DX eq App_Select > ; Switch session request
              CALL APPSELECTSESSION
            .ELSEIF < DX eq App_Set >    ; Set session request
              CALL APPSETSESSION
            .ELSE                        ; DX MUST = app_stop ; Terminate session request
              CALL APPSTOPSESSION
            .ENDIF

;           ************************************************
;           *  If the shell is the foreground process      *
;           *  and a start or set selectability is made,   *
;           *  notify the shell to redraw the switch list  *
;           ************************************************
            PUSH AX                             ; Save return code
            MOV  EAX, TopMost                   ; Get Top SGCB @
            .IF  < BaseShell eq EAX > AND       ; Is Shell foreground?
            .IF  < DX eq App_Start > OR         ; Start request
            .IF  < DX eq App_Set > AND          ; Set request
            .IF  < ES:[DI].RQSetSelectOpt a 0 > ; Selectability change

;CJ10         PUSH ShellRedrawSem[2]    ; Redraw semaphore
              PUSH DWORD PTR ShellRedrawSem                             ;CJ10
              CALL DOSSEMCLEAR

;CJ10         PUSH ShellRedrawSem[2]    ; Redraw semaphore
              PUSH DWORD PTR ShellRedrawSem                             ;CJ10
              CALL DOSSEMSET
            .ENDIF
            POP  AX                     ; Restore return code
          .ENDIF                        ; Check to see if sessions related

;         ***************************************
;         *  Save return code in request block  *
;         ***************************************
          MOV  ES:[DI].ReqReturnCode, AX

;         *********************************************
;         *  Clear Synchrosem so parent exit can run  *
;         *********************************************
          PUSH AX                        ; Save meaningful return code
;CJ10     MOV  SI, DI                    ; Start of request block
          LEA  SI, [DI].Req_SynchroSem   ; Offset from ES               ;CJ10
          PUSH ES                        ; Clear semaphore set
          PUSH SI                        ; on app side
          CALL DOSSEMCLEAR

;         ********************************
;         *  Wake up requesting process  *
;         ********************************
          PUSH ES                       ; Segment of Semaphore
          ADD  DI, OFFSET ReqBlockSem
          PUSH DI                       ; Offset of Semaphore
          CALL DOSSEMCLEAR
          POP  AX                       ; Restore meaningful rc

        .ELSE                           ; Not a legal requests
;         ******************************************************
;         *  Notify caller an invalid request block was sent   *
;         ******************************************************
          MOV  AX, Error_SMG_Bad_Action
        .ENDIF
      .ENDIF

;     *************************************
;     *  Clear synchronization semaphore  *
;     *************************************
      PUSH AX                           ; Save meaningful return code
      PUSH DS                           ; Clear synchronization semaphore
      PUSH OFFSET SMRoutSem
      CALL DOSFSRAMSEMCLEAR
      POP  AX                           ; Restore meaningful rc

    .ELSE                               ; Not Shell
      MOV  AX, Error_SMG_Not_Baseshell
    .ENDIF

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

    MMPHPostDOSSMDoAppReq               ; Performance Hook (8091h)      ;MHW

    POP  GS                             ; Restore registers
    POP  FS
    POP  ES
    POP  DS
    POPA

    LEAVE
    DOSSMDOAPPREQ_POSTDT LABEL FAR
    RET  ApGetLen                       ; Return & pop off input parameters from stack

DOSSMDOAPPREQ ENDP
endif

CODE_TUNE1 ENDS                                                         ;MDLL
    END
