Subversion Repositories Kolibri OS

Compare Revisions

Ignore whitespace Rev 6672 → Rev 6673

/programs/fs/kfar/trunk/kfar_arc/archiver_deflate.txt
1,4 → 1,7
archiver.obj ýêñïîðòèðóåò äâå ôóíêöèè äëÿ ðàñïàêîâêè deflate-äàííûõ.
À òàêæå ôóíêöèè: deflateInit, deflateInit2, deflateReset, deflate,
deflateEnd äëÿ óïàêîâêè deflate-äàííûõ, ñäåëàííûå íà îñíîâå ñâîáîäíî
ðàñïðîñòðàíÿåìîé áèáëèîòåêè zlib.
 
Ïåðâàÿ: deflate_unpack
Îáúÿâëåíèå â ñòèëå Ñè: void* __stdcall deflate_unpack(const void* data, unsigned* pLength);
64,3 → 67,17
mov [ecx], length
mov eax, buffer
ret 8
 
Àëãîðèòì äëÿ óïàêîâêè äàííûõ:
1) Âûçîâ ôóíêöèè deflateInit èëè deflateInit2.
2) Ðàçáèåíèå âõîäíîãî ïîòîêà äàííûõ íà ïîðöèè ïî 64 Êá.
Äëÿ êàæäîãî áëîêà â 64 Êá â öèêëå äîëæåí äåëàòüñÿ âûçîâ ôóíêöèè deflate.
Çà îäèí âûçîâ ôóíêöèè deflate ñæàòûõ äàííûõ îáðàçóåòñÿ íå áîëåå 16 Êá.
Ò. å. åñëè ñæèìàåìûõ äàííûõ ìåíåå 16 Êá, òî èõ ìîæíî óïàêîâàòü çà îäèí âûçîâ deflate.
Åñëè ñæèìàåìûõ äàííûõ ìåíåå 64 Êá, òî èõ ìîæíî óïàêîâàòü îðãàíèçîâàâ îäèí öèêë ñ âûçîâîì deflate.
Åñëè ñæèìàåìûõ äàííûõ áîëåå 64 Êá, òî èõ ìîæíî óïàêîâàòü îðãàíèçîâàâ äâîéíîé öèêë ñ âûçîâîì deflate.
3) Âûçîâ ôóíêöèè deflateEnd äëÿ î÷èñòêè ïàìÿòè.
Çàìå÷àíèÿ:
Áîëüøèå óðîâíè ñæàòèÿ ïîêà ÷òî íå ïîääåðæèâàþòñÿ.
Ôóíêöèÿ deflate íå êîðåêòíî ðàáîòàåò ñ ïàðàìåòðîì Z_NO_FLUSH.
(Ïîêà ïðîáëåìà íå óñòðàíåíà ðåêîìåíäóåòñÿ âñåãäà ñòàâèòü Z_FINISH)
/programs/fs/kfar/trunk/kfar_arc/kfar_arc.asm
3,7 → 3,7
; target platform: KolibriOS
; compiler: FASM 1.67.14
; version: 0.17
; last update: 2009-09-03 (Sep 03, 2009)
; last update: 2016-11-04 (Nov 04, 2016)
; minimal KFar version: 0.43
; minimal kernel: no limit
;
19,19 → 19,20
section '.flat' code readable align 16
 
; include auxiliary procedures
include 'kglobals.inc' ; iglobal/uglobal
include 'lang.inc' ; define language for localized strings
include 'crc.inc' ; CRC32 calculation
include 'sha256.inc' ; SHA-256 hash algorithm
include 'aes.inc' ; AES crypto algorithm
include 'kglobals.inc' ; iglobal/uglobal
include 'lang.inc' ; define language for localized strings
include 'crc.inc' ; CRC32 calculation
include 'sha256.inc' ; SHA-256 hash algorithm
include 'aes.inc' ; AES crypto algorithm
; include main code for archives loading
include '7z.inc' ; *.7z
include 'lzma.inc' ; LZMA-decoder for *.7z
include 'ppmd.inc' ; PPMD-decoder for *.7z
include '7zbranch.inc' ; branch filters for *.7z
include '7zaes.inc' ; AES cryptor for *.7z
include 'zip.inc' ; *.zip
include 'deflate.inc' ; Deflate[64] decoder for *.7z and *.zip
include '7z.inc' ; *.7z
include 'lzma.inc' ; LZMA-decoder for *.7z
include 'ppmd.inc' ; PPMD-decoder for *.7z
include '7zbranch.inc' ; branch filters for *.7z
include '7zaes.inc' ; AES cryptor for *.7z
include 'zip.inc' ; *.zip
include 'deflate.inc' ; Deflate[64] decoder for *.7z and *.zip
include '../zlib/zlib.asm' ; deflate coder
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;; Interface for KFar ;;;;;;;;;;;;;;
38,64 → 39,64
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
virtual at 0
kfar_info_struc:
.lStructSize dd ?
.kfar_ver dd ?
.open dd ?
.open2 dd ?
.read dd ?
.write dd ?
.seek dd ?
.tell dd ?
.flush dd ?
.filesize dd ?
.close dd ?
.pgalloc dd ?
.pgrealloc dd ?
.pgfree dd ?
.getfreemem dd ?
.pgalloc2 dd ?
.pgrealloc2 dd ?
.pgfree2 dd ?
.menu dd ?
.menu_centered_in dd ?
.DialogBox dd ?
.SayErr dd ?
.Message dd ?
.cur_console_size dd ?
.lStructSize dd ?
.kfar_ver dd ?
.open dd ?
.open2 dd ?
.read dd ?
.write dd ?
.seek dd ?
.tell dd ?
.flush dd ?
.filesize dd ?
.close dd ?
.pgalloc dd ?
.pgrealloc dd ?
.pgfree dd ?
.getfreemem dd ?
.pgalloc2 dd ?
.pgrealloc2 dd ?
.pgfree2 dd ?
.menu dd ?
.menu_centered_in dd ?
.DialogBox dd ?
.SayErr dd ?
.Message dd ?
.cur_console_size dd ?
end virtual
 
; int __stdcall plugin_load(kfar_info* info);
; Initialization of plugin + Save used KFar functions.
plugin_load:
mov eax, [esp+4]
mov [kfar_info], eax
push [eax+kfar_info_struc.open2]
pop [open2]
push [eax+kfar_info_struc.filesize]
pop [filesize]
push [eax+kfar_info_struc.read]
pop [read]
push [eax+kfar_info_struc.seek]
pop [seek]
push [eax+kfar_info_struc.close]
pop [close]
lea esi, [eax+kfar_info_struc.DialogBox]
mov edi, DialogBox
movsd
movsd
movsd
movsd
lea esi, [eax+kfar_info_struc.pgalloc]
mov edi, pgalloc
movsd
movsd
movsd
movsd
call init_crc_table
call init_aes
call init_ppmd
xor eax, eax ; success
ret 4
mov eax, [esp+4]
mov [kfar_info], eax
push [eax+kfar_info_struc.open2]
pop [open2]
push [eax+kfar_info_struc.filesize]
pop [filesize]
push [eax+kfar_info_struc.read]
pop [read]
push [eax+kfar_info_struc.seek]
pop [seek]
push [eax+kfar_info_struc.close]
pop [close]
lea esi, [eax+kfar_info_struc.DialogBox]
mov edi, DialogBox
movsd
movsd
movsd
movsd
lea esi, [eax+kfar_info_struc.pgalloc]
mov edi, pgalloc
movsd
movsd
movsd
movsd
call init_crc_table
call init_aes
call init_ppmd
xor eax, eax ; success
ret 4
 
; HANDLE __stdcall OpenFilePlugin(HANDLE basefile,
; const void* attr, const void* data, int datasize,
105,52 → 106,52
; and if so, loads information and returns
; handle to be used in subsequent calls to ReadFolder, SetFolder and so on.
OpenFilePlugin:
mov [bPasswordDefined], 0
mov esi, [esp+12]
mov ebp, [esp+4]
mov [bPasswordDefined], 0
mov esi, [esp+12]
mov ebp, [esp+4]
; test for 7z archive
cmp dword [esp+16], 20h ; minimal size of 7z archive is 20h bytes
jb .no_7z
cmp word [esi], '7z' ; signature, part 1
jnz .no_7z
cmp dword [esi+2], 0x1C27AFBC ; signature, part 2
jnz .no_7z
call open_7z
ret 28
cmp dword [esp+16], 20h ; minimal size of 7z archive is 20h bytes
jb .no_7z
cmp word [esi], '7z' ; signature, part 1
jnz .no_7z
cmp dword [esi+2], 0x1C27AFBC ; signature, part 2
jnz .no_7z
call open_7z
ret 28
.no_7z:
; test for zip archive
cmp dword [esp+16], 22 ; minimal size of zip archive is 22 bytes
jb .no_zip
cmp word [esi], 0x4B50
jnz .no_zip
cmp word [esi+2], 0x0403
jz .zip
cmp word [esi+2], 0x0201
jz .zip
cmp word [esi+2], 0x0606
jz .zip
cmp word [esi+2], 0x0706
jz .zip
cmp word [esi+2], 0x0605
jnz .no_zip
cmp dword [esp+16], 22 ; minimal size of zip archive is 22 bytes
jb .no_zip
cmp word [esi], 0x4B50
jnz .no_zip
cmp word [esi+2], 0x0403
jz .zip
cmp word [esi+2], 0x0201
jz .zip
cmp word [esi+2], 0x0606
jz .zip
cmp word [esi+2], 0x0706
jz .zip
cmp word [esi+2], 0x0605
jnz .no_zip
.zip:
call open_zip
ret 28
call open_zip
ret 28
.no_zip:
xor eax, eax
ret 28
xor eax, eax
ret 28
 
; Handle of plugin in kfar_arc is as follow:
virtual at 0
handle_common:
.type dd ?
.root.subfolders dd ?
.root.subfolders.end dd ?
.root.subfiles dd ?
.root.subfiles.end dd ?
.root.NumSubItems dd ?
.curdir dd ?
.NumFiles dd ?
.type dd ?
.root.subfolders dd ?
.root.subfolders.end dd ?
.root.subfiles dd ?
.root.subfiles.end dd ?
.root.NumSubItems dd ?
.curdir dd ?
.NumFiles dd ?
; ... some plugin-specific data follows ...
end virtual
 
157,153 → 158,153
; and for each archive item there is one file info structure, which begins as follow:
virtual at 0
file_common:
.fullname dd ? ; pointer to cp866 string
.name dd ? ; name without path (end of .fullname)
.namelen dd ? ; strlen(.name)
.bIsDirectory db ?
.bPseudoFolder db ?
rb 2
.parent dd ? ; pointer to parent directory record
.subfolders dd ? ; head of L2-list of subfolders [for folders]
.subfolders.end dd ?
.subfiles dd ? ; head of L2-list of files [for folders]
.subfiles.end dd ?
.NumSubItems dd ?
.next dd ? ; next item in list of subfolders/files
.prev dd ? ; previous item in list of subfolders/files
.stamp dd ? ; stamp for GetFiles
.fullname dd ? ; pointer to cp866 string
.name dd ? ; name without path (end of .fullname)
.namelen dd ? ; strlen(.name)
.bIsDirectory db ?
.bPseudoFolder db ?
rb 2
.parent dd ? ; pointer to parent directory record
.subfolders dd ? ; head of L2-list of subfolders [for folders]
.subfolders.end dd ?
.subfiles dd ? ; head of L2-list of files [for folders]
.subfiles.end dd ?
.NumSubItems dd ?
.next dd ? ; next item in list of subfolders/files
.prev dd ? ; previous item in list of subfolders/files
.stamp dd ? ; stamp for GetFiles
end virtual
 
; void __stdcall ClosePlugin(HANDLE hPlugin);
; This function frees all resources allocated in OpenFilePlugin.
ClosePlugin:
mov eax, [esp+4] ; get hPlugin
mov eax, [eax] ; hPlugin is pointer to internal data structure
; first dword is archive type (type_xxx constants)
dec eax ; types start from 1
jmp dword [ClosePluginTable+eax*4]
mov eax, [esp+4] ; get hPlugin
mov eax, [eax] ; hPlugin is pointer to internal data structure
; first dword is archive type (type_xxx constants)
dec eax ; types start from 1
jmp dword [ClosePluginTable+eax*4]
 
; int __stdcall ReadFolder(HANDLE hPlugin,
; unsigned dirinfo_start, unsigned dirinfo_size, void* dirdata);
ReadFolder:
; init header
mov edi, [esp+16]
mov ecx, 32/4
xor eax, eax
rep stosd
mov byte [edi-32], 1 ; version
mov ebp, [esp+4]
mov edi, [esp+16]
mov ecx, 32/4
xor eax, eax
rep stosd
mov byte [edi-32], 1 ; version
mov ebp, [esp+4]
; get current directory
lea ebx, [ebp+handle_common.root.subfolders]
cmp [ebp+handle_common.curdir], 0
jz @f
mov ebx, [ebp+handle_common.curdir]
add ebx, file_common.subfolders
lea ebx, [ebp+handle_common.root.subfolders]
cmp [ebp+handle_common.curdir], 0
jz @f
mov ebx, [ebp+handle_common.curdir]
add ebx, file_common.subfolders
@@:
mov ecx, [ebx+16]
mov [edi-24], ecx ; number of files
mov ecx, [ebx+16]
mov [edi-24], ecx ; number of files
; edi points to BDFE
push 6 ; assume EOF
pop eax
sub ecx, [esp+8]
ja @f
and dword [edi-28], 0 ; number of files read
ret 10h
push 6 ; assume EOF
pop eax
sub ecx, [esp+8]
ja @f
and dword [edi-28], 0 ; number of files read
ret 10h
@@:
cmp ecx, [esp+12]
jb @f
mov ecx, [esp+12]
xor eax, eax ; OK
cmp ecx, [esp+12]
jb @f
mov ecx, [esp+12]
xor eax, eax ; OK
@@:
mov [edi-28], ecx
push eax
mov [edi-28], ecx
push eax
; copy files data
jecxz .done
jecxz .done
; seek to required item
mov eax, [esp+8+4]
mov esi, [ebx]
mov eax, [esp+8+4]
mov esi, [ebx]
.0:
test esi, esi
jnz .1
mov esi, [ebx+8]
test esi, esi
jnz .1
mov esi, [ebx+8]
.1:
add esi, ebp
dec eax
js .2
mov esi, [esi+file_common.next]
jmp .0
add esi, ebp
dec eax
js .2
mov esi, [esi+file_common.next]
jmp .0
.2:
.copy:
pushad
mov eax, esi
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
pop edi esi
push esi edi
add edi, 40
mov ecx, [esi+file_common.namelen]
mov esi, [esi+file_common.name]
rep movsb
mov byte [edi], 0
popad
add edi, 304
mov esi, [esi+file_common.next]
test esi, esi
jnz @f
mov esi, [ebx+8]
pushad
mov eax, esi
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
pop edi esi
push esi edi
add edi, 40
mov ecx, [esi+file_common.namelen]
mov esi, [esi+file_common.name]
rep movsb
mov byte [edi], 0
popad
add edi, 304
mov esi, [esi+file_common.next]
test esi, esi
jnz @f
mov esi, [ebx+8]
@@:
add esi, ebp
loop .copy
add esi, ebp
loop .copy
.done:
pop eax
ret 10h
pop eax
ret 10h
 
; bool __stdcall SetFolder(HANDLE hPlugin,
; const char* relative_path, const char* absolute_path);
SetFolder:
mov ebp, [esp+4]
mov edx, [ebp+handle_common.curdir]
mov esi, [esp+8]
cmp dword [esi], '..'
jz .toparent
xor ecx, ecx
mov ebp, [esp+4]
mov edx, [ebp+handle_common.curdir]
mov esi, [esp+8]
cmp dword [esi], '..'
jz .toparent
xor ecx, ecx
@@:
inc ecx
cmp byte [esi+ecx], 0
jnz @b
mov ebx, [ebp+handle_common.root.subfolders]
test edx, edx
jz .scan
mov ebx, [edx+file_common.subfolders]
inc ecx
cmp byte [esi+ecx], 0
jnz @b
mov ebx, [ebp+handle_common.root.subfolders]
test edx, edx
jz .scan
mov ebx, [edx+file_common.subfolders]
.scan:
test ebx, ebx
jz .err
add ebx, ebp
cmp [ebx+file_common.namelen], ecx
jnz .cont
push ecx esi
mov edi, [ebx+file_common.name]
repz cmpsb
pop esi ecx
jz .set
test ebx, ebx
jz .err
add ebx, ebp
cmp [ebx+file_common.namelen], ecx
jnz .cont
push ecx esi
mov edi, [ebx+file_common.name]
repz cmpsb
pop esi ecx
jz .set
.cont:
mov ebx, [ebx+file_common.next]
jmp .scan
mov ebx, [ebx+file_common.next]
jmp .scan
.toparent:
test edx, edx
jz .err
mov ebx, [edx+file_common.parent]
test ebx, ebx
jz @f
add ebx, ebp
test edx, edx
jz .err
mov ebx, [edx+file_common.parent]
test ebx, ebx
jz @f
add ebx, ebp
@@:
.set:
mov [ebp+handle_common.curdir], ebx
mov al, 1
ret 12
mov [ebp+handle_common.curdir], ebx
mov al, 1
ret 12
.err:
xor eax, eax
ret 12
xor eax, eax
ret 12
 
iglobal
cur_stamp dd 0
310,7 → 311,7
endg
 
uglobal
tmp_bdfe rb 304
tmp_bdfe rb 304
endg
 
; void __stdcall GetFiles(HANDLE hPlugin, int NumItems, void* items[],
318,220 → 319,220
; bool __stdcall addfile(const char* name, void* bdfe_info, HANDLE hFile);
; bool __stdcall adddir(const char* name, void* bdfe_info);
GetFiles:
mov ebp, [esp+4]
mov ecx, [ebp+handle_common.NumFiles]
test ecx, ecx
jz .ret
mov ebx, ebp
mov eax, [ebx]
add ebx, [basesizes+(eax-1)*8]
inc [cur_stamp]
mov ebp, [esp+4]
mov ecx, [ebp+handle_common.NumFiles]
test ecx, ecx
jz .ret
mov ebx, ebp
mov eax, [ebx]
add ebx, [basesizes+(eax-1)*8]
inc [cur_stamp]
.loop:
push ecx
mov esi, [ebx+file_common.fullname]
mov edx, [ebp+handle_common.curdir]
test edx, edx
jz .incur
mov eax, [cur_stamp]
mov [edx+file_common.stamp], eax
mov edi, [edx+file_common.fullname]
mov ecx, [edx+file_common.namelen]
add ecx, [edx+file_common.name]
sub ecx, edi
repz cmpsb
jnz .cont
push ecx
mov esi, [ebx+file_common.fullname]
mov edx, [ebp+handle_common.curdir]
test edx, edx
jz .incur
mov eax, [cur_stamp]
mov [edx+file_common.stamp], eax
mov edi, [edx+file_common.fullname]
mov ecx, [edx+file_common.namelen]
add ecx, [edx+file_common.name]
sub ecx, edi
repz cmpsb
jnz .cont
.incur:
cmp byte [esi], '/'
jnz @f
inc esi
cmp byte [esi], '/'
jnz @f
inc esi
@@:
mov ecx, [esp+12] ; NumItems
mov edx, [esp+16] ; items
cmp ecx, -1
jz .ok
mov ecx, [esp+12] ; NumItems
mov edx, [esp+16] ; items
cmp ecx, -1
jz .ok
.check:
sub ecx, 1
js .cont
push esi
mov edi, [edx]
add edi, 40
sub ecx, 1
js .cont
push esi
mov edi, [edx]
add edi, 40
@@:
lodsb
scasb
jnz @f
test al, al
jz .ok2
jmp @b
lodsb
scasb
jnz @f
test al, al
jz .ok2
jmp @b
@@:
pop esi
cmp al, '/'
jnz @f
cmp byte [edi-1], 0
jz .ok
pop esi
cmp al, '/'
jnz @f
cmp byte [edi-1], 0
jz .ok
@@:
add edx, 4
jmp .check
add edx, 4
jmp .check
.ok2:
pop esi
pop esi
.ok:
; add all parents directories if needed
.parloope:
mov ecx, [ebx+file_common.parent]
jecxz .pardone
add ecx, ebp
mov eax, [cur_stamp]
cmp [ecx+file_common.stamp], eax
jz .pardone
mov ecx, [ebx+file_common.parent]
jecxz .pardone
add ecx, ebp
mov eax, [cur_stamp]
cmp [ecx+file_common.stamp], eax
jz .pardone
.parloopi:
mov edx, ecx
mov ecx, [ecx+file_common.parent]
jecxz @f
add ecx, ebp
cmp [ecx+file_common.stamp], eax
jnz .parloopi
mov edx, ecx
mov ecx, [ecx+file_common.parent]
jecxz @f
add ecx, ebp
cmp [ecx+file_common.stamp], eax
jnz .parloopi
@@:
mov [edx+file_common.stamp], eax
push esi
mov ecx, [edx+file_common.name]
add ecx, [edx+file_common.namelen]
xor eax, eax
xchg al, [ecx]
push eax ecx
mov eax, edx
mov edi, tmp_bdfe
push edi
sub esi, [ebx+file_common.fullname]
add esi, [edx+file_common.fullname]
push esi
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
mov eax, [esp+24+20]
call eax
pop ecx edx
mov [ecx], dl
pop esi
test al, al
jz .forced_exit
jmp .parloope
mov [edx+file_common.stamp], eax
push esi
mov ecx, [edx+file_common.name]
add ecx, [edx+file_common.namelen]
xor eax, eax
xchg al, [ecx]
push eax ecx
mov eax, edx
mov edi, tmp_bdfe
push edi
sub esi, [ebx+file_common.fullname]
add esi, [edx+file_common.fullname]
push esi
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
mov eax, [esp+24+20]
call eax
pop ecx edx
mov [ecx], dl
pop esi
test al, al
jz .forced_exit
jmp .parloope
.pardone:
cmp [ebx+file_common.bIsDirectory], 0
jz .addfile
mov eax, [cur_stamp]
cmp [ebx+file_common.stamp], eax
jz .cont
mov [ebx+file_common.stamp], eax
push esi
mov ecx, [ebx+file_common.name]
add ecx, [ebx+file_common.namelen]
xor eax, eax
xchg al, [ecx]
push eax ecx
mov eax, ebx
mov edi, tmp_bdfe
push edi
push esi
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
mov eax, [esp+24+20]
call eax
pop ecx edx
mov [ecx], dl
pop esi
test al, al
jz .forced_exit
jmp .cont
cmp [ebx+file_common.bIsDirectory], 0
jz .addfile
mov eax, [cur_stamp]
cmp [ebx+file_common.stamp], eax
jz .cont
mov [ebx+file_common.stamp], eax
push esi
mov ecx, [ebx+file_common.name]
add ecx, [ebx+file_common.namelen]
xor eax, eax
xchg al, [ecx]
push eax ecx
mov eax, ebx
mov edi, tmp_bdfe
push edi
push esi
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
mov eax, [esp+24+20]
call eax
pop ecx edx
mov [ecx], dl
pop esi
test al, al
jz .forced_exit
jmp .cont
.addfile:
push ebx esi ebp
push 11h
pop edi
mov eax, ebx
mov ecx, [ebp]
call dword [openTable+(ecx-1)*4]
pop ebp esi ebx
test eax, eax
jz .cont
push eax
push eax
mov edi, tmp_bdfe
push edi
push esi
mov eax, ebx
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
mov eax, [esp+20+16]
call eax
pop ecx
push eax ebp
push ebx
push ecx
call myclose
pop ebx
pop ebp eax
test al, al
jz .forced_exit
push ebx esi ebp
push 11h
pop edi
mov eax, ebx
mov ecx, [ebp]
call dword [openTable+(ecx-1)*4]
pop ebp esi ebx
test eax, eax
jz .cont
push eax
push eax
mov edi, tmp_bdfe
push edi
push esi
mov eax, ebx
mov ecx, [ebp]
call dword [getattrTable+(ecx-1)*4]
mov eax, [esp+20+16]
call eax
pop ecx
push eax ebp
push ebx
push ecx
call myclose
pop ebx
pop ebp eax
test al, al
jz .forced_exit
.cont:
mov eax, [ebp]
add ebx, [basesizes+(eax-1)*8+4]
pop ecx
dec ecx
jnz .loop
mov eax, [ebp]
add ebx, [basesizes+(eax-1)*8+4]
pop ecx
dec ecx
jnz .loop
.ret:
ret 20
ret 20
.forced_exit:
pop ecx
jmp .ret
pop ecx
jmp .ret
 
; void __stdcall GetOpenPluginInfo(HANDLE hPlugin, OpenPluginInfo* info);
GetOpenPluginInfo:
mov eax, [esp+8] ; get info ptr
mov byte [eax], 3 ; flags: add non-existing '..' entry automatically
; use GetFiles for copying
ret 8
mov eax, [esp+8] ; get info ptr
mov byte [eax], 3 ; flags: add non-existing '..' entry automatically
; use GetFiles for copying
ret 8
 
; int __stdcall getattr(HANDLE hPlugin, const char* filename, void* info);
mygetattr:
call lookup_file_name
test eax, eax
jz @f
mov edx, [ebp]
dec edx
mov edi, [esp+12] ; info ptr
call dword [getattrTable+edx*4]
xor eax, eax
ret 12
call lookup_file_name
test eax, eax
jz @f
mov edx, [ebp]
dec edx
mov edi, [esp+12] ; info ptr
call dword [getattrTable+edx*4]
xor eax, eax
ret 12
@@:
mov al, 5 ; ERROR_FILE_NOT_FOUND
ret 12
mov al, 5 ; ERROR_FILE_NOT_FOUND
ret 12
 
; HANDLE __stdcall open(HANDLE hPlugin, const char* filename, int mode);
myopen:
call lookup_file_name
test eax, eax
jz @f
mov edx, [ebp]
dec edx
mov edi, [esp+12] ; mode
call dword [openTable+edx*4]
call lookup_file_name
test eax, eax
jz @f
mov edx, [ebp]
dec edx
mov edi, [esp+12] ; mode
call dword [openTable+edx*4]
@@:
ret 12
ret 12
 
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
myread:
mov ebx, [esp+4]
mov eax, [ebx]
jmp dword [readTable+eax*4]
mov ebx, [esp+4]
mov eax, [ebx]
jmp dword [readTable+eax*4]
 
; void __stdcall setpos(HANDLE hFile, __int64 pos);
mysetpos:
mov ebx, [esp+4]
mov eax, [ebx]
jmp dword [setposTable+eax*4]
mov ebx, [esp+4]
mov eax, [ebx]
jmp dword [setposTable+eax*4]
 
; void __stdcall close(HANDLE hFile);
myclose:
mov ebx, [esp+4]
mov eax, [ebx]
jmp dword [closeTable+eax*4]
mov ebx, [esp+4]
mov eax, [ebx]
jmp dword [closeTable+eax*4]
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;; Auxiliary procedures ;;;;;;;;;;;;;
540,122 → 541,122
; return.err and return.clear are labels to jmp if something is invalid
; the caller must previously define [_esp], [_ebp] and [error_proc], [clear_proc]
return.err:
mov esp, [_esp]
mov ebp, [_ebp]
jmp [error_proc]
mov esp, [_esp]
mov ebp, [_ebp]
jmp [error_proc]
return.clear:
mov esp, [_esp]
mov ebp, [_ebp]
jmp [clear_proc]
mov esp, [_esp]
mov ebp, [_ebp]
jmp [clear_proc]
 
; data for following routine
iglobal
align 4
_24 dd 24
_60 dd 60
_10000000 dd 10000000
days400year dd 365*400+100-4+1
days100year dd 365*100+25-1
days4year dd 365*4+1
days1year dd 365
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
_400 dd 400
_100 dd 100
_24 dd 24
_60 dd 60
_10000000 dd 10000000
days400year dd 365*400+100-4+1
days100year dd 365*100+25-1
days4year dd 365*4+1
days1year dd 365
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
_400 dd 400
_100 dd 100
endg
 
; Convert QWORD FILETIME to BDFE format.
ntfs_datetime_to_bdfe:
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
push eax
mov eax, edx
xor edx, edx
div [_10000000]
xchg eax, [esp]
div [_10000000]
pop edx
push eax
mov eax, edx
xor edx, edx
div [_10000000]
xchg eax, [esp]
div [_10000000]
pop edx
; edx:eax = number of seconds since January 1, 1601
push eax
mov eax, edx
xor edx, edx
div [_60]
xchg eax, [esp]
div [_60]
mov [edi], dl
pop edx
push eax
mov eax, edx
xor edx, edx
div [_60]
xchg eax, [esp]
div [_60]
mov [edi], dl
pop edx
; edx:eax = number of minutes
div [_60]
mov [edi+1], dl
div [_60]
mov [edi+1], dl
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
xor edx, edx
div [_24]
mov [edi+2], dl
mov [edi+3], byte 0
xor edx, edx
div [_24]
mov [edi+2], dl
mov [edi+3], byte 0
; eax = number of days since January 1, 1601
xor edx, edx
div [days400year]
imul eax, 400
add eax, 1601
mov [edi+6], ax
mov eax, edx
xor edx, edx
div [days100year]
cmp al, 4
jnz @f
dec eax
add edx, [days100year]
xor edx, edx
div [days400year]
imul eax, 400
add eax, 1601
mov [edi+6], ax
mov eax, edx
xor edx, edx
div [days100year]
cmp al, 4
jnz @f
dec eax
add edx, [days100year]
@@:
imul eax, 100
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days4year]
shl eax, 2
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days1year]
cmp al, 4
jnz @f
dec eax
add edx, [days1year]
imul eax, 100
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days4year]
shl eax, 2
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days1year]
cmp al, 4
jnz @f
dec eax
add edx, [days1year]
@@:
add [edi+6], ax
push esi edx
mov esi, months
movzx eax, word [edi+6]
test al, 3
jnz .noleap
xor edx, edx
push eax
div [_400]
pop eax
test edx, edx
jz .leap
xor edx, edx
div [_100]
test edx, edx
jz .noleap
add [edi+6], ax
push esi edx
mov esi, months
movzx eax, word [edi+6]
test al, 3
jnz .noleap
xor edx, edx
push eax
div [_400]
pop eax
test edx, edx
jz .leap
xor edx, edx
div [_100]
test edx, edx
jz .noleap
.leap:
mov esi, months2
mov esi, months2
.noleap:
pop edx
xor eax, eax
inc eax
pop edx
xor eax, eax
inc eax
@@:
sub edx, [esi]
jb @f
add esi, 4
inc eax
jmp @b
sub edx, [esi]
jb @f
add esi, 4
inc eax
jmp @b
@@:
add edx, [esi]
pop esi
inc edx
mov [edi+4], dl
mov [edi+5], al
add edi, 8
ret
add edx, [esi]
pop esi
inc edx
mov [edi+4], dl
mov [edi+5], al
add edi, 8
ret
 
; By given array of files information, initialize links between them
; ("[folder] contains [item]" relations).
665,329 → 666,329
; in: edx->file infos, ebx = number of files, [esp+4] = size,
; edi->{dd root.subfolders, dd root.subfolders.end,
; dd root.subfiles, dd root.subfiles.end, dd root.NumItems}
xor eax, eax
mov [.free], eax
push edi
stosd
stosd
stosd
stosd
stosd
pop edi
xor eax, eax
mov [.free], eax
push edi
stosd
stosd
stosd
stosd
stosd
pop edi
; Loop through all files
.mainloop:
dec ebx
js .mainloopdone
dec ebx
js .mainloopdone
; Parse file name
; esi->current character in name
; dword [esp] = start of current component in file name
; ecx->{dd curdir.subfolders, dd curdir.subfolders.end,
; dd curdir.subfiles, dd curdir.subfiles.end}
mov esi, [edx+file_common.fullname]
mov ecx, edi
mov esi, [edx+file_common.fullname]
mov ecx, edi
.parseloop:
push esi
push esi
.parsename:
lodsb
test al, al
jz @f
cmp al, '/'
jnz .parsename
lodsb
test al, al
jz @f
cmp al, '/'
jnz .parsename
@@:
; we have found next component of current name; look for it in current directory
sub esi, [esp]
dec esi ; esi = strlen(component)
cmp esi, 259
jbe @f
push ContinueBtn
push 1
push aNameTooLong_ptr
push 1
call [SayErr]
jmp return.clear
sub esi, [esp]
dec esi ; esi = strlen(component)
cmp esi, 259
jbe @f
push ContinueBtn
push 1
push aNameTooLong_ptr
push 1
call [SayErr]
jmp return.clear
@@:
push ecx
mov eax, [ecx] ; eax->subfolders list
mov ecx, esi
push ecx
mov eax, [ecx] ; eax->subfolders list
mov ecx, esi
.scansubfolders:
test eax, eax
jz .nofolder
add eax, [hOut]
cmp [eax+file_common.namelen], ecx
jnz .scancont
mov esi, [esp+4]
push ecx edi
mov edi, [eax+file_common.name]
repz cmpsb
pop edi ecx
jz .subfound
test eax, eax
jz .nofolder
add eax, [hOut]
cmp [eax+file_common.namelen], ecx
jnz .scancont
mov esi, [esp+4]
push ecx edi
mov edi, [eax+file_common.name]
repz cmpsb
pop edi ecx
jz .subfound
.scancont:
mov eax, [eax+file_common.next]
jmp .scansubfolders
mov eax, [eax+file_common.next]
jmp .scansubfolders
.subfound:
; found subfolder, set it as current and continue parsing name
add [esp+4], ecx
pop ecx
lea ecx, [eax+file_common.subfolders]
pop esi
lodsb
test al, al
jnz .parseloop
add [esp+4], ecx
pop ecx
lea ecx, [eax+file_common.subfolders]
pop esi
lodsb
test al, al
jnz .parseloop
; that was the last component of the name, and we have found subfolder
; so found subfolder is a virtual subfolder and must be replaced with current
; name
mov eax, [ecx-file_common.subfolders+file_common.namelen]
mov [edx+file_common.namelen], eax
sub esi, eax
dec esi
mov [edx+file_common.name], esi
sub edx, [hOut] ; convert pointer to relative
mov eax, [ecx-file_common.subfolders+file_common.namelen]
mov [edx+file_common.namelen], eax
sub esi, eax
dec esi
mov [edx+file_common.name], esi
sub edx, [hOut] ; convert pointer to relative
; replace item in L2-list
mov eax, [ecx-file_common.subfolders+file_common.prev]
test eax, eax
jnz .1
mov eax, [ecx-file_common.subfolders+file_common.parent]
sub eax, file_common.next - file_common.subfolders
jnc .1
lea eax, [edi-file_common.next]
jmp .2
mov eax, [ecx-file_common.subfolders+file_common.prev]
test eax, eax
jnz .1
mov eax, [ecx-file_common.subfolders+file_common.parent]
sub eax, file_common.next - file_common.subfolders
jnc .1
lea eax, [edi-file_common.next]
jmp .2
.1:
add eax, [hOut]
add eax, [hOut]
.2:
mov [eax+file_common.next], edx
mov eax, [ecx-file_common.subfolders+file_common.next]
test eax, eax
jnz .3
mov eax, [ecx-file_common.subfolders+file_common.parent]
sub eax, file_common.prev - file_common.subfolders.end
jnc .3
lea eax, [edi-file_common.prev+4]
jmp .4
mov [eax+file_common.next], edx
mov eax, [ecx-file_common.subfolders+file_common.next]
test eax, eax
jnz .3
mov eax, [ecx-file_common.subfolders+file_common.parent]
sub eax, file_common.prev - file_common.subfolders.end
jnc .3
lea eax, [edi-file_common.prev+4]
jmp .4
.3:
add eax, [hOut]
add eax, [hOut]
.4:
mov [eax+file_common.prev], edx
mov [eax+file_common.prev], edx
; correct parent links in childrens
mov eax, [ecx]
mov eax, [ecx]
@@:
test eax, eax
jz @f
add eax, [hOut]
mov [eax+file_common.parent], edx
mov eax, [eax+file_common.next]
jmp @b
test eax, eax
jz @f
add eax, [hOut]
mov [eax+file_common.parent], edx
mov eax, [eax+file_common.next]
jmp @b
@@:
mov eax, [ecx+8]
mov eax, [ecx+8]
@@:
test eax, eax
jz @f
add eax, [hOut]
mov [eax+file_common.parent], edx
mov eax, [eax+file_common.next]
jmp @b
test eax, eax
jz @f
add eax, [hOut]
mov [eax+file_common.parent], edx
mov eax, [eax+file_common.next]
jmp @b
@@:
add edx, [hOut]
add edx, [hOut]
; set children links
mov eax, [ecx]
mov [edx+file_common.subfolders], eax
mov eax, [ecx+4]
mov [edx+file_common.subfolders.end], eax
mov eax, [ecx+8]
mov [edx+file_common.subfiles], eax
mov eax, [ecx+12]
mov [edx+file_common.subfiles.end], eax
mov eax, [ecx+16]
mov [edx+file_common.NumSubItems], eax
mov eax, [ecx]
mov [edx+file_common.subfolders], eax
mov eax, [ecx+4]
mov [edx+file_common.subfolders.end], eax
mov eax, [ecx+8]
mov [edx+file_common.subfiles], eax
mov eax, [ecx+12]
mov [edx+file_common.subfiles.end], eax
mov eax, [ecx+16]
mov [edx+file_common.NumSubItems], eax
; set prev/next links
mov eax, [ecx-file_common.subfolders+file_common.next]
mov [edx+file_common.next], eax
mov eax, [ecx-file_common.subfolders+file_common.prev]
mov [edx+file_common.prev], eax
mov eax, [ecx-file_common.subfolders+file_common.next]
mov [edx+file_common.next], eax
mov eax, [ecx-file_common.subfolders+file_common.prev]
mov [edx+file_common.prev], eax
; add old item to list of free items
uglobal
align 4
init_file_links.free dd ?
init_file_links.free dd ?
endg
sub ecx, file_common.subfolders
mov eax, [.free]
mov [ecx], eax
sub ecx, [hOut]
mov [.free], ecx
jmp .mainloopcont
sub ecx, file_common.subfolders
mov eax, [.free]
mov [ecx], eax
sub ecx, [hOut]
mov [.free], ecx
jmp .mainloopcont
.nofolder:
mov eax, edx
mov esi, [esp+4]
cmp byte [esi+ecx], 0
jz .newitem
mov eax, edx
mov esi, [esp+4]
cmp byte [esi+ecx], 0
jz .newitem
; the current item is as 'dir1/item1' and 'dir1' has not been found
; allocate virtual subfolder 'dir1'
mov eax, [init_file_links.free]
test eax, eax
jz .realloc
add eax, [hOut]
push dword [eax]
pop [init_file_links.free]
jmp .allocated
mov eax, [init_file_links.free]
test eax, eax
jz .realloc
add eax, [hOut]
push dword [eax]
pop [init_file_links.free]
jmp .allocated
.realloc:
; there is no free space, so reallocate [hOut] block
mov eax, [hOut]
sub [esp], eax ; make pointers relative
sub edx, eax
sub edi, eax
push ecx
mov ecx, [hOut.allocated]
add ecx, [esp+12+4]
mov [hOut.allocated], ecx
push ecx
and ecx, 0xFFF
cmp ecx, [esp+16+4]
pop ecx
ja @f
push edx
mov edx, eax
call [pgrealloc]
pop edx
test eax, eax
jnz @f
mov ecx, [hOut]
call [pgfree]
mov esp, [_esp]
or eax, -1
ret
mov eax, [hOut]
sub [esp], eax ; make pointers relative
sub edx, eax
sub edi, eax
push ecx
mov ecx, [hOut.allocated]
add ecx, [esp+12+4]
mov [hOut.allocated], ecx
push ecx
and ecx, 0xFFF
cmp ecx, [esp+16+4]
pop ecx
ja @f
push edx
mov edx, eax
call [pgrealloc]
pop edx
test eax, eax
jnz @f
mov ecx, [hOut]
call [pgfree]
mov esp, [_esp]
or eax, -1
ret
@@:
pop ecx
mov [hOut], eax
add [esp], eax ; make pointers absolute
add edx, eax
add edi, eax
add eax, [hOut.allocated]
sub eax, [esp+8+4]
pop ecx
mov [hOut], eax
add [esp], eax ; make pointers absolute
add edx, eax
add edi, eax
add eax, [hOut.allocated]
sub eax, [esp+8+4]
.allocated:
; eax -> new item
mov [eax+file_common.bIsDirectory], 1
mov [eax+file_common.bPseudoFolder], 1
mov [eax+file_common.bIsDirectory], 1
mov [eax+file_common.bPseudoFolder], 1
.newitem:
mov [eax+file_common.namelen], ecx
mov [eax+file_common.namelen], ecx
; !!! in this case .fullname is not null-terminated !!!
mov ecx, [edx+file_common.fullname]
mov [eax+file_common.fullname], ecx
push edi eax
lea edi, [eax+file_common.parent]
xor eax, eax
push 7
pop ecx
rep stosd
pop eax edi
pop ecx
pop esi
mov ecx, [edx+file_common.fullname]
mov [eax+file_common.fullname], ecx
push edi eax
lea edi, [eax+file_common.parent]
xor eax, eax
push 7
pop ecx
rep stosd
pop eax edi
pop ecx
pop esi
; ecx = parent item, eax = current item
mov [eax+file_common.name], esi
inc dword [ecx+16] ; new item in parent folder
push ecx
mov [eax+file_common.name], esi
inc dword [ecx+16] ; new item in parent folder
push ecx
; add new item to end of L2-list
cmp [eax+file_common.bIsDirectory], 0
jnz @f
add ecx, 8
cmp [eax+file_common.bIsDirectory], 0
jnz @f
add ecx, 8
@@:
push eax
sub eax, [hOut]
cmp dword [ecx], 0
jnz @f
mov [ecx], eax
push eax
sub eax, [hOut]
cmp dword [ecx], 0
jnz @f
mov [ecx], eax
@@:
xchg eax, [ecx+4]
xchg eax, ecx
pop eax
mov [eax+file_common.prev], ecx
jecxz @f
add ecx, [hOut]
sub eax, [hOut]
mov [ecx+file_common.next], eax
add eax, [hOut]
xchg eax, [ecx+4]
xchg eax, ecx
pop eax
mov [eax+file_common.prev], ecx
jecxz @f
add ecx, [hOut]
sub eax, [hOut]
mov [ecx+file_common.next], eax
add eax, [hOut]
@@:
pop ecx
pop ecx
; set parent link
cmp ecx, edi
jz @f
sub ecx, file_common.subfolders
sub ecx, [hOut]
mov [eax+file_common.parent], ecx
cmp ecx, edi
jz @f
sub ecx, file_common.subfolders
sub ecx, [hOut]
mov [eax+file_common.parent], ecx
@@:
; set current directory to current item
lea ecx, [eax+file_common.subfolders]
lea ecx, [eax+file_common.subfolders]
; if that was not last component, continue parse name
add esi, [eax+file_common.namelen]
lodsb
test al, al
jnz .parseloop
add esi, [eax+file_common.namelen]
lodsb
test al, al
jnz .parseloop
.mainloopcont:
; continue main loop
add edx, [esp+4]
jmp .mainloop
add edx, [esp+4]
jmp .mainloop
.mainloopdone:
; Loop done.
ret 4
ret 4
 
; This subroutine is called by getattr and open.
; This subroutine looks for file name and returns NULL or pointer to file info record.
lookup_file_name:
mov ebp, [esp+8] ; hPlugin
mov esi, [esp+12] ; filename
lea edi, [ebp+handle_common.root.subfolders]
xor eax, eax
mov ebp, [esp+8] ; hPlugin
mov esi, [esp+12] ; filename
lea edi, [ebp+handle_common.root.subfolders]
xor eax, eax
; KFar operates with absolute names, skip first '/'
cmp byte [esi], '/'
jnz .notfound
inc esi
cmp byte [esi], '/'
jnz .notfound
inc esi
.mainloop:
; get next component of name
push -1
pop ecx
push -1
pop ecx
@@:
inc ecx
cmp byte [esi+ecx], '/'
jz @f
cmp byte [esi+ecx], 0
jnz @b
inc ecx
cmp byte [esi+ecx], '/'
jz @f
cmp byte [esi+ecx], 0
jnz @b
@@:
; esi->component, ecx=length
; scan for required item in subfolders list
push -1
mov eax, [edi] ; .subfolders
push -1
mov eax, [edi] ; .subfolders
.scan1:
test eax, eax
jz .notfound1
add eax, ebp
cmp [eax+file_common.namelen], ecx
jnz .cont1
push ecx esi edi
mov edi, [eax+file_common.name]
repz cmpsb
pop edi esi ecx
jz .found1
test eax, eax
jz .notfound1
add eax, ebp
cmp [eax+file_common.namelen], ecx
jnz .cont1
push ecx esi edi
mov edi, [eax+file_common.name]
repz cmpsb
pop edi esi ecx
jz .found1
.cont1:
mov eax, [eax+file_common.next]
jmp .scan1
mov eax, [eax+file_common.next]
jmp .scan1
.notfound1:
pop edx
pop edx
; if this is last component in file name, scan in subfiles list
cmp byte [esi+ecx], al
jnz .notfound
inc edx
jnz .notfound
mov eax, [edi+8] ; .subfiles
push edx
jmp .scan1
cmp byte [esi+ecx], al
jnz .notfound
inc edx
jnz .notfound
mov eax, [edi+8] ; .subfiles
push edx
jmp .scan1
.found1:
pop edi
pop edi
; item is found, go to next component
lea edi, [eax+file_common.subfolders]
lea esi, [esi+ecx+1]
cmp byte [esi-1], 0
jnz .mainloop
lea edi, [eax+file_common.subfolders]
lea esi, [esi+ecx+1]
cmp byte [esi-1], 0
jnz .mainloop
; this was the last component
.notfound:
ret
ret
 
; Memory streams handling.
; Archive handlers create memory stream for small files:
999,48 → 1000,48
 
virtual at 0
mem_stream:
.type dd ? ; type_mem_stream
.size dd ?
.pos dd ?
.type dd ? ; type_mem_stream
.size dd ?
.pos dd ?
.buf:
end virtual
 
; unsigned __stdcall read(ebx = HANDLE hFile, void* buf, unsigned size);
read_mem_stream:
mov eax, [esp+12]
mov ecx, [ebx+mem_stream.size]
sub ecx, [ebx+mem_stream.pos]
jnc @f
xor ecx, ecx
mov eax, [esp+12]
mov ecx, [ebx+mem_stream.size]
sub ecx, [ebx+mem_stream.pos]
jnc @f
xor ecx, ecx
@@:
cmp eax, ecx
jb @f
mov eax, ecx
cmp eax, ecx
jb @f
mov eax, ecx
@@:
mov ecx, eax
lea esi, [ebx+mem_stream.buf]
add esi, [ebx+mem_stream.pos]
add [ebx+mem_stream.pos], eax
mov edi, [esp+8]
mov edx, ecx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
ret 12
mov ecx, eax
lea esi, [ebx+mem_stream.buf]
add esi, [ebx+mem_stream.pos]
add [ebx+mem_stream.pos], eax
mov edi, [esp+8]
mov edx, ecx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
ret 12
 
; void __stdcall setpos(ebx = HANDLE hFile, __int64 pos);
setpos_mem_stream:
mov eax, [esp+8]
mov [ebx+mem_stream.pos], eax
ret 12
mov eax, [esp+8]
mov [ebx+mem_stream.pos], eax
ret 12
 
; void __stdcall close(ebx = HANDLE hFile);
close_mem_stream:
mov ecx, ebx
call [pgfree]
ret 4
mov ecx, ebx
call [pgfree]
ret 4
 
; Allocate handle for file
; esi -> handle table, ecx = size of handle
1047,144 → 1048,144
alloc_handle:
; Handle table is L2-list of allocated pages.
; Scan for free entry
mov edx, esi
mov edx, esi
@@:
mov edx, [edx]
cmp edx, esi
jz .alloc_new
mov eax, [edx+8] ; head of L1-list of free entries
test eax, eax ; has free entry?
jz @b
mov edx, [edx]
cmp edx, esi
jz .alloc_new
mov eax, [edx+8] ; head of L1-list of free entries
test eax, eax ; has free entry?
jz @b
; we have found allocated page with free entry; allocate entry and return
inc dword [edx+12] ; number of busy entries
push dword [eax]
pop dword [edx+8]
inc dword [edx+12] ; number of busy entries
push dword [eax]
pop dword [edx+8]
.ret:
ret
ret
.alloc_new:
; no free pages; get new page and initialize
push ecx
mov ecx, 0x1000
call [pgalloc]
pop ecx
test eax, eax
jz .ret
push ecx
mov ecx, 0x1000
call [pgalloc]
pop ecx
test eax, eax
jz .ret
; insert new page to start of L2-list
mov edx, [esi]
mov [eax], edx
mov [esi], eax
mov [eax+4], esi
mov [edx+4], eax
mov dword [eax+12], 1 ; 1 allocated entry
mov edx, [esi]
mov [eax], edx
mov [esi], eax
mov [eax+4], esi
mov [edx+4], eax
mov dword [eax+12], 1 ; 1 allocated entry
; initialize list of free entries
lea edx, [eax+16]
push edx ; save return value
add edx, ecx
mov [eax+8], edx
add eax, 0x1000
lea edx, [eax+16]
push edx ; save return value
add edx, ecx
mov [eax+8], edx
add eax, 0x1000
@@:
mov esi, edx
add edx, ecx
mov [esi], edx
cmp edx, eax
jb @b
and dword [esi], 0
pop eax
ret
mov esi, edx
add edx, ecx
mov [esi], edx
cmp edx, eax
jb @b
and dword [esi], 0
pop eax
ret
 
; Free handle allocated in previous procedure
; esi = handle
free_handle:
mov ecx, esi
and ecx, not 0xFFF ; get page
mov ecx, esi
and ecx, not 0xFFF ; get page
; add entry to head of L1-list of free entries
mov eax, [ecx+8]
mov [esi], eax
mov [ecx+8], esi
dec dword [ecx+12] ; decrement number of allocated entries
jnz .ret
mov eax, [ecx+8]
mov [esi], eax
mov [ecx+8], esi
dec dword [ecx+12] ; decrement number of allocated entries
jnz .ret
; delete page from common L2-list
mov eax, [ecx]
mov edx, [ecx+4]
mov [eax+4], edx
mov [edx], eax
mov eax, [ecx]
mov edx, [ecx+4]
mov [eax+4], edx
mov [edx], eax
; free page
call [pgfree]
call [pgfree]
.ret:
ret
ret
 
; Ask user to enter password.
; Out: ZF set <=> user pressed Esc
; 'password_ansi', 'password_unicode', 'password_size' filled
query_password:
cmp [bPasswordDefined], 0
jnz .ret
mov edi, password_data
mov eax, password_maxlen
stosd ; maximum length
xor eax, eax
stosd ; start of visible part
stosd ; position of cursor
stosb ; initial state: empty string
mov eax, [cur_console_size]
mov eax, [eax] ; get current console width
sub eax, 12
mov edi, password_dlg
mov [edi+password_dlg.width-password_dlg], eax
dec eax
dec eax
mov [edi+password_dlg.width1-password_dlg], eax
mov [edi+password_dlg.width2-password_dlg], eax
push edi
call [DialogBox]
inc eax
jz .ret
cmp [bPasswordDefined], 0
jnz .ret
mov edi, password_data
mov eax, password_maxlen
stosd ; maximum length
xor eax, eax
stosd ; start of visible part
stosd ; position of cursor
stosb ; initial state: empty string
mov eax, [cur_console_size]
mov eax, [eax] ; get current console width
sub eax, 12
mov edi, password_dlg
mov [edi+password_dlg.width-password_dlg], eax
dec eax
dec eax
mov [edi+password_dlg.width1-password_dlg], eax
mov [edi+password_dlg.width2-password_dlg], eax
push edi
call [DialogBox]
inc eax
jz .ret
; convert ANSI-cp866 to UNICODE string; also calculate 'password_size'
mov esi, password_ansi
mov edi, password_unicode
or [password_size], -1
mov esi, password_ansi
mov edi, password_unicode
or [password_size], -1
.cvt:
inc [password_size]
lodsb
mov ah, 0
inc [password_size]
lodsb
mov ah, 0
; 0x00-0x7F - trivial map
cmp al, 0x80
jb .symb
cmp al, 0x80
jb .symb
; 0x80-0xAF -> 0x410-0x43F
cmp al, 0xB0
jae @f
add ax, 0x410-0x80
jmp .symb
cmp al, 0xB0
jae @f
add ax, 0x410-0x80
jmp .symb
@@:
; 0xE0-0xEF -> 0x440-0x44F
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jae @f
add ax, 0x440-0xE0
jmp .symb
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jae @f
add ax, 0x440-0xE0
jmp .symb
@@:
; 0xF0 -> 0x401
; 0xF1 -> 0x451
cmp al, 'ð'
jz .yo1
cmp al, 'ñ'
jz .yo2
cmp al, 'ð'
jz .yo1
cmp al, 'ñ'
jz .yo2
.unk:
mov al, '_'
jmp .symb
mov al, '_'
jmp .symb
.yo1:
mov ax, 0x401
jmp .symb
mov ax, 0x401
jmp .symb
.yo2:
mov ax, 0x451
mov ax, 0x451
.symb:
stosw
test al, al
jnz .cvt
inc [bPasswordDefined] ; clears ZF flag
stosw
test al, al
jnz .cvt
inc [bPasswordDefined] ; clears ZF flag
.ret:
ret
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; API for other programs ;;;;;;;;;;;;
1192,162 → 1193,162
; void* __stdcall deflate_unpack(void* packed_data, unsigned* pLength)
deflate_unpack:
push dword [esp+8]
push esp
push deflate_unpack_cb
call deflate_unpack2
ret 8
push esp
push deflate_unpack_cb
call deflate_unpack2
ret 8
 
deflate_unpack_cb:
mov edx, [esp+4]
push edx
mov edx, [edx+12]
mov edx, [edx]
mov eax, [esp+8+4]
mov [eax], edx
pop edx
xor eax, eax
xchg eax, [edx+8]
ret 8
mov edx, [esp+4]
push edx
mov edx, [edx+12]
mov edx, [edx]
mov eax, [esp+8+4]
mov [eax], edx
pop edx
xor eax, eax
xchg eax, [edx+8]
ret 8
 
; void* __stdcall deflate_unpack2(void* get_next_chunk, void* parameter, unsigned* pUnpackedLength)
; void* __stdcall get_next_chunk(void* parameter, unsigned* pLength)
; void* __stdcall get_next_chunk(void* parameter, unsigned* pLength)
deflate_unpack2:
pusha
mov ecx, 0x11000
call mypgalloc
test eax, eax
jz .ret
or dword [eax+streamInfo.fullSize], -1
or dword [eax+streamInfo.fullSize+4], -1
and dword [eax+streamInfo.bufSize], 0
mov dword [eax+streamInfo.fillBuf], .fillBuf
mov edx, [esp+32+4]
mov [eax+streamInfo.size], edx
mov edx, [esp+32+8]
mov [eax+streamInfo.size+4], edx
mov [eax+streamInfo.size+8+deflate_decoder.inStream], eax
add eax, streamInfo.size+8
lea edi, [eax+deflate_decoder.size]
mov [eax+streamInfo.bufPtr], edi
mov ebp, eax
call deflate_init_decoder
xor edx, edx
mov ecx, 10000h
pusha
mov ecx, 0x11000
call mypgalloc
test eax, eax
jz .ret
or dword [eax+streamInfo.fullSize], -1
or dword [eax+streamInfo.fullSize+4], -1
and dword [eax+streamInfo.bufSize], 0
mov dword [eax+streamInfo.fillBuf], .fillBuf
mov edx, [esp+32+4]
mov [eax+streamInfo.size], edx
mov edx, [esp+32+8]
mov [eax+streamInfo.size+4], edx
mov [eax+streamInfo.size+8+deflate_decoder.inStream], eax
add eax, streamInfo.size+8
lea edi, [eax+deflate_decoder.size]
mov [eax+streamInfo.bufPtr], edi
mov ebp, eax
call deflate_init_decoder
xor edx, edx
mov ecx, 10000h
.loop:
push @f
pushad
mov [_esp], esp
mov [_ebp], ebp
mov [error_proc], .error
mov ecx, 10000h
jmp [eax+streamInfo.fillBuf]
push @f
pushad
mov [_esp], esp
mov [_ebp], ebp
mov [error_proc], .error
mov ecx, 10000h
jmp [eax+streamInfo.fillBuf]
@@:
push 68
pop eax
push 20
pop ebx
int 0x40
test eax, eax
jz .nomem
mov edx, eax
mov eax, ebp
mov esi, edi
push edi
lea edi, [edx+ecx-0x10000]
push ecx
mov ecx, 0x10000/4
rep movsd
pop ecx
pop edi
add ecx, 0x10000
jmp .loop
push SF_SYS_MISC
pop eax
push SSF_MEM_REALLOC
pop ebx
int 0x40
test eax, eax
jz .nomem
mov edx, eax
mov eax, ebp
mov esi, edi
push edi
lea edi, [edx+ecx-0x10000]
push ecx
mov ecx, 0x10000/4
rep movsd
pop ecx
pop edi
add ecx, 0x10000
jmp .loop
.error:
pop eax
push edi
popad
pop eax
mov eax, ebp
lea esi, [eax+deflate_decoder.size]
sub ecx, 0x10000
sub edi, esi
add ecx, edi
mov eax, [esp+32+12]
test eax, eax
jz @f
mov [eax], ecx
pop eax
push edi
popad
pop eax
mov eax, ebp
lea esi, [eax+deflate_decoder.size]
sub ecx, 0x10000
sub edi, esi
add ecx, edi
mov eax, [esp+32+12]
test eax, eax
jz @f
mov [eax], ecx
@@:
test ecx, ecx
jnz @f
inc ecx
test ecx, ecx
jnz @f
inc ecx
@@:
push 68
pop eax
push 20
pop ebx
int 0x40
test eax, eax
jz .nomem
sub ecx, edi
mov edx, edi
lea edi, [eax+ecx]
mov ecx, edx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
push eax
push 68
pop eax
push 13
pop ebx
lea ecx, [ebp-streamInfo.size-8]
int 40h
pop eax
jmp .ret
push SF_SYS_MISC
pop eax
push SSF_MEM_REALLOC
pop ebx
int 0x40
test eax, eax
jz .nomem
sub ecx, edi
mov edx, edi
lea edi, [eax+ecx]
mov ecx, edx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
push eax
push SF_SYS_MISC
pop eax
push SSF_MEM_FREE
pop ebx
lea ecx, [ebp-streamInfo.size-8]
int 40h
pop eax
jmp .ret
.nomem:
push 68
pop eax
push 13
pop ebx
test edx, edx
jz @f
mov ecx, edx
push eax
int 0x40
pop eax
push SF_SYS_MISC
pop eax
push SSF_MEM_FREE
pop ebx
test edx, edx
jz @f
mov ecx, edx
push eax
int 0x40
pop eax
@@:
lea ecx, [ebp-streamInfo.size-8]
int 0x40
xor eax, eax
lea ecx, [ebp-streamInfo.size-8]
int 0x40
xor eax, eax
.ret:
mov [esp+28], eax
popa
ret 12
mov [esp+28], eax
popa
ret 12
.fillBuf:
push eax
push eax
push esp
push dword [eax+streamInfo.size+4]
call dword [eax+streamInfo.size]
pop edx
pop ebp
mov [ebp+streamInfo.bufPtr], eax
and [ebp+streamInfo.bufDataLen], 0
test eax, eax
jz @f
mov [ebp+streamInfo.bufDataLen], edx
push eax
push eax
push esp
push dword [eax+streamInfo.size+4]
call dword [eax+streamInfo.size]
pop edx
pop ebp
mov [ebp+streamInfo.bufPtr], eax
and [ebp+streamInfo.bufDataLen], 0
test eax, eax
jz @f
mov [ebp+streamInfo.bufDataLen], edx
@@:
popad
ret
popad
ret
 
mypgalloc:
push 68
pop eax
push 12
pop ebx
int 0x40
ret
push SF_SYS_MISC
pop eax
push SSF_MEM_ALLOC
pop ebx
int 0x40
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; Initialized data ;;;;;;;;;;;;;;;
1356,77 → 1357,91
; export table
align 4
EXPORTS:
dd aVersion, 3
dd aPluginLoad, plugin_load
dd aOpenFilePlugin,OpenFilePlugin
dd aClosePlugin, ClosePlugin
dd aReadFolder, ReadFolder
dd aSetFolder, SetFolder
dd aGetFiles, GetFiles
dd aGetOpenPluginInfo, GetOpenPluginInfo
dd aGetattr, mygetattr
dd aOpen, myopen
dd aRead, myread
dd aSetpos, mysetpos
dd aClose, myclose
dd aDeflateUnpack, deflate_unpack
dd aDeflateUnpack2,deflate_unpack2
dd 0
dd aVersion, 3
dd aPluginLoad, plugin_load
dd aOpenFilePlugin,OpenFilePlugin
dd aClosePlugin, ClosePlugin
dd aReadFolder, ReadFolder
dd aSetFolder, SetFolder
dd aGetFiles, GetFiles
dd aGetOpenPluginInfo, GetOpenPluginInfo
dd aGetattr, mygetattr
dd aOpen, myopen
dd aRead, myread
dd aSetpos, mysetpos
dd aClose, myclose
dd aDeflateUnpack, deflate_unpack
dd aDeflateUnpack2,deflate_unpack2
dd adeflateInit, deflateInit
dd adeflateInit2, deflateInit2
dd adeflateReset, deflateReset
dd adeflate, deflate
dd adeflateEnd, deflateEnd
dd azError, zError
dd acalc_crc32, calc_crc32
dd 0
 
; exported names
aVersion db 'version',0
aPluginLoad db 'plugin_load',0
aOpenFilePlugin db 'OpenFilePlugin',0
aClosePlugin db 'ClosePlugin',0
aReadFolder db 'ReadFolder',0
aSetFolder db 'SetFolder',0
aGetFiles db 'GetFiles',0
aGetOpenPluginInfo db 'GetOpenPluginInfo',0
aGetattr db 'getattr',0
aOpen db 'open',0
aRead db 'read',0
aSetpos db 'setpos',0
aClose db 'close',0
aDeflateUnpack db 'deflate_unpack',0
aDeflateUnpack2 db 'deflate_unpack2',0
aVersion db 'version',0
aPluginLoad db 'plugin_load',0
aOpenFilePlugin db 'OpenFilePlugin',0
aClosePlugin db 'ClosePlugin',0
aReadFolder db 'ReadFolder',0
aSetFolder db 'SetFolder',0
aGetFiles db 'GetFiles',0
aGetOpenPluginInfo db 'GetOpenPluginInfo',0
aGetattr db 'getattr',0
aOpen db 'open',0
aRead db 'read',0
aSetpos db 'setpos',0
aClose db 'close',0
aDeflateUnpack db 'deflate_unpack',0
aDeflateUnpack2 db 'deflate_unpack2',0
adeflateInit db 'deflateInit',0
adeflateInit2 db 'deflateInit2',0
adeflateReset db 'deflateReset',0
adeflate db 'deflate',0
adeflateEnd db 'deflateEnd',0
azError db 'zError',0
acalc_crc32 db 'calc_crc32',0
 
; common strings
if lang eq ru
aContinue db 'à®¤®«¦¨âì',0
aCancel db 'Žâ¬¥­ ',0
aHeaderError db 'Žè¨¡ª  ¢ § £®«®¢ª¥  à娢 ',0
aReadError db 'Žè¨¡ª  ç⥭¨ï',0
aNoFreeRam db '¥¤®áâ â®ç­® ᢮¡®¤­®© ®¯¥à â¨¢­®© ¯ ¬ïâ¨',0
aEncodingProblem db 'à®¡«¥¬  á ª®¤¨à®¢ª®©',0
aContinue db 'à®¤®«¦¨âì',0
aCancel db 'Žâ¬¥­ ',0
aHeaderError db 'Žè¨¡ª  ¢ § £®«®¢ª¥  à娢 ',0
aReadError db 'Žè¨¡ª  ç⥭¨ï',0
aNoFreeRam db '¥¤®áâ â®ç­® ᢮¡®¤­®© ®¯¥à â¨¢­®© ¯ ¬ïâ¨',0
aEncodingProblem db 'à®¡«¥¬  á ª®¤¨à®¢ª®©',0
aEncodingProblem_str db 'ˆ¬¥­  ­¥ª®â®àëå ä ©«®¢ ¢  à娢¥ ᮤ¥à¦ â ᨬ¢®«ë,',0
.2 db '­¥ ¯à¥¤áâ ¢¨¬ë¥ ¢ ª®¤¨à®¢ª¥ cp866.',0
.3 db 'â¨ ᨬ¢®«ë ¡ã¤ãâ § ¬¥­¥­ë ­  ¯®¤çñન¢ ­¨ï.',0
aEnterPassword db '‚¢¥¤¨â¥ ¯ à®«ì:',0
.2 db '­¥ ¯à¥¤áâ ¢¨¬ë¥ ¢ ª®¤¨à®¢ª¥ cp866.',0
.3 db 'â¨ ᨬ¢®«ë ¡ã¤ãâ § ¬¥­¥­ë ­  ¯®¤çñન¢ ­¨ï.',0
aEnterPassword db '‚¢¥¤¨â¥ ¯ à®«ì:',0
aEnterPasswordLen = $ - aEnterPassword - 1
aEnterPasswordTitle db '‚¢®¤ ¯ à®«ï',0
aArchiveDataError db 'Žè¨¡ª  ¢ ¤ ­­ëå  à娢 ',0
aEnterPasswordTitle db '‚¢®¤ ¯ à®«ï',0
aArchiveDataError db 'Žè¨¡ª  ¢ ¤ ­­ëå  à娢 ',0
aArchiveDataErrorPass db 'Žè¨¡ª  ¢ ¤ ­­ëå  à娢  ¨«¨ ­¥¢¥à­ë© ¯ à®«ì',0
aChangePass db '‚¢¥á⨠¯ à®«ì',0
aNameTooLong db '‘«¨èª®¬ ¤«¨­­®¥ ¨¬ï',0
aCannotOpenFile db '¥ ¬®£ã ®âªàëâì ä ©«',0
aChangePass db '‚¢¥á⨠¯ à®«ì',0
aNameTooLong db '‘«¨èª®¬ ¤«¨­­®¥ ¨¬ï',0
aCannotOpenFile db '¥ ¬®£ã ®âªàëâì ä ©«',0
else
aContinue db 'Continue',0
aCancel db 'Cancel',0
aHeaderError db 'Invalid archive header',0
aReadError db 'Read error',0
aNoFreeRam db 'There is not enough of free RAM',0
aEncodingProblem db 'Encoding problem',0
aContinue db 'Continue',0
aCancel db 'Cancel',0
aHeaderError db 'Invalid archive header',0
aReadError db 'Read error',0
aNoFreeRam db 'There is not enough of free RAM',0
aEncodingProblem db 'Encoding problem',0
aEncodingProblem_str db 'The names of some files in the archive contain',0
.2 db 'characters which can not be represented in cp866.',0
.3 db 'Such characters will be replaced to underscores.',0
aEnterPassword db 'Enter password:',0
.2 db 'characters which can not be represented in cp866.',0
.3 db 'Such characters will be replaced to underscores.',0
aEnterPassword db 'Enter password:',0
aEnterPasswordLen = $ - aEnterPassword - 1
aEnterPasswordTitle db 'Get password',0
aArchiveDataError db 'Error in archive data',0
aEnterPasswordTitle db 'Get password',0
aArchiveDataError db 'Error in archive data',0
aArchiveDataErrorPass db 'Error in archive data or incorrect password',0
aChangePass db 'Enter password',0
aNameTooLong db 'Name is too long',0
aCannotOpenFile db 'Cannot open file',0
aChangePass db 'Enter password',0
aNameTooLong db 'Name is too long',0
aCannotOpenFile db 'Cannot open file',0
end if
 
; kfar_arc supports many archive types.
1433,7 → 1448,7
; OpenFilePlugin looks for supported archive signature and gives control
; to concrete handler if found.
; Other functions just determine type of opened archive and jump to corresponding handler.
type_mem_stream = 0 ; memory stream - for file handles (returned from 'open')
type_mem_stream = 0 ; memory stream - for file handles (returned from 'open')
type_7z = 1
type_zip = 2
 
1440,72 → 1455,72
; archive functions (types start from type_7z)
align 4
ClosePluginTable:
dd close_7z
dd close_zip
dd close_7z
dd close_zip
getattrTable:
dd getattr_7z
dd getattr_zip
dd getattr_7z
dd getattr_zip
openTable:
dd open_file_7z
dd open_file_zip
dd open_file_7z
dd open_file_zip
basesizes:
dd handle_7z.basesize, file_in_7z.size
dd handle_zip.basesize, file_in_zip.size
dd handle_7z.basesize, file_in_7z.size
dd handle_zip.basesize, file_in_zip.size
 
; file functions (types start from type_mem_stream)
readTable:
dd read_mem_stream
dd read_7z
dd read_zip
dd read_mem_stream
dd read_7z
dd read_zip
setposTable:
dd setpos_mem_stream
dd setpos_7z
dd setpos_zip
dd setpos_mem_stream
dd setpos_7z
dd setpos_zip
closeTable:
dd close_mem_stream
dd close_file_7z
dd close_file_zip
dd close_mem_stream
dd close_file_7z
dd close_file_zip
 
; pointers for SayErr and Message
ContinueBtn dd aContinue
HeaderError_ptr dd aHeaderError
aReadError_ptr dd aReadError
aNoFreeRam_ptr dd aNoFreeRam
ContinueBtn dd aContinue
HeaderError_ptr dd aHeaderError
aReadError_ptr dd aReadError
aNoFreeRam_ptr dd aNoFreeRam
aEncodingProblem_str_ptr:
dd aEncodingProblem_str
dd aEncodingProblem_str.2
dd aEncodingProblem_str.3
aNameTooLong_ptr dd aNameTooLong
dd aEncodingProblem_str
dd aEncodingProblem_str.2
dd aEncodingProblem_str.3
aNameTooLong_ptr dd aNameTooLong
aArchiveDataError_ptr dd aArchiveDataError
aArchiveDataErrorPass_ptr dd aArchiveDataErrorPass
CancelPassBtn dd aCancel
dd aChangePass
CancelPassBtn dd aCancel
dd aChangePass
 
; "enter password" dialog for KFar
password_dlg:
dd 1 ; use standard dialog colors
dd -1 ; center window by x
dd -1 ; center window by y
.width dd ? ; width (will be filled according to current console width)
dd 2 ; height
dd 4, 2 ; border size
dd aEnterPasswordTitle ; title
dd ? ; colors (will be set by KFar)
dd 0 ; used internally by dialog manager, ignored
dd 0, 0 ; reserved for DlgProc
dd 2 ; 2 controls
dd 1 ; use standard dialog colors
dd -1 ; center window by x
dd -1 ; center window by y
.width dd ? ; width (will be filled according to current console width)
dd 2 ; height
dd 4, 2 ; border size
dd aEnterPasswordTitle ; title
dd ? ; colors (will be set by KFar)
dd 0 ; used internally by dialog manager, ignored
dd 0, 0 ; reserved for DlgProc
dd 2 ; 2 controls
; the string "enter password"
dd 1 ; type: static
dd 1,0 ; upper-left position
.width1 dd ?,0 ; bottom-right position
dd aEnterPassword ; data
dd 0 ; flags
dd 1 ; type: static
dd 1,0 ; upper-left position
.width1 dd ?,0 ; bottom-right position
dd aEnterPassword ; data
dd 0 ; flags
; editbox for password
dd 3 ; type: edit
dd 1,1 ; upper-left position
.width2 dd ?,0 ; bottom-right position
dd password_data ; data
dd 2Ch ; flags
dd 3 ; type: edit
dd 1,1 ; upper-left position
.width2 dd ?,0 ; bottom-right position
dd password_data ; data
dd 2Ch ; flags
 
IncludeIGlobals
 
1512,51 → 1527,53
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;; Uninitialized data ;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
purge data ;used in 'macros.inc'
purge section ;used in 'macros.inc'
 
section '.udata' data readable writable align 16
kfar_info dd ?
crc_table rd 256
_esp dd ?
_ebp dd ?
bufsize dd ?
bufptr dd ?
bufend dd ?
buffer rb 1024
inStream dd ?
hOut dd ?
.allocated dd ?
kfar_info dd ?
crc_table rd 256
_esp dd ?
_ebp dd ?
bufsize dd ?
bufptr dd ?
bufend dd ?
buffer rb 1024
inStream dd ?
hOut dd ?
.allocated dd ?
 
error_proc dd ?
clear_proc dd ?
error_proc dd ?
clear_proc dd ?
 
; import from kfar
open2 dd ?
filesize dd ?
read dd ?
seek dd ?
close dd ?
pgalloc dd ?
pgrealloc dd ?
pgfree dd ?
getfreemem dd ?
DialogBox dd ?
SayErr dd ?
Message dd ?
cur_console_size dd ?
open2 dd ?
filesize dd ?
read dd ?
seek dd ?
close dd ?
pgalloc dd ?
pgrealloc dd ?
pgfree dd ?
getfreemem dd ?
DialogBox dd ?
SayErr dd ?
Message dd ?
cur_console_size dd ?
 
; data for editbox in kfar dialog
password_maxlen = 512
password_data:
.maxlen dd ?
.pos dd ?
.start dd ?
password_ansi rb password_maxlen+1
bPasswordDefined db ?
.maxlen dd ?
.pos dd ?
.start dd ?
password_ansi rb password_maxlen+1
bPasswordDefined db ?
 
; converted password
password_unicode rw password_maxlen+1
password_size dd ?
password_unicode rw password_maxlen+1
password_size dd ?
 
IncludeUGlobals
 
bWasWarning db ?
bWasWarning db ?
/programs/fs/kfar/trunk/zlib/build.bat
1,5 → 1,3
@fasm.exe -m 32768 zlib.asm zlib.obj
@kpack zlib.obj
@fasm.exe -m 32768 example1.asm example1.kex
@kpack example1.kex
pause
/programs/fs/kfar/trunk/zlib/crc32.asm
23,8 → 23,8
 
align 4
crc_table_empty dd 1
align 4
crc_table rd TBLS*256
;align 4
;crc_table rd TBLS*256
 
; Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
; x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
/programs/fs/kfar/trunk/zlib/example1.asm
245,12 → 245,6
align 4
import_archiver:
deflate_unpack dd sz_deflate_unpack
dd 0,0
sz_deflate_unpack db 'deflate_unpack',0
 
align 4
import_zlib:
; dd sz_lib_init
deflateInit dd sz_deflateInit
deflateInit2 dd sz_deflateInit2
deflateReset dd sz_deflateReset
257,10 → 251,8
deflate dd sz_deflate
deflateEnd dd sz_deflateEnd
calc_crc32 dd sz_calc_crc32
 
dd 0,0
 
; sz_lib_init db 'lib_init',0
sz_deflate_unpack db 'deflate_unpack',0
sz_deflateInit db 'deflateInit',0
sz_deflateInit2 db 'deflateInit2',0
sz_deflateReset db 'deflateReset',0
272,21 → 264,14
system_dir_0 db '/sys/lib/'
lib_name_0 db 'archiver.obj',0
 
system_dir_1 db '/sys/lib/'
lib_name_1 db 'zlib.obj',0
 
err_message_found_lib0 db 'Sorry I cannot load library archiver.obj',0
err_message_found_lib1 db 'Sorry I cannot load library zlib.obj',0
head_f_i:
head_f_l db 'System error',0
err_message_import0 db 'Error on load import library archiver.obj',0
err_message_import1 db 'Error on load import library zlib.obj',0
 
l_libs_start:
lib0 l_libs lib_name_0, cur_dir_path, library_path, system_dir_0,\
err_message_found_lib0, head_f_l, import_archiver,err_message_import0, head_f_i
lib1 l_libs lib_name_1, cur_dir_path, library_path, system_dir_1,\
err_message_found_lib1, head_f_l, import_zlib, err_message_import1, head_f_i
load_lib_end:
;---------------------------------------------------------------------
 
/programs/fs/kfar/trunk/zlib/zlib.asm
1,8 → 1,4
format MS COFF
public EXPORTS
 
section '.flat' code readable align 16
 
include '../../../../proc32.inc'
include '../../../../macros.inc'
include '../../../../KOSfuncs.inc'
44,7 → 40,7
include 'zlib.inc'
include 'deflate.inc'
include 'zutil.asm'
include '../kfar_arc/crc.inc'
;include '../kfar_arc/crc.inc'
include 'crc32.asm'
include 'adler32.asm'
include 'trees.asm'
170,25 → 166,3
@@:
ret
 
; export table
align 4
EXPORTS:
dd adeflateInit, deflateInit
dd adeflateInit2, deflateInit2
dd adeflateReset, deflateReset
dd adeflate, deflate
dd adeflateEnd, deflateEnd
dd adeflateCopy, deflateCopy
dd azError, zError
dd acalc_crc32, calc_crc32
dd 0
 
; exported names
adeflateInit db 'deflateInit',0
adeflateInit2 db 'deflateInit2',0
adeflateReset db 'deflateReset',0
adeflate db 'deflate',0
adeflateEnd db 'deflateEnd',0
adeflateCopy db 'deflateCopy',0
azError db 'zError',0
acalc_crc32 db 'calc_crc32',0
/programs/fs/kfar/trunk/zlib/zlib.inc
226,30 → 226,15
; unsigned char *next;
; z_off64_t pos;
;};
;int gzgetc_ OF((gzFile file)); /* backward compatibility */
;if Z_PREFIX_SET
 
if Z_PREFIX_SET eq 1
;# undef z_gzgetc
;# define z_gzgetc(g) \
; ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
;#else
else
;# define gzgetc(g) \
; ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
end if
 
; provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
; change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
; both are true, the application gets the *64 functions, and the regular
; functions are changed to 64 bits) -- in case these are set on systems
; without large file support, _LFS64_LARGEFILE must also be true
end if
 
; undocumented functions
;const char * zError OF((int));
;int inflateSyncPoint OF((z_streamp));
;const z_crc_t FAR * get_crc_table OF((void));
;int inflateUndermine OF((z_streamp, int));
;int inflateResetKeep OF((z_streamp));
;#if defined(_WIN32) && !defined(Z_SOLO)
;gzFile gzopen_w OF((const wchar_t *path,
; const char *mode));
;end if