home *** CD-ROM | disk | FTP | other *** search
- .SEQ
- Name PKV
- Page 51,132
- Title PKV.ASM
-
- Comment |
- Author BF Gavin, Online Reference BBS. All rights reserved.
- Format Standard .COM file format.
- Intent View contents of ZIP file using local file headers.
-
- Usage
- Origin 14OCT90 Version 1.00
- Update
- Remark Use .SEQ or Assemble with /S parm for segments in source file order.
-
- |
-
-
- Code Segment Para Public 'Code'
-
- Org 100H ; .COM type entry point
- Assume CS:CODE
- Assume DS:CODE
- Assume ES:CODE
-
- Cr Equ 13 ; Carriage return
- Lf Equ 10 ; Line feed
-
-
- Entry: Jmp Main_Line
-
- Db Cr,Lf,Lf
- Db 'PKV - v1.00',Cr,Lf
- Db '(C) BF Gavin - All rights reserved',Cr,Lf
- Db 'Release date is 14OCT90',Cr,Lf
- Db 'Written entirely in TURBO ASM v2.00',Cr,Lf
- Db 1Ah
-
- Include Pkv100.Var ; Program variables
- Include Pkv100.Inc ; Generic subroutines
-
-
-
-
-
- Parse_Parms Proc Near
- Mov SI,81h ; 1st command line parm
- Call Leading_Blanks ; Get first non-blank char
- Jnc _parse_cmdline ; NC = non-blank command line
- Lea DX,NoParm$ ; Point at error message
- Jmp Error_Exit ; Display message and quit
-
- _parse_cmdline:
- Lea DI,ZipFile ; Input file name
- Call Upper_Case ; Convert AL to upper case
- Stosb ; Store 1st parm byte
-
- _parse_copyloop:
- Lodsb ; Read command line parm bytes
- Cmp AL,20h ; Blank space?
- Jz _parse_copydone ; Yes - parm is done
- Cmp AL,09h ; Tab?
- Jz _parse_copydone ; Yes - parm is done
- Cmp AL,Cr ; Carriage return?
- Jz _parse_copydone ; Yes - parm is done
- Call Upper_Case ; Convert AL to upper case
- Stosb ; No - store byte in ZipFile
- Jmp Short _parse_copyloop ; Go again
-
- _parse_copydone:
- Xor AX,AX ; Fast zero of AX
- Stosw ; Append ASCIIZ terminators
- Ret ; To main line
- Parse_Parms Endp
-
-
-
-
-
- Open_ZipFile Proc Near
- Xor AL,AL ; Fast zero of AL
- Mov CX,0FFFFh ; Scan counter
- Lea DI,ZipFile ; Scan input file name
- Repne Scasb ; Scan input for ASCIIZ
- Not CX ; Get length of ZipFile
- Mov BX,CX ; Save length in BX
- Dec BX ; Adjust it -1
-
- Mov AL,'.' ; Scan for dot
- Lea DI,ZipFile ; Scan input file name
- Repne Scasb ; Scan for dot
- Or CX,CX ; Was file extent found?
- Jnz _open_input ; Yes - dot was found
-
- ;Add .ZIP file extent
- Lea DI,ZipFile ; Start of input file name
- Add DI,BX ; Point at ASCIIZ terminator
- Mov AX,'Z.' ; Reversed for STOSW
- Stosw ; Append '.Z'
- Mov AX,'PI' ; Reversed for STOSW
- Stosw ; Append 'IP'
- Xor AL,AL ; Fast setup of ASCIIZ
- Stosb ; Append ASCIIZ
-
- _open_input:
- Mov AX,3D00h ; Open file handle function
- Lea DX,ZipFile ; Input file
- Int 21h ; Call DOS
- Jnc _open_ok ; Continue if no error
- Lea DX,Open_Err$ ; Point at error message
- Jmp Error_Exit ; Display message and quit
-
- _open_ok:
- Mov ZIP_Handle,AX ; Save the input file handle
- Ret ; To main line
- Open_ZipFile Endp
-
-
-
-
-
- Show_Header Proc Near
- Lea DX,Search$ ; Searching:
- Call Display_Message ; Display it
- Lea DX,ZipFile ; ASCIIZ file name
- Call Display_Message ; Display it
- Lea DX,Newline ; Cr,Lf,0
- Call Display_Message ; Display it
- Call Display_Message ; Display it again
- Lea DX,Header1$ ; Top column text
- Call Display_Message ; Display it
- Lea DX,Header2$ ; Top column dashes
- Call Display_Message ; Display it
- Ret ; To main line
- Show_Header Endp
-
-
-
-
-
- GetRecord Proc Near ; Filepos = Record at entry
- Mov AH,3Fh ; Read handle function
- Mov BX,ZIP_Handle ; ZipFileopen handle
- Mov CX,Size ZIP ; Size of ZIP variable
- Lea DX,ZIP ; Read into offset zero
- Int 21h ; Call DOS
- Jnc _get_signature ; Continue if no errors
- Lea DX,Read_Err$ ; Read error message
- Jmp Error_Exit ; Display message and quit
-
- _get_signature:
- Mov AX,Word Ptr ZIP.Signature
- Mov DX,Word Ptr ZIP.Signature+2
- Cmp AX,Word Ptr LocalSignature
- Jnz _check_dirsig
- Cmp DX,Word Ptr LocalSignature+2
- Jnz _check_dirsig
-
- ;Local header signature was found
- Mov CX,ZIP.FilenameLen ; Length of compressed file data
- Add CX,ZIP.XFieldLen ; Add in extra field length
- Mov AH,3Fh ; Read from file handle
- Mov BX,ZIP_Handle ; Get the open file handle
- Lea DX,LocalFileName ; Read into here
- Int 21h ; Call DOS
- Jnc _getrecord_filepointer ; No error reading filename
- Lea DX,Hdr_Err$ ; Set error message
- Jmp Error_Exit ; Display message and quit
-
- _getrecord_filepointer:
- ;Update file position pointer after record, filename, xfield reads
- Mov BX,AX ; Save number of bytes read
- Mov AX,Word Ptr ZipFilePtr ; Get file position pointer
- Mov DX,Word Ptr ZipFilePtr+2 ; Into DX:AX
- Add AX,Size ZIP ; Add size of bytes just read
- Adc DX,0 ; Add in carry, if any
- Add AX,BX ; Add in filename,xfield bytes
- Adc DX,0 ; Add in carry, if any
- Add AX,Word Ptr ZIP.CompSize ; Add in length of member file
- Adc DX,Word Ptr ZIP.CompSize+2
- Mov Word Ptr ZipFilePtr,AX ; Save the updated pointer
- Mov Word Ptr ZipFilePtr+2,DX
- Mov CX,DX ; Hi order position to CX
- Mov DX,AX ; Lo order position to DX
- Mov AX,4200h ; Move pointer CX:DX from top
- Mov BX,ZIP_Handle ; Set open file handle
- Int 21h ; Call DOS
- Jnc _getrecord_exit ; No errors during seek
- Lea DX,Seek_Err$ ; Set error message
- Jmp Error_Exit ; Display message and quit
-
- _getrecord_exit:
- Xor AL,AL ; Return 00 for local file sig
- Ret ; To Process_Zipfile
-
- _check_dirsig:
- ;Check for Central Directory signature
- Cmp AX,Word Ptr DirSignature
- Jnz _corrupted
- Cmp DX,Word Ptr DirSignature+2
- Jnz _corrupted
- Mov AL,1 ; Return 01 for Directory sig
- Ret ; To Process_Zipfile
-
- _corrupted:
- Mov AL,0FFh ; Return FF for error
- Ret ; To Process_Zipfile
- GetRecord Endp
-
-
-
-
-
- GetRatio Proc Near ; DX:AX = larger, CX:BX = smaller
- Cmp AX,BX ; LO original = LO zipped?
- Jnz _getratio_loop ; No - get actual ratios
- Cmp DX,CX ; HI original = HI zipped?
- Jnz _getratio_loop ; No - get actual ratios
- Xor AX,AX ; Yes - fast exit with 0%
- Mov DX,AX ; Insure HI order is also zero
- Ret ; To caller
-
- ;Get ratio of two sizes: ratio := ((orig-zipped)*100 / orig)
- ;Shift original size, zipped size >> until both are 16 bit values.
- ;This allows using hardware DIV instead of doing 32 bit divide in software.
-
- _getratio_loop:
- Or DX,DX ; HI original size = zero?
- Jz _getratio_rotate_done ; Yes - now find ratio
-
- _getratio_rotate: ; 32 bit divide by two
- Clc ; Clear carry flag
- Rcr DX,1 ; HI(orig-zipped)*100
- Rcr AX,1 ; LO(orig-zipped)*100
-
- Clc ; Clear carry flag
- Rcr CX,1 ; HI(orig)
- Rcr BX,1 ; LO(orig)
- Jmp Short _getratio_loop ; Go again until both HI=0
-
- _getratio_rotate_done:
- ;Get (orig-zipped)*100 as 16 bit values
- Push AX ; Original size as 16 bit value
- Sub AX,BX ; Assume LO remainder <= FFFFh
- Sbb DX,CX ; Assume HI remainder DX = 0
- Mov DX,100 ; Multiplier
- Mul DX ; DX:AX = AX * DX
-
- ;Divide all 16 bit values: ((orig-zipped)*100) / orig)
- Pop BX ; Original size as 16 bit value
- Div BX ; AX(Ratio) = DX:AX / BX
- Or DX,DX ; Is remainder zero?
- Jz _getratio_exit ; Yes - don't fudge AX +1
- Inc AX ; No - set next higher percent
-
- _getratio_exit:
- Xor DX,DX ; Insure HI order is also zero
- Ret ; To caller with AX %
- GetRatio Endp
-
-
-
-
-
- Display_Record Proc Near
- Mov AL,20h ; Blanks
- Lea DI,@Length ; Start of display buffer
- Mov CX,80 ; Length of display buffer
- Rep Stosb ; Clear the display buffer
- Xor AL,AL ; ASCIIZ
- Stosb ; Append it to display buffer
-
- ;Length = Uncompressed Size
- Mov AX,Word Ptr ZIP.UnCompSize
- Mov DX,Word Ptr ZIP.UnCompSize+2
- Lea DI,@TBuffer ; Temp 10 byte AXDX2Dec buffer
- Stc ; Want leading blanks
- Call AXDX2Dec ; Convert DX:AX to ASCII
- Lea SI,@TBuffer ; Temp buffer
- Add SI,3 ; Drop first 3 bytes
- Lea DI,@Length ; Display buffer field
- Mov CX,7 ; Length of display buffer
- Rep Movsb ; Copy temp buffer to display
-
- ;Get compression method
- Mov AX,ZIP.CompMethod ; Get the compression method
- Cmp AX,6 ; Valid range is 0..6
- Jbe _getratio_method_setup ; Range is good - continue
- Mov AX,7 ; Bad value, force 'Unknown'
-
- _getratio_method_setup:
- ;Set compression method into display buffer
- Shl AX,1 ; Convert to WORD offset
- Lea BX,MethodTbl ; Get base of jump table
- Add BX,AX ; Add in the offset
- Mov SI,[BX] ; Get pointer to method string
- Lea DI,@Method ; Destination in display buffer
- Mov CX,8 ; All strings 8 bytes long
- Rep Movsb ; Copy into display buffer
-
- ;Size = Compressed Size
- Mov AX,Word Ptr ZIP.CompSize
- Mov DX,Word Ptr ZIP.CompSize+2
- Lea DI,@TBuffer ; Temp 10 byte AXDX2Dec buffer
- Stc ; Want leading blanks
- Call AXDX2Dec ; Convert DX:AX to ASCII
- Lea SI,@TBuffer ; Temp buffer
- Add SI,3 ; Drop first 3 bytes
- Lea DI,@Size ; Display buffer field
- Mov CX,7 ; Length of display buffer
- Rep Movsb ; Copy temp buffer to display
- Xor AX,AX ; Assume STORED compression method
-
- Mov AX,Word Ptr ZIP.UncompSize ; LO original size
- Mov DX,Word Ptr ZIP.UncompSize+2 ; HI original size
- Mov BX,Word Ptr ZIP.CompSize ; LO zipped size
- Mov CX,Word Ptr ZIP.CompSize+2 ; HI zipped size
- Call GetRatio ; Set DX:AX ratio
-
- Lea DI,@TBuffer ; Point at temp buffer
- Stc ; Setup for leading blanks
- Call AXDX2Dec ; Convert DX:AX in @TBuffer
- Mov SI,DI ; Start of @TBuffer
- Add SI,8 ; Last two bytes of @TBuffer
- Lea DI,@Ratio ; Ratio in display buffer
- Mov CX,2 ; Move two bytes
- Rep Movsb ; Copy into display buffer
- Mov AL,'%' ; Percent sign
- Stosb ; Append to ratio
-
- ;Get ZIP file data
- ;ZIP_File_Month:
- Mov AX,ZIP.DateStamp ; Get ZIP file date word
- And AX,01E0h ; Isolate month bits
- Mov CL,5 ; Shift count
- Shr AX,CL ; Shift month bits into AL
- Xor DX,DX ; Zero hi order
- Stc ; Ask for leading blanks
- Lea DI,@TBuffer ; Point at temp buffer
- Call AXDX2Dec ; Convert AL to ASCII in AX
- Lea DI,@Date ; Start of date field
- Lea SI,@TBuffer ; Start of temp buffer
- Add SI,8 ; Get last two digits
- Lodsw ; Read from temp buffer
- Stosw ; Store in display buffer
-
- ;ZIP_File_Day:
- Mov AX,ZIP.DateStamp ; Get ZIP file date word
- And AX,001Fh ; Isolate day bits
- Xor DX,DX ; Zero hi order
- Clc ; Ask for leading zeros
- Lea DI,@TBuffer ; Point at temp buffer
- Call AXDX2Dec ; Convert AL to ASCII in AX
- Lea DI,@Date ; Start of date field
- Add DI,2 ; Dash before day field
- Mov AL,'-' ; Dash
- Stosb ; Store in day field
- Lea SI,@TBuffer ; Start of temp buffer
- Add SI,8 ; Get last two digits
- Lodsw ; Read from temp buffer
- Stosw ; Store in display buffer
-
- ;ZIP_File_Year:
- Mov AX,ZIP.DateStamp ; Get ZIP file date word
- Shr AH,1 ; Shift into lo bits
- Add AH,80 ; Base year is 1980
- Cmp AH,100 ; Check of correction needed
- Jb _zip_fileyear1 ; No correction necessary
- Sub AH,100 ; Correct for next century
-
- _zip_fileyear1:
- Mov AL,AH ; Put bits into AL
- Lea DI,@TBuffer ; Start of temp buffer
- Xor AH,AH ; Zero hi nybble
- Xor DX,DX ; Zero hi order
- Clc ; Ask for leading zeros
- Call AXDX2Dec ; Convert AL to ASCII in AX
- Lea DI,@Date ; Start of date field
- Add DI,5 ; Dash before year field
- Lea SI,@TBuffer ; Start of temp buffer
- Add SI,8 ; Get last two digits
- Mov AL,'-' ; Year dash
- Stosb ; Store in display buffer
- Lodsw ; Read from temp buffer
- Stosw ; Store in display buffer
-
- ;File time stamp
- Mov AX,ZIP.TimeStamp ; Get ZIP file time word
- And AX,0F800h ; Isolate hour bits
- Mov CL,11 ; Shift count
- Shr AX,CL ; Shift bits to lo order
- Xor DX,DX ; Zero hi order
- Clc ; Ask for leading zeros
- Lea DI,@TBuffer ; Point at temp buffer
- Call AXDX2Dec ; Convert AL to ASCII in AX
- Lea DI,@Time ; Start of time field
- Lea SI,@TBuffer ; Start of temp buffer
- Add SI,8 ; Get last two digits
- Lodsw ; Read from temp buffer
- Stosw ; Store in display buffer
- Mov AL,':' ; Time separator
- Stosb ; Store in display buffer
-
- ;_zip_fileminute:
- Mov AX,ZIP.TimeStamp ; Get ZIP file time word
- And AX,07E0h ; Isolate minute bits
- Mov CL,5 ; Shift count
- Shr AX,CL ; Shift into low order bits
- Xor DX,DX ; Zero hi order
- Clc ; Ask for leading zeros
- Lea DI,@TBuffer ; Point at temp buffer
- Call AXDX2Dec ; Convert AL to ASCII in AX
- Lea DI,@Time ; Start of time field
- Add DI,3 ; Point to minutes field
- Lea SI,@TBuffer ; Start of temp buffer
- Add SI,8 ; Get last two digits
- Lodsw ; Read from temp buffer
- Stosw ; Store in display buffer
-
- ;Set CRC-32 in display buffer
- Mov AX,Word Ptr ZIP.Crc32 ; CRC word LO
- Mov DX,Word Ptr ZIP.Crc32+2 ; CRC word HI
- Lea DI,@CRC ; CRC field in display buffer
- Clc ; Request leading zeros
- Call AXDX2Hex ; Convert to ASCII Hex display
-
- ;Dummy up the attribute field
- Lea DI,@Attr
- Mov AL,'-'
- Stosb
- Stosb
- Stosb
-
- ;Display ZIP local filename
- Mov CX,Word Ptr ZIP.FilenameLen; Length of file name
- Lea SI,LocalFileName ; Name from ZIP data
- Lea DI,@Name ; Name in display buffer
- Rep Movsb ; Copy to display buffer
- Mov AX,0A0Dh ; Reserved CRLF for STOSW
- Stosw ; Store CRLF in display buffer
- Xor AL,AL ; ASCII terminator
- Stosb ; Append to display buffer
- Lea DX,@Length ; Point at display buffer
- Call Display_Message ; Display it
- Ret ; To Process_Zipfile
- Display_Record Endp
-
-
-
-
-
- UpdateStats Proc Near
- Mov AX,Word Ptr TotalLength ; Get total uncompressed bytes
- Mov DX,Word Ptr TotalLength+2
- Add AX,Word Ptr ZIP.UnCompSize ; Add in this member size
- Adc DX,Word Ptr ZIP.UnCompSize+2
- Mov Word Ptr TotalLength,AX ; Save the updated total
- Mov Word Ptr TotalLength+2,DX
-
- Mov AX,Word Ptr TotalSize ; Get total compressed bytes
- Mov DX,Word Ptr TotalSize+2
- Add AX,Word Ptr ZIP.CompSize ; Add in this member size
- Adc DX,Word Ptr ZIP.CompSize+2
- Mov Word Ptr TotalSize,AX ; Save the update total
- Mov Word Ptr TotalSize+2,DX
-
- Inc TotalFiles ; Bump number of member files
-
- Ret ; To Process_Zipfile
- UpdateStats Endp
-
-
-
-
-
- Process_Zipfile Proc Near
- Call GetRecord ; Get local file header
- Or AL,AL ; Is AL zero?
- Jnz _process_01 ; No - check for 01h
- Call UpdateStats ; Update files totals
- Call Display_Record ; Display ZIP member file
- Jmp Short Process_Zipfile ; Go until Central Dir found
-
- _process_01:
- Cmp AL,01h ; Central Dir signature?
- Jnz _process_FF ; No - must be an error
- Ret ; To main line - all done
-
- _process_FF:
- Lea DX,Bad_Zip$ ; Invalid header message
- Jmp Error_Exit ; Display message and quit
- Process_Zipfile Endp
-
-
-
-
-
- Show_Trailer Proc Near
- Cld ; Ascending direction
- Cli ; Interrupts off
- Push BP ; Create stack framer
- Sub SP,100 ; Create 100 byte buffer
- Mov BP,SP ; For temp display buffer
- Sti ; Interrupts on
- Push AX ; Move stack pointer for safety
-
- Mov AL,20h ; Double blanks
- Mov CX,78 ; Byte count
- Mov DI,BP ; Start of display buffer
- Rep Stosb ; Blank the display buffer
- Mov AX,0A0Dh ; Reversed CRLF for Stosw
- Stosw ; Store it
- Xor AX,AX ; ASCIIZ terminator
- Stosw ; Store it
-
- Lea DX,Trailer1$ ; Point at trailer string
- Call Display_Message ; Display it
-
- ;Display in reverse order to avoid display buffer overwrite
- ;Display total count of members in ZIP file
- Mov DI,BP ; Start of display buffer
- Add DI,61 ; Total files field
- Mov AX,Word Ptr TotalFiles ; Get total compressed bytes
- Xor DX,DX ; Zero the high order
- Stc ; Request leading blanks
- Call AXDX2Dec ; Convert it in display buffer
-
- ;Display average compression ratio
- Mov DI,BP ; Start of display buffer
- Add DI,20 ; Ratio field
- Mov AX,Word Ptr TotalLength ; LO total original length
- Mov DX,Word Ptr TotalLength+2 ; HI total original length
- Mov BX,Word Ptr TotalSize ; LO total zipped size
- Mov CX,Word Ptr TotalSize+2 ; HI total zipped size
- Call GetRatio ; Set DX:AX = ratio
-
- Stc ; Request leading blanks
- Call AXDX2Dec ; Convert it in display buffer
- Mov Byte Ptr [BP+30],'%' ; Store the percent sign
-
- ;Display total compressed size
- Mov DI,BP ; Start of display buffer
- Add DI,16 ; Point at size field
- Mov AX,Word Ptr TotalSize ; Get total compressed bytes
- Mov DX,Word Ptr TotalSize+2
- Stc ; Request leading blanks
- Call AXDX2Dec ; Convert it in display buffer
-
- ;Display total uncompressed length
- Mov DI,BP ; Start of display buffer
- Mov AX,Word Ptr TotalLength ; Get total uncompressed bytes
- Mov DX,Word Ptr TotalLength+2
- Stc ; Request leading blanks
- Call AXDX2Dec ; Convert it in display buffer
-
- Mov DX,BP ; Base of display buffer
- Add DX,3 ; Drop 3 leading characters
- Call Display_Message
-
- Cli ; Interrupts off
- Mov SP,BP ; Restore the stack frame
- Add SP,100 ; Restore stack pointer
- Sti ; Interrupts on
- Pop BP ; Restore entry value
- Ret ; To main line
- Show_Trailer Endp
-
-
-
-
-
- Close_ZipFile Proc Near
- Mov AH,3Eh ; Close handle function
- Mov BX,ZIP_Handle ; Get file handle
- Int 21h ; Call DOS
- Ret ; To main line
- Close_ZipFile Endp
-
-
-
-
-
- Main_Line Proc Near
- Cld ; Ascending direction
-
- Call DOS_Version ; Check for DOS 2 or higher
- Call Parse_Parms ; Get command line name
- Call Open_ZipFile ; Open the input ZIP file
- Call Show_Header ; Display top columns
- Call Process_Zipfile ; Display ZIP members
- Call Show_Trailer ; Display totals
- Call Close_ZipFile ; Close the input ZIP file
-
- Exit:
- Mov AX,4C00h ; Return code = 0
- Int 21h ; Call DOS
-
- Error_Exit:
- Call Display_Message ; Error message at [DX]
- Mov AX,4C01h ; Return code = 1
- Int 21h ; Call DOS
- Main_Line Endp
-
- Code Ends
- End Entry ; Required for COM entry point
-
-
-
-
-
-
-
-
-