how do i write a program that compresses files like winzip
Posted on 2001-11-25 05:12:44 by qwerty
qwerty,

The only code for compression I have seen in assembler is Jeremy Collake's code. Do a google search on PECOMPACT and you should find his site.

Regards,

hutch@movsd.com
Posted on 2001-11-25 05:16:06 by hutch--


;###########################################################################
;###########################################################################
; ABOUT QC:
; Quick Compress is a program designed to be of use to programmers. It's
; sole objective is to compress files for use as resources. The
; progammer first compresses the file with QC then compiles it into the
; resource script.
;
; Then, at run time, the programmer uses the ExpandResource funtion to
; de-compress the compressed file. Expand file requires the actual file
; size, the DEST name, and a resource's locked memory handle to operate.
;
;###########################################################################
; Program Info:
; The programmer must make sure the file size specified is correct
; otherwise the file will be corrupted. The reason that this will
; occurr is inproperly allocated memory.
;
; This new version uses a LZ compression algorithm.
;
;###########################################################################
;###########################################################################


;###########################################################################
;###########################################################################
; THE COMPILER OPTIONS
;###########################################################################
;###########################################################################

.386
.model flat, stdcall
option casemap :none ; case sensitive

;###########################################################################
;###########################################################################
; THE INCLUDES SECTION
;###########################################################################
;###########################################################################

include \masm32\include\windows.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc

includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

;###########################################################################
;###########################################################################
; LOCAL MACROS
;###########################################################################
;###########################################################################

szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM

m2m MACRO M1, M2
push M2
pop M1
ENDM

return MACRO arg
mov eax, arg
ret
ENDM

RGB MACRO red, green, blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
ENDM

hWrite MACRO handle, buffer, size
mov edi, handle
add edi, Dest_index
mov ecx, 0
mov cx, size
add Dest_index, ecx
mov esi, buffer
movsb
ENDM

hRead MACRO handle, buffer, size
mov edi, handle
add edi, Spot
mov ecx, 0
mov cx, size
add Spot, ecx
mov esi, buffer
movsb
ENDM

;#################################################################################
;#################################################################################
; LOCAL PROTOTYPES
;#################################################################################
;#################################################################################

;==================================
; Main Program Procedures
;==================================
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
Open PROTO
CompressFile PROTO
ExpandFile PROTO
Output PROTO
AboutProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
MiscCenterWnd PROTO :DWORD,:DWORD

;#################################################################################
;#################################################################################
; BEGIN INITIALIZED DATA
;#################################################################################
;#################################################################################

.data

;================================================================
; HERE ARE THE STRUCTURES THAT WE WILL USE
;================================================================

;========================
; The HASH RECORD
;========================
HASH_REC STRUC
next dw 0 ;Prefix code
char db 0 ;Suffix char
HASH_REC ENDS

;==============================
;Text for the Window Title
;==============================
szDisplayName db "Quick Compress",0

;==============================
;Windows handles and Misc
;==============================
CommandLine dd 0 ; for the commandline params
hRGN dd 0 ; Handle to a region
hOBJ dd 0 ; Handle to an object
hBRUSH dd 0 ; Handle to the Brush
hDC dd 0 ; Handle to device context
hMainWnd dd 0 ; Handle to the main window
hMenu dd 0 ; Handle to the menu
hWnd dd 0 ; Handle to a second window
hInst dd 0 ; Handle to an Instance
hIcon dd 0 ; Handle to the icon
hFile dd 0 ; Handle to the file that we open
Dest_index dd 0 ; Holds the index into Dest mem
Spot dd 0 ; Holds offset into source for expand
written dd 0 ; Holds our output bytes
hComp dd 0 ; Holds icon's handle

;========================================================
; For the Source & Destination files used in Compression
;========================================================
hSrc_Memory dd 0 ; Handle to the source file's memory
hDest_Memory dd 0 ; Handle to the dest. file's memory
Dest_Size dd 0 ; Holds the true size of the dest file
Src_Size dd 0 ; Handle to the size of the source file
Amount_Read dd 0 ; Pointer to the amount read

;===============================
; Strings for the application
;===============================
szClassName db "QC_Class",0
NoHomePage db "Unable to open [url]www.fastsoftware.com[/url] homepage!",0
Homepage db "Http://www.fastsoftware.com/",0
OpenErr db "Unable to Open file!",0
OutputErr db "Error Writing Compressed File!",0
CompressErr db "Error Compressing File!",0
szCompress db "Select a file to compress or expand!",0

HowUse db "Quick Compress is a compression program for programmers.",13,10
db "Simply compress any file of your choice.Then compile that",13,10
db "file into your resource file as RC_DATA.The next step is to",13,10
db "download the decompression routine from my web-site.Include",13,10
db "that file in your program, follow the directions for calling",13,10
db "and WOW! You have your own run-time decompression and a smaller",13,10
db "application than you probably deserve! Have fun. -Chris Hobbs",0

;=======================================================
; To open a file
;=======================================================
szFile db 800 dup(0)
szFileTitle db 800 dup(0)
ofn OPENFILENAME <SIZEOF(OPENFILENAME), NULL, NULL,\
OFFSET szOpenFilter, NULL, NULL, 1h, OFFSET szFile,\
800, OFFSET szFileTitle, 800, NULL, NULL,\
OFN_PATHMUSTEXIST,0, 0, 0, 0, 0, 0>

;=====================================================
;Initialize the Font structure for generic app then
; change what is necessary before calls
;=====================================================
Font LOGFONT <14,0,0,0,FW_NORMAL,\
0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,\
CLIP_STROKE_PRECIS,DEFAULT_QUALITY,\
DEFAULT_PITCH or FF_SWISS,"MS Sans Serif">

;#################################################################################
;#################################################################################
; BEGIN CONSTANTS
;#################################################################################
;#################################################################################

szOpenFilter SBYTE "All Files (*.*)",0,"*.*",0,0
szSaveFilter SBYTE "QC Files (*.qck)",0,"*.qck",0,0
szDefExt SBYTE "qck",0

;#################################################################################
;#################################################################################
; BEGIN EQUATES
;#################################################################################
;#################################################################################

;=================
;Utility Equates
;=================
FALSE equ 0
TRUE equ 1

;================
; resource IDs
;================
IDI_COMP equ 400
IDI_ICON equ 500
IDM_MENU equ 600
IDD_ABOUT equ 700

;================
; Menu ID's
;================
IDM_COMPRESS equ 1000
IDM_EXPAND equ 1100
IDM_EXIT equ 1500
IDM_HOW equ 3400
IDM_ABOUT equ 3500

;======================
; Compression equates
;======================
CLEAR equ 256
EOF equ 257
FIRST_FREE equ 258
MAX_MAX equ 4096

;#################################################################################
;#################################################################################
; BEGIN THE CODE SECTION
;#################################################################################
;#################################################################################

.code

start:
invoke GetModuleHandle, NULL
mov hInst, eax

invoke GetCommandLine
mov CommandLine, eax

invoke WinMain,hInst,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax

;#########################################################################

WinMain proc hInstance :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD

;====================
; Put LOCALs on stack
;====================

LOCAL wc :WNDCLASSEX
LOCAL msg :MSG

LOCAL B_RECT :RECT ; a rectangle struct
LOCAL hFONT :DWORD ; handle to the font
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD

;==================================================
; Fill WNDCLASSEX structure with required variables
;==================================================

mov wc.cbSize,sizeof WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc,offset WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
m2m wc.hInstance,hInst ;<< NOTE: macro not mnemonic
mov wc.hbrBackground,COLOR_BACKGROUND
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,offset szClassName
invoke LoadIcon,hInst,IDI_ICON ; icon ID
mov hIcon,eax
mov wc.hIcon,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
mov wc.hIconSm,0

invoke RegisterClassEx, ADDR wc

;================================
; Create window at following size
;================================
mov Wwd, 250
mov Wht, 200

;===========================================
; Create the main screen
;===========================================
invoke CreateWindowEx,NULL,
ADDR szClassName,
ADDR szDisplayName,
WS_POPUP or WS_SYSMENU or\
WS_MINIMIZEBOX or WS_CAPTION,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL

;===========================================
; Put the window handle in for future uses
;===========================================
mov hMainWnd,eax

;============================================
;Load the menu
;============================================
invoke LoadMenu,hInst,IDM_MENU ; menu ID
mov hMenu, eax
invoke SetMenu,hMainWnd,hMenu

;================================
; Load the icon
;================================
;=================================
; Load all of the icons
;=================================
invoke LoadIcon,hInst,IDI_COMP ; icon ID
mov hComp,eax

;================================
; Show the window
;================================
invoke ShowWindow,hMainWnd,SW_SHOWNORMAL
invoke UpdateWindow,hMainWnd

;================================
; Center window at following size
;================================
invoke GetDesktopWindow
invoke MiscCenterWnd, hMainWnd, eax

;===================================
; Loop until PostQuitMessage is sent
;===================================

StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:

return msg.wParam

WinMain endp

;#########################################################################

WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD

;========================================
; LOCAL VARIABLES
;=========================================

.if uMsg == WM_COMMAND
;======== menu commands ========
.if wParam == IDM_COMPRESS
;==The open and compress code===

;========================
; Get the open file name
;========================
mov eax, offset szOpenFilter
mov ofn.lpstrFilter, eax
mov ofn.lpstrDefExt, NULL
invoke GetOpenFileName, ADDR ofn

;========================
; Test for file
;========================
.if (eax)
;========================
; jump to open code
;========================
invoke Open

;========================
; Test for an error
;========================
.if eax == 0

;==================
; Give error msg
;==================
invoke MessageBox, hWin, ADDR OpenErr,\
NULL,MB_OK

return 0

.endif

;============================
; We were good so compress
;============================
invoke CompressFile

;===========================
; Test for an error
;===========================
.if eax == 0
;===================
; Give Message
;===================
invoke MessageBox, hWin, ADDR CompressErr,\
NULL,MB_OK

return 0

.endif

;==========================
; Now write the file out
;==========================
mov eax, offset szSaveFilter
mov ofn.lpstrFilter, eax
mov eax, offset szDefExt
mov ofn.lpstrDefExt, eax
invoke Output

;===========================
; Test for an error
;===========================
.if eax == 0
;===================
; Give Message
;===================
invoke MessageBox, hWin, ADDR OutputErr,\
NULL,MB_OK

.endif

;===============================
; Release the allocated memory
;===============================
invoke GlobalFree, hSrc_Memory
invoke GlobalFree, hDest_Memory

.endif

.elseif wParam == IDM_EXPAND
;==The open and compress code===

;========================
; Get the open file name
;========================
mov eax, offset szOpenFilter
mov ofn.lpstrFilter, eax
mov ofn.lpstrDefExt, NULL
invoke GetOpenFileName, ADDR ofn

;========================
; Test for file
;========================
.if (eax)
;========================
; jump to open code
;========================
invoke Open

;========================
; Test for an error
;========================
.if eax == 0

;==================
; Give error msg
;==================
invoke MessageBox, hWin, ADDR OpenErr,\
NULL,MB_OK

return 0

.endif


;============================
; We were good so expand
;============================
invoke ExpandFile

;===========================
; Test for an error
;===========================
.if eax == 0
;===================
; Give Message
;===================
invoke MessageBox, hWin, ADDR CompressErr,\
NULL,MB_OK

return 0
.endif

;==========================
; Now write the file out
;==========================
mov ofn.lpstrFilter, NULL
mov ofn.lpstrDefExt, NULL
invoke Output

;===========================
; Test for an error
;===========================
.if eax == 0
;===================
; Give Message
;===================
invoke MessageBox, hWin, ADDR OutputErr,\
NULL,MB_OK

.endif

;===============================
; Release the allocated memory
;===============================
invoke GlobalFree, hSrc_Memory
invoke GlobalFree, hDest_Memory

.endif

.elseif wParam == IDM_EXIT
;===========================
; THIS IS THE FILE-EXIT
;===========================
invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL

.elseif wParam == IDM_HOW
;============================
; This will tell the user
; how to use it
;============================
invoke MessageBox, hMainWnd, ADDR HowUse,ADDR szDisplayName,MB_OK

.elseif wParam == IDM_ABOUT
;===========================
;THIS IS THE HELP-ABOUT
;===========================
invoke DialogBoxParam, hInst, IDD_ABOUT, hMainWnd, ADDR AboutProc, NULL

.endif
;====== end menu commands ======
.elseif uMsg == WM_PAINT
;============================
; get the DC
;============================
invoke GetDC, hMainWnd
mov hDC, eax

;============================
; Set text and bkgnd mode
;============================
invoke SetTextColor, hDC, 00000000h
invoke SetBkMode, hDC, TRANSPARENT

;============================
; Output the text
;============================
invoke TextOut,hDC,5,30,ADDR szCompress,SIZEOF szCompress - 1

;======================================================
; Draw the Icon as an image at the specified location
;======================================================
invoke DrawIconEx,hDC,85,60,hComp,64,64,NULL,\
NULL,DI_NORMAL

;================================
; release the device context
;================================
invoke ReleaseDC, hMainWnd, hDC

.elseif uMsg == WM_DESTROY
;===========================
; Kill the application
;===========================
invoke PostQuitMessage,NULL
return 0

.endif

invoke DefWindowProc,hWin,uMsg,wParam,lParam

ret

WndProc endp
;########################################################################
; End of Main Windows Callback Procedure
;########################################################################

;########################################################################
;########################################################################
; MY FUNCTIONS
;########################################################################
;########################################################################

;########################################################################
; Open Function
;########################################################################
Open proc

;================================================
; Code to open the document and read into mem
;================================================

;=================================
; Create the file
;=================================
invoke CreateFile, offset szFile, GENERIC_READ or GENERIC_WRITE, \
FILE_SHARE_READ, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL
mov hFile, eax

;===============================
; Test for an error
;===============================
.if eax == INVALID_HANDLE_VALUE
jmp err
.endif

;===============================
; Get the file size
;===============================
invoke GetFileSize, hFile, NULL
mov Src_Size, eax

;================================
; test for an error
;================================
.if eax == -1
jmp err
.endif

;==============================================
; Allocate enough memeory to hold the file
;==============================================
invoke GlobalAlloc, GMEM_FIXED, Src_Size
mov hSrc_Memory, eax
mov Spot, 0

;===================================
; test for an error
;===================================
.if eax == 0
jmp err
.endif

;==============================================
; Allocate worst case scenario memory
; for compression program
;==============================================
mov eax, Src_Size
shl eax, 4
invoke GlobalAlloc, GMEM_FIXED, eax
mov hDest_Memory, eax
mov Dest_index, 0

;===============================
; test for an error
;===============================
.if eax == 0
jmp err
.endif

;===================================
; Put the file into memory
;===================================
invoke ReadFile, hFile, hSrc_Memory, Src_Size, offset Amount_Read, NULL

;===============================
; test for an error
;===============================
.if eax == 0
jmp err
.endif

;============================
; Close the handle
;============================
invoke CloseHandle,hFile

done:
return 1

err:
;============================
; Close the handle
;============================
invoke CloseHandle,hFile

return 0

Open endp
;########################################################################
; END of Open
;########################################################################

;########################################################################
; CompressFile Function
;########################################################################
CompressFile proc

;=====================================
; Code to compress the chosen file
;=====================================

;=====================================
; define all of the local variables
;=====================================
LOCAL Buf_Count:BYTE
LOCAL Char:BYTE
LOCAL index:BYTE
LOCAL Prev_Char1:BYTE
LOCAL Prev_Char2:BYTE
LOCAL Bit_Mask:BYTE
LOCAL pcTable:DWORD
LOCAL Num_In_Mask:BYTE

;======================================
; Allocate memory for our table
;======================================
invoke GlobalAlloc, GMEM_FIXED, 32768
mov pcTable, eax

;========================================
; Set to ascii 32 because it's most used
;=========================================
invoke RtlFillMemory, pcTable, 32768, 20h

;=====================================
; Initialize file vars just in case
;=====================================
mov Dest_index, 0
mov Spot, 0
mov Bit_Mask, 0
mov Prev_Char1, 0
mov Prev_Char2, 0
mov Num_In_Mask, 0
mov Buf_Count, 0

;======================================
; get the byte from file
;======================================
jmp tstEOF
top: mov ebx, hSrc_Memory
add ebx, Spot
mov al, BYTE PTR [ebx]
mov Char, al
inc Spot

;================================
; Aren't done so try and predict
; the character
;================================
mov bl, Prev_Char1
mov bh, 0
mov dl, Prev_Char2
mov dh, 0
shl bx, 7
xor bx, dx
push bx
xor ebx, ebx
pop bx
mov eax, pcTable
add eax, ebx
mov cl, BYTE PTR [eax]
mov al, Char

;==============================
; Was the prediction correct
;==============================
.if al == cl
;===================
; Yes, we did it so
; adjust mask
;===================
mov al,1
mov cl, Num_In_Mask
shl al, cl
xor al, Bit_Mask
mov Bit_Mask, al

.else
;==========================
; We were wrong this time
; so update the table
;==========================
mov bl, Prev_Char1
mov bh, 0
mov dl, Prev_Char2
mov dh, 0
shl bx, 7
xor bx, dx
push bx
xor ebx, ebx
pop bx
mov eax, pcTable
add eax, ebx
mov dx, 0
mov dl, Char
mov cl, BYTE PTR [eax]
mov BYTE PTR [eax], dl

;=============================
; Put character in buffer
;=============================
push dx
inc Buf_Count

.endif

;===========================================
; Inc Num in mask and test for full status
;===========================================
inc Num_In_Mask

.if Num_In_Mask == 8
;========================
; Write out the mask
;========================
mov ebx, hDest_Memory
add ebx, Dest_index
mov cl, Bit_Mask
mov BYTE PTR [ebx], cl
inc Dest_index

;=============================
; Setup to write what we kept
;=============================
mov index, 0
xor ecx, ecx
mov cl, Buf_Count
mov edx, Dest_index
add Dest_index, ecx
write:
.if cl > 0
;=========================
; Actual write
;=========================
mov ebx, hDest_Memory
add ebx, edx
add ebx, ecx
dec ebx
pop ax
mov BYTE PTR [ebx], al
dec cl
jmp write

.endif

;============================
; Reset the variables we used
;============================
mov Num_In_Mask, 0
mov Buf_Count, 0
mov Bit_Mask, 0

.endif

;==============================
; Shift the characters
;==============================
mov al, Prev_Char2
mov bl, Char
mov Prev_Char2, bl
mov Prev_Char1, al

tstEOF:
;============================
; test for over file
;============================
mov eax, Spot
.if eax > Src_Size
jmp check
.endif

;=============================
; Jump up and do it again
;=============================
jmp top

check:
;=============================
; We hit eof but stuff could
; be in the buffer still
;=============================
.if Num_In_Mask !=0
;========================
; Write out the mask
;========================
mov ebx, hDest_Memory
add ebx, Dest_index
mov cl, Bit_Mask
mov BYTE PTR [ebx], cl
inc Dest_index

;=============================
; Setup to write what we kept
;=============================
mov index, 0
xor ecx, ecx
mov cl, Buf_Count
mov edx, Dest_index
add Dest_index, ecx
dec Dest_index
dec Dest_index
write2:
.if cl > 0
;=========================
; Actual write
;=========================
mov ebx, hDest_Memory
add ebx, edx
add ebx, ecx
dec ebx
pop ax
mov BYTE PTR [ebx], al
dec cl
jmp write2

.endif


.endif

done:
;===============================
; Free the memory we used
;===============================
invoke GlobalFree, pcTable

return 1
err:
return 0

CompressFile endp
;########################################################################
; END of CompressFile
;########################################################################

;########################################################################
; ExpandFile Function
;########################################################################
ExpandFile proc

;=====================================
; Code to decompress the chosen file
;=====================================

;=====================================
; define all of the local variables
;=====================================
LOCAL Char_In:BYTE
LOCAL Char_Out:BYTE
LOCAL Prev_Char1:BYTE
LOCAL Prev_Char2:BYTE
LOCAL Bit_Mask:BYTE
LOCAL pcTable:DWORD
LOCAL Num_In_Mask:BYTE

;======================================
; Allocate memory for our table
;======================================
invoke GlobalAlloc, GMEM_FIXED, 32768
mov pcTable, eax

;========================================
; Set to ascii 32 because it's most used
;=========================================
invoke RtlFillMemory, pcTable, 32768, 20h

;=====================================
; Initialize file vars just in case
;=====================================
mov Dest_index, 0
mov Spot, 0
mov Bit_Mask, 0
mov Prev_Char1, 0
mov Prev_Char2, 0
mov Num_In_Mask, 0

;======================================
; get the byte from file
;======================================
jmp tstEOF
top: mov eax, Spot
.if eax <= Src_Size
mov ebx, hSrc_Memory
add ebx, Spot
mov al, BYTE PTR [ebx]
mov Char_In, al
inc Spot

.endif

;==================================
; Put it into the mask for the loop
;===================================
mov Bit_Mask, al

;====================================
; Loop for every bit in the mask
;====================================
mov Num_In_Mask, 0
msk:
cmp Num_In_Mask, 8
je StopFor

;====================================
; Find out if we predicted this char
;====================================
mov al, Bit_Mask
mov dx, 1
mov cl, Num_In_Mask
mov ah, 0
shl dx, cl
test ax,dx
je notpred

;===================================
; Yes, we predicted it, so process
;===================================
mov bl, Prev_Char1
mov bh, 0
mov dl, Prev_Char2
mov dh, 0
shl bx, 7
xor bx, dx
push bx
xor ebx, ebx
pop bx
mov eax, pcTable
add eax, ebx
mov cl, BYTE PTR [eax]
mov Char_Out, cl

;=============================
; Jump over not pred
;=============================
jmp donepred


;===============================
; We didn't predict this one
;===============================
notpred:
;=============================
; Read in the character we
; will write out
;=============================
mov eax, Spot
.if eax <= Src_Size
mov ebx, hSrc_Memory
add ebx, Spot
mov cl, BYTE PTR [ebx]
mov Char_Out, cl
inc Spot

.endif

;============================
; Update the table
;============================
mov bl, Prev_Char1
mov bh, 0
mov dl, Prev_Char2
mov dh, 0
shl bx, 7
xor bx, dx
push bx
xor ebx, ebx
pop bx
mov eax, pcTable
add eax, ebx
mov cl, Char_Out
mov BYTE PTR [eax], cl

donepred:
;=============================
; Write the character out to
; our destination memory
;=============================
mov ebx, hDest_Memory
add ebx, Dest_index
mov cl, Char_Out
mov BYTE PTR [ebx], cl
inc Dest_index

;=============================
; Shift the characters over
;=============================
mov al, Prev_Char2
mov bl, Char_Out
mov Prev_Char2, bl
mov Prev_Char1, al

;==========================
; Inc and go back to mask
; processing
;==========================
inc Num_In_Mask
jmp msk

;===========================
; Get another byte and do
; it again
;===========================
StopFor:

;=============================
; Test to see if we are over
; limit for source
;=============================
tstEOF:
mov eax, Spot
.if eax >= Src_Size
jmp done
.endif


jmp top

done:
;===============================
; Free the memory we used
;===============================
invoke GlobalFree, pcTable

return 1

err:
return 0

ExpandFile endp
;########################################################################
; END of ExpandFile
;########################################################################

;########################################################################
; Output Function
;########################################################################
Output proc

;=====================================
; Code to save file out
;=====================================

;======================================
; Setup the filename to write out to
;======================================
invoke GetSaveFileName, ADDR ofn

;==========================
; End if they cancel
;==========================
.if eax == 0
jmp done
.endif

;======================================
; Create the file to write to
;======================================
invoke CreateFile, offset szFile, GENERIC_READ or GENERIC_WRITE, \
FILE_SHARE_READ, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL
mov hFile, eax

;===============================
; Test for an error
;===============================
.if eax == INVALID_HANDLE_VALUE
jmp err
.endif

;======================================
; Write to the file
;======================================
invoke WriteFile, hFile, hDest_Memory, Dest_index, offset written, NULL

;======================================
; Test for an error
;======================================
.if eax == 0
;=========================
; Jump to error
;=========================
jmp err

.endif

;======================================
; Close the handle to the file
;======================================
invoke CloseHandle, hFile

done:
return 1

err:
return 0

Output endp
;########################################################################
; END of Output
;########################################################################

;########################################################################
; Handle the about box
;########################################################################
AboutProc proc hDlg :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD

;=================================
; The equate for the homepage code
;=================================
IDHOME equ 2

;=========================
; Get the message into eax
;=========================
mov eax, uMsg
.IF (eax == WM_INITDIALOG)
invoke MiscCenterWnd, hDlg, hMainWnd

.ELSEIF (eax == WM_COMMAND) && (wParam == IDOK)
invoke EndDialog, hDlg, TRUE

.ELSEIF (eax == WM_COMMAND) && (wParam == IDHOME)
invoke EndDialog, hDlg, TRUE

;===================================
; Execute our homepage
;===================================
invoke ShellExecute,0,0,ADDR Homepage,0,0,0

.if eax <= 32
;======================
; Tell them we can't
; open the homepage
;======================
invoke MessageBox, hMainWnd, offset NoHomePage, NULL, MB_OK

.endif

.ELSE
mov eax, FALSE ; show message not processed
jmp Return
.ENDIF
mov eax, TRUE ; show message was processed

Return: ret

AboutProc endp
;########################################################################
; END ABOUTPROC
;########################################################################

;########################################################################
; Misc Center Window from SIB by Steve Gibson. Thanks Steve!
;########################################################################
MiscCenterWnd proc hChild:DWORD,
hParent:DWORD

; Define the local variables
LOCAL rcP:RECT, rcC:RECT, xNew:DWORD, yNew:DWORD

invoke GetWindowRect, hParent, ADDR rcP

.IF (eax)
invoke GetWindowRect, hChild, ADDR rcC
.IF (eax)
mov eax, rcP.right ;center horizontally
sub eax, rcP.left ;x=Px+(Pdx-Cdx)/2
sub eax, rcC.right
add eax, rcC.left
sar eax, 1
add eax, rcP.left

; check if off screen at left
.IF (sign?)
mov eax, 0
.ENDIF
mov xNew, eax

invoke GetSystemMetrics, SM_CXFULLSCREEN
sub eax, rcC.right
add eax, rcC.left

; check if off screen at right
.IF (eax < xNew)
mov xNew, eax
.ENDIF

mov eax, rcP.bottom ; center vertically
sub eax, rcP.top ; y=Py+(Pdy-Cdy)/2
sub eax, rcC.bottom
add eax, rcC.top
sar eax, 1
add eax, rcP.top

; check if off screen at top
.IF (sign?)
mov eax, 0
.ENDIF
mov yNew,eax

invoke GetSystemMetrics, SM_CYFULLSCREEN
sub eax, rcC.bottom
add eax, rcC.top
.IF (eax < yNew)
mov yNew, eax
.ENDIF

invoke SetWindowPos, hChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE + SWP_NOZORDER

.ENDIF
.ENDIF

Return: ret

MiscCenterWnd ENDP
;########################################################################
; END MISC CENTER WINDOW
;########################################################################

;######################################
; THIS IS THE END OF THE PROGRAM CODE #
;######################################
end start
Posted on 2001-11-25 09:49:12 by bazik