;       SCCSID = @(#)smgsgset.asm	6.2 91/08/28
PAGE 60,132                             ;
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************

;***************************************************************************
;
; Source File Name:     SMGSGSET.ASM
;
; Subroutine Name:      DOSSMSGSET
;
; Descriptive Name:     Set session status
;
; Function:     Establish or break a bond between a parent and
;               child session.
;
; 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
;       @GDW   08/26/91   PTR B725436 Fix to allow semaphore loop on INTERUPT
;
; Entry Point:
;       Linkage:  EXTRN DOSSMSGSET:FAR
;                       PUSH    WORD   ParentID   ; Parent Session ID
;                       PUSH    WORD   ChildID    ; Child Session ID
;                       PUSH    WORD   SelectOpt  ; Select Options
;                       PUSH    WORD   BondOpt    ; Bond Options
;                       CALL    DOSSMSGSET
;
; Inputs:
;       WORD    ParentID    Parent session ID
;       WORD    ChildID     Child session ID
;       WORD    SelectOpt   Options to mark child selectable or not
;       WORD    BondOpt     Options to bond or break bond with
;                           child session
;
; Exit Normal:
;       AX      ReturnCode Value = 0, Session set status successful
;
; Exit Errors:
;       AX      ReturnCode error_smg_not_baseshell
;                          error_smg_session_not_found
;
;                          DOSSMBASESHELL  errors
;                          DOSSMGETSGQUEUE errors
;
; Effects:      All other registers preserved.
;
; Internal References:
;          Routines:    DOSSMBASESHELL
;                       DOSSMGETSGQUEUE
;
; External References:
;          Routines:    DOSSEMREQUEST
;                       DOSSEMCLEAR
;
;***************************************************************************
ifdef I1
;
;   DOSSMBASESHELL (Verify caller is Shell)
;   IF (No_Error)
;      DOSSMGETSGCB (Get child session sgcb)
;      IF (NOT Error_SMG_Session_Not_Found)
;         DOSSMGETSGCB (Get parent session sgcb)
;         IF (NOT Error_SMG_Session_Not_Found)
;            DOSFSRAMSEMREQUEST (Get queue access semaphore)
;            IF (Select Option ne no_change)
;               Change selectability
;            ENDIF
;
;            IF (Bond Option ne no_change)
;               IF (Bond Option e Bond)
;                  Bond child
;               ELSE
;                  Break bond
;               ENDIF
;            ENDIF
;            DOSFSRAMSEMCLEAR (Release queue access semaphore)
;         ENDIF
;      ENDIF
;   ENDIF
;
;***************************************************************************
else

.386C
    EXTRN SGCB_QueueRamSem : DWORD      ; Queue access ram semaphore

    EXTRN DOSSMBASESHELL      : NEAR    ; Verify Base Shell calling
    EXTRN DOSFSRAMSEMREQUEST  : FAR     ; Request semaphore ownership
    EXTRN DOSFSRAMSEMCLEAR    : FAR     ; Clear semaphore ownership
    EXTRN DOSSMGETSGCB        : FAR

.xlist
    INCLUDE SMRSGCB.INC
    INCLUDE SMGSGSET.INC
    INCLUDE INFOSEG.INC                 ; needed by smmmpha.inc         ;MHW
    INCLUDE SMMMPHA.INC                 ; Performance hook macros       ;MHW
.xcref
    INCLUDE SMRRDATA.INC
    INCLUDE STRUC.INC
    INCLUDE ERROR2.INC
.cref
.list

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

    PUBLIC DOSSMSGSET
    PUBLIC DOSSMSGSET_POSTDT
DOSSMSGSET PROC FAR

    Local_Bytes EQU  4
    Local_Var1  EQU SS:[BP][-2]         ; Local variable on stack
    Local_Var2  EQU SS:[BP][-4]         ; Local variable on stack

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

    MOV  AX, RDATA
    MOV  DS, AX

    MMPHPreDOSSMSGSet                   ; Performance Hook (800Bh)      ;MHW

;   *********************************
;   *  Verify caller is Base Shell  *
;   *********************************
    CALL DOSSMBASESHELL
    .IF  < zero AX >                                                    ;CJ10

;     ******************************************************
;     *  Get parent and child screen group queue elements  *
;     ******************************************************
      MOV  DX, SS:[BP].SGSetChildSGID   ; Child screen group
      LEA  SI, Local_Var2               ; @ return @ of SGCB
      PUSH SS
      PUSH SI
      PUSH DX                           ; Parent's SGID
      PUSH SGID_Lookup + 8000H          ; Look up SGID not PID and      ;CJ10
      CALL DOSSMGETSGCB                 ;   don't serialize QueueRamSem

      .IF  < AX ne Error_SMG_Session_Not_Found >
        LFS  SI, Local_Var2             ; FS:[SI] --> Parent's SGCB

        LEA  DI, Local_Var2             ; @ return @ of SGCB
        PUSH SS
        PUSH DI
        PUSH SS:[BP].SGSetParentSGID    ; Parent's SGID
        PUSH SGID_Lookup + 8000H        ; Look up SGID not PID and      ;CJ10
        CALL DOSSMGETSGCB               ;   don't serialize QueueRamSem

;       **********************************************
;       *  Process select and bond options specified *
;       **********************************************
        .IF  < AX ne Error_SMG_Session_Not_Found >
          SUB  AX, AX                                                   ;CJ10
          MOV  BX, SS:[BP].SGSetSelectOption

;         *************************************************
;         *  Get SGCB Semaphore since we're accessing it  *
;         *************************************************
;CJ10     LGS  DI, SGCB_QueueRamSem     ; Queue access semaphore
          .repeat                                                       ;@GDW
            PUSH SGCB_QueueRamSem                                       ;CJ10
;CJ10       PUSH DI
            PUSH DWORD PTR -1           ; Wait until queue available    ;CJ10
;CJ10       PUSH -1
            CALL DOSFSRAMSEMREQUEST
          .until  <ax ne ERROR_INTERRUPT>                               ;@GDW

          LGS  DI, Local_Var2           ; GS:[DI] --> Parent's SGCB
                                        ; FS:[SI] --> Child's SGCB
          .IF  < nonzero BX >                                           ;CJ10
            DEC  BX                     ; Change selectability
            MOV  FS:[SI].SGCB_SelectStatus, BX
          .ENDIF

          MOV  BX, SS:[BP].SGSetBondOption
          CMP  BX, 1                                                    ;CJ10
         .IF   < e >                                                    ;CJ10
           MOV  GS:[DI].SGCB_Bound, DX  ; Bond child
         .ELSEIF < a >                                                  ;CJ10
           MOV  GS:[DI].SGCB_Bound, 0   ; Break bond
         .ENDIF

;         *****************************
;         *  Free the SGCB semaphore  *
;         *****************************
          PUSH AX                       ; Save meaningful return code
;CJ10     LGS  DI, SGCB_QueueRamSem     ; Queue access semaphore
          PUSH SGCB_QueueRamSem         ; Queue access semaphore        ;CJ10
;CJ10     PUSH DI
          CALL DOSFSRAMSEMCLEAR
          POP  AX                       ; Restore meaningful return code
        .ENDIF
      .ENDIF
    .ENDIF

    MOV  AX_Reg[-Local_Bytes], AX       ; Place return code on the stack

    MMPHPostDOSSMSGSet                  ; Performance Hook (808Bh)      ;MHW

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

    LEAVE
    DOSSMSGSET_POSTDT LABEL FAR
    RET  SGSetFrmLen                    ; Return to caller

DOSSMSGSET ENDP
CODE ENDS
endif
    END
