;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
        page        ,132
;/*****************************************************************************
;*
;* SOURCE FILE NAME = VALIDATE.ASM
;*
;* DESCRIPTIVE NAME = DDC validation program
;*
;*
;* VERSION      V2.0
;*
;* DATE         8/4/92
;*
;* DESCRIPTION  Set up segment sequence and device driver header for an
;*              OS/2 device driver.  Provide STRATEGY and IDC entry
;*              points for this device driver.  These small functions
;*              take the registers passed in and push them onto the
;*              stack for C routines to use.
;*
;* FUNCTIONS    ddc_validate
;*              
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*
;*****************************************************************************/

ifdef FIREWALLS

        .xlist
        include cmacros.inc
        include pmgre.inc
DDC_VALIDATE_DEFINED    equ                      1
        include driver.inc
        .list


sBegin  Data

        externB ddcInit

sEnd    Data

sBegin  Code
        assumes cs,Code

        externW CodeData


;/*
;**     SURFACE     validate that the surface parameters are consistant
;**                 in the given ddc.
;**
;**     MEMORYDDC   validate that the ddc is a memory ddc
;**
;**     LEVELS      validate all the levels of the ddc.  If not given,
;**                 only the topmost level is validated
;*/

;/*
;** The stack frame as it will be set up by all the validation routines:
;*/

stack_handle    equ     (dword ptr [bp][26])
stack_cmd       equ     ( word ptr [bp][24])
stack_retf      equ     (dword ptr [bp][20])
stack_ax        equ     ( word ptr [bp][18])
stack_cx        equ     ( word ptr [bp][16])
stack_dx        equ     ( word ptr [bp][14])
stack_bx        equ     ( word ptr [bp][12])
stack_sp        equ     ( word ptr [bp][10])
stack_bp        equ     ( word ptr [bp][08])
stack_si        equ     ( word ptr [bp][06])
stack_di        equ     ( word ptr [bp][04])
stack_flags     equ     ( word ptr [bp][02])
stack_ds        equ     ( word ptr [bp][00])     ;<--BP


                public  ddc_validate
ddc_validate    proc    far

        pusha
        pushf
        push    ds
        mov     bp,sp
        mov     ds,CodeData
        assumes ds,Data

;/*
;** Always validate the hddc to make sure the handle type is correct
;** and that the memory pointed to is a ddc.
;*/

        cmp     stack_handle.hi,HDDC_IDENT
        je      @F
        rip     text,<Validate - ddc identifier is invalid>
        jmp     validate_exit
@@:
        mov     dx,DDC_IDENT
        mov     bx,stack_handle.lo

ddcv_level_loop:
        cmp     [bx].ddc_usId,dx
        je      @F
        rip     text,<Validate - ddc does not point to a ddc>
        jmp     validate_exit
@@:

;/*
;** If this is supposed to be a memory ddc, make sure it is.
;*/

        test    stack_cmd,DDC?MEMORYDDC
        jz      @F
        test    [bx].ddc_fb,DDC_DEVICE
        jz      @F
        rip     text,<Validate - ddc is not a memory ddc>
        jmp     validate_exit
@@:

;/*
;** Validate the surface if requested
;*/

        test    stack_cmd,DDC?SURFACE
        jnz     @F
        jmp     surface_validated
@@:
        mov     si,[bx].ddc_npsd                 ;INVALID_ADDRESS if no surface selected
        test    [bx].ddc_fb,DDC_PRESENT
        jnz     need_a_surface

;/*
;**  Validate that no surface is selected into the ddc.
;** 
;**  We don't want to find a surface selected into the ddc.  We also don't
;**  want to find a non-zero ddc_crcsClip, which would be inconsistant with
;**  the DDC_VISIBLE flag.
;*/

        inc     si
        jz      @F
        .errnz  INVALID_ADDRESS+1
        rip     text,<Validate - Pointer to surface should be null>
        jmp     validate_exit
@@:
        test    [bx].ddc_fb,DDC_VISIBLE
        jz      @F
        rip     text,<Validate - A null surface was marked visible>
        jmp     validate_exit
@@:
        jmp     surface_validated

;/*
;** Validate that a surface is selected into the ddc.
;**
;**     The pointer to surface should be non-null and have a
;**     SURFACE_IDENT id.
;**
;**     If this is a bitmap, it must be owned by the ddc and have a
;**     non-zero select count.
;**
;**     DDC_DEVICE and SD_DEVICE must be the same.
;**
;**     If either extent of the surface is 0, then SD_NONNULL must be
;**     clear.  If both extents are non-zero, then SD_NONNULL must be
;**     set.
;**
;**     If SD_NONNULL is clear, then the DDC_VISIBLE flag must be clear
;*/
need_a_surface:
        inc     si
        jnz     @F
        rip     text,<Validate - Pointer to surface should not be null>
        jmp     validate_exit
@@:
        dec     si                                ;Must have the correct ident
        cmp     [si].sd_usId,SURFACE_IDENT
        .errnz  bm_sd.sd_usId
        .errnz  sd_usId
        je      @F
        rip     text,<Validate - The Id field of the selected surface is invalid>
        jmp     validate_exit
@@:
        mov     al,[si].sd_fb                     ;If a bitmap, must be owned
        test    al,SD_DEVICE                      ;  by this ddc and have a
        jnz     surface_check_cont                ;  non-zero select count
        cmp     [bx].ddc_usId,SAVED_DDC_IDENT     ; saved DDC can't own a bitmap!
        jz      @F
        cmp     [si].bm_hddc,bx
        je      @F
        rip     text,<Validate - The bitmap selected into the ddc is owned by a different ddc>
        jmp     validate_exit
@@:
        cmp     [si].bm_cSelect,0
        jne     @F
        rip     text,<Validate - The bitmap selected into the ddc has a lock count of 0>
        jmp     validate_exit
@@:

surface_check_cont:
        xor     al,[bx].ddc_fb                    ;The DDC_DEVICE and SD_DEVICE
        test    al,DDC_DEVICE                     ;  flags must be consistant
        jz      @F                                ;  with each other
        .errnz  DDC_DEVICE-SD_DEVICE
        rip     text,<Validate - Device flags in ddc and surface do not match>
        jmp     validate_exit
@@:
        xor     cx,cx                             ;Set CX = 0 if surface should
        cmp     [si].bm_sd.sd_cx,cx               ; be null, else 0FFFFh
        je      @F
        cmp     cx,[si].bm_sd.sd_cy
        je      @F
        dec     cx
@@:
        test    [si].sd_fb,SD_NONNULL
        jnz     surface_is_flagged_nonnull

surface_is_flagged_null:
        cmp     [si].sd_pBits.sel,INVALID_SEL     ;Surface pointer must be null
        je      @F                                ;  if flagged as null
        rip     text,<Validate - A null surface with a selector was detected>
        jmp     validate_exit
@@:


        jcxz    @F                                ;Null surface with a non-zero
                                                  ;  extent is wrong
        test    [bx].ddc_fbAbove,DDC_INFO_DC     ;INFO DC now have a surface
        jnz     @F                                 ;  size see data.asm
        rip     text,<Validate - A null surface with non-zero extents was detected>
        jmp     validate_exit
@@:

        test    [bx].ddc_fb,DDC_VISIBLE ;Null surface can never be
        jz      @F                                ;  visible
        rip     text,<Validate - A null surface was marked visible>
        jmp     validate_exit
@@:
        jmp     short surface_validated


surface_is_flagged_nonnull:
        inc     cx                                ;Non-null with a zero extent
        jz      @F                                ;  is wrong
        rip     text,NonnullSurfaceWith0Extents,<Validate - A non-null surface with zero extents was detected>
        jmp     validate_exit
@@:
surface_validated:

;/*
;**  Some general validations of the ddc fields
;**
;**     If the save level is 1, there should be no previous link.  If
;**     the save level isn't 1, then there should be a previous link
;**     which points to a SAVED_DDC_IDENT type ddc.
;**
;**     If DDC_CLIP_NOTIFY is clear, then DDC_VISIBLE must be clear.
;**
;**     If DDC_VISIBLE is clear, then ddc_crcsClip must be 0.
;**
;**     Validate the color table pointer and mapping function
;*/

general_validations:
        cmp     [bx].ddc_cLevel,1
        je      ddc_at_level_1
        mov     si,[bx].ddc_npddcPrev
        inc     si
        jz      ddc_bad_link
        dec     si
        cmp     [si].ddc_usId,SAVED_DDC_IDENT
        je      @F
ddc_bad_link:
        rip     text,<Validate - The pointer to a save level of the ddc is invalid>
        jmp     validate_exit
ddc_at_level_1:
        cmp     [bx].ddc_npddcPrev,INVALID_ADDRESS
        jne     ddc_bad_link
@@:
        mov     al,[bx].ddc_fb
        test    al,DDC_CLIP_NOTIFY
        jnz     @F
        test    al,DDC_VISIBLE
        jz      @F
        rip     text,<Validate - ddc marked visible with no clip notification>
        jmp     validate_exit
@@:
        cmp     [bx].ddc_crcsClip,0
        jne     @F
        test    al,DDC_VISIBLE
        jz      @F
        rip     text,<Validate - ddc marked visible with no clip rectangles present>
        jmp     validate_exit
@@:

        mov     ds,CodeData
        assumes ds,Data


;/*
;**  If VALIDATE_LEVELS was specified, then all saved levels of the ddc
;**  are to be validated.
;*/

        test    stack_cmd,DDC?LEVELS
        jz      @F
        mov     bx,[bx].ddc_npddcPrev
        inc     bx
        jz      @F
        dec     bx
        mov     dx,SAVED_DDC_IDENT
        jmp     ddcv_level_loop
@@:
validate_exit:
        pop     ds
        assumes ds,nothing
        popf
        popa
        ret     SIZE_DWORD+SIZE_WORD

ddc_validate    endp

sEnd    Code
endif
end
