Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

252 lines
5.7 KiB

; This module implements an lz unpacking function.
;
; (C) Microsoft Corperation
; Written by Steven Zeck May 1989
.model small,c
cBufMax equ 4096
cStrMax equ 18
cbIndex equ 2
.data
; The following sets of pointers provide input and output buffers
; The ??End pointers are the end points of the buffers. When
; the current buffer point equals this value, functions must be
; called to flush, read more data.
extrn pOutBuff:dWord, pOutBuffEnd:dWord
extrn pInBuff:dWord, pInBuffEnd:dWord
extrn cbExpanded:dWord ; expanded file size, set by caller to unpack
extrn ringBuf:byte ; byte buffer of cBufMax size
.code
; Functions to read data into pInBuff, and write to pOutBuff.
;
; readInBuff returns the next character in AL and resets pInBuff.
;
; writeOutBuff writes the buffer bounded by pOutBuff and the beginning
; of the buffer (initial pOutBuff). It also resets pOutBuff.
extrn readInBuff:proc, writeOutBuff:Proc
unpack proc uses si di
local cbOut:dWord
; register useage:
;
; dx - flags
; es:si - pInBuff
; es:di - pOutBuff
; bx - iBuffCur, pointer to ringBuff
xor ax,ax
mov word ptr (cbOut),ax
mov word ptr (cbOut).2,ax
mov dx,ax
mov bx, cBufMax - cStrMax
mov ax, " " ; initial ringBuf to blanks
push ds
pop es
mov di, offset ringBuf
mov cx, (cBufMax - cStrMax)/2
rep stosw
les si,pInBuff ; pInBuff and pOutBuff are based
mov di,word ptr pOutBuff
;
; pOutBuff must be incremented initially to simulate the
; effect of calls to writeOutBuff. After flushing the buffer,
; writeOutBuff does the following, leaving pOutBuff incremented:
;
; pOutBuff = pCopyBuff2;
; *pOutBuff++ = c;
;
inc word ptr pOutBuff ; Very tricky -- confer with IO.C
jmp decodeChar
@@:
push bx
call readInBuff
pop bx
mov dx,si
les si,pInBuff
jmp fromReloadInBuff
reloadInBuff:
mov si,di ; if (cbOut + byteInCurrent record >=
sub si,word ptr pOutBuff ; cbExpanded)
inc si ; return -- done
mov ax,word ptr (cbOut)
add ax,si
mov si,dx
mov dx,word ptr (cbOut).2 ; AX:DX -> bytes written
adc dx,0
cmp dx,word ptr cbExpanded.2
jb @B
ja exit
cmp ax,word ptr cbExpanded
jb @B
exit:
mov word ptr pOutBuff,di
ret
@@:
mov si,dx
push bx
call readInBuff
pop bx
mov dx,si
les si,pInBuff
jmp short fromGetFlagWord
getFlagWord: ; process char as a flag byte
mov dh,0ffh
mov dl,al ; flag = 0ff | char
cmp si, word ptr pInBuffEnd
jae @B
lods byte ptr es:[si]
test dl,1
jz putString
addChar: ; process char as literal character
mov [bx].ringBuf,al ; ringBuff[bx] = char
inc bx
and bh,0fh ; bx = bx+1 % cBufMax
cmp di, word ptr pOutBuffEnd
jae writeOutBuff1
stos byte ptr es:[di] ; writeChar(char)
decodeChar:
cmp si, word ptr pInBuffEnd ; al = char = readChar()
jae reloadInBuff
lods byte ptr es:[si]
fromReloadInBuff:
shr dx,1 ; flag >>= 1
or dh,dh
jz getFlagWord ; if high byte 0, then al is flag byte
fromGetFlagWord:
test dl,1
jnz addChar ; if (flag&1) procss as single character
putString:
; char & next byte form string index & count
mov cl,al
cmp si, word ptr pInBuffEnd
jae reloadInBuff1
lods byte ptr es:[si] ; al = readChar()
fromReloadInBuff1:
push si
xchg al,cl ; cx = cb = char
xor ah,ah ; compute ring index to SI
mov si,ax ; si = (cb&0f0 << 4) | char
mov al,cl
and al,0f0h
shl ax,1
shl ax,1
shl ax,1
shl ax,1
or si,ax
and cx,0fh ; cx = cb = (cb&0fh) + 3
add cl,3
putStringChar:
mov al, byte ptr [si].ringBuf ; al = ringBuf[si]
inc si
and si,0fffh
; si = si+1 % cBufMax
cmp di, word ptr pOutBuffEnd
jae writeOutBuff2
stosb ; writeChar(al)
fromWriteOutBuff2:
mov [bx].ringBuf,al ; ringBug[bx] = al
inc bx
and bh,0fh ; bx = bx+1 % cBufMax
loop putStringChar ; while(--cb)
pop si
jmp decodeChar
; The following are out of line functions to reading and writing into the
; input and output buffers
reloadInBuff1:
push cx
push bx
mov si,dx
call readInBuff
pop bx
pop cx
mov dx,si
les si,pInBuff
jmp fromReloadInBuff1
writeOutBuff1:
mov word ptr pOutBuff,di
push di
push bx
push ax
mov di,dx
call writeOutBuff
pop ax
pop bx
mov dx,di
les di,pOutBuff
pop cx
sub cx,di ; cbOut += sizeof buffer written
inc cx ; increment ONCE to get size
add word ptr (cbOut),cx
adc word ptr (cbOut).2,0
jmp decodeChar
writeOutBuff2:
push cx
push di
mov word ptr pOutBuff,di
mov di,dx
push bx
push ax ; write wants a character on stack
call writeOutBuff
mov dx,di
pop ax
pop bx
les di,pOutBuff
pop cx
sub cx,di ; cbOut += sizeof buffer written
inc cx ; increment ONCE to get size
add word ptr (cbOut),cx
adc word ptr (cbOut).2,0
pop cx
jmp short fromWriteOutBuff2
unpack endp
end