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 ? |