Category : Batch File Utilities - mostly for DOS
Archive   : ABFS.ZIP
Filename : ATTR.ASM

Output of file : ATTR.ASM contained in archive : ABFS.ZIP

; ATTR.ASM -- File Attribute Utility
; ==================================

CSEG Segment
Org 0080h
Parameter Label Byte ; Parameter is here
Org 0100h
Entry: Jmp Begin ; Entry Point

; Most Data (some more at end of program)
; ---------------------------------------

db "ATTR (C) 1986, Ziff-Davis Publishing Co.",1Ah
db " Programmed by Charles Petzold ",1Ah
SyntaxMsg db "Syntax: ATTR [+A|-A] [+S|-S] [+H|-H] [+R|-R] "
db "[drive:][path]filename",13,10
db " Archive System Hidden Read-Only$"
DosVersMsg db "ATTR: Needs DOS 2.0 +$"
FlagErrMsg db "ATTR: Incorrect flag$"
FileSpecMsg db "ATTR: Incorrect File Spec$"
Delimiters db 9,' ,;=',13
FlagList db "ASHR", 20h, 04h, 02h, 01h
AllFlagList db " $Arc $Dir $$$$$$Sys $Hid $R-O$"
ChangeFlag db 0
AndAttrBits db 0
OrAttrBits db 0
SearchString dw ?
AppendFileName dw ?

; Check DOS Version
; -----------------

Begin: Mov AH, 30h ; Check for DOS Version
Int 21h ; through DOS call
Cmp AL, 2 ; See if it's 2.0 or above
Jae DosVersOK ; If so, continue

Mov DX, Offset DosVersMsg ; Error message
ErrorExit: Mov AH, 9 ; Print String function call
Int 21h ; Do it
Int 20h ; And exit prematurely

; Parse Command Line to get file specification
; --------------------------------------------

DosVersOK: Mov SI, 1+Offset Parameter ; Parameter string pointer
Cld ; Directions forward

FlagSearch: Lodsb ; Get Byte
Mov DI, Offset Delimiters ; Check if delimiter
Mov CX, 5 ; Five delimiters to check
Repne Scasb ; Scan the string
Je FlagSearch ; If delimiter, circle back
Mov DX, Offset SyntaxMsg ; Possible error msg
Cmp AL, 13 ; If carriage return, no file
Je ErrorExit ; so exit with message

Mov DI, Offset OrAttrBits ; Pointer to plus flag saver
Cmp AL, '+' ; See if plus sign
Je PlusOrMinus ; If so, save the bit
Mov DI, Offset AndAttrBits ; Pointer to minus flag saver
Cmp AL, '-' ; See if minus sign
Jne MustBeFile ; If not, it must be file name

PlusOrMinus: Mov [ChangeFlag],-1 ; Set for changing
Lodsb ; Get the next byte
And AL, 0DFh ; Capitalize it
Mov BX, Offset FlagList ; List for scanning
Mov CX, 4 ; Scan for A, S, H, and R

SearchList: Cmp AL, [BX] ; See if a match
Jz FoundFlag ; If so, proceed to save
Inc BX ; Kick up pointer
Loop SearchList ; And loop around for next
Mov DX, Offset FlagErrMsg ; Otherwise, set message
Jmp ErrorExit ; And terminate

FoundFlag: Mov AL, [BX + 4] ; Get bit mask
Or [DI], AL ; Turn saved bit on
Jmp FlagSearch ; And continue looking

MustBeFile: Not [AndAttrBits] ; Invert bits for turn off
Mov [SearchString], SI ; Save file name pointer
Dec [SearchString] ; Actually one byte lower

EndSearch: Lodsb ; Get Byte
Mov DI, Offset Delimiters ; Check if delimiter
Mov CX, 6 ; Six delimiters including CR
Repne Scasb ; Scan the string
Jne EndSearch ; If not delimiter, keep going

; Transfer Search String down at end of program
; ---------------------------------------------

Dec SI ; Points after file spec
Mov Byte Ptr [SI], 0 ; Make it ASCIIZ string
Mov CX, SI ; CX points to end
Mov SI, [SearchString] ; SI points to beginning
Sub CX, SI ; Now CX is length of it
Mov DI, Offset PathAndFile ; Destination of string
Mov [AppendFileName], DI ; Save it here also

SearchTrans: Lodsb ; Get byte of search string
Stosb ; And save it down below
Cmp AL, ':' ; See if drive marker
Je PossibleEnd ; If so, take note of it
Cmp AL, '\' ; See if path separator
Jne NextCharacter ; If not, skip next code

PossibleEnd: Mov [AppendFileName], DI ; This is the new end
NextCharacter: Loop SearchTrans ; Do it again until done

; Find Files from Search String
; -----------------------------

Mov DX, Offset DTABuffer ; Set File Find buffer
Mov AH, 1Ah ; by calling DOS
Int 21h

Mov DX, [SearchString] ; Search string
Mov CX, 16h ; Search Everything
Mov AH, 4Eh ; Find first file

FindFile: Int 21h ; Call DOS to find file
Jnc Continue ; If no error continue
Cmp AX, 18 ; If not "no more files" error
Jnz FindError ; print error message
Jmp NoMoreFiles ; Now get out of the loop

FindError: Mov DX, Offset FileSpecMsg ; Error message for file spec
Jmp ErrorExit ; Exit and print message

Continue: Mov SI, 30+Offset DTABuffer ; Points to filename
Cmp Byte Ptr [SI], '.' ; See if "dot" entry
Jnz FileIsOK ; If not, continue
Jmp FindNextFile ; If so, skip it

FileIsOK: Mov DI, [AppendFileName] ; Destination of file name
Mov CX, 14 ; Number of bytes to display

TransferName: Lodsb ; Get the byte in file name
Stosb ; Save it
Or AL, AL ; See if terminating zero
Jz PadWithBlanks ; If so, display blanks
Call DisplayChar ; Display the character
Loop TransferName ; And loop back around

PadWithBlanks: Mov AL, ' ' ; Pad names with blanks
Call DisplayChar
Loop PadWithBlanks ; And loop until CX is zero

; Change And Display File Attributes
; ----------------------------------

Mov DX, Offset PathAndFile ; Points to ASCIIZ string
Test [ChangeFlag], -1 ; See if changing attributes
Jz DisplayIt ; If not, just display them

Mov AX, 4300h ; Get file attribute
Int 21h ; by calling DOS
And CL, 27h ; Zero out some bits
And CL, [AndAttrBits] ; Turn off some bits
Or CL, [OrAttrBits] ; Turn on some bits
Mov AX, 4301h ; Set file attribute
Int 21h ; by calling DOS

DisplayIt: Mov AX, 4300h ; Get file attribute
Int 21h ; by calling DOS
Mov BL, CL ; BL is attributes
Or BL, 08h ; Turn on Volume bit
Shl BL, 1 ; Shift to get rid of
Shl BL, 1 ; unused bits
Mov CX, 6 ; Number of bits left
Mov DX, 5+Offset AllFlagList; Storage of abbreviations

AttrListLoop: Push DX ; Save abbreviation pointer
Shl BL, 1 ; Shift bit into carry
Jc FlagIsOn ; See if it's on
Mov DX, Offset AllFlagList ; If not, print blanks

FlagIsOn: Mov AH, 9 ; Print string
Int 21h ; by calling DOS
Pop DX ; Get back abbreviation ptr
Add DX, 5 ; Kick up for next bit
Loop AttrListLoop ; And loop around
Mov AL, 13 ; Print carriage return
Call DisplayChar
Mov AL, 10 ; Print line feed
Call DisplayChar

FindNextFile: Mov AH, 4Fh ; Find next file
Jmp FindFile ; By looping around

NoMoreFiles: Int 20h ; Terminate

; SUBROUTINE: Display Character in AL
; -----------------------------------

DisplayChar: Push AX
Push DX
Mov DL, AL ; Move character to DL
Mov AH, 2 ; Display it
Int 21h ; by calling DOS
Pop DX
Pop AX

; Some data stored at end to cut down COM size
; --------------------------------------------

DTABuffer Label Byte ; For file find calls
PathAndFile equ DTABuffer + 43 ; For file path and name
CSEG EndS ; End of the segment
End Entry ; Denotes entry point

  3 Responses to “Category : Batch File Utilities - mostly for DOS
Archive   : ABFS.ZIP
Filename : ATTR.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: