;; IsAncestor determines whether the specified directory is an ancestor
;; of the current directory. A directory qualifies as an ancestor if it
;; lies anywhere in the path to the current directory.
;;
;; Call with: DS:BX -> ASCIIZ directory name
;;
;; Returns:   Carry set if the specified directory is an ancestor
;;            Carry clear if the specified directory is not an ancestor
;;
;; Note:      Carry will always return set if the specified directory
;;            is the root directory or the current directory.

BUFFERLENGTH    equ     66                      ;Size of directory name buffer

IsAncestor      proc    near
                sub     sp,3*BUFFERLENGTH       ;Allocate stack space for
                                                ;temporary storage
                mov     si,sp                   ;Copy SP to SI
                mov     byte ptr [si],"\"       ;Initialize first byte to "\"
                inc     si                      ;Advance SI to next byte
                mov     ah,47h                  ;Get the name of the
                xor     dl,dl                   ;current directory with
                int     21h                     ;function 47h

                mov     ah,60h                  ;Convert the directory name
                mov     si,sp                   ;to fully qualified form
                mov     di,si                   ;with DOS function 60h
                add     di,BUFFERLENGTH
                int     21h

                mov     ah,60h                  ;Convert the directory name
                mov     si,bx                   ;addressed by DS:BX to fully
                mov     di,sp                   ;qualified form also
                add     di,2*BUFFERLENGTH
                int     21h

                mov     si,sp                   ;Point SI to the name of the
                add     si,BUFFERLENGTH         ;current directory (Dir1)
                mov     di,si                   ;Point DI to the name of the
                add     di,BUFFERLENGTH         ;specified directory (Dir2)

                cmp     byte ptr [di+3],0       ;Branch if Dir2 is not the
                jne     IsAnc2                  ;root directory
                mov     al,[si]                 ;Ancestor found if drive
                cmp     al,[di]                 ;letters are equal
                je      IsAnc5
                cld                             ;Clear direction flag

IsAnc2:         lodsb                           ;Read a character from Dir1
                mov     ah,[di]                 ;Read a character from Dir2
                inc     di                      ;Advance DI to next byte

                or      ah,ah                   ;Branch if this is not the
                jnz     IsAnc3                  ;end of Dir2
                or      al,al                   ;Ancestor found if this is
                jz      IsAnc5                  ;the end of both strings
                cmp     al,"\"                  ;Ancestor found if match
                je      IsAnc5                  ;ends on a "\" character
                jmp     short IsAnc4            ;Not an ancestor

IsAnc3:         cmp     al,ah                   ;Compare the characters
                je      IsAnc2                  ;Repeat if characters equal

IsAnc4:         add     sp,3*BUFFERLENGTH       ;Clear the stack
                clc                             ;Clear the carry flag
                ret                             ;Return to caller

IsAnc5:         add     sp,3*BUFFERLENGTH       ;Clear the stack
                stc                             ;Set the carry flag
                ret                             ;Return to caller
IsAncestor      endp
