From d7512224b5057be03a945f9c1a260636dda75526 Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Thu, 20 Sep 2007 16:20:58 +0000 Subject: [PATCH] KFar 0.41 + KFar_Arc 0.11 git-svn-id: svn://kolibrios.org@631 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/fs/kfar/trunk/api.txt | 20 +- programs/fs/kfar/trunk/filetool.inc | 89 ++++- programs/fs/kfar/trunk/kfar.asm | 35 +- programs/fs/kfar/trunk/kfar_arc/7z.inc | 338 ++---------------- programs/fs/kfar/trunk/kfar_arc/kfar_arc.asm | 351 +++++++++++++++++-- 5 files changed, 471 insertions(+), 362 deletions(-) diff --git a/programs/fs/kfar/trunk/api.txt b/programs/fs/kfar/trunk/api.txt index 164ce258aa..cc102ae457 100644 --- a/programs/fs/kfar/trunk/api.txt +++ b/programs/fs/kfar/trunk/api.txt @@ -4,7 +4,7 @@ при вызове экспортируемых функций и ожидает того же для callback-функций. int version; -Версия интерфейса kfar, на которую рассчитан плагин. Сейчас должна быть 1. +Версия интерфейса kfar, на которую рассчитан плагин. Сейчас должна быть 2. int __stdcall plugin_load(kfar_info* info); Вызывается при загрузке плагина. @@ -20,9 +20,14 @@ typedef struct // O_WRITE = 2 - доступ для записи // O_CREATE = 4 - если файл не существует, создать его // O_TRUNCATE = 8 - усечь файл до нулевой длины + void* open2; // HANDLE __stdcall open2(int plugin_id, HANDLE plugin_instance, + // const char* name, int mode); + // аналогично open, но открывает файл с панели плагина + // open2(0,,name,mode) = open(name,mode) void* read; // unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size); void* write; // ещё не реализовано void* seek; // void __stdcall seek(HANDLE hFile, int method, __int64 newpos); + void* tell; // __int64 __stdcall tell(HANDLE hFile); void* flush; // ещё не реализовано void* filesize; // __int64 __stdcall filesize(HANDLE hFile); void* close; // void __stdcall close(HANDLE hFile); @@ -60,14 +65,21 @@ typedef struct void __stdcall plugin_unload(void); Вызывается при выгрузке плагина (в процессе завершения работы kfar). -HANDLE __stdcall OpenFilePlugin(HANDLE basefile, const char* name, - const void* attr, const void* data, int datasize); +HANDLE __stdcall OpenFilePlugin(HANDLE basefile, + const void* attr, const void* data, int datasize, + int baseplugin_id, HANDLE baseplugin_instance, const char* name); Открывает плагин, эмулирующий файловую систему на базе файла (например, архива). + basefile - хэндл файла (к которому применимы функции read и seek из kfar_info) -name - имя файла (во временном буфере) attr - указатель на структуру с атрибутами файла в формате системной функции 70.1 data - буфер, содержащий данные из начала файла (может использоваться для определения типа файла) datasize - размер данных в data. В текущей реализации min(1024,размер файла) +baseplugin_id - идентификатор плагина, на панели которого располагается открываемый файл; + 0 в случае обычных панелей +baseplugin_instance - хэндл, возвращённый из функции GetOpenPluginInfo плагина, + определяемого по baseplugin_id +name - имя файла (во временном буфере) (полное имя относительно baseplugin) + Если плагин обрабатывает переданный файл, то он должен вернуть новый описатель, который в дальнейшем будет использовать kfar для обращения к плагину. В этом случае плагин должен самостоятельно закрыть basefile функцией close из kfar_info (например, diff --git a/programs/fs/kfar/trunk/filetool.inc b/programs/fs/kfar/trunk/filetool.inc index ca7991109f..286b827c92 100644 --- a/programs/fs/kfar/trunk/filetool.inc +++ b/programs/fs/kfar/trunk/filetool.inc @@ -1008,7 +1008,7 @@ open: jnz .ret0 ; file does not exist test [ecx+_FILE.mode], O_CREATE - jz .ret0z + jz .ret0 .truncate: lea ebx, [ecx+_FILE.fileinfo] mov byte [ebx], 2 @@ -1039,6 +1039,82 @@ open: popad ret 8 +; HANDLE __stdcall open2(int plugin_id, HANDLE plugin_instance, const char* name, int mode); +; Opens file on plugin panel +open2: + cmp dword [esp+4], 0 + jnz .plugin + pop eax + add esp, 8 + push eax + jmp open +.plugin: + pushad + mov ecx, _FILE.size + call xpgalloc + test eax, eax + jz .ret0z + mov [esp+28], eax + mov ecx, eax + mov esi, [esp+44] + lea edi, [eax+_FILE.finame] + lea edx, [eax+_FILE.finame+1024] +@@: + lodsb + stosb + test al, al + jz @f + cmp edi, edx + jb @b +.ret0: + call pgfree +.ret0z: + popad + xor eax, eax + ret 8 +@@: + mov edx, [esp+36] + mov [ecx+_FILE.hPlugin], edx + mov ebx, [esp+40] + mov eax, [esp+48] + mov [ecx+_FILE.mode], eax + push ebx ecx + push eax + lea eax, [ecx+_FILE.finame] + push eax + push ebx + call [edx+PluginInfo.open] + pop ecx ebx + test eax, eax + jz .ret0 + mov [ecx+_FILE.hFile], eax + mov edx, [esp+36] + push ecx + lea edi, [ecx+_FILE.fileinfo] + push edi + xor eax, eax + push ecx + push 10 + pop ecx + rep stosd + pop ecx + lea eax, [ecx+_FILE.finame] + push eax + push ebx + call [edx+PluginInfo.getattr] + pop ecx + xor eax, eax + mov dword [ecx+_FILE.pos], eax + mov dword [ecx+_FILE.pos+4], eax + mov dword [ecx+_FILE.bufpos], eax + mov dword [ecx+_FILE.bufpos+4], eax + mov [ecx+_FILE.bufsize], eax + mov dword [ecx+_FILE.fioffset], eax + mov dword [ecx+_FILE.fioffset+4], eax + mov [esp+28], ecx + popad + ret 16 + ; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size); read: xor eax, eax @@ -1072,6 +1148,10 @@ read: add [esp+28], ebx add dword [ecx+_FILE.pos], ebx adc dword [ecx+_FILE.pos+4], 0 + test dword [ecx+_FILE.pos], 2047 + jnz @f + and [ecx+_FILE.bufsize], 0 +@@: sub [esp+44], ebx jz .ret .nobuf0: @@ -1248,6 +1328,13 @@ setpos_default: call seek ret 12 +; __int64 __stdcall tell(HANDLE hFile); +tell: + mov eax, [esp+4] + mov edx, dword [eax+_FILE.pos+4] + mov eax, dword [eax+_FILE.pos] + ret 4 + ; __int64 __stdcall filesize(HANDLE hFile); filesize: mov eax, [esp+4] diff --git a/programs/fs/kfar/trunk/kfar.asm b/programs/fs/kfar/trunk/kfar.asm index 07c13d4e42..74b9a521fb 100644 --- a/programs/fs/kfar/trunk/kfar.asm +++ b/programs/fs/kfar/trunk/kfar.asm @@ -7,8 +7,8 @@ memsize dd mem dd stacktop dd 0, app_path -version equ '0.4' -version_dword equ 0*10000h + 40 +version equ '0.41' +version_dword equ 0*10000h + 41 include 'lang.inc' include 'font.inc' @@ -868,12 +868,13 @@ enum_plugins_callback: jnc @f xor eax, eax @@: -MIN_INTERFACE_VER = 1 -MAX_INTERFACE_VER = 1 +MIN_INTERFACE_VER = 2 +MAX_INTERFACE_VER = 2 cmp eax, MIN_INTERFACE_VER - jae @f + jb @f cmp eax, MAX_INTERFACE_VER - jbe @f + jbe .version_ok +@@: push aIncompatibleVersion .cantload: push saved_file_name @@ -886,7 +887,7 @@ MAX_INTERFACE_VER = 1 call SayErr add esp, 12 jmp .dec_ret -@@: +.version_ok: mov edi, esi mov esi, plugin_exported .import: @@ -919,6 +920,8 @@ plugin_unload_default: ret OpenFilePlugin_default: + xor eax, eax + ret 28 GetFiles_default: xor eax, eax ret 20 @@ -1324,11 +1327,13 @@ panels_OnKey: dec ecx js .plugdone pushad + push execdata + push [ebp+panel1_hFile-panel1_data] + push [ebp+panel1_hPlugin-panel1_data] push edi push filedata_buffer call get_curfile_folder_entry push ecx - push execdata push esi call [edx+PluginInfo.OpenFilePlugin] mov [esp+28], eax @@ -3930,7 +3935,10 @@ draw_panel: .native: mov edi, cur_header mov ecx, [ebp + panel1_width - panel1_data] - sub ecx, 7 + sub ecx, 6 + cmp byte [esi], '/' + jnz .copy_rest + dec ecx movsb @@: lodsb @@ -3940,6 +3948,7 @@ draw_panel: jz .header_created cmp al, '/' jnz @b +.copy_rest: mov edx, esi @@: lodsb @@ -7266,7 +7275,7 @@ nullstr db 0 aUntitled db 'untitled',0 aDotDot db '..',0,0 standard_dll_path: -libini_name db '/sys/dll/' +libini_name db '/sys/lib/' standard_dll_path_size = $ - standard_dll_path db 'libini.obj',0 aStart db 'START',0 @@ -7348,9 +7357,11 @@ kfar_info: dd .size dd version_dword dd open + dd open2 dd read dd -1 ; write: to be implemented dd seek + dd tell dd -1 ; flush: to be implemented dd filesize dd close @@ -7610,8 +7621,8 @@ active_screen_vtable dd ? active_screen_data dd ? default_attr dd ? -left_dotdot_entry rb 40+3 ; 40 bytes for attributes + '..' -right_dotdot_entry rb 40+3 +left_dotdot_entry rb 40+4 ; 40 bytes for attributes + '..' +right_dotdot_entry rb 40+4 aConfirmDeleteTextBuf rb aConfirmDeleteTextMax + 1 CopySourceTextBuf rb 512 diff --git a/programs/fs/kfar/trunk/kfar_arc/7z.inc b/programs/fs/kfar/trunk/kfar_arc/7z.inc index f4f1fc23f1..536ee93141 100644 --- a/programs/fs/kfar/trunk/kfar_arc/7z.inc +++ b/programs/fs/kfar/trunk/kfar_arc/7z.inc @@ -19,6 +19,7 @@ file_in_7z: .NumSubItems dd ? .next dd ? ; next item of list of subfolders or files .prev dd ? ; previous item of list of subfolders or files +.stamp dd ? .attr dd ? .FileCRC dd ? .startPos dq ? @@ -37,7 +38,6 @@ file_in_7z: .bLastWriteTimeDefined db ? .bHasStream db ? .bAnti db ? -.stamp dd ? .size = $ end virtual @@ -830,7 +830,7 @@ open_7z: mov esi, [inStream] mov [eax+handle_7z.host], esi lea edi, [eax+handle_7z.host_datetime] - mov esi, [esp+16] + mov esi, [esp+12] add esi, 8 mov ecx, 6 rep movsd @@ -2202,8 +2202,6 @@ fillBufFromInStream: push 0 push [inStream] call [seek] - pop eax - push eax push ecx push edi push [inStream] @@ -2273,6 +2271,20 @@ _7z.GetCoder: jnz @f cmp dword [eax+9], 1 jz .ret +@@: + inc edx +; Deflate decoder: method ID = [size=03] 04 01 08, NumInStreams = NumOutStreams = 1 + cmp dword [eax+4], 0x08010403 + jnz @f + cmp dword [eax+8], 1 + jz .ret +@@: + inc edx +; Deflate64 decoder: method ID = [size=03] 04 01 09, NumInStreams = NumOutStreams = 1 + cmp dword [eax+4], 0x09010403 + jnz @f + cmp dword [eax+8], 1 + jz .ret @@: stc .ret: @@ -2287,6 +2299,8 @@ label _7z.GetBufSizeTable dword dd bcj_get_buf_size dd bcj2_get_buf_size dd aes7z_get_buf_size + dd deflate_get_buf_size + dd deflate_get_buf_size label _7z.InitTable dword dd copy_init_decoder dd lzma_init_decoder @@ -2294,6 +2308,8 @@ label _7z.InitTable dword dd bcj_init_decoder dd bcj2_init_decoder dd aes7z_init_decoder + dd deflate_init_decoder + dd deflate64_init_decoder endg copy_get_buf_size: @@ -2343,164 +2359,6 @@ copy_fillBuf: popad ret -; int __stdcall ReadFolder([esp+4] = HANDLE hPlugin, -; [esp+8] = unsigned dirinfo_start, [esp+12] = unsigned dirinfo_size, -; [esp+16] = void* dirdata); -ReadFolder_7z: -; 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] -; get current directory - lea ebx, [ebp+handle_7z.root.subfolders] - cmp [ebp+handle_7z.curdir], 0 - jz @f - mov ebx, [ebp+handle_7z.curdir] - add ebx, file_in_7z.subfolders -@@: - 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 -@@: - cmp ecx, [esp+12] - jb @f - mov ecx, [esp+12] - xor eax, eax ; OK -@@: - mov [edi-28], ecx - push eax -; copy files data - test ecx, ecx - jz .done -; seek to required item - mov eax, [esp+8+4] - mov esi, [ebx] -.0: - test esi, esi - jnz .1 - mov esi, [ebx+8] -.1: - add esi, ebp - dec eax - js .2 - mov esi, [esi+file_in_7z.next] - jmp .0 -.2: -.copy: - cmp [esi+file_in_7z.bPseudoFolder], 0 - jnz .pseudo - xor eax, eax - cmp [esi+file_in_7z.bAttrDefined], 0 - jz @f - mov eax, [esi+file_in_7z.attr] -@@: - stosd - xor eax, eax - stosd - push esi ecx - add esi, file_in_7z.CreationTime - mov ecx, 8 - rep movsd - pop ecx esi - mov edx, [esi+file_in_7z.name] - push edi -@@: - mov al, [edx] - inc edx - stosb - test al, al - jnz @b - pop edi -.cont: - add edi, 264 - mov esi, [esi+file_in_7z.next] - test esi, esi - jnz @f - mov esi, [ebx+8] -@@: - add esi, ebp - loop .copy - jmp .done -.pseudo: - push 0x10 ; attributes: folder - pop eax - stosd - xor eax, eax - stosd - push ecx esi - lea esi, [ebp+handle_7z.host_datetime] - mov ecx, 6 - rep movsd - pop esi - stosd - stosd - push edi esi - mov ecx, [esi+file_in_7z.namelen] - mov esi, [esi+file_in_7z.name] - rep movsb - mov byte [edi], 0 - pop esi edi ecx - jmp .cont -.done: - pop eax - ret 10h - -; bool __stdcall SetFolder([esp+4] = HANDLE hPlugin, -; [esp+8] = const char* relative_path, [esp+12] = const char* absolute_path); -SetFolder_7z: - mov ebp, [esp+4] - mov edx, [ebp+handle_7z.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_7z.root.subfolders] - test edx, edx - jz .scan - mov ebx, [edx+file_in_7z.subfolders] -.scan: - test ebx, ebx - jz .err - add ebx, ebp - cmp [ebx+file_in_7z.namelen], ecx - jnz .cont - push ecx esi - mov edi, [ebx+file_in_7z.name] - repz cmpsb - pop esi ecx - jz .set -.cont: - mov ebx, [ebx+file_in_7z.next] - jmp .scan -.toparent: - test edx, edx - jz .err - mov ebx, [edx+file_in_7z.parent] - test ebx, ebx - jz @f - add ebx, ebp -@@: -.set: - mov [ebp+handle_7z.curdir], ebx - mov al, 1 - ret 12 -.err: - xor eax, eax - ret 12 - ; ebp=hPlugin, eax->item, edi->info getattr_7z: cmp [eax+file_in_7z.bPseudoFolder], 0 @@ -2514,23 +2372,17 @@ getattr_7z: rep movsd ret .pseudo: - mov esi, [eax+file_in_7z.name] - mov ecx, [eax+file_in_7z.namelen] push 0x10 ; attributes: folder pop eax stosd xor eax, eax stosd - push ecx esi lea esi, [ebp+handle_7z.host_datetime] push 6 pop ecx rep movsd - pop esi ecx stosd stosd - rep movsb - mov byte [edi], 0 ret virtual at 0 @@ -2986,153 +2838,3 @@ close_file_7z: call free_handle .ret: ret 4 - -iglobal -cur_stamp dd 0 -endg - -uglobal -tmp_bdfe rb 304 -endg - -GetFiles_7z: - mov ecx, [ebp+handle_7z.NumFiles] - test ecx, ecx - jz .ret - lea ebx, [ebp+handle_7z.basesize] - inc [cur_stamp] -.loop: - push ecx - mov esi, [ebx+file_in_7z.fullname] - mov edx, [ebp+handle_7z.curdir] - test edx, edx - jz .incur - mov eax, [cur_stamp] - mov [edx+file_in_7z.stamp], eax - mov edi, [edx+file_in_7z.fullname] - mov ecx, [edx+file_in_7z.namelen] - add ecx, [edx+file_in_7z.name] - sub ecx, edi - repz cmpsb - jnz .cont -.incur: - cmp byte [esi], '/' - jnz @f - inc esi -@@: - 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 -@@: - lodsb - scasb - jnz @f - test al, al - jz .ok2 - jmp @b -@@: - pop esi - cmp al, '/' - jnz @f - cmp byte [edi-1], 0 - jz .ok -@@: - add edx, 4 - jmp .check -.ok2: - pop esi -.ok: -; add all parents directories if needed -.parloope: - mov ecx, [ebx+file_in_7z.parent] - jecxz .pardone - add ecx, ebp - mov eax, [cur_stamp] - cmp [ecx+file_in_7z.stamp], eax - jz .pardone -.parloopi: - mov edx, ecx - mov ecx, [ecx+file_in_7z.parent] - jecxz @f - add ecx, ebp - cmp [ecx+file_in_7z.stamp], eax - jnz .parloopi -@@: - mov [edx+file_in_7z.stamp], eax - push esi - mov eax, edx - mov edi, tmp_bdfe - push edi - sub esi, [ebx+file_in_7z.fullname] - add esi, [edx+file_in_7z.fullname] - push esi - call getattr_7z - mov eax, [esp+16+20] - call eax - pop esi - test al, al - jz .forced_exit - jmp .parloope -.pardone: - cmp [ebx+file_in_7z.bIsDirectory], 0 - jz .addfile - mov eax, [cur_stamp] - cmp [ebx+file_in_7z.stamp], eax - jz .cont - mov [ebx+file_in_7z.stamp], eax - push esi - mov eax, ebx - mov edi, tmp_bdfe - push edi - push esi - call getattr_7z - mov eax, [esp+16+20] - call eax - pop esi - test al, al - jz .forced_exit - jmp .cont -.addfile: - push ebx esi - push 11h - pop edi - mov eax, ebx - call open_file_7z - pop esi ebx - test eax, eax - jz .cont - push eax - push eax - mov edi, tmp_bdfe - push edi - push esi - mov eax, ebx - call getattr_7z - mov eax, [esp+20+16] - call eax - pop ecx - push eax - push ebx - push ecx - call myclose - pop ebx - pop eax - test al, al - jz .forced_exit -.cont: - add ebx, file_in_7z.size - pop ecx - dec ecx - jnz .loop -.ret: - ret 20 -.forced_exit: - pop ecx - jmp .ret diff --git a/programs/fs/kfar/trunk/kfar_arc/kfar_arc.asm b/programs/fs/kfar/trunk/kfar_arc/kfar_arc.asm index 6a289a21da..a1bfd3ea93 100644 --- a/programs/fs/kfar/trunk/kfar_arc/kfar_arc.asm +++ b/programs/fs/kfar/trunk/kfar_arc/kfar_arc.asm @@ -2,9 +2,9 @@ ; project name: KFar_Arc - plugin for KFar, which supports various archives ; target platform: KolibriOS ; compiler: FASM 1.67.14 -; version: 0.1 -; last update: 2007-07-11 (Jul 11, 2007) -; minimal KFar version: 0.4 +; version: 0.11 +; last update: 2007-09-20 (Sep 20, 2007) +; minimal KFar version: 0.41 ; minimal kernel: no limit ; ; author: Diamond @@ -30,6 +30,8 @@ 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;; Interface for KFar ;;;;;;;;;;;;;; @@ -39,9 +41,11 @@ 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 ? @@ -65,6 +69,10 @@ end virtual 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] @@ -89,28 +97,48 @@ plugin_load: xor eax, eax ; success ret 4 -; HANDLE __stdcall OpenFilePlugin(HANDLE basefile, const char* name, -; const void* attr, const void* data, int datasize); +; HANDLE __stdcall OpenFilePlugin(HANDLE basefile, +; const void* attr, const void* data, int datasize, +; int baseplugin_id, HANDLE baseplugin_instance, const char* name); ; This function is called when user presses Enter (or Ctrl+PgDn) on file. ; Plugin tests whether given file is of supported type ; 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+16] + mov esi, [esp+12] mov ebp, [esp+4] ; test for 7z archive - cmp dword [esp+20], 20h ; minimal size of 7z archive is 20h bytes + 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 20 + 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 +.zip: + call open_zip + ret 28 +.no_zip: xor eax, eax - ret 20 + ret 28 ; Handle of plugin in kfar_arc is as follow: virtual at 0 @@ -121,6 +149,8 @@ handle_common: .root.subfiles dd ? .root.subfiles.end dd ? .root.NumSubItems dd ? +.curdir dd ? +.NumFiles dd ? ; ... some plugin-specific data follows ... end virtual @@ -141,6 +171,7 @@ file_common: .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); @@ -155,18 +186,132 @@ ClosePlugin: ; int __stdcall ReadFolder(HANDLE hPlugin, ; unsigned dirinfo_start, unsigned dirinfo_size, void* dirdata); ReadFolder: - mov eax, [esp+4] - mov eax, [eax] +; 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] +; 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 +@@: + 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 +@@: + cmp ecx, [esp+12] + jb @f + mov ecx, [esp+12] + xor eax, eax ; OK +@@: + mov [edi-28], ecx + push eax +; copy files data + jecxz .done +; seek to required item + mov eax, [esp+8+4] + mov esi, [ebx] +.0: + test esi, esi + jnz .1 + mov esi, [ebx+8] +.1: + add esi, ebp dec eax - jmp dword [ReadFolderTable+eax*4] + 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] +@@: + add esi, ebp + loop .copy +.done: + pop eax + ret 10h ; bool __stdcall SetFolder(HANDLE hPlugin, ; const char* relative_path, const char* absolute_path); SetFolder: - mov eax, [esp+4] - mov eax, [eax] - dec eax - jmp dword [SetFolderTable+eax*4] + 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] +.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 +.cont: + 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 +@@: +.set: + mov [ebp+handle_common.curdir], ebx + mov al, 1 + ret 12 +.err: + xor eax, eax + ret 12 + +iglobal +cur_stamp dd 0 +endg + +uglobal +tmp_bdfe rb 304 +endg ; void __stdcall GetFiles(HANDLE hPlugin, int NumItems, void* items[], ; void* addfile, void* adddir); @@ -174,9 +319,153 @@ SetFolder: ; 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] +.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 +.incur: + cmp byte [esi], '/' + jnz @f + inc esi +@@: + 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 +@@: + lodsb + scasb + jnz @f + test al, al + jz .ok2 + jmp @b +@@: + pop esi + cmp al, '/' + jnz @f + cmp byte [edi-1], 0 + jz .ok +@@: + add edx, 4 + jmp .check +.ok2: + 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 +.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 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+16+20] + call eax + 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 eax, ebx + mov edi, tmp_bdfe + push edi + push esi + mov ecx, [ebp] + call dword [getattrTable+(ecx-1)*4] + mov eax, [esp+16+20] + call eax + 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 +.cont: mov eax, [ebp] - dec eax - jmp dword [GetFilesTable+eax*4] + add ebx, [basesizes+(eax-1)*8+4] + pop ecx + dec ecx + jnz .loop +.ret: + ret 20 +.forced_exit: + pop ecx + jmp .ret ; void __stdcall GetOpenPluginInfo(HANDLE hPlugin, OpenPluginInfo* info); GetOpenPluginInfo: @@ -882,7 +1171,7 @@ query_password: ; export table align 4 EXPORTS: - dd aVersion, 1 + dd aVersion, 2 dd aPluginLoad, plugin_load dd aOpenFilePlugin,OpenFilePlugin dd aClosePlugin, ClosePlugin @@ -930,6 +1219,7 @@ aArchiveDataError db ' aArchiveDataErrorPass db 'Ошибка в данных архива или неверный пароль',0 aChangePass db 'Ввести пароль',0 aNameTooLong db 'Слишком длинное имя',0 +aCannotOpenFile db 'Не могу открыть файл',0 else aContinue db 'Continue',0 aCancel db 'Cancel',0 @@ -947,40 +1237,45 @@ 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 end if -; kfar_arc supports [hmm... will support...] many archive types. +; kfar_arc supports many archive types. ; OpenFilePlugin looks for supported archive signature and gives control ; to concrete handler if found. -; Other functions just determine type of opened archive and jumps to corresponding handler. +; 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_7z = 1 +type_zip = 2 ; archive functions (types start from type_7z) align 4 ClosePluginTable: dd close_7z -ReadFolderTable: - dd ReadFolder_7z -SetFolderTable: - dd SetFolder_7z -GetFilesTable: - dd GetFiles_7z + dd close_zip getattrTable: dd getattr_7z + dd getattr_zip openTable: 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 ; file functions (types start from type_mem_stream) readTable: dd read_mem_stream dd read_7z + dd read_zip setposTable: dd setpos_mem_stream dd setpos_7z + dd setpos_zip closeTable: dd close_mem_stream dd close_file_7z + dd close_file_zip ; pointers for SayErr and Message ContinueBtn dd aContinue @@ -1045,6 +1340,8 @@ error_proc dd ? clear_proc dd ? ; import from kfar +open2 dd ? +filesize dd ? read dd ? seek dd ? close dd ?