/programs/fs/kfar/trunk/api.txt |
---|
0,0 → 1,137 |
« £¨ ¯à¥¤áâ ¢«ï¥â ᮡ®© áâ ¤ àâãî ¤«ï ®«¨¡à¨ ¤¨ ¬¨ç¥áªãî ¡¨¡«¨®â¥ªã (ä®à¬ â COFF), |
íªá¯®àâ¨àãîéãî á«¥¤ãî騥 äãªæ¨¨ ¨ ¯¥à¥¬¥ë¥ (¥ª®â®àë¥ äãªæ¨¨ ¬®£ãâ ®âáãâá⢮¢ âì). |
ãªæ¨¨ ¬®£ãâ à §àãè âì «î¡ë¥ ॣ¨áâàë. kfar £ à â¨àã¥â á¡à®è¥ë© ä« £ ¯à ¢«¥¨ï DF |
¯à¨ ¢ë§®¢¥ íªá¯®àâ¨à㥬ëå äãªæ¨© ¨ ®¦¨¤ ¥â ⮣® ¦¥ ¤«ï callback-äãªæ¨©. |
int version; |
¥àá¨ï ¨â¥à䥩á kfar, ª®â®àãî à ááç¨â ¯« £¨. ¥©ç á ¤®«¦ ¡ëâì 1. |
int __stdcall plugin_load(kfar_info* info); |
ë§ë¢ ¥âáï ¯à¨ § £à㧪¥ ¯« £¨ . |
typedef struct |
{ |
int StructSize; // = sizeof(kfar_info) |
int kfar_ver; // 10000h*major + minor |
/* ᥠcallback-äãªæ¨¨ á®åà ïî⠢ᥠॣ¨áâàë, § ¨áª«î票¥¬ eax. */ |
/* ãªæ¨¨ à ¡®âë á ä ©« ¬¨: */ |
void* open; // HANDLE __stdcall open(const char* name, int mode); |
// mode - ª®¬¡¨ æ¨ï ¡¨â®¢ëå ä« £®¢ |
// O_READ = 1 - ¤®áâ㯠¤«ï ç⥨ï |
// O_WRITE = 2 - ¤®áâ㯠¤«ï § ¯¨á¨ |
// O_CREATE = 4 - ¥á«¨ ä ©« ¥ áãé¥áâ¢ã¥â, ᮧ¤ âì ¥£® |
// O_TRUNCATE = 8 - ãá¥çì ä ©« ¤® ã«¥¢®© ¤«¨ë |
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* flush; // ¥éñ ¥ ॠ«¨§®¢ ® |
void* filesize; // __int64 __stdcall filesize(HANDLE hFile); |
void* close; // void __stdcall close(HANDLE hFile); |
/* ãªæ¨¨ à ¡®âë á ¯ ¬ïâìî (¯®áâà ¨ç®): */ |
void* pgalloc; // in: ecx=size, out: eax=pointer or NULL |
// ¯à¨ ¥å¢ ⪥ ¯ ¬ï⨠ᮮ¡é ¥â ¯®«ì§®¢ â¥«î ¨ ¢®§¢à é ¥â NULL |
void* pgrealloc; // in: edx=pointer, ecx=new size, out: eax=pointer or NULL |
// ¯à¨ ¥å¢ ⪥ ¯ ¬ï⨠ᮮ¡é ¥â ¯®«ì§®¢ â¥«î ¨ ¢®§¢à é ¥â NULL |
void* pgfree; // in: ecx=pointer |
void* getfreemem; // unsigned __stdcall getfreemem(void); |
// ¢®§¢à é ¥â à §¬¥à ᢮¡®¤®© ®¯¥à ⨢®© ¯ ¬ï⨠¢ ¡ |
void* pgalloc2; // void* __stdcall pgalloc2(unsigned size); |
void* pgrealloc2; // void* __stdcall pgrealloc2(void* pointer, unsigned size); |
void* pgfree2; // void __stdcall pgfree2(void* pointer); |
/* ãªæ¨¨ à ¡®âë á ¤¨ «®£ ¬¨: */ |
void* menu; // int __stdcall menu(void* variants, const char* title, unsigned flags); |
// variants 㪠§ë¢ ¥â ⥪ã騩 í«¥¬¥â ¢ ¤¢ãá¢ï§®¬ ᯨ᪥ |
void* menu_centered_in; // int __stdcall menu_centered_in(unsigned left, unsigned top, |
// unsigned width, unsigned height, |
// void* variants, const char* title, unsigned flags); |
void* DialogBox; // int __stdcall DialogBox(DLGDATA* dlg); |
void* SayErr; // int __stdcall SayErr(int num_strings, const char** strings, |
// int num_buttons, const char** buttons); |
void* Message; // int __stdcall Message(const char* title, |
// int num_strings, const char** strings, |
// int num_buttons, const char** buttons); |
// may be x=-1 and/or y=-1 |
struct {unsigned width;unsigned height;}* cur_console_size; |
} kfar_info; |
®§¢à é ¥¬®¥ § 票¥: |
0 = ãᯥè ï ¨¨æ¨ «¨§ æ¨ï |
1 = ®è¨¡ª ¨¨æ¨ «¨§ 樨 (kfar ¢ë¤ áâ á®®¡é¥¨¥ ¯®«ì§®¢ ⥫î) |
2 = ®è¨¡ª ¨¨æ¨ «¨§ 樨 (kfar ¯à®¤®«¦¨â ¡¥§ á®®¡é¥¨©) |
void __stdcall plugin_unload(void); |
ë§ë¢ ¥âáï ¯à¨ ¢ë£à㧪¥ ¯« £¨ (¢ ¯à®æ¥áᥠ§ ¢¥à襨ï à ¡®âë kfar). |
HANDLE __stdcall OpenFilePlugin(HANDLE basefile, const char* name, |
const void* attr, const void* data, int datasize); |
âªàë¢ ¥â ¯« £¨, í¬ã«¨àãî騩 ä ©«®¢ãî á¨á⥬㠡 §¥ ä ©« ( ¯à¨¬¥à, à娢 ). |
basefile - åí¤« ä ©« (ª ª®â®à®¬ã ¯à¨¬¥¨¬ë äãªæ¨¨ read ¨ seek ¨§ kfar_info) |
name - ¨¬ï ä ©« (¢® ¢à¥¬¥®¬ ¡ãä¥à¥) |
attr - 㪠§ ⥫ì áâàãªâãàã á âਡãâ ¬¨ ä ©« ¢ ä®à¬ ⥠á¨á⥬®© äãªæ¨¨ 70.1 |
data - ¡ãä¥à, ᮤ¥à¦ 騩 ¤ ë¥ ¨§ ç « ä ©« (¬®¦¥â ¨á¯®«ì§®¢ âìáï ¤«ï ®¯à¥¤¥«¥¨ï ⨯ ä ©« ) |
datasize - à §¬¥à ¤ ëå ¢ data. ⥪ã饩 ॠ«¨§ 樨 min(1024,à §¬¥à ä ©« ) |
᫨ ¯« £¨ ®¡à ¡ âë¢ ¥â ¯¥à¥¤ ë© ä ©«, â® ® ¤®«¦¥ ¢¥àãâì ®¢ë© ®¯¨á ⥫ì, |
ª®â®àë© ¢ ¤ «ì¥©è¥¬ ¡ã¤¥â ¨á¯®«ì§®¢ âì kfar ¤«ï ®¡à é¥¨ï ª ¯« £¨ã. í⮬ á«ãç ¥ |
¯« £¨ ¤®«¦¥ á ¬®áâ®ïâ¥«ì® § ªàëâì basefile äãªæ¨¥© close ¨§ kfar_info ( ¯à¨¬¥à, |
¯à¨ § ªàë⨨ ®¯¨á â¥«ï ¯« £¨ ¢ ClosePlugin ¨«¨ ¥¯®á।á⢥® ¢ OpenFilePlugin, |
¥á«¨ basefile ¢®®¡é¥ ¢¯®á«¥¤á⢨¨ ¥ 㦥). |
᫨ ¯« £¨ ¥ ®¡à ¡ âë¢ ¥â ¯¥à¥¤ ë© ä ©«, ¤®«¦¥ ¢®§¢à é âìáï 0. |
᫨ ®¯¥à æ¨ï ¯à¥à¢ ¯®«ì§®¢ ⥫¥¬, ¤®«¦® ¢®§¢à é âìáï § 票¥ -1. |
void __stdcall ClosePlugin(HANDLE hPlugin); |
ªàë¢ ¥â ᮧ¤ ë© ¢ OpenFilePlugin ®¯¨á ⥫ì. |
void __stdcall GetOpenPluginInfo(HANDLE hPlugin, OpenPluginInfo* Info); |
®«ãç¨âì ¨ä®à¬ æ¨î ®¡ ®âªàë⮬ íª§¥¬¯«ïॠ¯« £¨ . |
typedef struct |
{ |
unsigned flags; // ¡¨â 0: ¤®¡ ¢«ïâì í«¥¬¥â '..', ¥á«¨ ® ®âáãâáâ¢ã¥â |
// ¡¨â 1: ª®¯¨à®¢ ¨¥ ®¡à ¡ âë¢ ¥âáï äãªæ¨¥© GetFiles |
} OpenPluginInfo; |
void __stdcall GetPanelTitle(HANDLE hPlugin, char title[1024], |
const char* host_file, const char* curdir); |
®«ãç¨âì § £®«®¢®ª ¯ ¥«¨ ¯« £¨ . à ¬¥âà host_file ᮢ¯ ¤ ¥â á ¨¬¥¥¬ ä ©« , ¯¥à¥¤ ë¬ |
¢ OpenFilePlugin. à ¬¥âà curdir ᮢ¯ ¤ ¥â á ⥪ã饩 ¯ ¯ª®©, ãáâ ¢«¨¢ ¥¬®© ¢ SetFolder. |
int __stdcall ReadFolder(HANDLE hPlugin, unsigned dirinfo_start, |
unsigned dirinfo_size, void* dirdata); |
¨â ¥â ⥪ãéãî ¯ ¯ªã. hPlugin - ¢®§¢à éñë© ¨§ OpenFilePlugin ®¯¨á ⥫ì. |
dirinfo_start - á ª ª®£® ä ©« ç¨â âì, dirinfo_size - ᪮«ìª® ä ©«®¢ ç¨â âì. |
®§¢à é ¥¬®¥ § 票¥ ¨ ¢®§¢à é ¥¬ë¥ ¢ dirdata ¤ ë¥ ¤®«¦ë ᮮ⢥âá⢮¢ âì äãªæ¨¨ 70.1. |
bool __stdcall SetFolder(HANDLE hPlugin, const char* relative_path, const char* absolute_path); |
áâ ®¢¨âì ⥪ãéãî ¯ ¯ªã. relative_path - ®â®á¨â¥«ìë© ¯ãâì (".." ¨«¨ ¨¬ï ¯®¤¯ ¯ª¨), |
absolute_path - ¡á®«îâë© ¯ãâì (¯ ¯ª í¬ã«¨à㥬®© ¯« £¨®¬ ä ©«®¢®© á¨á⥬ë). |
void __stdcall GetFiles(HANDLE hPlugin, int NumItems, void* items[], void* addfile, void* adddir); |
bool __stdcall addfile(const char* name, void* bdfe_info, HANDLE hFile); |
bool __stdcall adddir(const char* name, void* bdfe_info); |
ë§ë¢ ¥âáï ¤«ï ª®¯¨à®¢ ¨ï, ¥á«¨ ¢® ä« £ å, ¢®§¢à é ¥¬ëå GetOpenPluginInfo, ãáâ ®¢«¥ ¡¨â 1. |
âã äãªæ¨î ४®¬¥¤ã¥âáï ॠ«¨§®¢ë¢ âì ¢ á«ãç ¥, ¥á«¨ áâ ¤ àâë© à¥ªãàá¨¢ë© ®¡å®¤ ¯ ¯®ª |
¥ã¤®¡¥. |
hPlugin - ®¯¨á ⥫ì, ᮧ¤ ë© ¢ OpenFilePlugin. |
NumItems - ç¨á«® ª®¯¨à㥬ëå í«¥¬¥â®¢. |
items - ¬ áᨢ ª®¯¨à㥬ëå í«¥¬¥â®¢, ª ¦¤ë© ¨§ ª®â®àëå § ¤ ñâáï 㪠§ ⥫¥¬ áâàãªâãàã BDFE. |
¯¥æ¨ «ìë© á«ãç © NumItems=-1, items=NULL ®§ ç ¥â "¢á¥ ä ©«ë" (¢ ⥪ã饩 ¯ ¯ª¥ ¨ ¯®¤¯ ¯ª å). |
addfile, adddir - callback-äãªæ¨¨ kfar' . ®§¢à â false ®§ ç ¥â "¯à¥à¢ âì ª®¯¨à®¢ ¨¥". |
à ¬¥âà name ¤®«¦¥ § ¤ ¢ âì ¨¬ï ®â®á¨â¥«ì® ⥪ã饩 ¯ ¯ª¨. à ¬¥âà bdfe_info - |
㪠§ ⥫ì ᮪à éñãî (40 ¡ ©â) § ¯¨áì ¢ ä®à¬ ⥠äãªæ¨¨ 70.5. |
âªàë⨥¬ ¨ § ªàë⨥¬ ®¯¨á ⥫ï hFile ¤®«¦¥ § ¨¬ âìáï ¯« £¨. ãªæ¨ï addfile ¡ã¤¥â |
¢ë§ë¢ âì ⮫쪮 äãªæ¨î read. |
int __stdcall getattr(HANDLE hPlugin, const char* filename, void* info); |
®«ãç¨âì ¨ä®à¬ æ¨î ® ä ©«¥. ®§¢à é ¥¬®¥ § 票¥ ¨ ¤ ë¥ ¢ info ¤®«¦ë ᮮ⢥âá⢮¢ âì |
äãªæ¨¨ 70.5. |
HANDLE __stdcall open(HANDLE hPlugin, const char* filename, int mode); |
âªàëâì ä ©« filename. à ¬¥âà mode § १¥à¢¨à®¢ ¨ ¢ ⥪ã饩 ¢¥àᨨ kfar ¢á¥£¤ à ¢¥ 1. |
unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size); |
⥨¥ size ¡ ©â ¢ ¡ãä¥à buf ¨§ ä ©« hFile, à ¥¥ ®âªàë⮣® ç¥à¥§ open. |
kfar £ à â¨àã¥â, çâ® size ªà ⥠512 ¡ ©â. |
®§¢à é ¥¬®¥ § 票¥: ç¨á«® ¯à®ç¨â ëå ¡ ©â, -1 ¯à¨ ®è¨¡ª¥. |
void __stdcall setpos(HANDLE hFile, __int64 pos); |
áâ ®¢¨âì ⥪ãéãî ¯®§¨æ¨î ¢ ä ©«¥ hFile, à ¥¥ ®âªàë⮣® ç¥à¥§ open, ¢ pos. |
à â¨àã¥âáï, çâ® pos ªà â® 512 ¡ ©â. |
void __stdcall close(HANDLE hFile); |
/programs/fs/kfar/trunk/dialogs.inc |
---|
320,8 → 320,7 |
jz .redraw |
dec eax |
jz .key |
or eax, -1 |
int 40h |
jmp exit |
.redraw: |
push ebx ebp |
call draw_window |
772,6 → 771,10 |
jz .pgdn |
cmp al, 0x49 |
jz .pgup |
cmp al, 0x52 |
jz .ins |
cmp al, 0x53 |
jz .del |
mov edx, [ebx+36] |
@@: |
cmp dword [edx+4], 0 |
858,6 → 861,28 |
.enter: |
mov eax, [ebx+36] |
ret 16 |
.ins: |
push 5 |
pop edx |
jmp @f |
.del: |
push 4 |
pop edx |
@@: |
mov eax, [ebx+36] |
cmp byte [eax+8], '/' |
jnz @f |
cmp word [eax+9], 'cd' |
jnz @f |
movzx ecx, byte [eax+11] |
sub ecx, '0' |
push 24 |
pop eax |
mov ebx, edx |
int 40h |
@@: |
xor eax, eax |
ret 16 |
.line_prev: |
cmp eax, [ebx+44] |
1016,6 → 1041,7 |
; 8 = í«¥¬¥â ¬®¦¥â ¨¬¥âì 䮪ãá ¢¢®¤ |
; 10h: ¤«ï ª®¯ª¨ = ª®¯ª ¯® 㬮«ç ¨î (Enter ¥-ª®¯ª¥) |
; ¤«ï ¯®«ï ¢¢®¤ = ¤ ë¥ ¡ë«¨ ¬®¤¨ä¨æ¨à®¢ ë |
; 20h: ¤«ï ¯®«ï ¢¢®¤ = ¥ ®â®¡à ¦ âì ¢¢®¤¨¬ë¥ ¤ ë¥ (¯®ª §ë¢ âì '*') |
.size = $ |
end virtual |
; struct DLGDATA |
1309,7 → 1335,8 |
draw_text_esi: |
test esi, esi |
jz .ret |
or ecx, -1 |
push -1 |
pop ecx |
@@: |
inc ecx |
cmp byte [ecx+esi], 0 |
1372,6 → 1399,14 |
sub esi, ecx |
.text_copy: |
jecxz .ret |
; check for password editboxes |
cmp [ebx+dlgitemtemplate.type], 3 |
jnz @f |
test [ebx+dlgitemtemplate.flags], 20h |
jz @f |
mov al, '*' |
rep stosw |
jmp .ret |
@@: |
lodsb |
stosw |
1441,31 → 1476,30 |
call DialogBox |
ret |
; int __stdcall SayErr(const char* title, int x, int y, |
; int num_strings, const char* strings[], |
; int __stdcall SayErr(int num_strings, const char* strings[], |
; int num_buttons, const char* buttons[]); |
; may be x=-1 and/or y=-1 |
SayErr: |
pop eax |
push aError |
push eax |
push 2 |
jmp @f |
; int __stdcall Message(const char* title, int x, int y, |
; int __stdcall Message(const char* title, |
; int num_strings, const char* strings[], |
; int num_buttons, const char* buttons[]); |
Message: |
push 1 |
@@: |
pop eax |
; [esp+4] = title |
; [esp+8] = x |
; [esp+12] = y |
; [esp+16] = num_strings |
; [esp+20] = strings |
; [esp+24] = num_buttons |
; [esp+28] = buttons |
pop eax |
; [esp+8] = num_strings |
; [esp+12] = strings |
; [esp+16] = num_buttons |
; [esp+20] = buttons |
pushad |
mov ecx, [esp+4+16] |
add ecx, [esp+4+24] |
mov ecx, [esp+32+8] |
add ecx, [esp+32+16] |
imul ecx, dlgitemtemplate.size |
add ecx, dlgtemplate.size+12 |
call xpgalloc |
1479,13 → 1513,12 |
mov edi, eax |
mov eax, [esp+28] |
stosd ; dlgtemplate.flags |
mov eax, [esp+32+8] |
or eax, -1 |
stosd ; dlgtemplate.x |
mov eax, [esp+32+12] |
stosd ; dlgtemplate.y |
; calculate width |
mov ecx, [esp+32+16] |
mov esi, [esp+32+20] |
mov ecx, [esp+32+8] |
mov esi, [esp+32+12] |
xor edx, edx |
.calcwidth: |
lodsd |
1500,8 → 1533,8 |
mov edx, eax |
@@: |
loop .calcwidth |
mov ecx, [esp+32+24] |
mov esi, [esp+32+28] |
mov ecx, [esp+32+16] |
mov esi, [esp+32+20] |
xor ebp, ebp |
.calcwidth2: |
lodsd |
1527,7 → 1560,7 |
@@: |
mov eax, edx |
stosd ; dlgtemplate.width |
mov eax, [esp+32+16] |
mov eax, [esp+32+8] |
inc eax |
stosd ; dlgtemplate.height |
mov eax, 3 |
1540,12 → 1573,12 |
stosd ; (ignored) |
stosd ; DlgProc |
stosd ; userdata |
mov eax, [esp+32+16] |
add eax, [esp+32+24] |
mov eax, [esp+32+8] |
add eax, [esp+32+16] |
stosd ; num_items |
; fill strings |
xor ecx, ecx |
mov esi, [esp+32+20] |
mov esi, [esp+32+12] |
@@: |
mov eax, 1 |
stosd ; dlgitemtemplate.type |
1561,11 → 1594,11 |
mov eax, 1 |
stosd ; dlgitemtemplate.flags |
inc ecx |
cmp ecx, [esp+32+16] |
cmp ecx, [esp+32+8] |
jb @b |
; fill buttons |
mov ecx, [esp+32+24] |
mov esi, [esp+32+28] |
mov ecx, [esp+32+16] |
mov esi, [esp+32+20] |
sub edx, ebp |
jc .big |
shr edx, 1 |
1596,7 → 1629,7 |
mov eax, [esi-4] |
stosd ; dlgitemtemplate.data |
mov eax, 9 |
cmp ecx, [esp+32+24] |
cmp ecx, [esp+32+16] |
jnz @f |
or al, 4 |
@@: |
1611,10 → 1644,10 |
xor edx, edx |
mov ecx, dlgitemtemplate.size |
div ecx |
sub eax, [esp+32+16] |
sub eax, [esp+32+8] |
@@: |
mov [esp+28], eax |
mov ecx, ebx |
call pgfree |
popad |
ret 28 |
ret 20 |
/programs/fs/kfar/trunk/filetool.inc |
---|
29,9 → 29,6 |
push 4 |
push eax |
push 3 |
push -1 |
push -1 |
push aError |
call SayErr |
add esp, 3*4 |
cmp al, -1 |
66,6 → 63,8 |
mov esi, [esp+28] |
mov ecx, esi |
add esi, 40 |
cmp byte [edi-1], '/' |
jz .l1 |
mov al, '/' |
stosb |
.l1: |
239,9 → 238,6 |
push dword [eax+16] |
push eax |
push 3 |
push -1 |
push -1 |
push dword aError |
call SayErr |
add esp, 3*4 |
test eax, eax |
253,6 → 249,9 |
; in: execdata = source name, CopyDestEditBuf+12 = destination name, edx = BDFE block for source |
; out: CF and ZF not set <=> cancel job ("ja cancel_label") |
; destroys eax,esi,edi |
lea edi, [edx+40] |
and [source_hFile], 0 |
copy_file_worker2: |
push CopyDestEditBuf+12+513 |
cmp [bDestIsFolder], 0 |
jz .noaddtoname |
261,12 → 260,16 |
lodsb |
test al, al |
jnz @b |
mov byte [esi-1], '/' |
pop edi |
pop eax |
dec esi |
push esi |
mov edi, esi |
lea esi, [edx+40] |
cmp byte [esi-1], '/' |
jz @f |
mov byte [esi], '/' |
inc esi |
@@: |
xchg esi, edi |
@@: |
cmp edi, CopyDestEditBuf+12+513 |
jae .overflow |
lodsb |
277,12 → 280,14 |
.overflow: |
.ret_zf: |
pop esi |
and byte [esi-1], 0 ; ZF=1 |
and byte [esi], 0 ; ZF=1 |
ret |
.noaddtoname: |
; Íåëüçÿ ñêîïèðîâàòü ôàéë ïîâåðõ ñàìîãî ñåáÿ! |
; ¥«ì§ï ᪮¯¨à®¢ âì ä ©« ¯®¢¥àå á ¬®£® ᥡï! |
mov esi, execdata |
mov edi, CopyDestEditBuf+12 |
cmp [source_hModule], 0 |
jnz @f |
push esi edi |
call strcmpi |
pop edi esi |
294,15 → 299,12 |
push 1 |
push eax |
push 2 |
push -1 |
push -1 |
push aError |
call SayErr |
pop eax |
pop eax |
jmp .ret_zf |
@@: |
; Ñîáñòâåííî, êîïèðóåì |
; ®¡á⢥®, ª®¯¨à㥬 |
; esi->source name, edi->destination name |
push ebx |
mov [writeinfo.code], 2 |
316,8 → 318,40 |
mov [ebx+readinfo.size-readinfo], copy_buffer_size |
mov [ebx+readinfo.data-readinfo], copy_buffer |
mov [ebx+readinfo.name-readinfo], esi |
mov eax, [source_hFile] |
push eax |
test eax, eax |
jnz .copyloop |
.source_reopen: |
mov eax, [source_hModule] |
test eax, eax |
jz .copyloop |
pushad |
push O_READ+O_SEQUENTIAL_ONLY |
push esi |
push [source_hPlugin] |
call [eax+PluginInfo.open] |
mov [source_hFile], eax |
popad |
.copyloop: |
mov ebx, readinfo |
mov eax, [source_hModule] |
test eax, eax |
jz .native |
mov ecx, [source_hFile] |
jecxz .readerr |
pushad |
push [ebx+readinfo.size-readinfo] |
push [ebx+readinfo.data-readinfo] |
push ecx |
call [eax+PluginInfo.read] |
mov [esp+28], eax |
popad |
cmp eax, -1 |
jz .readerr |
mov ebx, eax |
jmp .copyreadok |
.native: |
push 70 |
pop eax |
int 0x40 |
325,6 → 359,7 |
jz .copyreadok |
cmp eax, 6 |
jz .copyreadok |
.readerr: |
cmp [copy_bSkipAll2], 0 |
jnz .copyfailed_del2 |
push esi |
336,14 → 371,15 |
push 4 |
push eax |
push 3 |
push -1 |
push -1 |
push dword aError |
call SayErr |
add esp, 3*4 |
test eax, eax |
jnz .copyfailed_parseuser |
cmp [source_hModule], 0 |
jz .copyloop |
jmp .copyfailed_parseuser |
cmp [source_hFile], 0 |
jz .source_reopen |
jmp .copyloop |
.copyreadok: |
add dword [readinfo.first], ebx |
adc dword [readinfo.first+4], 0 |
370,9 → 406,6 |
push 4 |
push eax |
push 3 |
push -1 |
push -1 |
push dword aError |
call SayErr |
add esp, 3*4 |
test eax, eax |
394,6 → 427,19 |
cmp ecx, copy_buffer_size |
jz .copyloop |
.copydone: |
pop ecx |
test ecx, ecx |
jnz @f |
mov eax, [source_hModule] |
test eax, eax |
jz @f |
mov ecx, [source_hFile] |
jecxz @f |
push edx |
push ecx |
call [eax+PluginInfo.close] |
pop edx |
@@: |
; now try to set attributes from source, ignore errors |
mov edi, attrinfo.attr |
mov esi, edx |
400,6 → 446,29 |
push 8 |
pop ecx |
rep movsd |
; replace zero dates with default values |
mov eax, [default_attr] |
cmp dword [edi-32+8], 0 |
jnz @f |
mov ecx, [eax+8] |
mov [edi-32+8], ecx |
mov ecx, [eax+12] |
mov [edi-32+12], ecx |
@@: |
cmp dword [edi-32+16], 0 |
jnz @f |
mov ecx, [eax+16] |
mov [edi-32+16], ecx |
mov ecx, [eax+20] |
mov [edi-32+20], ecx |
@@: |
cmp dword [edi-32+24], 0 |
jnz @f |
mov ecx, [eax+24] |
mov [edi-32+24], ecx |
mov ecx, [eax+28] |
mov [edi-32+28], ecx |
@@: |
mov ebx, attrinfo |
mov [ebx+attrinfo.name-attrinfo], CopyDestEditBuf+12 |
inc dword [ebx] |
413,12 → 482,23 |
.ret: |
pop ebx |
pop esi |
mov byte [esi-1], 0 |
mov byte [esi], 0 |
ret |
.copydone2: |
popf |
jmp .ret |
.copyfailed: |
pop ecx |
test ecx, ecx |
jnz @f |
mov eax, [source_hModule] |
test eax, eax |
jz @f |
mov ecx, [source_hFile] |
jecxz @f |
push ecx |
call [eax+PluginInfo.close] |
@@: |
cmp [bConfirmDeleteIncomplete], 0 |
jz .copyfailed_del |
cmp [writeinfo.code], 2 |
429,10 → 509,8 |
push 2 |
push eax |
push 1 |
push -1 |
push -1 |
push dword aCopyCaption |
call SayErr |
call Message |
add esp, 4 |
test eax, eax |
jnz .copydone2 |
468,6 → 546,8 |
@@: |
mov esi, [esp+28] |
add esi, 40 |
cmp byte [edi-1], '/' |
jz .l1 |
mov al, '/' |
stosb |
.l1: |
475,6 → 555,7 |
cmp edi, execdataend |
jb @f |
call panels_OnKey.bigfilename |
stc |
popad |
ret |
@@: |
504,7 → 585,12 |
lodsb |
test al, al |
jnz @b |
mov byte [esi-1], '/' |
dec esi |
cmp byte [esi-1], '/' |
jz @f |
mov byte [esi], '/' |
inc esi |
@@: |
mov edi, esi |
lea esi, [edx+40] |
@@: |
527,8 → 613,44 |
@@: |
cmp al, 1 |
jz .copy_dir_entry_done |
jmp .cancel |
jmp .cancel2 |
.target_created: |
mov edx, [source_hModule] |
test edx, edx |
jz .nosetdir |
mov esi, execdata |
push esi ; absolute_path |
@@: |
lodsb |
test al, al |
jnz @b |
@@: |
dec esi |
cmp byte [esi-1], '/' |
jnz @b |
push esi ; relative_path |
push [source_hPlugin] ; hPlugin |
call [edx+PluginInfo.SetFolder] |
test al, al |
jnz .nosetdir |
cmp [copy_bSkipAll3], 0 |
jz .skip2 |
push execdata |
push aCannotSetFolder |
mov eax, esp |
push DeleteErrorBtn |
push 4 |
push eax |
push 2 |
call SayErr |
pop ecx ecx |
test al, al |
jz .target_created |
cmp al, 2 |
setz [copy_bSkipAll3] |
ja .cancel2 |
jmp .skip2 |
.nosetdir: |
xor ebp, ebp ; ebp will contain number of copied items |
.return_from_recursion: |
.read_retry: |
537,9 → 659,23 |
mov [ebx+dirinfo.size-dirinfo], copy_dir_query_size |
mov [ebx+dirinfo.dirdata-dirinfo], copy_dir_query_area |
mov [ebx+dirinfo.name-dirinfo], execdata |
mov eax, [source_hModule] |
test eax, eax |
jz .readfolder_native |
push ebp |
push [ebx+dirinfo.dirdata-dirinfo] |
push [ebx+dirinfo.size-dirinfo] |
push [ebx+dirinfo.first-dirinfo] |
push [source_hPlugin] |
call [eax+PluginInfo.ReadFolder] |
pop ebp |
mov ebx, dword [copy_dir_query_area+4] |
jmp @f |
.readfolder_native: |
push 70 |
pop eax |
int 0x40 |
@@: |
test eax, eax |
jz .readok |
cmp eax, 6 |
546,7 → 682,7 |
jz .readok |
; read error |
cmp [copy_bSkipAll], 0 |
jz .skip1 |
jnz .skip1 |
push execdata |
push aCannotReadFolder |
call get_error_msg |
556,9 → 692,6 |
push 4 |
push eax |
push 3 |
push -1 |
push -1 |
push aError |
call SayErr |
add esp, 3*4 |
test al, al |
597,7 → 730,12 |
lodsb |
test al, al |
jnz @b |
mov byte [esi-1], '/' |
dec esi |
cmp byte [esi-1], '/' |
jz @f |
mov byte [esi], '/' |
inc esi |
@@: |
mov edi, esi |
lea esi, [edx+40] |
@@: |
612,7 → 750,12 |
lodsb |
test al, al |
jnz @b |
mov byte [esi-1], '/' |
dec esi |
cmp byte [esi-1], '/' |
jz @f |
mov byte [esi], '/' |
inc esi |
@@: |
mov edi, esi |
lea esi, [edx+40] |
@@: |
625,7 → 768,7 |
test byte [edx], 10h |
jnz .entry_is_folder |
call copy_file_worker |
ja .cancel |
ja .cancel3 |
jmp .restore_name |
.entry_is_folder: |
; allocate new item in directory stack |
642,7 → 785,6 |
.fullname2_big: |
mov esi, CopyDestEditBuf+12+512 |
jmp .restore_name2 |
.skip1: |
.restore_name: |
mov esi, CopyDestEditBuf+12 |
@@: |
665,8 → 807,23 |
.copy_dir_entry_continue: |
add edx, 304 |
jmp .copy_dir_entry_loop |
.skip1: |
.copy_dir_entry_done: |
; return to previous directory |
mov esi, execdata |
call delete_last_name_from_end |
mov eax, [source_hModule] |
test eax, eax |
jz @f |
push execdata |
push aDotDot |
push [source_hPlugin] |
call [eax+PluginInfo.SetFolder] |
jmp @f |
.skip2: |
mov esi, execdata |
call delete_last_name_from_end |
@@: |
; pop item from directory stack |
mov ecx, [copy_dir_stack_ptr] |
cmp ecx, copy_dir_stack |
675,16 → 832,34 |
mov [copy_dir_stack_ptr], ecx |
mov ebp, [ecx] |
; restore prev directory name |
mov esi, execdata |
call delete_last_name_from_end |
mov esi, CopyDestEditBuf+12 |
call delete_last_name_from_end |
jmp .return_from_recursion |
.done: |
.cancel: |
mov [dirinfo.first], 0 ; do not destroys flags |
popad |
ret |
.cancel2: |
sub [copy_dir_stack_ptr], 4 |
.cancel3: |
mov esi, execdata |
call delete_last_name_from_end |
.cancel: |
mov eax, [source_hModule] |
test eax, eax |
jz .cancel.ret |
cmp [copy_dir_stack_ptr], copy_dir_stack |
jb .cancel.ret |
push execdata |
push aDotDot |
push [source_hPlugin] |
call [eax+PluginInfo.SetFolder] |
jmp .cancel2 |
.cancel.ret: |
xor eax, eax |
inc eax |
popad |
ret |
delete_last_name_from_end: |
lodsb |
699,5 → 874,403 |
cmp al, '/' |
jnz @b |
cld |
inc esi |
cmp esi, execdata |
jz @f |
cmp esi, CopyDestEditBuf+12 |
jz @f |
dec esi |
@@: |
mov byte [esi+1], 0 |
ret |
copy_AddDir: |
push 1 |
pop eax ; for "return true" |
pushad |
mov esi, CopyDestEditBuf+12 |
@@: |
lodsb |
test al, al |
jnz @b |
cmp byte [esi-2], '/' |
jnz @f |
dec esi |
@@: |
push dword [esi-1] |
push esi |
mov byte [esi-1], '/' |
mov edi, esi |
mov esi, [esp+28h+4] |
.0: |
lodsb |
stosb |
cmp edi, CopyDestEditBuf+12+512 |
jae .done |
test al, al |
jnz .0 |
push RetryOrCancelBtn |
push 2 |
call makedir |
jz .done |
and dword [esp+8+1Ch], 0 |
.done: |
pop esi |
pop dword [esi-1] |
popad |
ret 8 |
copy_AddFile: |
pushad |
mov eax, [esp+20h+12] |
mov [source_hFile], eax |
mov edx, [esp+20h+8] |
mov edi, [esp+20h+4] |
call copy_file_worker2 |
popad |
setna al |
ret 12 |
virtual at 0 |
_FILE: |
.pos dq ? |
.bufpos dq ? |
.bufsize dd ? |
.mode dd ? |
.hPlugin dd ? |
.hFile dd ? |
.fileinfo: |
.fimode dd ? |
.fioffset dq ? |
.fisize dd ? |
.fibuf dd ? |
.finame rb 1024 |
.attr rb 40 |
align 512 |
.buf rb 2048 |
.size = $ |
end virtual |
O_READ = 1 ; allows read from file |
O_WRITE = 2 ; allows write to file |
O_CREATE = 4 ; if file does not exist and this flag is set, create file; |
; if file does not exist and this flag is not set, fail |
O_TRUNCATE = 8 ; truncate file if it exists |
O_SEQUENTIAL_ONLY = 10h ; there will be no 'seek'/'setpos' calls |
; HANDLE __stdcall open(const char* name, int mode); |
; Opens physical file |
open: |
pushad |
mov ecx, _FILE.size |
call xpgalloc |
test eax, eax |
jz .ret0z |
mov [esp+28], eax |
mov ecx, eax |
mov esi, [esp+36] |
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 eax, [esp+40] |
mov [ecx+_FILE.mode], eax |
.getattr: |
lea edi, [ecx+_FILE.fileinfo] |
mov ebx, edi |
push 5 |
pop eax |
stosd |
xor eax, eax |
stosd |
stosd |
stosd |
lea eax, [ecx+_FILE.attr] |
stosd |
push 70 |
pop eax |
int 0x40 |
test eax, eax |
jz .found |
cmp eax, 5 |
jnz .ret0 |
; file does not exist |
test [ecx+_FILE.mode], O_CREATE |
jz .ret0z |
.truncate: |
lea ebx, [ecx+_FILE.fileinfo] |
mov byte [ebx], 2 |
push 70 |
pop eax |
int 0x40 |
test eax, eax |
jz .getattr |
jmp .ret0 |
.found: |
test [ecx+_FILE.mode], O_TRUNCATE |
jz @f |
cmp dword [ecx+_FILE.attr+36], eax |
jnz .truncate |
cmp dword [ecx+_FILE.attr+32], eax |
jnz .truncate |
@@: |
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 [ecx+_FILE.hPlugin], eax |
mov [ecx+_FILE.hFile], eax |
mov dword [ecx+_FILE.fioffset], eax |
mov dword [ecx+_FILE.fioffset+4], eax |
mov [esp+28], ecx |
popad |
ret 8 |
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size); |
read: |
xor eax, eax |
pushad |
mov ecx, [esp+36] |
test [ecx+_FILE.mode], O_READ |
jnz @f |
.ret: |
popad |
ret 12 |
@@: |
cmp dword [esp+44], eax |
jz .ret |
mov [ecx+_FILE.fimode], eax |
mov ebx, [ecx+_FILE.bufsize] |
mov eax, dword [ecx+_FILE.pos] |
and eax, 2047 |
sub ebx, eax |
jbe .nobuf0 |
cmp ebx, [esp+44] |
jbe @f |
mov ebx, [esp+44] |
@@: |
push ecx |
lea esi, [ecx+eax+_FILE.buf] |
mov ecx, ebx |
mov edi, [esp+44] |
rep movsb |
pop ecx |
mov [esp+40], edi |
add [esp+28], ebx |
add dword [ecx+_FILE.pos], ebx |
adc dword [ecx+_FILE.pos+4], 0 |
sub [esp+44], ebx |
jz .ret |
.nobuf0: |
test dword [ecx+_FILE.pos], 2047 |
jz .aligned |
cmp dword [ecx+_FILE.bufsize], 0 |
jnz .ret |
lea ebx, [ecx+_FILE.fileinfo] |
mov dword [ebx+12], 2048 |
lea eax, [ecx+_FILE.buf] |
mov dword [ebx+16], eax |
mov eax, dword [ecx+_FILE.fioffset] |
mov dword [ecx+_FILE.bufpos], eax |
mov eax, dword [ecx+_FILE.fioffset+4] |
mov dword [ecx+_FILE.bufpos+4], eax |
call .doread |
test eax, eax |
jnz .ret |
mov [ecx+_FILE.bufsize], ebx |
mov eax, dword [ecx+_FILE.pos] |
and eax, 2047 |
sub ebx, eax |
jbe .ret |
cmp ebx, [esp+44] |
jbe @f |
mov ebx, [esp+44] |
@@: |
push ecx |
lea esi, [ecx+eax+_FILE.buf] |
mov ecx, ebx |
mov edi, [esp+44] |
rep movsb |
pop ecx |
add dword [ecx+_FILE.pos], ebx |
adc dword [ecx+_FILE.pos+4], 0 |
mov [esp+40], edi |
add [esp+28], ebx |
sub [esp+44], ebx |
jz .ret |
test dword [ecx+_FILE.pos], 2047 |
jnz .ret |
.aligned: |
lea ebx, [ecx+_FILE.fileinfo] |
mov eax, [esp+44] |
and eax, not 2047 |
jz .finish |
and [ecx+_FILE.bufsize], 0 |
mov [ebx+12], eax |
mov eax, [esp+40] |
mov [ebx+16], eax |
call .doread |
test eax, eax |
jnz .ret |
add dword [ecx+_FILE.pos], ebx |
adc dword [ecx+_FILE.pos+4], 0 |
add [esp+28], ebx |
add [esp+40], ebx |
sub [esp+44], ebx |
jz .ret |
cmp ebx, [ecx+_FILE.fisize] |
jb .ret |
.finish: |
lea ebx, [ecx+_FILE.fileinfo] |
mov dword [ebx+12], 2048 |
lea eax, [ecx+_FILE.buf] |
mov [ebx+16], eax |
and [ecx+_FILE.bufsize], 0 |
mov eax, dword [ecx+_FILE.fioffset] |
mov dword [ecx+_FILE.bufpos], eax |
mov eax, dword [ecx+_FILE.fioffset+4] |
mov dword [ecx+_FILE.bufpos+4], eax |
call .doread |
test eax, eax |
jnz .ret |
mov [ecx+_FILE.bufsize], ebx |
cmp ebx, [esp+44] |
jb @f |
mov ebx, [esp+44] |
@@: |
add [esp+28], ebx |
add dword [ecx+_FILE.pos], ebx |
adc dword [ecx+_FILE.pos+4], 0 |
lea esi, [ecx+_FILE.buf] |
mov edi, [esp+40] |
mov ecx, ebx |
rep movsb |
popad |
ret 12 |
.doread: |
mov eax, [ecx+_FILE.hPlugin] |
test eax, eax |
jz .native |
push ecx |
push [ecx+_FILE.fisize] |
push [ecx+_FILE.fibuf] |
push [ecx+_FILE.hFile] |
call [eax+PluginInfo.read] |
pop ecx |
cmp eax, -1 |
jz @f |
mov ebx, eax |
xor eax, eax |
jmp .addpos |
@@: |
ret |
.native: |
push 70 |
pop eax |
int 0x40 |
test eax, eax |
jz .addpos |
cmp eax, 6 |
jnz @b |
xor eax, eax |
.addpos: |
add dword [ecx+_FILE.fioffset], ebx |
adc dword [ecx+_FILE.fioffset+4], 0 |
ret |
; void __stdcall seek(HANDLE hFile, int method, __int64 newpos); |
seek: |
pushad |
mov ecx, [esp+36] |
mov eax, [esp+44] |
mov edx, [esp+48] |
cmp dword [esp+40], 1 |
jb .set |
ja .end |
add eax, dword [ecx+_FILE.pos] |
adc edx, dword [ecx+_FILE.pos+4] |
jmp .set |
.end: |
add eax, dword [ecx+_FILE.attr+32] |
adc edx, dword [ecx+_FILE.attr+36] |
.set: |
mov dword [ecx+_FILE.pos], eax |
mov dword [ecx+_FILE.pos+4], edx |
and eax, not 2047 |
cmp eax, dword [ecx+_FILE.bufpos] |
jnz @f |
cmp edx, dword [ecx+_FILE.bufpos+4] |
jz .bufposok |
@@: |
and [ecx+_FILE.bufsize], 0 |
mov dword [ecx+_FILE.bufpos], eax |
mov dword [ecx+_FILE.bufpos+4], edx |
.bufposok: |
cmp [ecx+_FILE.bufsize], 0 |
jnz .ret |
cmp eax, dword [ecx+_FILE.fioffset] |
jnz @f |
cmp edx, dword [ecx+_FILE.fioffset+4] |
jz .ret |
@@: |
mov dword [ecx+_FILE.fioffset], eax |
mov dword [ecx+_FILE.fioffset+4], edx |
mov eax, [ecx+_FILE.hPlugin] |
test eax, eax |
jz @f |
push dword [ecx+_FILE.fioffset+4] |
push dword [ecx+_FILE.fioffset] |
push [ecx+_FILE.hFile] |
call [eax+PluginInfo.setpos] |
@@: |
.ret: |
popad |
ret 16 |
setpos_default: |
push dword [esp+12] |
push dword [esp+12] |
push 0 |
push dword [esp+16] |
call seek |
ret 12 |
; __int64 __stdcall filesize(HANDLE hFile); |
filesize: |
mov eax, [esp+4] |
mov edx, dword [eax+_FILE.attr+36] |
mov eax, dword [eax+_FILE.attr+32] |
ret 4 |
; void __stdcall close(HANDLE hFile); |
close: |
pushad |
mov ecx, [esp+24h] |
mov eax, [ecx+_FILE.hPlugin] |
test eax, eax |
jz @f |
push ecx |
push [ecx+_FILE.hFile] |
call [eax+PluginInfo.close] |
pop ecx |
@@: |
call pgfree |
popad |
ret 4 |
getattr_default: |
mov eax, 2 |
ret 12 |
/programs/fs/kfar/trunk/kfar.asm |
---|
7,6 → 7,9 |
dd stacktop |
dd 0, app_path |
version equ '0.4' |
version_dword equ 0*10000h + 40 |
include 'lang.inc' |
include 'font.inc' |
include 'sort.inc' |
81,10 → 84,18 |
jz exit |
cmp [panel1_files], 0 |
jz exit |
mov [panel1_sortmode], 0 ; sort by name |
mov [panel2_sortmode], 0 |
push 2 ; "á।¨©" ä®à¬ â |
pop eax |
xor eax, eax |
mov [panel1_hPlugin], eax |
mov [panel1_parents], eax |
mov [panel1_parents_sz], eax |
mov [panel1_parents_alloc], eax |
mov [panel2_hPlugin], eax |
mov [panel2_parents], eax |
mov [panel2_parents_sz], eax |
mov [panel2_parents_alloc], eax |
mov [panel1_sortmode], al ; sort by name |
mov [panel2_sortmode], al |
mov al, 2 ; "á।¨©" ä®à¬ â |
mov [panel1_colmode], eax |
mov [panel2_colmode], eax |
mov [num_screens], 1 |
121,6 → 132,28 |
push dword app_path |
call [ini.get_int] |
mov [bConfirmDeleteIncomplete], al |
push 2 |
push aLeftViewMode |
push aPanels |
push app_path |
call [ini.get_int] |
cmp eax, 1 |
jb @f |
cmp eax, 4 |
ja @f |
mov [panel1_colmode], eax |
@@: |
push 2 |
push aRightViewMode |
push aPanels |
push app_path |
call [ini.get_int] |
cmp eax, 1 |
jb @f |
cmp eax, 4 |
ja @f |
mov [panel2_colmode], eax |
@@: |
mov ecx, 0x1000 |
call xpgalloc |
test eax, eax |
202,6 → 235,11 |
@@: |
loop .l3 |
.skip_shortcuts: |
; load plugins |
push enum_plugins_callback |
push aPlugins |
push app_path |
call [ini.enum_keys] |
.noini: |
mov esi, def_left_dir |
mov edi, panel1_dir |
239,6 → 277,86 |
jz key |
; button - we have only one button, close |
exit: |
; close all screens |
@@: |
mov ecx, [num_screens] |
mov eax, [screens] |
mov ebp, [eax+ecx*8-4] |
mov eax, [eax+ecx*8-8] |
push ebp |
call [eax+screen_vtable.OnExit] |
pop ecx |
call pgfree |
dec [num_screens] |
jnz @b |
; unload all plugins |
mov ecx, [num_plugins] |
imul esi, ecx, PluginInfo.size |
add esi, [plugins] |
.unload: |
dec ecx |
js .unload_done |
sub esi, PluginInfo.size |
push ecx esi |
call [esi+PluginInfo.unload] |
pop esi ecx |
jmp .unload |
.unload_done: |
if 0 ; commented due to bug in libini |
cmp [ini.set_int], aIniSetInt |
jz .nosave |
push [panel1_colmode] |
push aLeftViewMode |
push aPanels |
push app_path |
call [ini.set_int] |
push [panel2_colmode] |
push aRightViewMode |
push aPanels |
push app_path |
call [ini.set_int] |
.nosave: |
end if |
if CHECK_FOR_LEAKS |
mov ecx, [panel1_files] |
call pgfree |
mov ecx, [panel2_files] |
call pgfree |
mov ecx, [screens] |
call pgfree |
mov ecx, [associations] |
call pgfree |
mov ecx, [console_data_ptr] |
call pgfree |
mov ecx, [MemForImage] |
call pgfree |
mov esi, FolderShortcuts |
push 10 |
pop ecx |
@@: |
lodsd |
test eax, eax |
jnz @f |
loop @b |
jmp .nofreefs |
@@: |
mov ecx, eax |
call pgfree |
mov ecx, [plugins] |
call pgfree |
mov ecx, [panel1_parents] |
call pgfree |
mov ecx, [panel2_parents] |
call pgfree |
.nofreefs: |
mov eax, [numallocatedregions] |
test eax, eax |
jz @f |
mov edi, allocatedregions |
int3 |
jmp $ |
@@: |
end if |
or eax, -1 |
int 40h |
redraw: |
640,6 → 758,182 |
xor eax, eax |
ret 12 |
enum_plugins_callback: |
; LongBool __stdcall callback(f_name,sec_name,key_name); |
; [esp+4] = f_name, [esp+8] = sec_name, [esp+12] = key_name |
push nullstr |
push 1024 |
push saved_file_name |
push dword [esp+12+12] |
push dword [esp+16+8] |
push dword [esp+20+4] |
call [ini.get_str] |
test eax, eax |
jnz .ret |
mov esi, saved_file_name |
cmp byte [esi], '/' |
jz .absolute |
; convert path to absolute |
mov edi, execdata |
push esi |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
pop edi |
mov esi, app_path |
push esi |
xor ecx, ecx |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
mov ecx, esi |
jmp @b |
@@: |
pop esi |
sub ecx, esi |
rep movsb |
mov esi, execdata |
.z: |
cmp word [esi], '.' |
jz .ret |
cmp word [esi], './' |
jnz @f |
add esi, 2 |
jmp .z |
@@: |
cmp word [esi], '..' |
jnz .c |
cmp byte [esi+2], 0 |
jz .ret |
cmp byte [esi+2], '/' |
jnz .c |
add esi, 3 |
@@: |
dec edi |
cmp edi, saved_file_name |
jbe .ret |
cmp byte [edi-1], '/' |
jnz @b |
jmp .z |
.c: |
lodsb |
stosb |
test al, al |
jz @f |
cmp edi, saved_file_name+1024 |
jb .c |
mov esi, execdata |
call load_dll_and_import.big |
.ret: |
mov al, 1 |
ret 12 |
@@: |
.absolute: |
; allocate space for plugin info |
mov eax, [num_plugins] |
inc eax |
mov [num_plugins], eax |
imul ecx, eax, PluginInfo.size |
cmp ecx, [alloc_plugins] |
jbe .norealloc |
mov edx, [plugins] |
call xpgrealloc |
test eax, eax |
jnz @f |
.dec_ret: |
dec [num_plugins] |
jmp .ret |
@@: |
mov [plugins], eax |
lea eax, [ecx+0xFFF] |
and eax, not 0xFFF |
mov [alloc_plugins], eax |
.norealloc: |
mov esi, [plugins] |
lea esi, [esi+ecx-PluginInfo.size] |
; load plugin DLL |
or ebp, -1 |
mov eax, saved_file_name |
call load_dll_and_import.do |
test eax, eax |
jnz .dec_ret |
; find exported functions |
mov eax, aVersion |
call load_dll_and_import.find_exported_function |
jnc @f |
xor eax, eax |
@@: |
MIN_INTERFACE_VER = 1 |
MAX_INTERFACE_VER = 1 |
cmp eax, MIN_INTERFACE_VER |
jae @f |
cmp eax, MAX_INTERFACE_VER |
jbe @f |
push aIncompatibleVersion |
.cantload: |
push saved_file_name |
push aCannotLoadPlugin |
mov eax, esp |
push ContinueBtn |
push 1 |
push eax |
push 3 |
call SayErr |
add esp, 12 |
jmp .dec_ret |
@@: |
mov edi, esi |
mov esi, plugin_exported |
.import: |
lodsd |
test eax, eax |
jz .import_done |
call load_dll_and_import.find_exported_function |
jnc @f |
mov eax, [esi-4+plugin_exported_default-plugin_exported] |
@@: |
stosd |
jmp .import |
.import_done: |
; initialize plugin |
mov eax, aPluginLoad |
call load_dll_and_import.find_exported_function |
jc .ok |
push kfar_info |
call eax |
cmp eax, 1 |
jb .ok |
ja .dec_ret |
push aInitFailed |
jmp .cantload |
.ok: |
mov al, 1 |
ret 12 |
plugin_unload_default: |
ret |
OpenFilePlugin_default: |
GetFiles_default: |
xor eax, eax |
ret 20 |
ClosePlugin_default: |
ret 4 |
GetOpenPluginInfo_default: |
ret 8 |
SetFolder_default: |
open_default: |
xor eax, eax |
ret 12 |
new_screen: |
; in: ecx=sizeof(screen data), edx->vtable |
; out: ebp=pointer or NULL, eax!=0 if successful |
967,6 → 1261,152 |
call get_curfile_folder_entry |
test byte [ecx], 10h |
jnz .enter_folder |
; todo: add <Enter> handling on plugin panel |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jnz .ret |
; generate full file name |
lea esi, [ebp + panel1_dir - panel1_data] |
mov edi, execdata |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
cmp edi, execdataend-1 |
jae .bigfilename |
jmp @b |
@@: |
lea esi, [ecx+40] |
mov al, '/' |
stosb |
@@: |
lodsb |
stosb |
cmp edi, execdataend |
ja .bigfilename |
test al, al |
jnz @b |
; try to open file and look for all plugins |
push O_READ |
push execdata |
call open |
test eax, eax |
jz .noplugins ; if can't open, just try to execute |
mov esi, eax ; save handle |
push filedata_buffer_size |
push filedata_buffer |
push esi |
call read |
mov edi, eax ; save size of read data |
; test for Kolibri executable |
cmp eax, 24h |
jb .enter.noexec |
cmp dword [filedata_buffer], 'MENU' |
jnz @f |
cmp word [filedata_buffer+4], 'ET' |
jnz @f |
.close_run: |
push esi |
call close |
jmp .run_app |
@@: |
cmp dword [filedata_buffer], 'KPCK' |
jnz @f |
cmp dword [filedata_buffer+12], 0x26914601 |
jz .close_run |
@@: |
.enter.noexec: |
mov ecx, [num_plugins] |
mov edx, [plugins] |
sub edx, PluginInfo.size |
.plugloop: |
add edx, PluginInfo.size |
dec ecx |
js .plugdone |
pushad |
push edi |
push filedata_buffer |
call get_curfile_folder_entry |
push ecx |
push execdata |
push esi |
call [edx+PluginInfo.OpenFilePlugin] |
mov [esp+28], eax |
popad |
test eax, eax |
jz .plugloop |
cmp eax, -1 |
jnz .pluginok |
push esi |
call close |
ret |
.pluginok: |
; save current directory and set root directory of hPlugin |
mov edi, eax ; save handle |
mov esi, execdata |
@@: |
lodsb |
test al, al |
jnz @b |
sub esi, execdata-9 |
; allocate esi bytes in buffer 'parents' |
mov ecx, [ebp + panel1_parents_sz - panel1_data] |
add ecx, esi |
cmp ecx, [ebp + panel1_parents_alloc - panel1_data] |
jbe .enter.norealloc |
push edx |
mov edx, [ebp + panel1_parents - panel1_data] |
call xpgrealloc |
pop edx |
test eax, eax |
jnz @f |
push edi |
call [edx+PluginInfo.ClosePlugin] |
ret |
@@: |
mov [ebp + panel1_parents - panel1_data], eax |
.enter.norealloc: |
mov [ebp + panel1_parents_sz - panel1_data], ecx |
; save current state to the end of buffer |
sub ecx, esi |
add ecx, [ebp + panel1_parents - panel1_data] |
xchg edx, [ebp + panel1_hPlugin - panel1_data] |
mov [ecx], edx |
xchg edi, [ebp + panel1_hFile - panel1_data] |
mov [ecx+4], edi |
mov byte [ecx+8], 0 |
lea edi, [ecx+9] |
lea ecx, [esi-9] |
mov esi, execdata |
rep movsb |
mov word [ebp + panel1_dir - panel1_data], '/' |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
lea ebx, [ebp + panel1_plugin_info - panel1_data] |
and dword [ebx], 0 |
push ebp |
push ebx |
push [ebp + panel1_hFile - panel1_data] |
call [eax+PluginInfo.GetOpenPluginInfo] |
pop ebp |
call get_curfile_folder_entry |
mov esi, ecx |
mov edi, left_dotdot_entry |
cmp ebp, panel1_data |
jz @f |
add edi, right_dotdot_entry-left_dotdot_entry |
@@: |
mov ecx, 10 |
rep movsd |
mov byte [edi-40], 10h ; attributes: folder |
mov eax, '..' |
stosd |
jmp .reread |
.plugdone: |
push esi |
call close |
.noplugins: |
; run program or association |
call get_curfile_folder_entry |
call find_extension |
jc .run_app |
.run_association: |
996,27 → 1436,6 |
mov [execptr], execdata |
and [execparams], 0 |
.dorun: |
lea esi, [ebp + panel1_dir - panel1_data] |
mov edi, execdata |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
cmp edi, execdataend-1 |
jae .bigfilename |
jmp @b |
@@: |
lea esi, [ecx+40] |
mov al, '/' |
stosb |
@@: |
lodsb |
stosb |
cmp edi, execdataend |
ja .bigfilename |
test al, al |
jnz @b |
; for fasm call - special handling, because |
; 1) fasm command line convention is different : fasm infile,outfile[,path] rather than tinypad infile |
; 2) fasm will probably create new file in directory, so we want to reload panel data |
1096,9 → 1515,6 |
push 1 |
push eax |
push 2 |
push -1 |
push -1 |
push dword aError |
call SayErr |
pop eax |
pop eax |
1133,9 → 1549,6 |
push 1 |
push eax |
push 1 |
push -1 |
push -1 |
push dword aError |
call SayErr |
pop eax |
ret |
1143,7 → 1556,13 |
mov eax, aCmdLineTooBig |
jmp .l2 |
.bigfoldername2: |
mov byte [ecx], 0 |
mov esi, prev_dir |
lea edi, [ebp + panel1_dir - panel1_data] |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
.bigfoldername: |
mov eax, aFolderNameTooBig |
jmp .l2 |
1167,7 → 1586,6 |
cmp esi, edx |
pop esi |
jae .bigfoldername |
mov ecx, edi |
mov al, '/' |
cmp [edi-1], al |
jz @f |
1179,6 → 1597,28 |
stosb |
test al, al |
jnz @b |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
test eax, eax |
jz .reread |
push ebp |
lea esi, [ebp + panel1_dir - panel1_data] |
push esi |
add ecx, 40 |
push ecx |
push [ebp + panel1_hFile - panel1_data] |
call [eax+PluginInfo.SetFolder] |
pop ebp |
test al, al |
jnz .reread |
mov esi, prev_dir |
lea edi, [ebp + panel1_dir - panel1_data] |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
.retd: |
ret |
.reread: |
call read_folder |
.done_cmdbar: |
1186,6 → 1626,14 |
jmp .done_redraw |
.dotdot: |
lea edi, [ebp + panel1_dir - panel1_data] |
cmp word [edi], '/' |
jnz .dotdot_noroot |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jz .retd |
call close_plugin_panel |
jmp .dotdot |
.dotdot_noroot: |
mov edx, edi |
mov al, 0 |
or ecx, -1 |
repnz scasb |
1195,11 → 1643,37 |
repnz scasb |
cld |
inc edi |
cmp edi, edx |
jnz @f |
inc edi |
@@: |
push dword [edi] |
mov byte [edi], 0 |
inc edi |
push edi |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
test eax, eax |
jz .dotdot_native |
push ebp |
lea esi, [ebp + panel1_dir - panel1_data] |
push esi |
push aDotDot |
push [ebp + panel1_hFile - panel1_data] |
call [eax+PluginInfo.SetFolder] |
pop ebp |
test al, al |
jnz .dotdot_native |
pop edi |
pop dword [edi] |
ret |
.dotdot_native: |
call read_folder |
pop edi |
pop dword [edi] |
push edi |
cmp byte [edi], '/' |
jnz @f |
inc edi |
@@: |
mov edx, [ebp + panel1_files - panel1_data] |
mov ecx, [ebp + panel1_numfiles - panel1_data] |
.scanloop: |
1228,6 → 1702,8 |
inc edx |
mov [ebp + panel1_start - panel1_data], edx |
.scandone: |
pop edi |
mov byte [edi], 0 |
jmp .done_cmdbar |
.ctrl_f39: |
sub al, 0x3D |
1356,6 → 1832,10 |
@@: |
mov ecx, edx |
lea edi, [ebp + panel1_dir - panel1_data] |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jz .find_cur_drive_loop |
mov edi, [ebp + panel1_parents - panel1_data] |
add edi, 8 |
.find_cur_drive_loop: |
push edi |
lea esi, [ecx+8] |
1391,15 → 1871,22 |
push [ebp + panel1_left - panel1_data] |
call menu_centered_in |
cmp eax, -1 |
jz .ret2 |
lea esi, [eax+8] |
jnz @f |
mov ecx, edx |
call pgfree |
ret |
@@: |
push eax |
call close_plugin_panels |
lea edi, [ebp + panel1_dir - panel1_data] |
push ecx esi edi |
push edi |
mov esi, edi |
mov edi, prev_dir |
mov ecx, 1024/4 |
rep movsd |
pop edi esi ecx |
pop edi |
pop esi |
add esi, 8 |
@@: |
lodsb |
stosb |
1410,6 → 1897,11 |
call read_folder |
jmp .done_redraw |
.shift_f5: |
; todo: copy to plugin panel |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jz @f |
ret |
@@: |
mov esi, ebp |
cmp [ebp + panel1_selected_num - panel1_data], 0 |
jnz .f5_2 |
1429,9 → 1921,23 |
stosb |
jmp @b |
.f5: |
; todo: copy to plugin panel |
mov esi, ebp |
xor esi, panel1_data xor panel2_data |
cmp [esi + panel1_hPlugin - panel1_data], 0 |
jz .f5_2 |
ret |
.f5_2: |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
mov [source_hModule], eax |
mov eax, [ebp + panel1_hFile - panel1_data] |
mov [source_hPlugin], eax |
mov eax, left_dotdot_entry |
cmp ebp, panel1_data |
jz @f |
add eax, right_dotdot_entry-left_dotdot_entry |
@@: |
mov [default_attr], eax |
add esi, panel1_dir - panel1_data |
mov edi, CopyDestEditBuf |
mov eax, CopyDestEditBuf.length |
1699,9 → 2205,6 |
push 1 |
push eax |
push 2 |
push -1 |
push -1 |
push aError |
call SayErr |
pop eax |
pop eax |
1767,6 → 2270,9 |
mov [bDestIsFolder], dl |
mov [copy_bSkipAll], 0 |
mov [copy_bSkipAll2], 0 |
mov [copy_bSkipAll3], 0 |
test [ebp + panel1_plugin_flags - panel1_data], 2 |
jnz .copy_GetFiles |
cmp [ebp + panel1_selected_num - panel1_data], 0 |
jnz .f5_selected3 |
call copy_file |
1799,6 → 2305,43 |
loop .f5_selected_copyloop |
.f5_multiple_cancel: |
jmp .copydone |
.copy_GetFiles: |
mov ecx, [ebp + panel1_selected_num - panel1_data] |
cmp ecx, 1 |
adc ecx, 0 |
shl ecx, 2 |
call xpgalloc |
test eax, eax |
jnz @f |
ret |
@@: |
push ebp eax ; save |
push copy_AddDir ; adddir |
push copy_AddFile ; addfile |
push eax ; items |
shr ecx, 2 |
push ecx ; NumItems |
push [ebp + panel1_hFile - panel1_data] |
mov edi, eax |
call get_curfile_folder_entry |
mov [edi], ecx |
cmp [ebp + panel1_selected_num - panel1_data], 0 |
jz .cgf1 |
mov esi, [ebp + panel1_files - panel1_data] |
mov ecx, [ebp + panel1_numfiles - panel1_data] |
.cgf0: |
lodsd |
test byte [eax+303], 1 |
jz @f |
stosd |
@@: |
loop .cgf0 |
.cgf1: |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
call [eax+PluginInfo.GetFiles] |
pop ecx ebp |
call pgfree |
jmp .copydone |
.f3: |
call view_file |
1849,8 → 2392,6 |
push 2 |
push eax |
push 2 |
push -1 |
push -1 |
push aDeleteCaption |
call Message |
add esp, 8 |
1871,6 → 2412,11 |
.f8_multiple_cancel: |
jmp .copydone |
.f8: |
; todo: delete files from plugin panel |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jz @f |
ret |
@@: |
cmp [ebp + panel1_selected_num - panel1_data], 0 |
jnz .f8_has_selected |
call get_curfile_folder_entry |
1901,8 → 2447,6 |
push 2 |
push eax |
push 2 |
push -1 |
push -1 |
push aDeleteCaption |
call Message |
add esp, 8 |
1975,6 → 2519,11 |
@@: |
jmp .done_redraw |
.menu: |
; todo: context menu for plugin panel |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jz @f |
ret |
@@: |
; display context menu |
; ignore folders |
call get_curfile_folder_entry |
2253,8 → 2802,10 |
jnz @f |
ret |
@@: |
push eax |
call close_plugin_panels |
lea esi, [ebp + panel1_dir - panel1_data] |
push eax esi |
push esi |
mov edi, prev_dir |
@@: |
lodsb |
2383,6 → 2934,113 |
.galoopdone: |
jmp .done_redraw |
@@: |
call close_plugin_panel |
close_plugin_panels: |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jnz @b |
ret |
close_plugin_panel: |
; close plugin and restore old directory |
mov esi, [ebp + panel1_parents - panel1_data] |
add esi, [ebp + panel1_parents_sz - panel1_data] |
@@: |
dec esi |
cmp byte [esi-1], 0 |
jnz @b |
push esi |
lea edi, [ebp + panel1_dir - panel1_data] |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
pop esi |
sub esi, 9 |
mov edx, [esi] ; hPlugin |
mov ebx, [esi+4] ; hFile |
sub esi, [ebp + panel1_parents - panel1_data] |
mov [ebp + panel1_parents_sz - panel1_data], esi |
xchg edx, [ebp + panel1_hPlugin - panel1_data] |
xchg ebx, [ebp + panel1_hFile - panel1_data] |
push edx ebx |
lea ebx, [ebp + panel1_plugin_info - panel1_data] |
and dword [ebx], 0 |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
test eax, eax |
jz @f |
push ebp |
push ebx |
push [ebp + panel1_hFile - panel1_data] |
call [eax+PluginInfo.GetOpenPluginInfo] |
pop ebp |
@@: |
pop ebx edx |
close_handle_if_unused: |
; edx=hPlugin, ebx=hFile |
push ebp |
xor ecx, ecx |
@@: |
mov eax, [screens] |
mov ebp, [eax+ecx*8+4] |
mov eax, [eax+ecx*8] |
call [eax+screen_vtable.IsHandleUsed] |
jz .used |
inc ecx |
cmp ecx, [num_screens] |
jb @b |
push ebx |
call [edx+PluginInfo.ClosePlugin] |
.used: |
pop ebp |
ret |
panels_IsHandleUsed: |
; edx=hPlugin, ebx=hFile |
mov ebp, panel1_data |
call .1 |
jz .ret |
mov ebp, panel2_data |
.1: |
cmp edx, [ebp+panel1_hPlugin-panel1_data] |
jnz @f |
cmp ebx, [ebp+panel1_hFile-panel1_data] |
jz .ret |
@@: |
mov esi, [ebp + panel1_parents_sz - panel1_data] |
test esi, esi |
jnz @f |
inc esi |
.ret: |
ret |
@@: |
add esi, [ebp + panel1_parents - panel1_data] |
@@: |
dec esi |
cmp byte [esi-1], 0 |
jnz @b |
sub esi, 9 |
cmp edx, [esi] ; hPlugin |
jnz .no |
mov ebx, [esi+4] ; hFile |
jz .ret |
.no: |
cmp esi, [ebp + panel1_parents - panel1_data] |
jnz @b |
inc esi |
ret |
panels_OnExit: |
; close plugin panels |
mov ebp, panel1_data |
call close_plugin_panels |
mov ebp, panel2_data |
call close_plugin_panels |
ret |
panels_OnRedraw: |
call draw_cmdbar |
mov ebp, panel1_data |
2458,12 → 3116,43 |
end if |
sub ecx, 13 |
mov ebp, [active_panel] |
lea esi, [ebp + panel1_dir - panel1_data] |
push 3 |
pop edx |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jz .native |
mov esi, [ebp + panel1_parents - panel1_data] |
add esi, [ebp + panel1_parents_sz - panel1_data] |
@@: |
dec esi |
cmp byte [esi-1], 0 |
jz @f |
cmp byte [esi-1], '/' |
jnz @b |
@@: |
push ecx edi |
shr ecx, 1 |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
loop @b |
@@: |
sub edi, [esp] |
sub [esp+4], edi |
add [esp], edi |
pop edi ecx |
lea esi, [ebp + panel1_dir - panel1_data] |
cmp byte [esi+1], 0 |
jnz @f |
inc esi |
@@: |
jmp .main |
.native: |
lea esi, [ebp + panel1_dir - panel1_data] |
@@: |
lodsb |
stosb |
dec ecx |
test al, al |
jz @f |
2477,6 → 3166,7 |
dec esi |
dec edi |
@@: |
.main: |
push esi |
@@: |
lodsb |
2518,11 → 3208,11 |
jz .nodir |
cmp esi, [esp] |
jae @b |
mov esi, [esp+4] |
mov al, '/' |
stosb |
dec ecx |
jz .nodir |
mov esi, [esp+4] |
@@: |
cmp esi, [esp+8] |
jb .nodir |
3058,6 → 3748,44 |
and dword [edi], 0 |
ret |
GetPanelTitle_default: |
mov edi, [esp+8] |
mov ecx, 1024 |
mov esi, [esp+12] |
test esi, esi |
jz .nohost |
mov edx, esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
mov edx, esi |
jmp @b |
@@: |
mov esi, edx |
@@: |
lodsb |
stosb |
test al, al |
loopnz @b |
dec edi |
inc ecx |
.nohost: |
mov esi, [esp+16] |
cmp word [esi], '/' |
jz .nodir |
@@: |
lodsb |
stosb |
test al, al |
loopnz @b |
dec edi |
.nodir: |
mov byte [edi], 0 |
ret 10h |
draw_panel: |
mov eax, [ebp + panel1_left - panel1_data] |
mov edx, [ebp + panel1_top - panel1_data] |
3182,6 → 3910,24 |
jnz .columns_loop |
; £®«®¢®ª ¯ ¥«¨ (⥪ãé ï ¯ ¯ª ) |
lea esi, [ebp + panel1_dir - panel1_data] |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
test eax, eax |
jz .native |
push ebp |
push esi |
mov esi, [ebp + panel1_parents - panel1_data] |
add esi, [ebp + panel1_parents_sz - panel1_data] |
@@: |
dec esi |
cmp byte [esi-1], 0 |
jnz @b |
push esi |
push execdata |
push [ebp + panel1_hFile - panel1_data] |
call [eax+PluginInfo.GetPanelTitle] |
pop ebp |
mov esi, execdata |
.native: |
mov edi, cur_header |
mov ecx, [ebp + panel1_width - panel1_data] |
sub ecx, 7 |
4038,10 → 4784,30 |
mov dword [ebp + panel1_selected_size - panel1_data], eax |
mov dword [ebp + panel1_selected_size+4 - panel1_data], eax |
.retry: |
mov eax, [ebp + panel1_hPlugin - panel1_data] |
test eax, eax |
jz .native |
mov ecx, [dirinfo.size] |
test [ebp + panel1_plugin_flags - panel1_data], 1 |
jz @f |
dec ecx ; reserve one entry for '..' |
@@: |
push ebp |
push [dirinfo.dirdata] |
push ecx |
push 0 |
push [ebp + panel1_hFile - panel1_data] |
call [eax + PluginInfo.ReadFolder] |
pop ebp |
mov ebx, [dirinfo.dirdata] |
mov ebx, [ebx+4] |
jmp .read |
.native: |
push 70 |
pop eax |
mov ebx, dirinfo |
int 40h |
.read: |
test eax, eax |
jz .ok |
cmp eax, 6 |
4061,14 → 4827,14 |
push 2 |
push eax |
push 3 |
push -1 |
push -1 |
push dword aError |
call SayErr |
add esp, 5*4 |
test eax, eax |
jz .retry |
.dont_notify: |
; If not on plugin panel, try to return to previous directory |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jnz @f |
mov esi, prev_dir |
cmp byte [esi], 0 |
jz @f |
4079,6 → 4845,7 |
ret |
@@: |
mov [bSilentFolderMode], 1 ; enter silent mode |
; Try to read parent folder |
mov esi, [dirinfo.name] |
xor edx, edx |
.up1: |
4091,11 → 4858,27 |
lea edi, [esi-1] |
jmp .up1 |
.up1done: |
cmp [ebp + panel1_hPlugin - panel1_data], 0 |
jz .4 |
cmp edx, 1 |
ja .up |
; ç⥨¥ á ¯ ¥«¨ ¯« £¨ ®¡«®¬ «®áì ¯® ¯®«®© |
; ¯à¨ í⮬ ¬ë 㦥 ¢ ª®à¥ |
; ¤¥« ¥¬ ¢¨¤, çâ® äãªæ¨ï çâ¥¨ï ¢¥àã« 0 í«¥¬¥â®¢ |
; (¥á«¨ 㦥 ¢å®¤ "..", ® ¡ã¤¥â ¤®¡ ¢«¥ ¢â®¬ â¨ç¥áª¨) |
xor ebx, ebx ; 0 items read |
mov eax, [dirinfo.dirdata] |
mov [eax+8], ebx ; 0 items total |
jmp .ok |
.4: |
cmp edx, 2 |
jbe .noup |
.up: |
stosb |
jmp read_folder |
.noup: |
; There is no parent folder, and we are not on plugin panel |
; Try to read ramdisk |
mov esi, [dirinfo.name] |
mov edi, esi |
lodsd |
4142,9 → 4925,10 |
mov [prev_dir], 0 |
jmp read_folder |
.readdone: |
and [ebp + panel1_start - panel1_data], 0 |
and [ebp + panel1_index - panel1_data], 0 |
and [ebp + panel1_start - panel1_data], 0 |
xor edx, edx |
mov [ebp + panel1_start - panel1_data], edx |
mov [ebp + panel1_index - panel1_data], edx |
mov [ebp + panel1_start - panel1_data], edx |
mov edi, [ebp + panel1_files - panel1_data] |
mov eax, [ebp + panel1_nfa - panel1_data] |
lea eax, [edi + eax*4 + 32] |
4151,7 → 4935,6 |
mov ecx, [eax-32+4] |
test ecx, ecx |
jz .loopdone |
xor edx, edx |
; £®à¨à㥬 á¯¥æ¨ «ìë¥ ¢å®¤ë, ᮮ⢥âáâ¢ãî騥 ¯ ¯ª¥ '.' ¨ ¬¥âª¥ ⮬ |
.ptrinit: |
cmp word [eax+40], '.' |
4192,6 → 4975,58 |
.dotdot: |
; ¯®¤á¢¥âª |
; call insert_last_dot |
call highlight_init |
; call delete_last_dot |
.loopcont: |
add eax, 304 |
dec ecx |
jnz .ptrinit |
.loopdone: |
push edi |
sub edi, [ebp + panel1_files - panel1_data] |
shr edi, 2 |
mov [ebp + panel1_numfiles - panel1_data], edi |
pop edi |
test edx, edx |
jnz @f |
test [ebp + panel1_plugin_flags - panel1_data], 1 |
jz @f |
mov ecx, [ebp + panel1_numfiles - panel1_data] |
inc [ebp + panel1_numfiles - panel1_data] |
lea esi, [edi-4] |
std |
rep movsd |
cld |
mov eax, left_dotdot_entry |
cmp ebp, panel1_data |
jz .zq |
add eax, right_dotdot_entry-left_dotdot_entry |
.zq: |
stosd |
call highlight_init |
@@: |
; ®àâ¨à®¢ª |
sort_files: |
movzx eax, [ebp + panel1_sortmode - panel1_data] |
mov ebx, [compare_fns + eax*4] |
.mode: |
mov edx, [ebp + panel1_files - panel1_data] |
mov ecx, [ebp + panel1_numfiles - panel1_data] |
jecxz .skip |
mov eax, [edx] |
cmp word [eax+40], '..' |
jnz .nodotdot |
cmp byte [eax+42], 0 |
jnz .nodotdot |
dec ecx |
add edx, 4 |
.nodotdot: |
call sort |
.skip: |
mov [bSilentFolderMode], 0 ; leave silent mode |
ret |
highlight_init: |
pushad |
mov ebp, eax |
lea esi, [ebp+40] |
4256,35 → 5091,7 |
mov ah, [panel_selected_cursor_color] |
mov [ebp+7], ah |
.doname: |
; call delete_last_dot |
popad |
.loopcont: |
add eax, 304 |
dec ecx |
jnz .ptrinit |
.loopdone: |
sub edi, [ebp + panel1_files - panel1_data] |
shr edi, 2 |
mov [ebp + panel1_numfiles - panel1_data], edi |
.done: |
; ®àâ¨à®¢ª |
sort_files: |
movzx eax, [ebp + panel1_sortmode - panel1_data] |
mov ebx, [compare_fns + eax*4] |
mov edx, [ebp + panel1_files - panel1_data] |
mov ecx, [ebp + panel1_numfiles - panel1_data] |
jecxz .skip |
mov eax, [edx] |
cmp word [eax+40], '..' |
jnz .nodotdot |
cmp byte [eax+42], 0 |
jnz .nodotdot |
dec ecx |
add edx, 4 |
.nodotdot: |
call sort |
.skip: |
mov [bSilentFolderMode], 0 ; leave silent mode |
ret |
compare_name: |
4689,7 → 5496,12 |
stc |
ret |
ReadFolder_default: |
mov eax, 2 |
ret 10h |
if 0 |
; Following subroutines work, but are slow |
match_mask: |
; in: esi->name, edi->mask |
; out: CF clear <=> match |
5273,7 → 6085,7 |
pop esi |
ret |
header db 'Kolibri Far 0.35',0 |
header db 'Kolibri Far ',version,0 |
nomem_draw db 'No memory for redraw.',0 |
.size = $ - nomem_draw |
5703,6 → 6515,8 |
.OnKey dd ? |
.keybar dd ? |
.getname dd ? |
.OnExit dd ? |
.IsHandleUsed dd ? |
end virtual |
panels_vtable: |
5710,6 → 6524,8 |
dd panels_OnKey |
dd keybar_panels |
dd panels_getname |
dd panels_OnExit |
dd panels_IsHandleUsed |
viewer_vtable: |
dd viewer_OnRedraw |
5716,6 → 6532,8 |
dd viewer_OnKey |
dd keybar_viewer |
dd viewer_getname |
dd viewer_OnExit |
dd viewer_IsHandleUsed |
; additions to this table require changes in tools.inc::get_error_msg |
errors1: |
6293,6 → 7111,7 |
ContinueBtn: |
dd aContinue |
aCannotOpenFile_ptr dd aCannotOpenFile |
if lang eq ru |
aDeleteCaption db '¤ «¥¨¥',0 |
aConfirmDeleteText db 'ë å®â¨â¥ 㤠«¨âì',0 |
6354,6 → 7173,7 |
aDate db 4,' â ' |
aTime db 5,'६ï' |
aCannotLoadDLL db '¥ ¬®£ã § £à㧨âì DLL',0 |
aCannotLoadPlugin db '¥ ¬®£ã § £à㧨âì ¯« £¨',0 |
aInvalidDLL db ' ©« ¥ ©¤¥ ¨«¨ ¨¬¥¥â ¥¢¥àë© ä®à¬ â',0 |
aMissingExport db '¥®¡å®¤¨¬ ï äãªæ¨ï ¥ ©¤¥ ',0 |
aInitFailed db '訡ª ¯à¨ ¨¨æ¨ «¨§ 樨',0 |
6361,6 → 7181,8 |
aTables db ' ¡«¨æë',0 |
aSelect db '®¬¥â¨âì',0 |
aDeselect db 'ïâì',0 |
aCannotOpenFile db '訡ª ¯à¨ ®âªàë⨨ ä ©« ',0 |
aCannotSetFolder db '¥ ¬®£ã § ©â¨ ¢ ¯ ¯ªã',0 |
else |
aDeleteCaption db 'Delete',0 |
aConfirmDeleteText db 'Do you wish to delete',0 |
6426,6 → 7248,7 |
aDate db 4,'Date' |
aTime db 4,'Time' |
aCannotLoadDLL db 'Cannot load DLL',0 |
aCannotLoadPlugin db 'Cannot load plugin',0 |
aInvalidDLL db 'File is not found or invalid',0 |
aMissingExport db 'Required function is not present',0 |
aInitFailed db 'Initialization failed',0 |
6433,11 → 7256,15 |
aTables db 'Tables',0 |
aSelect db 'Select',0 |
aDeselect db 'Deselect',0 |
aCannotOpenFile db 'Cannot open the file',0 |
aCannotSetFolder db 'Cannot enter to folder',0 |
end if |
aOk db 'OK',0 |
aNoMemory db 'No memory!' |
nullstr db 0 |
aUntitled db 'untitled',0 |
aDotDot db '..',0,0 |
standard_dll_path: |
libini_name db '/sys/dll/' |
standard_dll_path_size = $ - standard_dll_path |
6447,13 → 7274,33 |
aVersion db 'version',0 |
aIniGetInt db 'ini.get_int',0 |
aIniGetStr db 'ini.get_str',0 |
aIniSetInt db 'ini.set_int',0 |
aIniEnumKeys db 'ini.enum_keys',0 |
aPluginLoad db 'plugin_load',0 |
aPluginUnload db 'plugin_unload',0 |
aGetattr db 'getattr',0 |
aOpen db 'open',0 |
aRead db 'read',0 |
aSetpos db 'setpos',0 |
aClose db 'close',0 |
aOpenFilePlugin db 'OpenFilePlugin',0 |
aClosePlugin db 'ClosePlugin',0 |
aReadFolder db 'ReadFolder',0 |
aSetFolder db 'SetFolder',0 |
aGetOpenPluginInfo db 'GetOpenPluginInfo',0 |
aGetPanelTitle db 'GetPanelTitle',0 |
aGetFiles db 'GetFiles',0 |
aConfirmations db 'Confirmations',0 |
aConfirmDelete db 'Delete',0 |
aConfirmDeleteIncomplete db 'DeleteIncomplete',0 |
aPanels db 'Panels',0 |
aLeftViewMode db 'LeftViewMode',0 |
aRightViewMode db 'RightViewMode',0 |
aAssociations db 'Associations',0 |
aPlugins db 'Plugins',0 |
aMenu db 'Menu',0 |
aFolderShortcuts db 'FolderShortcuts',0 |
aShortcut db 'Shortcut' |
6464,9 → 7311,87 |
ini.get_int dd aIniGetInt |
ini.get_str dd aIniGetStr |
ini.enum_keys dd aIniEnumKeys |
ini.set_int dd aIniSetInt |
dd 0 |
plugin_exported: |
dd aPluginUnload |
dd aGetattr |
dd aOpen |
dd aRead |
dd aSetpos |
dd aClose |
dd aOpenFilePlugin |
dd aClosePlugin |
dd aReadFolder |
dd aSetFolder |
dd aGetOpenPluginInfo |
dd aGetPanelTitle |
dd aGetFiles |
dd 0 |
plugin_exported_default: |
dd plugin_unload_default |
dd getattr_default |
dd open_default |
dd read |
dd setpos_default |
dd close |
dd OpenFilePlugin_default |
dd ClosePlugin_default |
dd ReadFolder_default |
dd SetFolder_default |
dd GetOpenPluginInfo_default |
dd GetPanelTitle_default |
dd GetFiles_default |
kfar_info: |
dd .size |
dd version_dword |
dd open |
dd read |
dd -1 ; write: to be implemented |
dd seek |
dd -1 ; flush: to be implemented |
dd filesize |
dd close |
dd xpgalloc |
dd xpgrealloc |
dd pgfree |
dd getfreemem |
dd libini_alloc |
dd libini_realloc |
dd libini_free |
dd menu |
dd menu_centered_in |
dd DialogBox |
dd SayErr |
dd Message |
dd cur_width |
.size = $ - kfar_info |
plugins dd 0 |
num_plugins dd 0 |
alloc_plugins dd 0 |
virtual at 0 |
PluginInfo: |
.unload dd ? |
.getattr dd ? |
.open dd ? |
.read dd ? |
.setpos dd ? |
.close dd ? |
.OpenFilePlugin dd ? |
.ClosePlugin dd ? |
.ReadFolder dd ? |
.SetFolder dd ? |
.GetOpenPluginInfo dd ? |
.GetPanelTitle dd ? |
.GetFiles dd ? |
.size = $ |
end virtual |
virtual at 0 |
PanelMode: |
; up to 16 columns on one panel |
.NumColumns dd ? |
6592,6 → 7517,11 |
panel1_nfa dd ? |
panel1_numfiles dd ? |
panel1_files dd ? |
panel1_hPlugin dd ? |
panel1_hFile dd ? |
panel1_parents dd ? |
panel1_parents_sz dd ? |
panel1_parents_alloc dd ? |
panel1_colmode dd ? |
panel1_colwidths rd 16+1 |
panel1_total_num dd ? |
6598,6 → 7528,8 |
panel1_total_size dq ? |
panel1_selected_num dd ? |
panel1_selected_size dq ? |
panel1_plugin_info: |
panel1_plugin_flags dd ? |
panel1_dir rb 1024 |
panel2_data: |
6614,6 → 7546,11 |
panel2_nfa dd ? |
panel2_numfiles dd ? |
panel2_files dd ? |
panel2_hPlugin dd ? |
panel2_hFile dd ? |
panel2_parents dd ? |
panel2_parents_sz dd ? |
panel2_parents_alloc dd ? |
panel2_colmode dd ? |
panel2_colwidths rd 16+1 |
panel2_total_num dd ? |
6620,6 → 7557,8 |
panel2_total_size dq ? |
panel2_selected_num dd ? |
panel2_selected_size dq ? |
panel2_plugin_info: |
panel2_plugin_flags dd ? |
panel2_dir rb 1024 |
;console_data rb max_width*max_height*2 |
6670,6 → 7609,10 |
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 |
aConfirmDeleteTextBuf rb aConfirmDeleteTextMax + 1 |
CopySourceTextBuf rb 512 |
CopyDestEditBuf rb 12+512+1 |
6686,6 → 7629,12 |
copy_buffer_size = 65536 |
copy_buffer rb copy_buffer_size |
filedata_buffer_size = 1024 |
filedata_buffer rb filedata_buffer_size |
source_hModule dd ? |
source_hPlugin dd ? |
source_hFile dd ? |
; data for directory delete |
; If directory nested level is >1024, then its full name is too big, |
; so we see the overflow when creating full name (we check for this!) |
6701,6 → 7650,7 |
del_bSkipAll db ? ; for directory errors |
label copy_bSkipAll byte at del_bSkipAll |
copy_bSkipAll2 db ? ; for file read/write errors |
copy_bSkipAll3 db ? ; for SetFolder errors |
bEndSlash db ? |
bDestIsFolder db ? |
6708,7 → 7658,7 |
; stack |
align 4 |
rb 512 |
rb 32768 |
stacktop: |
mem: |
/programs/fs/kfar/trunk/kfar.ini |
---|
0,0 → 1,43 |
[Associations] |
asm=/rd/1/TinyPad; AsmMenu1,AsmMenu2 |
inc=/rd/1/TinyPad |
ini=/rd/1/TinyPad |
txt=/rd/1/TinyPad |
jpg=/rd/1/JpegView |
jpeg=/rd/1/JpegView |
gif=/rd/1/GIFVIEW; GifMenu1,MenuAnimage |
wav=/rd/1/AC97SND |
mp3=/rd/1/AC97SND |
mid=/rd/1/MIDAMP |
bmp=/rd/1/MV; BmpMenu1,MenuAnimage |
png=/rd/1/@rcher |
rtf=/rd/1/RtfRead |
3ds=/rd/1/3d/view3ds |
lif=/rd/1/demos/life2 |
skn=/rd/1/desktop |
[Menu] |
AsmMenu1=&¥¤ ªâ®à,/rd/1/TinyPad |
AsmMenu2=&®¬¯¨«¨à®¢ âì,/rd/1/develop/fasm |
GifMenu1=&à®á¬®âà,/rd/1/GIFVIEW |
BmpMenu1=&à®á¬®âà,/rd/1/MV |
MenuAnimage=&¥¤ ªâ®à,/rd/1/animage |
[Panels] |
LeftViewMode=2 |
RightViewMode=2 |
[FolderShortcuts] |
# ®¦® ®¯à¥¤¥«¨âì ¤® ¤¥áï⨠ááë«®ª ¯ ¯ª¨ Shortcut0...Shortcut9, |
# â ª¨¥ ¯ ¯ª¨ ¬®¦® ᤥ« âì ¡ëáâàë© ¯¥à¥å®¤ ¯® RCtrl+<æ¨äà > |
Shortcut0=/rd/1 |
[Confirmations] |
Delete=1 |
DeleteIncomplete=0 |
# «¥¢ ®â § ª à ¢¥á⢠¬®¦® áâ ¢¨âì «î¡®¥ ®á¬ëá«¥®¥ ¨«¨ ¡¥áá¬ëá«¥®¥ |
# ¨¬ï; á¯à ¢ - ¯ãâì ª ¯« £¨ã. |
# ᫨ ¯ãâì ¥ ¡á®«îâ¥, â® ® ®âáç¨âë¢ ¥âáï ®â ¯ ¯ª¨ á ¡¨ ਪ®¬ kfar. |
[Plugins] |
ArchiveReader=kfar_arc.obj |
/programs/fs/kfar/trunk/kfar_arc/7z.inc |
---|
0,0 → 1,3138 |
; Loading of 7z archives was ported from 7z sources (file 7zip\Archive\7z\7zIn.cpp). |
; The version 7-Zip 4.42 was used. |
; 7-Zip is copyright (C) 1999-2006 Igor Pavlov. |
; Assembler version as KFar plugin has been written by diamond, 2007. |
virtual at 0 |
file_in_7z: |
.fullname dd ? ; pointer to cp866 string |
.name dd ? |
.namelen dd ? |
.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 of list of subfolders or files |
.prev dd ? ; previous item of list of subfolders or files |
.attr dd ? |
.FileCRC dd ? |
.startPos dq ? |
.CreationTime dq ? |
.LastAccessTime dq ? |
.LastWriteTime dq ? |
.UnPackSize dq ? |
.folder dd ? |
.folder_index dd ? |
.folderStart dq ? |
.bAttrDefined db ? |
.bStartPosDefined db ? |
.bCRCDefined db ? |
.bCreationTimeDefined db ? |
.bLastAccessTimeDefined db ? |
.bLastWriteTimeDefined db ? |
.bHasStream db ? |
.bAnti db ? |
.stamp dd ? |
.size = $ |
end virtual |
virtual at 0 |
handle_7z: |
.type dd ? |
.root.subfolders dd ? |
.root.subfolders.end dd ? |
.root.subfiles dd ? |
.root.subfiles.end dd ? |
.root.NumSubItems dd ? |
.curdir dd ? |
.NumFiles dd ? |
.names_buf dd ? |
.host dd ? |
.host_datetime rd 6 |
; streams info |
.numPackStreams dd ? |
.packSizes dd ? |
.numFolders dd ? |
.unpackCRCsDefined dd ? |
.unpackCRCs dd ? |
.folders dd ? |
.last_folder dd ? |
.last_pos dq ? |
.last_context dd ? |
.last_main_stream dd ? |
.password_len dd ? ; -1 if no password defined; in characters |
.password rw password_maxlen |
.basesize = $ |
; .size = .basesize + .NumFiles * file_in_7z.size |
end virtual |
iglobal |
align 4 |
empty_7z_handle: |
dd type_7z |
dd 0,0,0,0,0,0 |
endg |
kEnd = 0 |
kHeader = 1 |
kArchiveProperties = 2 |
kAdditionalStreamsInfo = 3 |
kMainStreamsInfo = 4 |
kFilesInfo = 5 |
kPackInfo = 6 |
kUnPackInfo = 7 |
kSubStreamsInfo = 8 |
kSize = 9 |
kCRC = 10 |
kFolder = 11 |
kCodersUnPackSize = 12 |
kNumUnPackStream = 13 |
kEmptyStream = 14 |
kEmptyFile = 15 |
kAnti = 16 |
kName = 17 |
kCreationTime = 18 |
kLastAccessTime = 19 |
kLastWriteTime = 20 |
kWinAttributes = 21 |
kComment = 22 |
kEncodedHeader = 23 |
kStartPos = 24 |
_7z.ReadByte: |
cmp edi, [bufend] |
jae return.err |
mov al, [edi] |
inc edi |
ret |
_7z.ReadWord: |
add edi, 2 |
cmp edi, [bufend] |
ja return.err |
mov ax, [edi-2] |
ret |
_7z.ReadDword: |
add edi, 4 |
cmp edi, [bufend] |
ja return.err |
mov eax, [edi-4] |
ret |
_7z.SkipSize: |
test edx, edx |
jnz return.err |
add edi, eax |
jc return.err |
cmp edi, [bufend] |
ja return.err |
ret |
_7z.ReadNumber: |
xor eax, eax |
push eax |
push eax |
call _7z.ReadByte |
push ecx |
xor ecx, ecx |
@@: |
add al, al |
jnc @f |
inc ecx |
jmp @b |
@@: |
shr eax, cl |
shr eax, 1 |
jz @f |
mov [esp+4+ecx], al |
@@: |
jecxz .ret |
push edx |
xor edx, edx |
@@: |
call _7z.ReadByte |
mov [esp+8+edx], al |
inc edx |
loop @b |
pop edx |
.ret: |
pop ecx |
pop eax |
pop edx |
ret |
_7z.ReadNum: |
push edx |
call _7z.ReadNumber |
test edx, edx |
jnz return.err |
test eax, eax |
js return.err |
pop edx |
ret |
open_7z: |
; CInArchive::ReadDatabase() |
cmp byte [esi+6], 0 ; major version must be 0 |
; minor version does not be checked ([byte +7]=2 for now) |
jz @f |
xor eax, eax |
ret |
@@: |
and [hOut], 0 |
and [_7z.FreeSubStreams], 0 |
and [_7z.tmpVector], 0 |
push esi |
add esi, 12 |
mov ecx, 20 |
call crc |
pop esi |
cmp eax, [esi+8] |
jnz .header_crc_error |
cmp dword [esi+24], 0 |
jnz .header_error |
mov edi, buffer |
mov ecx, [esi+20] |
mov [bufsize], ecx |
test ecx, ecx |
jnz .notempty |
mov eax, empty_7z_handle |
push ebp |
call [close] |
ret |
.notempty: |
cmp ecx, 1024 |
jbe @f |
call [pgalloc] |
test eax, eax |
jz .reterr |
mov edi, eax |
@@: |
mov [bufptr], edi |
lea eax, [edi+ecx] |
mov [bufend], eax |
mov eax, [esi+12] |
mov edx, [esi+16] |
add eax, 20h ; end of main header |
adc edx, 0 |
push edx |
push eax |
push 0 |
push ebp |
call [seek] |
push ecx |
push edi |
push ebp |
call [read] |
cmp eax, ecx |
jnz .header_error |
push esi |
mov esi, edi |
call crc |
pop esi |
cmp eax, [esi+28] |
jz .header_ok |
.header_crc_error: |
.header_error: |
push ContinueBtn |
push 1 |
push HeaderError_ptr |
push 1 |
call [SayErr] |
.clear: |
mov ecx, [_7z.tmpVector] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [hOut] |
jecxz @f |
call _7z.CloseHandle |
@@: |
mov ebx, [_7z.dataVectorSize] |
test ebx, ebx |
jz @f |
call _7z.ReadAndDecodePackedStreams.free2 |
@@: |
mov ecx, [_7z.FreeSubStreams] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [bufptr] |
cmp ecx, buffer |
jz .reterr |
call [pgfree] |
.reterr: |
or eax, -1 |
ret |
.header_ok: |
mov [_esp], esp |
mov [inStream], ebp |
.loop: |
mov [error_proc], .header_error |
mov [clear_proc], .clear |
and [_7z.dataVectorSize], 0 |
call _7z.ReadNum |
cmp eax, kHeader |
jz .found_header |
cmp eax, kEncodedHeader |
jnz .header_error |
call _7z.ReadAndDecodePackedStreams |
cmp [_7z.StreamsInfo.numFolders], 0 |
jz .free_empty |
cmp [_7z.StreamsInfo.numFolders], 1 |
jnz return.err |
mov ecx, [bufptr] |
cmp ecx, buffer |
jz @f |
call [pgfree] |
@@: |
mov edi, [_7z.unpbuf+4] |
mov [bufptr], edi |
mov ecx, [_7z.unpbuf] |
add ecx, edi |
mov [bufend], ecx |
mov [error_proc], .header_error |
mov [clear_proc], .clear |
and [_7z.dataVectorSize], 0 |
call _7z.ReadNum |
cmp eax, kHeader |
jz .found_header |
jmp return.err |
.free_empty: |
mov ecx, [bufptr] |
cmp ecx, buffer |
jz @f |
call [pgfree] |
@@: |
push [inStream] |
call [close] |
mov eax, empty_7z_handle |
ret |
.found_header: |
call _7z.ReadNum |
cmp eax, kArchiveProperties |
jnz .no_archive_props |
@@: |
call _7z.ReadNum |
test eax, eax |
jz @f |
call _7z.SkipData |
jmp @b |
@@: |
call _7z.ReadNum |
.no_archive_props: |
cmp eax, kAdditionalStreamsInfo |
jnz .no_additional_streams |
call _7z.ReadAndDecodePackedStreams |
mov eax, [_7z.unpacked] |
mov [_7z.dataVector], eax |
mov eax, [_7z.StreamsInfo.numFolders] |
mov [_7z.dataVectorSize], eax |
mov [error_proc], .header_error |
mov [clear_proc], .clear |
call _7z.ReadNum |
.no_additional_streams: |
cmp eax, kMainStreamsInfo |
jnz return.err |
call _7z.ReadStreamsInfo |
call _7z.ReadNum |
test eax, eax |
jnz .notempty2 |
.empty2: |
mov ebx, [_7z.dataVectorSize] |
test ebx, ebx |
jz @f |
call _7z.ReadAndDecodePackedStreams.free2 |
@@: |
mov ecx, [_7z.FreeSubStreams] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [bufptr] |
cmp ecx, buffer |
jz @f |
call [pgfree] |
@@: |
push [inStream] |
call [close] |
mov eax, empty_7z_handle |
ret |
.notempty2: |
cmp eax, kFilesInfo |
jnz return.err |
call _7z.ReadNum |
test eax, eax |
jz .empty2 |
mov ebx, eax ; number of files in archive |
imul ecx, ebx, file_in_7z.size |
add ecx, handle_7z.basesize |
mov [hOut.allocated], ecx |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov [hOut], eax |
mov [eax+handle_7z.type], type_7z |
mov [eax+handle_7z.NumFiles], ebx |
push edi |
lea edi, [eax+handle_7z.numPackStreams] |
mov esi, _7z.StreamsInfo |
mov ecx, 6 |
rep movsd |
or [eax+handle_7z.password_len], -1 |
or [eax+handle_7z.last_folder], -1 |
mov [eax+handle_7z.last_context], ecx |
mov [eax+handle_7z.names_buf], ecx |
mov [eax+handle_7z.host], ecx |
cmp [bPasswordDefined], cl |
jz @f |
mov ecx, [password_size] |
mov [eax+handle_7z.password_len], ecx |
lea edi, [eax+handle_7z.password] |
mov esi, password_unicode |
shr ecx, 1 |
rep movsd |
adc ecx, ecx |
rep movsw |
@@: |
lea edi, [eax+handle_7z.basesize] |
imul ecx, ebx, file_in_7z.size/4 |
xor eax, eax |
rep stosd |
pop edi |
mov eax, [_7z.StreamsInfo.SubStreamsSizes] |
mov [_7z.FreeSubStreams], eax |
mov [error_proc], .header_error |
mov [clear_proc], .clear |
mov ecx, ebx |
shl ecx, 2 |
call [pgalloc] |
test eax, eax |
jz return.clear |
push edi |
mov edi, eax |
mov [_7z.tmpVector], eax |
add eax, ebx |
mov [_7z.emptyStreams], eax |
add eax, ebx |
mov [_7z.emptyFiles], eax |
add eax, ebx |
mov [_7z.antiFiles], eax |
mov ecx, ebx |
xor eax, eax |
rep stosd |
pop edi |
mov [_7z.numEmptyStreams], eax |
.parse_header: |
call _7z.ReadNum |
test eax, eax |
jz .parse_header_done |
mov ecx, eax ; ecx = type |
call _7z.ReadNum ; eax = size |
cmp ecx, kName |
jz .parse_names |
cmp ecx, kWinAttributes |
jz .parse_winAttr |
cmp ecx, kStartPos |
jz .parse_startPos |
cmp ecx, kEmptyStream |
jz .parse_emptyStream |
cmp ecx, kEmptyFile |
jz .parse_emptyFile |
cmp ecx, kAnti |
jz .parse_anti |
cmp ecx, kCreationTime |
jz .parse_time |
cmp ecx, kLastWriteTime |
jz .parse_time |
cmp ecx, kLastAccessTime |
jz .parse_time |
xor edx, edx |
call _7z.SkipSize |
jmp .parse_header |
.parse_names: |
push eax |
call _7z.SwitchStream |
pop eax |
jz @f |
mov eax, [bufend] |
sub eax, edi |
@@: |
shr eax, 1 ; size of ANSI string is a half of size of UNICODE string |
mov ecx, eax |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov ebp, eax |
mov esi, [hOut] |
mov [esi+handle_7z.names_buf], eax |
add eax, ecx |
push eax ; remember limit |
mov ecx, ebx |
add esi, handle_7z.basesize + file_in_7z.fullname |
mov [bWasWarning], 0 |
.parse_names_loop: |
mov [esi], ebp |
add esi, file_in_7z.size |
.parse_names_loop_int: |
cmp ebp, [esp] |
jae return.err |
call _7z.ReadWord |
; UNICODE char -> cp866 char |
cmp ax, 0x80 |
jb .id |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
cmp [bWasWarning], 0 |
jnz @f |
push ContinueBtn |
push 1 |
push aEncodingProblem_str_ptr |
push 3 |
push aEncodingProblem |
call [Message] |
inc [bWasWarning] |
@@: |
mov al, '_' |
jmp .id |
.yo1: |
mov al, 'ð' |
jmp .id |
.yo2: |
mov al, 'ñ' |
jmp .id |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .id |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.id: |
mov [ebp], al |
inc ebp |
test al, al |
jnz .parse_names_loop_int |
loop .parse_names_loop |
pop eax |
call _7z.UnswitchStream |
jmp .parse_header |
.parse_winAttr: |
mov edx, [_7z.tmpVector] |
push ebx |
mov ecx, ebx |
mov ebx, edx |
call _7z.ReadBoolVector2 |
pop ebx |
call _7z.SwitchStream |
mov esi, [hOut] |
add esi, handle_7z.basesize |
mov ecx, ebx |
.winAttrLoop: |
mov al, [edx] |
inc edx |
mov [esi+file_in_7z.bAttrDefined], al |
test al, al |
jz @f |
call _7z.ReadDword |
mov [esi+file_in_7z.attr], eax |
@@: |
add esi, file_in_7z.size |
loop .winAttrLoop |
call _7z.UnswitchStream |
jmp .parse_header |
.parse_startPos: |
mov edx, [_7z.tmpVector] |
push ebx |
mov ecx, ebx |
mov ebx, edx |
call _7z.ReadBoolVector2 |
pop ebx |
call _7z.SwitchStream |
mov esi, [hOut] |
add esi, handle_7z.basesize |
mov ecx, ebx |
.startPosLoop: |
mov al, [edx] |
inc edx |
mov [esi+file_in_7z.bStartPosDefined], al |
test al, al |
jz @f |
call _7z.ReadDword |
mov dword [esi+file_in_7z.startPos], eax |
call _7z.ReadDword |
mov dword [esi+file_in_7z.startPos+4], eax |
@@: |
add esi, file_in_7z.size |
loop .startPosLoop |
call _7z.UnswitchStream |
jmp .parse_header |
.parse_emptyStream: |
mov edx, [_7z.emptyStreams] |
push ebx |
mov ecx, ebx |
mov ebx, edx |
call _7z.ReadBoolVector |
pop ebx |
and [_7z.numEmptyStreams], 0 |
mov ecx, ebx |
.emptyStrLoop: |
cmp byte [edx], 0 |
jz @f |
inc [_7z.numEmptyStreams] |
@@: |
inc edx |
loop .emptyStrLoop |
jmp .parse_header |
.parse_emptyFile: |
push ebx |
mov ecx, [_7z.numEmptyStreams] |
mov ebx, [_7z.emptyFiles] |
call _7z.ReadBoolVector |
pop ebx |
jmp .parse_header |
.parse_anti: |
push ebx |
mov ecx, [_7z.numEmptyStreams] |
mov ebx, [_7z.antiFiles] |
call _7z.ReadBoolVector |
pop ebx |
jmp .parse_header |
.parse_time: |
push ecx |
push ebx |
mov ecx, ebx |
mov ebx, [_7z.tmpVector] |
call _7z.ReadBoolVector2 |
pop ebx |
call _7z.SwitchStream |
mov esi, [hOut] |
add esi, handle_7z.basesize |
xor ecx, ecx |
.timeLoop: |
mov eax, [_7z.tmpVector] |
mov al, [eax+ecx] |
pop edx |
push edx |
mov [esi + file_in_7z.bCreationTimeDefined + edx - kCreationTime], al |
test al, al |
jz @f |
call _7z.ReadDword |
push eax |
call _7z.ReadDword |
mov edx, eax |
pop eax |
push edi |
mov edi, [esp+4] |
lea edi, [esi + file_in_7z.CreationTime + (edi-kCreationTime)*8] |
call ntfs_datetime_to_bdfe |
pop edi |
@@: |
add esi, file_in_7z.size |
inc ecx |
cmp ecx, ebx |
jb .timeLoop |
call _7z.UnswitchStream |
pop eax |
jmp .parse_header |
.parse_header_done: |
xor ecx, ecx ; index in emptyFiles |
xor edx, edx ; index in subStreams |
xor ebp, ebp ; index in files |
mov esi, [hOut] |
add esi, handle_7z.basesize |
.filesLoop: |
mov eax, [_7z.emptyStreams] |
mov al, [eax+ebp] |
xor al, 1 |
mov [esi+file_in_7z.bHasStream], al |
jz .nostream |
mov [esi+file_in_7z.bIsDirectory], 0 |
mov [esi+file_in_7z.bAnti], 0 |
mov eax, [_7z.StreamsInfo.SubStreamsSizes] |
push dword [eax+edx*8] |
pop dword [esi+file_in_7z.UnPackSize] |
push dword [eax+edx*8+4] |
pop dword [esi+file_in_7z.UnPackSize+4] |
mov eax, [_7z.StreamsInfo.SubStreamsCRCsDefined] |
mov al, [eax+edx] |
mov [esi+file_in_7z.bCRCDefined], al |
test al, al |
jz @f |
mov eax, [_7z.StreamsInfo.SubStreamsCRCs] |
mov eax, [eax+edx*4] |
mov [esi+file_in_7z.FileCRC], eax |
@@: |
inc edx |
jmp .filesCont |
.nostream: |
mov eax, [_7z.emptyFiles] |
cmp byte [eax+ecx], 0 |
setz [esi+file_in_7z.bIsDirectory] |
mov eax, [_7z.antiFiles] |
cmp byte [eax+ecx], 0 |
setnz [esi+file_in_7z.bAnti] |
and dword [esi+file_in_7z.UnPackSize], 0 |
and dword [esi+file_in_7z.UnPackSize+4], 0 |
mov [esi+file_in_7z.bCRCDefined], 0 |
inc ecx |
.filesCont: |
inc ebp |
add esi, file_in_7z.size |
dec ebx |
jnz .filesLoop |
mov ecx, [_7z.tmpVector] |
call [pgfree] |
and [_7z.tmpVector], 0 |
mov ebx, [_7z.dataVectorSize] |
test ebx, ebx |
jz @f |
call _7z.ReadAndDecodePackedStreams.free2 |
and [_7z.dataVectorSize], 0 |
@@: |
mov ecx, [_7z.FreeSubStreams] |
jecxz @f |
call [pgfree] |
and [_7z.FreeSubStreams], 0 |
@@: |
mov ecx, [bufptr] |
cmp ecx, buffer |
jz @f |
call [pgfree] |
mov [bufptr], buffer |
@@: |
xor esi, esi ; index of folder |
mov edi, [hOut] |
mov ebx, [edi+handle_7z.NumFiles] |
add edi, handle_7z.basesize ; pointer to fileinfo |
push 0 ; start index of packed stream for folder |
.getfoldersloop0: |
xor edx, edx ; index in folder |
push edx edx ; position in folder |
.getfoldersloop: |
dec ebx |
js .getfoldersdone |
cmp [edi+file_in_7z.bHasStream], 0 |
jnz @f |
test edx, edx |
jz .nofolder |
@@: |
test edx, edx |
jnz .notfirst |
; skip empty folders |
@@: |
mov eax, [hOut] |
cmp esi, [eax+handle_7z.numFolders] |
jae return.err |
mov eax, [eax+handle_7z.folders] |
mov eax, [eax+esi*4] |
cmp edx, [eax+_7z.StreamsInfo.numUnPackStreams] |
jb @f |
inc esi |
jmp @b |
@@: |
.notfirst: |
mov [edi+file_in_7z.folder], esi |
mov [edi+file_in_7z.folder_index], edx |
mov eax, [esp] |
mov dword [edi+file_in_7z.folderStart], eax |
mov eax, [esp+4] |
mov dword [edi+file_in_7z.folderStart+4], eax |
mov ecx, dword [edi+file_in_7z.UnPackSize] |
add [esp], ecx |
mov ecx, dword [edi+file_in_7z.UnPackSize+4] |
adc [esp+4], ecx |
add edi, file_in_7z.size |
inc edx |
mov eax, [hOut] |
mov eax, [eax+handle_7z.folders] |
mov eax, [eax+esi*4] |
cmp edx, [eax+_7z.StreamsInfo.numUnPackStreams] |
jb .getfoldersloop |
inc esi |
pop edx edx |
jmp .getfoldersloop0 |
.nofolder: |
push -1 |
pop eax |
mov [edi+file_in_7z.folder], eax |
mov [edi+file_in_7z.folder_index], eax |
mov dword [edi+file_in_7z.folderStart], eax |
mov dword [edi+file_in_7z.folderStart+4], eax |
add edi, file_in_7z.size |
jmp .getfoldersloop |
.getfoldersdone: |
pop eax eax eax |
mov ebp, [hOut] |
mov esi, [ebp+handle_7z.folders] |
xor ebx, ebx |
cmp ebx, [ebp+handle_7z.numFolders] |
jae .getoffsdone |
.getoffsloop: |
lodsd |
test ebx, ebx |
jnz .getoffs2 |
mov edx, dword [_7z.StreamsInfo.dataOffset] |
mov dword [eax+_7z.StreamsInfo.packOffset], edx |
mov edx, dword [_7z.StreamsInfo.dataOffset+4] |
mov dword [eax+_7z.StreamsInfo.packOffset+4], edx |
jmp .getoffscont |
.getoffs2: |
mov ecx, [esi-8] |
mov edx, dword [ecx+_7z.StreamsInfo.packOffset] |
mov dword [eax+_7z.StreamsInfo.packOffset], edx |
mov edx, dword [ecx+_7z.StreamsInfo.packOffset+4] |
mov dword [eax+_7z.StreamsInfo.packOffset+4], edx |
mov edi, [ecx+_7z.StreamsInfo.startPackedStream] |
mov ecx, [ecx+_7z.StreamsInfo.numPackedStreams] |
push ecx |
add ecx, edi |
cmp ecx, [ebp+handle_7z.numPackStreams] |
ja return.err |
pop ecx |
shl edi, 3 |
add edi, [ebp+handle_7z.packSizes] |
@@: |
dec ecx |
js @f |
mov edx, [edi] |
add dword [eax+_7z.StreamsInfo.packOffset], edx |
mov edx, [edi+4] |
adc dword [eax+_7z.StreamsInfo.packOffset+4], edx |
add edi, 8 |
jmp @b |
@@: |
.getoffscont: |
inc ebx |
cmp ebx, [ebp+handle_7z.numFolders] |
jb .getoffsloop |
.getoffsdone: |
mov edx, [hOut] |
mov ebx, [edx+handle_7z.NumFiles] |
lea edi, [edx+handle_7z.root.subfolders] |
add edx, handle_7z.basesize |
push file_in_7z.size |
call init_file_links |
mov eax, [hOut] |
and [eax+handle_7z.curdir], 0 ; set root directory |
mov esi, [inStream] |
mov [eax+handle_7z.host], esi |
lea edi, [eax+handle_7z.host_datetime] |
mov esi, [esp+16] |
add esi, 8 |
mov ecx, 6 |
rep movsd |
ret |
_7z.CloseHandle: |
mov esi, ecx |
push [esi+handle_7z.host] |
call [close] |
mov ecx, [esi+handle_7z.packSizes] |
call [pgfree] |
mov ecx, [esi+handle_7z.folders] |
call [pgfree] |
mov ecx, [esi+handle_7z.names_buf] |
call [pgfree] |
mov ecx, [esi+handle_7z.last_context] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, esi |
call [pgfree] |
ret |
close_7z: |
mov ecx, [esp+4] |
cmp ecx, empty_7z_handle |
jz @f |
call _7z.CloseHandle |
@@: |
ret 4 |
uglobal |
align 4 |
_7z.unpacked dd ? |
_7z.unpbuf rd 2*8 |
_7z.CurInStream dd ? |
_7z.dataVector dd ? |
_7z.dataVectorSize dd ? |
_7z.FreeSubStreams dd ? |
_7z.tmpVector dd ? |
_7z.emptyStreams dd ? |
_7z.numEmptyStreams dd ? |
_7z.emptyFiles dd ? |
_7z.antiFiles dd ? |
endg |
_7z.ReadAndDecodePackedStreams: |
call _7z.ReadStreamsInfo |
mov ecx, [_7z.StreamsInfo.numFolders] |
test ecx, ecx |
jz .ret2 |
push ecx |
mov ecx, [_7z.StreamsInfo.SubStreamsSizes] |
jecxz @f |
call [pgfree] |
and [_7z.StreamsInfo.SubStreamsSizes], 0 |
@@: |
pop ecx |
mov eax, _7z.unpbuf |
cmp ecx, 8 |
jbe .1 |
shl ecx, 3 |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov esi, eax |
@@: |
and dword [esi], 0 |
add esi, 4 |
sub ecx, 4 |
jnz @b |
.1: |
mov [_7z.unpacked], eax |
mov esi, eax |
xor ecx, ecx |
mov [_7z.CurInStream], ecx |
mov [error_proc], .error |
mov [clear_proc], .clear |
.loop: |
mov eax, [_7z.StreamsInfo.folders] |
mov ebx, [eax+ecx*4] |
call _7z.GetUnPackSize |
test edx, edx |
jnz return.err |
test eax, eax |
js return.err |
push ecx |
mov [esi], eax |
mov [_7z.decode.outBufferSize], eax |
mov ecx, eax |
call [pgalloc] |
test eax, eax |
jz return.err |
mov [esi+4], eax |
mov [_7z.decode.outBufferPtr], eax |
push esi |
call _7z.decode |
pop esi |
pop ecx |
push ecx |
mov eax, [_7z.StreamsInfo.unpackCRCsDefined] |
cmp byte [eax+ecx], 0 |
jz @f |
push esi |
mov ecx, [esi] |
mov esi, [esi+4] |
call crc |
pop esi |
pop ecx |
push ecx |
mov edx, [_7z.StreamsInfo.unpackCRCs] |
cmp [edx+ecx*4], eax |
jnz return.err |
@@: |
add esi, 8 |
pop ecx |
inc ecx |
cmp ecx, [_7z.StreamsInfo.numFolders] |
jb .loop |
.ret: |
mov ecx, [_7z.StreamsInfo.folders] |
call [pgfree] |
mov [error_proc], .error2 |
mov [clear_proc], .clear2 |
.ret2: |
mov ecx, [_7z.StreamsInfo.packSizes] |
call [pgfree] |
ret |
.error: |
call .free |
jmp _7z.ReadStreamsInfo.error |
.clear: |
call .free |
jmp _7z.ReadStreamsInfo.clear |
.error2: |
call .free |
jmp open_7z.header_error |
.clear2: |
call .free |
jmp open_7z.clear |
.free: |
mov ebx, [_7z.StreamsInfo.numFolders] |
.free2: |
dec ebx |
js @f |
mov ecx, [_7z.unpacked] |
mov ecx, [ecx+ebx*8+4] |
call [pgfree] |
jmp .free2 |
@@: |
mov ecx, [_7z.unpacked] |
cmp ecx, _7z.unpbuf |
jz @f |
call [pgfree] |
@@: |
ret |
_7z.GetUnPackSize: |
xor edx, edx |
mov eax, [ebx+_7z.StreamsInfo.numOutStreams] |
test eax, eax |
jz .ret |
.scan: |
dec eax |
js return.err |
push ecx |
mov ecx, [ebx+_7z.StreamsInfo.numBindPairs] |
mov edx, [ebx+_7z.StreamsInfo.bindPairs] |
@@: |
add edx, 8 |
dec ecx |
js .found |
cmp [edx-4], eax |
jnz @b |
pop ecx |
jmp .scan |
.found: |
mov [ebx+_7z.StreamsInfo.mainOutStream], eax |
mov ecx, [ebx+_7z.StreamsInfo.unpackSizes] |
mov edx, [ecx+eax*8+4] |
mov eax, [ecx+eax*8] |
pop ecx |
.ret: |
ret |
uglobal |
align 4 |
_7z.StreamsInfo: |
.numPackStreams dd ? |
.packSizes dd ? ; 8 bytes per item |
.numFolders dd ? |
.unpackCRCsDefined dd ? |
.unpackCRCs dd ? |
.folders dd ? |
.folders.size dd ? |
.folders.alloc dd ? |
.dataOffset dq ? |
.packCRCsDefined dd ? ; 1 byte per item |
.packCRCs dd ? ; 4 bytes per item |
virtual at 0 |
.numCoders dd ? |
.bindPairs dd ? |
.numBindPairs dd ? |
.packedStreams dd ? |
.numPackedStreams dd ? |
.startPackedStream dd ? |
.numOutStreams dd ? |
.unpackSizes dd ? |
.mainOutStream dd ? |
.numUnPackStreams dd ? |
.packOffset dq ? |
.fsz = $ |
end virtual |
.numSubStreams dd ? |
.SubStreamsSizes dd ? |
.SubStreamsCRCsDefined dd ? |
.SubStreamsCRCs dd ? |
.tmpSubStreamsCRCsDefined dd ? |
.tmpSubStreamsCRCs dd ? |
endg |
_7z.SkipData: |
call _7z.ReadNumber |
call _7z.SkipSize |
ret |
_7z.WaitAttribute: |
call _7z.ReadNumber |
cmp eax, ecx |
jz @f |
test eax, eax |
jz return.err |
call _7z.SkipData |
jmp _7z.WaitAttribute |
@@: |
ret |
_7z.ReadBoolVector2: |
; in: ebx->vector, ecx=size |
call _7z.ReadByte |
test al, al |
jz _7z.ReadBoolVector |
push ebx ecx |
jecxz .ret |
@@: |
mov byte [ebx], 1 |
inc ebx |
loop @b |
.ret: |
pop ecx ebx |
ret |
_7z.ReadBoolVector: |
push ebx ecx |
jecxz .ret |
xor eax, eax |
.1: |
add al, al |
jnz @f |
call _7z.ReadByte |
stc |
adc al, al |
@@: |
setc byte [ebx] |
inc ebx |
loop .1 |
.ret: |
pop ecx ebx |
ret |
_7z.ReadHashDigests: |
; in: ebx->bool vector, esi->crc, ecx=size |
call _7z.ReadBoolVector2 |
jecxz .ret |
.1: |
xor eax, eax |
cmp byte [ebx], al |
jz @f |
call _7z.ReadDword |
@@: |
mov [esi], eax |
add esi, 4 |
inc ebx |
loop .1 |
.ret: |
ret |
uglobal |
_7z.saved_edi dd ? |
_7z.saved_edi_end dd ? |
endg |
_7z.SwitchStream: |
mov eax, [bufend] |
mov [_7z.saved_edi_end], eax |
call _7z.ReadByte |
test al, al |
jnz @f |
ret |
@@: |
call _7z.ReadNum |
mov [_7z.saved_edi], edi |
cmp eax, [_7z.dataVectorSize] |
jae return.err |
shl eax, 3 |
add eax, [_7z.dataVector] |
mov edi, [eax+4] |
mov eax, [eax] |
add eax, edi |
mov [bufend], eax |
ret |
_7z.UnswitchStream: |
mov eax, [_7z.saved_edi_end] |
cmp eax, [bufend] |
jnz @f |
ret |
@@: |
mov [bufend], eax |
mov edi, [_7z.saved_edi] |
@@: |
ret |
; 6 ¯à®£à ¬¬¨á⮢ ¯ëâ «¨áì ª®¤ ¯®ïâì, |
; ¤¨ ¨§ ¨å á®èñ« á 㬠, ¨ ¨å ®áâ «®áì 5. |
_7z.ReadStreamsInfo: |
xor eax, eax |
mov [_7z.StreamsInfo.numPackStreams], eax |
mov [_7z.StreamsInfo.packSizes], eax |
mov [_7z.StreamsInfo.numFolders], eax |
mov [_7z.StreamsInfo.folders], eax |
mov [_7z.StreamsInfo.numSubStreams], eax |
mov [_7z.StreamsInfo.SubStreamsSizes], eax |
mov [_7z.StreamsInfo.tmpSubStreamsCRCsDefined], eax |
mov [error_proc], .error |
mov [clear_proc], .clear |
.mainloop: |
call _7z.ReadNum |
test eax, eax |
jz @b |
cmp eax, kSubStreamsInfo |
jz .SubStreamsInfo |
cmp eax, kUnPackInfo |
jz .UnpackInfo |
cmp eax, kPackInfo |
jnz return.err |
.PackInfo: |
cmp [_7z.StreamsInfo.numPackStreams], 0 |
jnz return.err |
call _7z.ReadNumber |
add eax, 0x20 |
adc edx, 0 |
mov dword [_7z.StreamsInfo.dataOffset], eax |
mov dword [_7z.StreamsInfo.dataOffset+4], edx |
call _7z.ReadNum |
mov [_7z.StreamsInfo.numPackStreams], eax |
mov ecx, kSize |
call _7z.WaitAttribute |
mov ecx, [_7z.StreamsInfo.numPackStreams] |
imul ecx, 8+1+4 |
jecxz .nostreams1 |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov [_7z.StreamsInfo.packSizes], eax |
mov ecx, [_7z.StreamsInfo.numPackStreams] |
push eax |
lea eax, [eax+ecx*8] |
mov [_7z.StreamsInfo.packCRCsDefined], eax |
mov ebx, eax |
add eax, ecx |
mov [_7z.StreamsInfo.packCRCs], eax |
@@: |
mov byte [ebx], 0 |
inc ebx |
loop @b |
pop eax |
.nostreams1: |
mov ecx, [_7z.StreamsInfo.numPackStreams] |
jecxz .noloop1 |
mov esi, eax |
@@: |
call _7z.ReadNumber |
mov [esi], eax |
mov [esi+4], edx |
add esi, 8 |
loop @b |
.noloop1: |
call _7z.ReadNum |
test eax, eax |
jz .mainloop |
cmp eax, kCRC |
jz .packInfo.crc |
call _7z.SkipData |
jmp .noloop1 |
.packInfo.crc: |
mov esi, [_7z.StreamsInfo.packCRCs] |
mov ebx, [_7z.StreamsInfo.packCRCsDefined] |
mov ecx, [_7z.StreamsInfo.numPackStreams] |
call _7z.ReadHashDigests |
jmp .noloop1 |
.UnpackInfo: |
cmp [_7z.StreamsInfo.folders], 0 |
jnz return.err |
mov ecx, kFolder |
call _7z.WaitAttribute |
call _7z.ReadNum |
mov ecx, eax |
mov [_7z.StreamsInfo.numFolders], eax |
call _7z.SwitchStream |
test ecx, ecx |
jz .nofolders |
push ecx |
mov ecx, 0x1000 |
and [_7z.StreamsInfo.folders.size], 0 |
mov [_7z.StreamsInfo.folders.alloc], ecx |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov [_7z.StreamsInfo.folders], eax |
pop ecx |
lea ecx, [ecx*9] |
call .folders_alloc |
xor ecx, ecx |
.folderloop: |
mov eax, [_7z.StreamsInfo.folders] |
push [_7z.StreamsInfo.folders.size] |
pop dword [eax+ecx*4] |
push ebp |
mov [_ebp], ebp |
push ecx |
mov ecx, _7z.StreamsInfo.fsz |
call .folders_alloc |
mov ebp, eax |
add ebp, [_7z.StreamsInfo.folders] |
call _7z.ReadNum |
mov [ebp+_7z.StreamsInfo.numCoders], eax |
test eax, eax |
jz return.err |
mov ecx, eax |
push ecx |
shl ecx, 2 |
sub ebp, [_7z.StreamsInfo.folders] |
call .folders_alloc |
add ebp, [_7z.StreamsInfo.folders] |
pop ecx |
add eax, [_7z.StreamsInfo.folders] |
@@: |
and dword [eax], 0 |
add eax, 4 |
loop @b |
push 0 ; numOutStreams |
push 0 ; numInStreams |
; [folders] = array of pointers to coders info |
; Format of coder info: |
; dd NextCoder |
; db MethodID.IDSize |
; times IDSize db MethodID.ID |
; dd NumInStreams |
; dd NumOutStreams |
; dd PropSize |
; times PropSize db Properties |
xor esi, esi |
.coders_loop: |
call _7z.ReadByte |
mov dl, al |
and eax, 0xF |
lea ecx, [eax+17] |
sub ebp, [_7z.StreamsInfo.folders] |
call .folders_alloc |
add ebp, [_7z.StreamsInfo.folders] |
push eax |
mov ecx, [_7z.StreamsInfo.folders] |
lea ebx, [ebp+esi*4+_7z.StreamsInfo.fsz] |
@@: |
cmp dword [ebx], 0 |
jz @f |
mov ebx, [ebx] |
add ebx, ecx |
jmp @b |
@@: |
mov [ebx], eax |
pop ebx |
add ebx, ecx |
and dword [ebx], 0 |
add ebx, 4 |
mov ecx, edx |
and ecx, 0xF |
mov byte [ebx], cl |
inc ebx |
jecxz .2 |
@@: |
call _7z.ReadByte |
mov byte [ebx], al |
inc ebx |
loop @b |
.2: |
test dl, 10h |
jnz .coder_multiple_streams |
mov dword [ebx], 1 |
mov dword [ebx+4], 1 |
inc dword [esp] |
inc dword [esp+4] |
jmp @f |
.coder_multiple_streams: |
call _7z.ReadNum |
mov [ebx], eax |
add dword [esp], eax |
call _7z.ReadNum |
mov [ebx+4], eax |
add dword [esp+4], eax |
; all currently defined 7z coders have 1 unpacked stream |
; moreover, all reasonable coders have 1 unpacked stream |
; so assume 1 output stream for unpacker - this simplifies decoding procedure |
cmp eax, 1 |
jnz return.err |
@@: |
and dword [ebx+8], 0 |
add ebx, 12 |
test dl, 20h |
jz .coder_no_properties |
call _7z.ReadNum |
test eax, eax |
jz .coder_no_properties |
mov [ebx-4], eax |
mov ecx, eax |
sub ebx, [_7z.StreamsInfo.folders] |
sub ebp, [_7z.StreamsInfo.folders] |
call .folders_alloc |
add ebp, [_7z.StreamsInfo.folders] |
add ebx, [_7z.StreamsInfo.folders] |
@@: |
call _7z.ReadByte |
mov [ebx], al |
inc ebx |
loop @b |
.coder_no_properties: |
test dl, dl |
js .coders_loop |
inc esi |
cmp esi, [ebp+_7z.StreamsInfo.numCoders] |
jb .coders_loop |
mov [ebp+_7z.StreamsInfo.numUnPackStreams], 1 |
mov eax, [esp+4] |
dec eax |
js return.err |
mov [ebp+_7z.StreamsInfo.numBindPairs], eax |
push eax |
mov ecx, eax |
shl ecx, 3 |
sub ebp, [_7z.StreamsInfo.folders] |
call .folders_alloc |
add ebp, [_7z.StreamsInfo.folders] |
mov [ebp+_7z.StreamsInfo.bindPairs], eax |
pop ecx |
jecxz .noloop3 |
mov esi, eax |
add esi, [_7z.StreamsInfo.folders] |
@@: |
call _7z.ReadNum |
mov [esi], eax |
cmp eax, [esp] |
jae return.err |
call _7z.ReadNum |
mov [esi+4], eax |
cmp eax, [esp+4] |
jae return.err |
add esi, 8 |
loop @b |
.noloop3: |
pop eax ; numInStreams |
pop edx ; numOutStreams |
mov [ebp+_7z.StreamsInfo.numOutStreams], edx |
sub eax, edx |
js return.err |
inc eax |
mov [ebp+_7z.StreamsInfo.numPackedStreams], eax |
mov ecx, eax |
push eax |
shl ecx, 2 |
sub ebp, [_7z.StreamsInfo.folders] |
call .folders_alloc |
add ebp, [_7z.StreamsInfo.folders] |
mov [ebp+_7z.StreamsInfo.packedStreams], eax |
pop ecx |
mov esi, eax |
add esi, [_7z.StreamsInfo.folders] |
cmp ecx, 1 |
jnz .multiplePackedStreams |
mov ebx, [ebp+_7z.StreamsInfo.bindPairs] |
add ebx, [_7z.StreamsInfo.folders] |
push edx |
xor ecx, ecx |
.3: |
push ebx |
mov edx, [ebp+_7z.StreamsInfo.numBindPairs] |
@@: |
dec edx |
js .5 |
cmp dword [ebx], ecx |
jz .4 |
add ebx, 8 |
jmp @b |
.4: |
pop ebx |
inc ecx |
jmp .3 |
.5: |
pop ebx |
pop edx |
mov [esi], ecx |
jmp .commonPackedStreams |
.multiplePackedStreams: |
call _7z.ReadNum |
mov [esi], eax |
add esi, 4 |
loop .multiplePackedStreams |
.commonPackedStreams: |
mov ecx, edx |
shl ecx, 3 |
sub ebp, [_7z.StreamsInfo.folders] |
call .folders_alloc |
add ebp, [_7z.StreamsInfo.folders] |
mov [ebp+_7z.StreamsInfo.unpackSizes], eax |
pop ecx |
xor edx, edx |
jecxz @f |
mov eax, [_7z.StreamsInfo.folders] |
mov eax, [eax+(ecx-1)*4] |
add eax, [_7z.StreamsInfo.folders] |
mov edx, [eax+_7z.StreamsInfo.numPackedStreams] |
add edx, [eax+_7z.StreamsInfo.startPackedStream] |
@@: |
mov [ebp+_7z.StreamsInfo.startPackedStream], edx |
pop ebp |
inc ecx |
cmp ecx, [_7z.StreamsInfo.numFolders] |
jb .folderloop |
.nofolders: |
call _7z.UnswitchStream |
mov ecx, kCodersUnPackSize |
call _7z.WaitAttribute |
xor ecx, ecx |
.6: |
cmp ecx, [_7z.StreamsInfo.numFolders] |
jae .7 |
mov eax, [_7z.StreamsInfo.folders] |
push ebp |
mov ebp, [eax+ecx*4] |
add ebp, eax |
mov esi, [ebp+_7z.StreamsInfo.numOutStreams] |
mov ebp, [ebp+_7z.StreamsInfo.unpackSizes] |
add ebp, [_7z.StreamsInfo.folders] |
@@: |
call _7z.ReadNumber |
mov dword [ebp], eax |
mov dword [ebp+4], edx |
add ebp, 8 |
dec esi |
jnz @b |
pop ebp |
inc ecx |
jmp .6 |
.7: |
; convert all relative addresses to pointers |
xor ecx, ecx |
mov edx, [_7z.StreamsInfo.folders] |
.8: |
cmp ecx, [_7z.StreamsInfo.numFolders] |
jae .9 |
lea eax, [edx+ecx*4] |
add [eax], edx |
mov eax, [eax] |
add [eax+_7z.StreamsInfo.bindPairs], edx |
add [eax+_7z.StreamsInfo.packedStreams], edx |
add [eax+_7z.StreamsInfo.unpackSizes], edx |
mov ebx, [eax+_7z.StreamsInfo.numCoders] |
add eax, _7z.StreamsInfo.fsz |
inc ecx |
.11: |
dec ebx |
js .8 |
push eax |
@@: |
cmp dword [eax], 0 |
jz @f |
add [eax], edx |
mov eax, [eax] |
jmp @b |
@@: |
pop eax |
add eax, 4 |
jmp .11 |
.9: |
; done |
mov eax, [_7z.StreamsInfo.numFolders] |
lea edx, [edx+eax*4] |
mov [_7z.StreamsInfo.unpackCRCsDefined], edx |
add edx, eax |
mov [_7z.StreamsInfo.unpackCRCs], edx |
@@: |
call _7z.ReadNum |
test eax, eax |
jz .mainloop |
cmp eax, kCRC |
jz .unpackInfo.crc |
call _7z.SkipData |
jmp @b |
.unpackInfo.crc: |
mov esi, [_7z.StreamsInfo.unpackCRCs] |
mov ebx, [_7z.StreamsInfo.unpackCRCsDefined] |
mov ecx, [_7z.StreamsInfo.numFolders] |
call _7z.ReadHashDigests |
jmp @b |
.SubStreamsInfo: |
cmp [_7z.StreamsInfo.numFolders], 0 |
jz return.err |
cmp [_7z.StreamsInfo.numSubStreams], 0 |
jnz return.err |
mov ebx, [_7z.StreamsInfo.folders] |
.ssloop1: |
call _7z.ReadNum |
cmp eax, kNumUnPackStream |
jz .NumUnPackStream |
cmp eax, kCRC |
jz .break1 |
cmp eax, kSize |
jz .break1 |
test eax, eax |
jz .break1 |
call _7z.SkipData |
jmp .ssloop1 |
.NumUnPackStream: |
xor ecx, ecx |
@@: |
call _7z.ReadNum |
mov edx, [ebx+ecx*4] |
mov [edx+_7z.StreamsInfo.numUnPackStreams], eax |
inc ecx |
cmp ecx, [_7z.StreamsInfo.numFolders] |
jb @b |
jmp .ssloop1 |
.break1: |
; calculate number of substreams and number of defined digests |
xor ecx, ecx |
xor ebp, ebp |
push 0 |
push eax |
xor eax, eax |
.ssloop2: |
mov edx, [ebx+ecx*4] |
mov edx, [edx+_7z.StreamsInfo.numUnPackStreams] |
cmp edx, 1 |
jz @f |
inc ebp |
@@: |
add eax, edx |
jc return.err |
cmp edx, 1 |
jnz @f |
push eax |
mov eax, [_7z.StreamsInfo.unpackCRCsDefined] |
cmp byte [eax+ecx], 0 |
pop eax |
jz @f |
xor edx, edx |
@@: |
add [esp+4], edx |
inc ecx |
cmp ecx, [_7z.StreamsInfo.numFolders] |
jb .ssloop2 |
mov [_7z.StreamsInfo.numSubStreams], eax |
imul ecx, eax, 4+8+1 |
jecxz .noss1 |
push eax |
call [pgalloc] |
pop ecx |
test eax, eax |
jz return.clear |
mov [_7z.StreamsInfo.SubStreamsSizes], eax |
lea eax, [eax+ecx*8] |
mov [_7z.StreamsInfo.SubStreamsCRCsDefined], eax |
add eax, ecx |
mov [_7z.StreamsInfo.SubStreamsCRCs], eax |
@@: |
dec eax |
mov byte [eax], 0 |
loop @b |
.noss1: |
mov ecx, [esp+4] |
jecxz @f |
imul ecx, 4+1 |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov [_7z.StreamsInfo.tmpSubStreamsCRCsDefined], eax |
add eax, [esp+4] |
mov [_7z.StreamsInfo.tmpSubStreamsCRCs], eax |
@@: |
test ebp, ebp |
jz @f |
cmp dword [esp], kSize |
jnz return.err |
@@: |
xor ecx, ecx |
mov ebp, [_7z.StreamsInfo.SubStreamsSizes] |
.ssloop3: |
mov ebx, [_7z.StreamsInfo.folders] |
mov ebx, [ebx+ecx*4] |
mov eax, [ebx+_7z.StreamsInfo.numUnPackStreams] |
dec eax |
js .sscont3 |
push 0 |
push 0 |
@@: |
dec eax |
js @f |
push eax |
call _7z.ReadNumber |
mov [ebp], eax |
mov [ebp+4], edx |
add ebp, 8 |
add [esp+4], eax |
adc [esp+8], edx |
jc return.err |
pop eax |
jmp @b |
@@: |
call _7z.GetUnPackSize |
sub eax, [esp] |
sbb edx, [esp+4] |
jc return.err |
mov [ebp], eax |
mov [ebp+4], edx |
add ebp, 8 |
add esp, 8 |
.sscont3: |
inc ecx |
cmp ecx, [_7z.StreamsInfo.numFolders] |
jb .ssloop3 |
pop eax |
cmp eax, kSize |
jnz @f |
call _7z.ReadNum |
@@: |
cmp eax, kCRC |
jz .sscrc |
test eax, eax |
jz .ssend |
call _7z.SkipData |
.ssloop4: |
call _7z.ReadNum |
jmp @b |
.sscrc: |
pop ecx |
push ecx |
mov ebx, [_7z.StreamsInfo.tmpSubStreamsCRCsDefined] |
mov esi, [_7z.StreamsInfo.tmpSubStreamsCRCs] |
call _7z.ReadHashDigests |
xor ecx, ecx ; index in out |
xor edx, edx ; index in tmp |
push -1 |
pop ebx ; index in folders |
.ssloop5: |
inc ebx |
cmp ebx, [_7z.StreamsInfo.numFolders] |
jae .ssloop4 |
mov eax, [_7z.StreamsInfo.folders] |
mov ebp, [eax+ebx*4] |
mov ebp, [ebp+_7z.StreamsInfo.numUnPackStreams] |
cmp ebp, 1 |
jnz @f |
mov eax, [_7z.StreamsInfo.unpackCRCsDefined] |
cmp byte [eax+ebx], 0 |
jz @f |
mov esi, [_7z.StreamsInfo.SubStreamsCRCsDefined] |
mov byte [esi+ecx], 1 |
mov esi, [_7z.StreamsInfo.unpackCRCs] |
mov eax, [esi+ebx*4] |
mov esi, [_7z.StreamsInfo.SubStreamsCRCs] |
mov [esi+ecx*4], eax |
inc ecx |
jmp .ssloop5 |
@@: |
dec ebp |
js .ssloop5 |
mov esi, [_7z.StreamsInfo.tmpSubStreamsCRCsDefined] |
mov al, [esi+edx] |
mov esi, [_7z.StreamsInfo.SubStreamsCRCsDefined] |
mov [esi+ecx], al |
mov esi, [_7z.StreamsInfo.tmpSubStreamsCRCs] |
mov eax, [esi+edx*4] |
mov esi, [_7z.StreamsInfo.SubStreamsCRCs] |
mov [esi+ecx*4], eax |
inc edx |
inc ecx |
jmp @b |
.ssend: |
mov ecx, [_7z.StreamsInfo.tmpSubStreamsCRCsDefined] |
call [pgfree] |
and [_7z.StreamsInfo.tmpSubStreamsCRCsDefined], 0 |
pop ecx |
jmp .mainloop |
.folders_alloc: |
push ecx |
add ecx, [_7z.StreamsInfo.folders.size] |
sub ecx, [_7z.StreamsInfo.folders.alloc] |
jbe @f |
push edx |
or ecx, 0xFFF |
inc ecx |
add ecx, [_7z.StreamsInfo.folders.alloc] |
mov [_7z.StreamsInfo.folders.alloc], ecx |
mov edx, [_7z.StreamsInfo.folders] |
call [pgrealloc] |
pop edx |
test eax, eax |
jz return.clear |
mov [_7z.StreamsInfo.folders], eax |
@@: |
pop ecx |
mov eax, [_7z.StreamsInfo.folders.size] |
add [_7z.StreamsInfo.folders.size], ecx |
ret |
.error: |
mov ecx, [_7z.StreamsInfo.packSizes] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [_7z.StreamsInfo.folders] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [_7z.StreamsInfo.SubStreamsSizes] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [_7z.StreamsInfo.tmpSubStreamsCRCsDefined] |
jecxz @f |
call [pgfree] |
@@: |
jmp open_7z.header_error |
.clear: |
mov ecx, [_7z.StreamsInfo.packSizes] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [_7z.StreamsInfo.folders] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [_7z.StreamsInfo.SubStreamsSizes] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [_7z.StreamsInfo.tmpSubStreamsCRCsDefined] |
jecxz @f |
call [pgfree] |
@@: |
jmp open_7z.clear |
uglobal |
align 4 |
_7z.decode.mainbuf dd ? |
_7z.decode.pStreams dd ? |
_7z.decode.pStreams_def rd 8 |
_7z.decode.outBufferSize dd ? |
_7z.decode.outBufferPtr dd ? |
_7z.decode.outBufferRead dd ? |
endg |
virtual at 0 |
streamInfo: |
.fullSize dq ? |
.fillBuf dd ? ; procedure which fills the buffer |
.bufSize dd ? |
.bufDataLen dd ? |
.bufPtr dd ? |
.size = $ |
end virtual |
_7z.decode: |
; in: ebx->folder, outBufferSize, outBufferPtr |
; N.B. We assume that every coder has 1 output (unpacked) stream. |
and [.mainbuf], 0 |
mov [.pStreams], .pStreams_def |
mov [error_proc], .error |
mov [clear_proc], .clear |
call .init |
and [.outBufferRead], 0 |
@@: |
push edi |
mov eax, [ebx+_7z.StreamsInfo.mainOutStream] |
mov esi, [.pStreams] |
mov eax, [esi+eax*4] |
call fillBuf |
mov ecx, [eax+streamInfo.bufSize] |
mov esi, [eax+streamInfo.bufPtr] |
mov edi, [.outBufferPtr] |
add edi, [.outBufferRead] |
add [.outBufferRead], ecx |
mov edx, ecx |
shr ecx, 2 |
rep movsd |
mov ecx, edx |
and ecx, 3 |
rep movsb |
pop edi |
mov eax, [.outBufferRead] |
cmp eax, [.outBufferSize] |
jb @b |
mov ecx, [.pStreams] |
cmp ecx, .pStreams_def |
jz @f |
call [pgfree] |
@@: |
mov ecx, [.mainbuf] |
jecxz @f |
call [pgfree] |
@@: |
mov [error_proc], _7z.ReadAndDecodePackedStreams.error |
mov [clear_proc], _7z.ReadAndDecodePackedStreams.clear |
ret |
.error: |
mov ecx, [.pStreams] |
cmp ecx, .pStreams_def |
jz @f |
call [pgfree] |
@@: |
mov ecx, [.mainbuf] |
jecxz @f |
call [pgfree] |
@@: |
jmp _7z.ReadAndDecodePackedStreams.error |
.clear: |
mov ecx, [.pStreams] |
cmp ecx, .pStreams_def |
jz @f |
call [pgfree] |
@@: |
mov ecx, [.mainbuf] |
jecxz @f |
call [pgfree] |
@@: |
jmp _7z.ReadAndDecodePackedStreams.clear |
.init: |
; We use stack to keep some information on streams, |
; to avoid stack overflow we limit possible number of coders. |
; Anyway, in real life maximum number of coders is 5 |
; (password protection filter + BCJ2 filter + 3 LZMA coders), |
; from command line user can define more coders, but |
; archive with, say, 32 coders is most likely bogus. |
cmp [ebx+_7z.StreamsInfo.numCoders], 128 |
ja return.err |
; allocate space for streams info array |
mov eax, .pStreams_def |
mov ecx, [ebx+_7z.StreamsInfo.numPackedStreams] |
add ecx, [ebx+_7z.StreamsInfo.numCoders] |
cmp ecx, 8 |
jbe @f |
shl ecx, 2 |
call [pgalloc] |
test eax, eax |
jz return.clear |
@@: |
mov [.pStreams], eax |
; calculate size of buffers required for decoders |
xor ecx, ecx |
push ecx |
mov ebp, [ebx+_7z.StreamsInfo.unpackSizes] |
.calcbufsz: |
; LZMA decoder: method ID = [size=03] 03 01 01, NumInStreams = NumOutStreams = 1 |
mov eax, [ebx+_7z.StreamsInfo.fsz+ecx*4] |
call _7z.GetCoder |
jnc .known_id |
.unknown_method_id: |
movzx esi, byte [eax+4] |
lea ecx, [eax+5] |
mov ebx, aUnknownMethod.z |
@@: |
dec esi |
js @f |
mov byte [ebx], ' ' |
inc ebx |
mov al, [ecx] |
push eax |
shr al, 4 |
cmp al, 10 |
sbb al, 69h |
das |
mov [ebx], al |
inc ebx |
pop eax |
and al, 0xF |
cmp al, 10 |
sbb al, 69h |
das |
mov [ebx], al |
inc ebx |
inc ecx |
jmp @b |
@@: |
mov byte [ebx], 0 |
push ContinueBtn |
push 1 |
push aUnknownMethod_ptr |
push 1 |
call [SayErr] |
jmp return.clear |
iglobal |
if lang eq ru |
aUnknownMethod db '¥¨§¢¥áâë© ¬¥â®¤:' |
else |
aUnknownMethod db 'Unknown method:' |
end if |
.z: |
times 16*3+1 db 0 |
aUnknownMethod_ptr dd aUnknownMethod |
endg |
.known_id: |
movzx esi, byte [eax+4] |
lea esi, [esi+eax+17] |
call [_7z.GetBufSizeTable+edx*4] |
add eax, 3 |
and al, not 3 |
add [esp], eax |
jc .nomem |
cmp dword [ebp+4], 0 |
jnz @f |
cmp dword [ebp], edx |
jae @f |
mov edx, [ebp] |
@@: |
add edx, 0xF |
and edx, not 0xF |
add [esp], edx |
jc .nomem |
add ebp, 8 |
inc ecx |
cmp ecx, [ebx+_7z.StreamsInfo.numCoders] |
jb .calcbufsz |
; add 4 pages for each of not binded input streams |
mov ecx, [ebx+_7z.StreamsInfo.numPackedStreams] |
shl ecx, 14 |
add [esp], ecx |
;; calculate free RAM |
; call [getfreemem] |
; sub eax, 64 ; keep at least 64 Kb of free RAM |
; jbe .nomem |
; pop ecx |
; push ecx |
; add ecx, 0x3FF |
; shr ecx, 10 |
; cmp eax, ecx |
; jae .memok |
jmp .memok |
.nomem: |
push ContinueBtn |
push 1 |
push aNoFreeRam_ptr |
push 1 |
call [SayErr] |
jmp return.clear |
.memok: |
; allocate streamInfos |
pop ecx |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov [.mainbuf], eax |
; initialize streamInfos for decoders |
xor ecx, ecx |
mov ebp, [ebx+_7z.StreamsInfo.unpackSizes] |
mov edx, [.pStreams] |
.init1: |
mov [edx], eax |
add edx, 4 |
push edx |
push dword [ebp] |
pop dword [eax] |
push dword [ebp+4] |
pop dword [eax+4] |
and dword [eax+streamInfo.size], 0 |
push eax |
mov eax, [ebx+_7z.StreamsInfo.fsz+ecx*4] |
call _7z.GetCoder |
movzx esi, byte [eax+4] |
lea esi, [esi+eax+17] |
call [_7z.GetBufSizeTable+edx*4] |
pop esi |
push esi |
add eax, 3 |
and al, not 3 |
add [esp], eax |
pop [esi+streamInfo.bufPtr] |
push [esi+streamInfo.bufPtr] |
cmp dword [ebp+4], 0 |
jnz @f |
cmp dword [ebp], edx |
jae @f |
mov edx, [ebp] |
@@: |
add edx, 0xF |
and edx, not 0xF |
mov [esi+streamInfo.bufSize], edx |
and [esi+streamInfo.bufDataLen], 0 |
pop eax |
add eax, edx |
pop edx |
add ebp, 8 |
inc ecx |
cmp ecx, [ebx+_7z.StreamsInfo.numCoders] |
jb .init1 |
; initialize streamInfos for input streams |
xor ecx, ecx |
@@: |
mov [edx], eax |
add edx, 4 |
mov esi, [_7z.CurInStream] |
inc [_7z.CurInStream] |
shl esi, 3 |
add esi, [_7z.StreamsInfo.packSizes] |
push dword [esi] |
pop dword [eax] |
push dword [esi+4] |
pop dword [eax+4] |
mov [eax+streamInfo.fillBuf], fillBufFromInStream |
lea esi, [eax+streamInfo.size+8] |
mov [eax+streamInfo.bufPtr], esi |
mov [eax+streamInfo.bufSize], 0x4000 - streamInfo.size - 8 |
and [eax+streamInfo.bufDataLen], 0 |
mov esi, dword [_7z.StreamsInfo.dataOffset] |
mov dword [eax+streamInfo.size], esi |
mov esi, dword [_7z.StreamsInfo.dataOffset+4] |
mov dword [eax+streamInfo.size+4], esi |
mov esi, [eax] |
add dword [_7z.StreamsInfo.dataOffset], esi |
mov esi, [eax+4] |
adc dword [_7z.StreamsInfo.dataOffset+4], esi |
add eax, 0x4000 |
inc ecx |
cmp ecx, [ebx+_7z.StreamsInfo.numPackedStreams] |
jb @b |
; initialize links between streams |
push -1 |
mov edx, [ebx+_7z.StreamsInfo.mainOutStream] |
xor ecx, ecx |
.init_links: |
mov eax, [ebx+_7z.StreamsInfo.fsz+edx*4] |
movzx esi, byte [eax+4] |
cmp ecx, [eax+esi+5] |
jb @f |
pop ecx |
cmp ecx, -1 |
jz .inited_links |
pop edx |
jmp .init_links |
@@: |
push edx |
push ecx |
@@: |
dec edx |
js @f |
mov eax, [ebx+_7z.StreamsInfo.fsz+edx*4] |
movzx esi, byte [eax+4] |
add ecx, [eax+esi+5] |
jmp @b |
@@: |
mov esi, [ebx+_7z.StreamsInfo.bindPairs] |
mov edx, [ebx+_7z.StreamsInfo.numBindPairs] |
@@: |
add esi, 8 |
dec edx |
js .link_to_in |
cmp ecx, [esi-8] |
jnz @b |
pop ecx |
pop edx |
mov eax, [.pStreams] |
mov eax, [eax+edx*4] |
lea eax, [eax+streamInfo.size+ecx*4] |
push edx |
inc ecx |
push ecx |
mov edx, [esi-4] |
mov ecx, [.pStreams] |
mov ecx, [ecx+edx*4] |
mov [eax], ecx |
cmp dword [ecx+streamInfo.size], 0 |
jnz return.err |
xor ecx, ecx |
jmp .init_links |
.link_to_in: |
mov esi, [ebx+_7z.StreamsInfo.packedStreams] |
mov edx, [ebx+_7z.StreamsInfo.numPackedStreams] |
@@: |
dec edx |
js return.err |
cmp ecx, [esi+edx*4] |
jnz @b |
add edx, [ebx+_7z.StreamsInfo.numCoders] |
mov esi, [.pStreams] |
mov eax, [esi+edx*4] |
pop ecx |
pop edx |
mov esi, [esi+edx*4] |
mov [esi+streamInfo.size+ecx*4], eax |
inc ecx |
jmp .init_links |
.inited_links: |
; initialize all decoders |
; bool zzz_init_decoder(stream_info* ebp, esi->params, [esi-4]=params_size); |
xor ecx, ecx |
.init_decoders: |
mov eax, [ebx+_7z.StreamsInfo.fsz+ecx*4] |
call _7z.GetCoder |
movzx esi, byte [eax+4] |
mov ebp, [.pStreams] |
mov ebp, [ebp+ecx*4] |
cmp dword [esi+eax], 0 |
jz @f |
cmp dword [ebp+streamInfo.size], 0 |
jz return.err |
@@: |
lea esi, [esi+eax+17] |
push ebx ecx edi |
xor ebx, ebx |
call [_7z.InitTable+edx*4] |
pop edi ecx ebx |
inc ecx |
cmp ecx, [ebx+_7z.StreamsInfo.numCoders] |
jb .init_decoders |
ret |
fillBuf: |
and [eax+streamInfo.bufDataLen], 0 |
fillBufNozero: |
pushad |
mov edx, [eax+streamInfo.bufSize] |
sub edx, [eax+streamInfo.bufDataLen] |
cmp dword [eax+streamInfo.fullSize+4], 0 |
jnz .full |
mov ecx, dword [eax+streamInfo.fullSize] |
cmp ecx, edx |
jbe @f |
.full: |
mov ecx, edx |
@@: |
sub dword [eax+streamInfo.fullSize], ecx |
sbb dword [eax+streamInfo.fullSize+4], 0 |
mov edi, [eax+streamInfo.bufPtr] |
add edi, [eax+streamInfo.bufDataLen] |
add [eax+streamInfo.bufDataLen], ecx |
jmp [eax+streamInfo.fillBuf] |
fillBufFromInStream: |
push eax |
push dword [eax+streamInfo.size+4] |
push dword [eax+streamInfo.size] |
push 0 |
push [inStream] |
call [seek] |
pop eax |
push eax |
push ecx |
push edi |
push [inStream] |
call [read] |
cmp eax, ecx |
pop eax |
jnz .error |
add dword [eax+streamInfo.size], ecx |
adc dword [eax+streamInfo.size+4], 0 |
popad |
ret |
.error: |
push ContinueBtn |
push 1 |
push aReadError_ptr |
push 1 |
call [SayErr] |
jmp return.clear |
_7z.GetCoder: |
; in: eax->coder |
; out: edx = coder type |
xor edx, edx |
; Copy decoder: method ID = [size=01] 00, NumInStreams = NumOutStreams = 1 |
cmp word [eax+4], 0x0001 |
jnz @f |
cmp dword [eax+6], 1 |
jz .ret |
@@: |
inc edx |
; LZMA decoder: method ID = [size=03] 03 01 01, NumInStreams = NumOutStreams = 1 |
cmp dword [eax+4], 0x01010303 |
jnz @f |
cmp dword [eax+8], 1 |
jz .ret |
@@: |
inc edx |
; PPMD decoder: method ID = [size=03] 03 04 01, NumInStreams = NumOutStreams = 1 |
cmp dword [eax+4], 0x01040303 |
jnz @f |
cmp dword [eax+8], 1 |
jz .ret |
@@: |
inc edx |
; BCJ filter: method ID = [size=04] 03 03 01 03, NumInStreams = NumOutStreams = 1 |
cmp byte [eax+4], 4 |
jnz @f |
cmp dword [eax+5], 0x03010303 |
jnz @f |
cmp dword [eax+9], 1 |
jz .ret |
@@: |
inc edx |
; BCJ2 filter: method ID = [size=04] 03 03 01 1B, NumInStreams = 4, NumOutStreams = 1 |
cmp byte [eax+4], 4 |
jnz @f |
cmp dword [eax+5], 0x1B010303 |
jnz @f |
cmp dword [eax+9], 4 |
jz .ret |
@@: |
inc edx |
; 7z-AES cryptor: method ID = [size=04] 06 F1 07 01, NumInStreams = NumOutStreams = 1 |
cmp byte [eax+4], 4 |
jnz @f |
cmp dword [eax+5], 0x0107F106 |
jnz @f |
cmp dword [eax+9], 1 |
jz .ret |
@@: |
stc |
.ret: |
ret |
iglobal |
align 4 |
label _7z.GetBufSizeTable dword |
dd copy_get_buf_size |
dd lzma_get_buf_size |
dd ppmd_get_buf_size |
dd bcj_get_buf_size |
dd bcj2_get_buf_size |
dd aes7z_get_buf_size |
label _7z.InitTable dword |
dd copy_init_decoder |
dd lzma_init_decoder |
dd ppmd_init_decoder |
dd bcj_init_decoder |
dd bcj2_init_decoder |
dd aes7z_init_decoder |
endg |
copy_get_buf_size: |
mov eax, streamInfo.size+8 |
mov edx, 0x10000 |
ret |
copy_init_decoder: |
mov [ebp+streamInfo.fillBuf], copy_fillBuf |
and dword [ebp+streamInfo.size+4], 0 |
ret |
copy_fillBuf: |
push eax |
mov esi, [eax+streamInfo.size+4] |
mov eax, [eax+streamInfo.size] |
.redo: |
push ecx |
mov edx, [eax+streamInfo.bufDataLen] |
sub edx, esi |
cmp ecx, edx |
jb @f |
mov ecx, edx |
@@: |
sub [esp], ecx |
add esi, [eax+streamInfo.bufPtr] |
mov edx, ecx |
shr ecx, 2 |
rep movsd |
mov ecx, edx |
and ecx, 3 |
rep movsb |
pop ecx |
jecxz .done |
cmp dword [eax+streamInfo.fullSize+4], 0 |
jnz @f |
cmp dword [eax+streamInfo.fullSize], ecx |
jb return.err |
@@: |
call fillBuf |
xor esi, esi |
jmp .redo |
.done: |
sub esi, [eax+streamInfo.bufPtr] |
pop eax |
mov [eax+streamInfo.size+4], esi |
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 |
jnz .pseudo |
lea esi, [eax+file_in_7z.attr] |
movsd |
xor eax, eax |
stosd |
add esi, -(file_in_7z.attr+4) + file_in_7z.CreationTime |
mov ecx, 8 |
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 |
file_handle_7z: |
.type dd ? |
.context dd ? |
.pos dq ? |
.base dd ? ; handle of archive |
.item dd ? ; pointer to file_in_7z |
.mainStream dd ? ; (pointer in context) |
.bError db ? |
rb 3 |
.size = $ |
end virtual |
iglobal |
align 4 |
handle_table_7z dd handle_table_7z,handle_table_7z |
endg |
; ebp=hPlugin, eax->item, edi=mode |
open_file_7z: |
cmp [eax+file_in_7z.bHasStream], 0 |
jnz @f |
mov eax, empty_7z_handle |
ret |
@@: |
mov ecx, [ebp+handle_7z.password_len] |
inc ecx |
setnz [bPasswordDefined] |
jz @f |
dec ecx |
lea esi, [ebp+handle_7z.password] |
push edi |
mov edi, password_unicode |
shr ecx, 1 |
rep movsd |
adc ecx, ecx |
rep movsw |
pop edi |
@@: |
mov [hOut], ecx |
mov [_7z.decode.mainbuf], ecx |
mov ecx, [ebp+handle_7z.host] |
mov [inStream], ecx |
mov [_7z.decode.pStreams], _7z.decode.pStreams_def |
push eax |
mov [_esp], esp |
mov [_ebp], ebp |
mov [error_proc], .error |
mov [clear_proc], .clear |
mov ebx, [ebp+handle_7z.folders] |
mov ecx, [eax+file_in_7z.folder] |
cmp [ebp+handle_7z.last_folder], ecx |
jnz .nolast |
mov edx, dword [eax+file_in_7z.folderStart] |
sub edx, dword [ebp+handle_7z.last_pos] |
mov esi, dword [eax+file_in_7z.folderStart+4] |
sbb esi, dword [ebp+handle_7z.last_pos+4] |
jb .nolast |
xor ecx, ecx |
xchg ecx, [ebp+handle_7z.last_context] |
mov [_7z.decode.mainbuf], ecx |
mov eax, [ebp+handle_7z.last_main_stream] |
mov dword [eax+streamInfo.fullSize], edx |
mov dword [eax+streamInfo.fullSize+4], esi |
or [ebp+handle_7z.last_folder], -1 |
pop esi |
push esi |
jmp .commonl |
.nolast: |
mov ebx, [ebx+ecx*4] |
mov eax, [ebx+_7z.StreamsInfo.startPackedStream] |
mov [_7z.CurInStream], eax |
mov eax, dword [ebx+_7z.StreamsInfo.packOffset] |
mov dword [_7z.StreamsInfo.dataOffset], eax |
mov eax, dword [ebx+_7z.StreamsInfo.packOffset+4] |
mov dword [_7z.StreamsInfo.dataOffset+4], eax |
mov eax, [ebp+handle_7z.packSizes] |
mov [_7z.StreamsInfo.packSizes], eax |
push ebp |
call _7z.decode.init |
pop ebp |
mov eax, [ebx+_7z.StreamsInfo.mainOutStream] |
mov esi, [_7z.decode.pStreams] |
mov eax, [esi+eax*4] |
pop esi |
push esi |
mov ecx, dword [esi+file_in_7z.folderStart] |
mov dword [eax+streamInfo.fullSize], ecx |
mov ecx, dword [esi+file_in_7z.folderStart+4] |
mov dword [eax+streamInfo.fullSize+4], ecx |
.commonl: |
call skip_7z |
mov ecx, dword [esi+file_in_7z.UnPackSize] |
mov dword [eax+streamInfo.fullSize], ecx |
mov edx, dword [esi+file_in_7z.UnPackSize+4] |
mov dword [eax+streamInfo.fullSize+4], edx |
test edx, edx |
jnz .nomemstream |
if defined LIMIT_FOR_MEM_STREAM |
cmp ecx, LIMIT_FOR_MEM_STREAM |
ja .nomemstream |
end if |
push eax ecx |
add ecx, 0x3FF |
shr ecx, 10 ; get size in Kb |
call [getfreemem] |
shr eax, 2 |
cmp ecx, eax |
pop ecx eax |
ja .nomemstream |
; create memory stream and unpack to memory |
push eax ecx |
add ecx, mem_stream.buf |
call [pgalloc] |
test eax, eax |
jz return.clear |
mov edi, eax |
pop ecx |
push edi |
mov [hOut], eax |
xor eax, eax ; type_mem_stream |
stosd ; mem_stream.type |
mov eax, ecx |
stosd ; mem_stream.size |
xor eax, eax |
stosd ; mem_stream.pos |
mov eax, [esp+4] |
push esi |
push ecx edi |
call read_7z_to_buf |
pop esi ecx |
mov ebx, [esp+12] |
cmp [ebx+file_in_7z.bCRCDefined], 0 |
jz @f |
call crc |
cmp eax, [ebx+file_in_7z.FileCRC] |
jnz return.err |
@@: |
pop esi |
xor ecx, ecx |
xchg ecx, [_7z.decode.mainbuf] |
xchg ecx, [ebp+handle_7z.last_context] |
jecxz @f |
call [pgfree] |
@@: |
and [hOut], 0 |
mov eax, [esi+file_in_7z.folder] |
mov [ebp+handle_7z.last_folder], eax |
mov eax, [esp+4] |
mov [ebp+handle_7z.last_main_stream], eax |
mov ecx, dword [esi+file_in_7z.UnPackSize] |
add ecx, dword [esi+file_in_7z.folderStart] |
mov dword [ebp+handle_7z.last_pos], ecx |
mov ecx, dword [esi+file_in_7z.UnPackSize+4] |
adc ecx, dword [esi+file_in_7z.folderStart+4] |
mov dword [ebp+handle_7z.last_pos+4], ecx |
call .done |
pop eax edi ecx |
ret |
.nomemstream: |
mov edi, eax |
push esi |
mov esi, handle_table_7z |
push file_handle_7z.size |
pop ecx |
call alloc_handle |
pop esi |
test eax, eax |
jz .clear |
mov [eax+file_handle_7z.type], type_7z |
xor edx, edx |
mov dword [eax+file_handle_7z.pos], edx |
mov dword [eax+file_handle_7z.pos+4], edx |
mov [eax+file_handle_7z.bError], dl |
xchg edx, [_7z.decode.mainbuf] |
mov [eax+file_handle_7z.context], edx |
mov [eax+file_handle_7z.mainStream], edi |
mov [eax+file_handle_7z.base], ebp |
mov [eax+file_handle_7z.item], esi |
push eax |
call .done |
pop eax ecx |
ret |
.done: |
cmp [bPasswordDefined], 0 |
jz @f |
mov ecx, [password_size] |
mov [ebp+handle_7z.password_len], ecx |
mov esi, password_unicode |
lea edi, [ebp+handle_7z.password] |
shr ecx, 1 |
rep movsd |
adc ecx, ecx |
rep movsw |
@@: |
jmp .clear |
.error: |
cmp [bPasswordDefined], 0 |
jz .realerror |
push CancelPassBtn |
push 2 |
push aArchiveDataErrorPass_ptr |
push 1 |
call [SayErr] |
cmp al, 1 |
jnz .clear |
; user wants to re-enter password |
call .clear |
pop eax |
jmp open_file_7z |
.realerror: |
push ContinueBtn |
push 1 |
push aArchiveDataError_ptr |
push 1 |
call [SayErr] |
.clear: |
mov ecx, [_7z.decode.pStreams] |
cmp ecx, _7z.decode.pStreams_def |
jz @f |
call [pgfree] |
@@: |
mov ecx, [_7z.decode.mainbuf] |
jecxz @f |
call [pgfree] |
@@: |
mov ecx, [hOut] |
jecxz @f |
call [pgfree] |
@@: |
cmp esp, [_esp] |
jnz @f |
pop eax |
@@: |
xor eax, eax |
ret |
read_7z_to_buf: |
mov esi, [eax+streamInfo.bufDataLen] |
cmp esi, [eax+streamInfo.bufSize] |
jnz @f |
xor esi, esi |
mov [eax+streamInfo.bufDataLen], esi |
@@: |
call fillBufNozero |
mov ecx, [eax+streamInfo.bufDataLen] |
sub ecx, esi |
add esi, [eax+streamInfo.bufPtr] |
mov edx, ecx |
shr ecx, 2 |
rep movsd |
mov ecx, edx |
and ecx, 3 |
rep movsb |
cmp dword [eax+streamInfo.fullSize], 0 |
jnz read_7z_to_buf |
ret |
skip_7z: |
push edx |
mov edx, [eax+streamInfo.bufDataLen] |
cmp edx, [eax+streamInfo.bufSize] |
jnz @f |
and [eax+streamInfo.bufDataLen], 0 |
@@: |
pop edx |
call fillBufNozero |
cmp dword [eax+streamInfo.fullSize], 0 |
jnz skip_7z |
cmp dword [eax+streamInfo.fullSize+4], 0 |
jnz skip_7z |
ret |
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size); |
read_7z: |
mov eax, [ebx+file_handle_7z.mainStream] |
test eax, eax |
jz .ret ; empty stream - return 0 bytes read |
cmp [ebx+file_handle_7z.bError], 0 |
jnz .reterr |
mov ecx, [ebx+file_handle_7z.base] |
mov ecx, [ecx+handle_7z.host] |
mov [inStream], ecx |
mov edi, [esp+8] |
mov ecx, [esp+12] |
mov dword [eax+streamInfo.fullSize], ecx |
and dword [eax+streamInfo.fullSize+4], 0 |
jecxz .nodata |
mov [_esp], esp |
mov [_ebp], ebp |
mov [error_proc], .error |
mov [clear_proc], .clear ; should not be called |
mov esi, [ebx+file_handle_7z.item] |
mov edx, dword [esi+file_in_7z.UnPackSize] |
mov esi, dword [esi+file_in_7z.UnPackSize+4] |
sub edx, dword [ebx+file_handle_7z.pos] |
sbb esi, dword [ebx+file_handle_7z.pos+4] |
jnz .do |
cmp edx, ecx |
jae .do |
mov dword [eax+streamInfo.fullSize], edx |
.do: |
call read_7z_to_buf |
.nodata: |
sub edi, [esp+8] |
mov eax, edi |
add dword [ebx+file_handle_7z.pos], eax |
adc dword [ebx+file_handle_7z.pos+4], 0 |
.ret: |
ret 12 |
.error: |
.clear: |
mov ebx, [esp+4] |
mov [ebx+file_handle_7z.bError], 1 |
push ContinueBtn |
push 1 |
push aArchiveDataError_ptr |
push 1 |
call [SayErr] |
.reterr: |
or eax, -1 |
ret 12 |
; void __stdcall setpos(HANDLE hFile, __int64 pos); |
setpos_7z: |
cmp [ebx+file_handle_7z.context], 0 |
jz .ret |
mov edi, [ebx+file_handle_7z.base] |
mov ecx, [edi+handle_7z.host] |
mov [inStream], ecx |
mov [_esp], esp |
mov [_ebp], ebp |
mov [error_proc], read_7z.error |
mov [clear_proc], read_7z.clear ; should not be called |
cmp [ebx+file_handle_7z.bError], 0 |
jnz .backward ; if was error, force reinitialization |
mov ecx, [esp+8] |
mov edx, [esp+12] |
sub ecx, dword [ebx+file_handle_7z.pos] |
sbb edx, dword [ebx+file_handle_7z.pos+4] |
jb .backward |
; move forward - skip some data |
mov eax, [ebx+file_handle_7z.mainStream] |
mov dword [eax+streamInfo.fullSize], ecx |
mov dword [eax+streamInfo.fullSize+4], edx |
call skip_7z |
add dword [ebx+file_handle_7z.pos], ecx |
adc dword [ebx+file_handle_7z.pos], edx |
.ret: |
ret 12 |
.backward: |
; move backward - reinitialize and skip start data |
mov [ebx+file_handle_7z.bError], 0 |
mov ebp, [ebx+file_handle_7z.context] |
mov eax, [ebx+file_handle_7z.item] |
mov ebx, [edi+handle_7z.folders] |
mov eax, [eax+file_in_7z.folder] |
mov ebx, [ebx+eax*4] |
; initialize streamInfos for decoders |
xor ecx, ecx |
mov esi, [ebx+_7z.StreamsInfo.unpackSizes] |
@@: |
lodsd |
mov [ebp], eax |
lodsd |
mov [ebp+4], eax |
and [ebp+streamInfo.bufDataLen], 0 |
push esi |
mov eax, [ebx+_7z.StreamsInfo.fsz+ecx*4] |
call _7z.GetCoder |
movzx esi, byte [eax+4] |
lea esi, [esi+eax+17] |
push ebx ecx edi |
mov bl, 1 |
call [_7z.InitTable+edx*4] |
pop edi ecx ebx esi |
mov edx, [ebp+streamInfo.bufSize] |
mov ebp, [ebp+streamInfo.bufPtr] |
add ebp, edx |
inc ecx |
cmp ecx, [ebx+_7z.StreamsInfo.numCoders] |
jb @b |
; initialize streamInfos for input streams |
xor ecx, ecx |
mov esi, [ebx+_7z.StreamsInfo.startPackedStream] |
shl esi, 3 |
add esi, [edi+handle_7z.packSizes] |
mov edi, dword [ebx+_7z.StreamsInfo.packOffset] |
mov edx, dword [ebx+_7z.StreamsInfo.packOffset+4] |
@@: |
mov dword [ebp+streamInfo.size], edi |
mov dword [ebp+streamInfo.size+4], edx |
and [ebp+streamInfo.bufDataLen], 0 |
lodsd |
add edi, eax |
mov [ebp], eax |
lodsd |
adc edx, eax |
mov [ebp+4], eax |
add ebp, 0x4000 |
inc ecx |
cmp ecx, [ebx+_7z.StreamsInfo.numPackedStreams] |
jb @b |
mov ebx, [esp+4] |
mov esi, [ebx+file_handle_7z.item] |
mov eax, [ebx+file_handle_7z.mainStream] |
mov ecx, dword [esi+file_in_7z.folderStart] |
add ecx, [esp+8] |
mov dword [eax+streamInfo.fullSize], ecx |
mov ecx, dword [esi+file_in_7z.folderStart+4] |
adc ecx, [esp+12] |
mov dword [eax+streamInfo.fullSize+4], ecx |
and dword [ebx+file_handle_7z.pos], 0 |
and dword [ebx+file_handle_7z.pos+4], 0 |
and [eax+streamInfo.bufDataLen], 0 |
call skip_7z |
mov eax, [esp+8] |
mov dword [ebx+file_handle_7z.pos], eax |
mov eax, [esp+12] |
mov dword [ebx+file_handle_7z.pos+4], eax |
ret 12 |
close_file_7z: |
mov ecx, [ebx+file_handle_7z.context] |
jecxz .ret |
cmp [ebx+file_handle_7z.bError], 0 |
jnz @f |
push ebp |
mov ebp, [ebx+file_handle_7z.base] |
xchg ecx, [ebp+handle_7z.last_context] |
mov eax, [ebx+file_handle_7z.item] |
mov edx, [eax+file_in_7z.folder] |
mov [ebp+handle_7z.last_folder], edx |
mov edx, [ebx+file_handle_7z.mainStream] |
mov [ebp+handle_7z.last_main_stream], edx |
mov edx, dword [eax+file_in_7z.folderStart+4] |
mov eax, dword [eax+file_in_7z.folderStart] |
add eax, dword [ebx+file_handle_7z.pos] |
adc edx, dword [ebx+file_handle_7z.pos+4] |
mov dword [ebp+handle_7z.last_pos], eax |
mov dword [ebp+handle_7z.last_pos+4], edx |
pop ebp |
@@: |
jecxz @f |
call [pgfree] |
@@: |
mov esi, ebx |
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 |
/programs/fs/kfar/trunk/kfar_arc/7zaes.inc |
---|
0,0 → 1,216 |
; Password handling in 7-Zip: "7zAES" filter (SHA256 + AES256). |
; Ported from C++ sources of 7-Zip (c) Igor Pavlov. |
aes7z_decoder: |
virtual at 0 |
.outStream rb streamInfo.size |
.inStream dd ? |
.inLen dd ? |
.inPtr dd ? |
.bufRest dd ? |
; key data |
.NumCyclesPower dd ? |
.SaltSize dd ? |
.Salt rb 16 |
; AES data |
.iv rb 16 |
.Key rb 32 |
.nr dd ? |
.KeyExpanded rb 32*15 |
.size = $ |
end virtual |
.fillBuf: |
mov esi, [eax+.inPtr] |
mov ebp, eax |
add edi, [eax+.bufRest] |
sub ecx, [eax+.bufRest] |
js .rest1 |
and [eax+.bufRest], 0 |
.mainloop: |
test ecx, ecx |
jz .done |
sub [ebp+.inLen], 16 |
js .refill |
.refilled: |
push esi edi ecx |
mov ebx, edi |
lea edi, [ebp+.nr] |
call aes_decode |
pop ecx edi esi |
mov eax, dword [ebp+.iv] |
xor [edi], eax |
lodsd |
mov dword [ebp+.iv], eax |
mov eax, dword [ebp+.iv+4] |
xor [edi+4], eax |
lodsd |
mov dword [ebp+.iv+4], eax |
mov eax, dword [ebp+.iv+8] |
xor [edi+8], eax |
lodsd |
mov dword [ebp+.iv+8], eax |
mov eax, dword [ebp+.iv+12] |
xor [edi+12], eax |
lodsd |
mov dword [ebp+.iv+12], eax |
add edi, 16 |
sub ecx, 16 |
jns .mainloop |
.rest1: |
neg ecx |
mov [ebp+.bufRest], ecx |
.done: |
mov [ebp+.inPtr], esi |
popad |
ret |
.refill: |
mov edx, [ebp+.inLen] |
add edx, 16 |
jnz .rest |
js return.err |
mov eax, [ebp+.inStream] |
call fillBuf |
mov edx, [eax+streamInfo.bufDataLen] |
test edx, edx |
jz return.err |
mov esi, [eax+streamInfo.bufPtr] |
mov [ebp+.inLen], edx |
sub [ebp+.inLen], 16 |
jns .refilled |
.rest: |
; ASSERT([eax+streamInfo.fullSize] == 0); |
sub edx, ecx |
jb return.err |
add ecx, edx |
rep movsb |
mov [ebp+.bufRest], edx |
jmp .done |
aes7z_get_buf_size: |
mov eax, aes7z_decoder.size |
mov edx, 0x4000 |
ret |
aes7z_init_decoder: |
; zero all |
xor eax, eax |
mov [ebp+aes7z_decoder.inLen], eax |
mov [ebp+aes7z_decoder.bufRest], eax |
mov [ebp+aes7z_decoder.NumCyclesPower], eax |
mov [ebp+aes7z_decoder.SaltSize], eax |
lea edi, [ebp+aes7z_decoder.Salt] |
push 8 |
pop ecx |
rep stosd ; zero .Salt and .iv |
mov [ebp+streamInfo.fillBuf], aes7z_decoder.fillBuf |
; parse parameters |
cmp dword [esi-4], eax |
jz .parok ; no parameters - OK |
lodsb |
mov cl, al |
and al, 0x3F |
mov byte [ebp+aes7z_decoder.NumCyclesPower], al |
test cl, 0xC0 |
jz .parok |
test cl, 0x80 |
setnz byte [ebp+aes7z_decoder.SaltSize] |
shr cl, 6 |
and ecx, 1 |
cmp dword [esi-1-4], 2 |
jb return.err |
lodsb |
mov dl, al |
shr al, 4 |
add byte [ebp+aes7z_decoder.SaltSize], al |
and edx, 0xF |
add ecx, edx |
lea edx, [ecx+2] |
push ecx |
mov ecx, [ebp+aes7z_decoder.SaltSize] |
add edx, ecx |
cmp dword [esi-2-4], edx |
jb return.err |
lea edi, [ebp+aes7z_decoder.Salt] |
rep movsb |
pop ecx |
lea edi, [ebp+aes7z_decoder.iv] |
rep movsb |
.parok: |
test bl, bl |
jnz .ret ; if reinitializing - all calculations have been already done |
call query_password |
jz return.clear |
;.CalculateDigest: |
mov cl, byte [ebp+aes7z_decoder.NumCyclesPower] |
cmp cl, 0x3F |
jnz .sha |
lea edi, [ebp+aes7z_decoder.Key] |
mov ecx, [ebp+aes7z_decoder.SaltSize] |
push 32 |
pop edx |
sub edx, ecx |
lea esi, [ebp+aes7z_decoder.Salt] |
rep movsb |
mov ecx, [password_size] |
add ecx, ecx |
cmp ecx, edx |
jbe @f |
mov ecx, edx |
@@: |
sub edx, ecx |
mov esi, password_unicode |
rep movsb |
mov ecx, edx |
xor eax, eax |
rep stosb |
jmp .setkey |
.sha: |
cmp cl, 32 |
jb .normal |
push 1 |
shl dword [esp], cl |
push 0 |
jmp @f |
.normal: |
push 0 |
push 1 |
shl dword [esp], cl |
@@: |
push 0 |
push 0 |
call sha256_init |
.loop: |
lea esi, [ebp+aes7z_decoder.Salt] |
mov edx, [ebp+aes7z_decoder.SaltSize] |
call sha256_update |
mov esi, password_unicode |
mov edx, [password_size] |
add edx, edx |
call sha256_update |
mov esi, esp |
push 8 |
pop edx |
call sha256_update |
mov esi, esp |
dec esi |
@@: |
inc esi |
inc byte [esi] |
jz @b |
sub dword [esp+8], 1 |
sbb dword [esp+12], 0 |
mov eax, [esp+8] |
or eax, [esp+12] |
jnz .loop |
lea edi, [ebp+aes7z_decoder.Key] |
call sha256_final |
add esp, 16 |
.setkey: |
lea esi, [ebp+aes7z_decoder.Key] |
push 8 |
pop edx ; 7z uses 256-bit keys |
lea edi, [ebp+aes7z_decoder.nr] |
call aes_setkey |
.ret: |
ret |
/programs/fs/kfar/trunk/kfar_arc/7zbranch.inc |
---|
0,0 → 1,469 |
; Branch filters for 7-Zip archives: BCJ and BCJ2. |
; Ported from C++ sources of 7-Zip (c) Igor Pavlov. |
virtual at 0 |
bcj_decoder: |
.outStream rb streamInfo.size |
.inStream dd ? |
.inPtr dd ? |
.inSize dd ? |
.nowPos dd ? ; offset in stream |
.prevPos dd ? ; pointer in buffer |
.prevMask db ? |
.numRest db ? |
rw 1 |
.dwordRest dd ? |
.tempSize dd ? |
.tempDword dd ? |
.size = $ |
end virtual |
bcj_get_buf_size: |
mov eax, bcj_decoder.size |
mov edx, 0x4000 |
ret |
bcj_init_decoder: |
mov [ebp+streamInfo.fillBuf], bcj_fillBuf |
xor edx, edx |
mov [ebp+bcj_decoder.inPtr], edx |
mov [ebp+bcj_decoder.inSize], edx |
mov [ebp+bcj_decoder.prevPos], edx |
mov [ebp+bcj_decoder.nowPos], edx |
mov [ebp+bcj_decoder.numRest], dl |
ret |
bcj_fillBuf: |
add [eax+bcj_decoder.nowPos], ecx |
mov ebp, ecx ; save output size |
mov esi, [eax+bcj_decoder.inPtr] |
mov ebx, [eax+bcj_decoder.inStream] |
mov ecx, [eax+bcj_decoder.inSize] |
add esi, [ebx+streamInfo.bufPtr] |
mov ebx, eax |
cmp [eax+bcj_decoder.prevPos], 0 |
jz @f |
add [eax+bcj_decoder.prevPos], edi |
@@: |
cmp [ebx+bcj_decoder.numRest], 0 |
jz .mainloop |
sub ebp, 1 |
js .mainloopdone |
dec [ebx+bcj_decoder.numRest] |
mov eax, [ebx+bcj_decoder.dwordRest] |
stosb |
shr eax, 8 |
mov [ebx+bcj_decoder.dwordRest], eax |
jmp @b |
.mainloop: |
sub ebp, 1 |
js .mainloopdone |
sub ecx, 1 |
js .refill1 |
.filled1: |
lodsb |
.filled2: |
stosb |
cmp al, 0xE8 |
jz .filter |
cmp al, 0xE9 |
jnz .mainloop |
.filter: |
and [ebx+bcj_decoder.tempSize], 0 |
sub ecx, 4 |
jb .nopos |
js .nopos2 |
lodsd |
push eax |
.posok: |
xor edx, edx |
mov eax, edi |
sub eax, [ebx+bcj_decoder.prevPos] |
cmp eax, 5 |
ja .maskok |
movzx edx, [ebx+bcj_decoder.prevMask] |
@@: |
and edx, 0x77 |
add edx, edx |
sub eax, 1 |
jnz @b |
.maskok: |
mov [ebx+bcj_decoder.prevMask], dl |
mov [ebx+bcj_decoder.prevPos], edi |
mov al, [esp+3] |
add al, 1 |
cmp al, 2 |
jae .miss |
cmp dl, 0x20 |
jae .miss2 |
lea eax, [edx-1] |
test eax, edx |
jnz .miss2 |
pop eax |
shr edx, 1 |
push ecx |
mov cl, [bcj_kMaskToBitNumber+edx] |
iglobal |
bcj_kMaskToBitNumber db 24,16,8,8,0,0,0,0 |
endg |
@@: |
sub eax, [ebx+bcj_decoder.nowPos] |
add eax, [ebx+streamInfo.bufDataLen] |
sub eax, edi |
sub eax, 4 |
add eax, [ebx+streamInfo.bufPtr] |
cmp cl, 24 |
jz @f |
push eax |
shr eax, cl |
add al, 1 |
cmp al, 2 |
pop eax |
jae @f |
mov edx, 0x100 |
shl edx, cl |
sub edx, 1 |
xor eax, edx |
jmp @b |
@@: |
pop ecx |
shl eax, 7 |
sar eax, 7 |
sub ebp, 4 |
jb .finalize_dword |
stosd |
jmp .mainloop |
.miss2: |
or [ebx+bcj_decoder.prevMask], 10h |
.miss: |
or [ebx+bcj_decoder.prevMask], 1 |
cmp [ebx+bcj_decoder.tempSize], 0 |
jz @f |
lea esi, [ebx+bcj_decoder.tempDword] |
pop dword [esi] |
mov ecx, [ebx+bcj_decoder.tempSize] |
jmp .mainloop |
@@: |
pop eax |
sub esi, 4 |
add ecx, 4 |
jmp .mainloop |
.finalize_dword: |
add ebp, 4 |
mov [ebx+bcj_decoder.numRest], 4 |
@@: |
dec ebp |
js .save_dword |
stosb |
dec [ebx+bcj_decoder.numRest] |
shr eax, 8 |
jmp @b |
.save_dword: |
mov [ebx+bcj_decoder.dwordRest], eax |
.mainloopdone: |
mov eax, [ebx+bcj_decoder.prevPos] |
test eax, eax |
jz .noprev |
sub eax, edi |
mov [ebx+bcj_decoder.prevPos], eax |
.noprev: |
mov eax, [ebx+bcj_decoder.inStream] |
sub esi, [eax+streamInfo.bufPtr] |
mov [ebx+bcj_decoder.inPtr], esi |
mov [ebx+bcj_decoder.inSize], ecx |
popad |
ret |
.refill1: |
cmp ecx, -1 |
jz .refill0 |
lodsb |
cmp ecx, -4 |
jnz @f |
mov ecx, [ebx+bcj_decoder.inStream] |
mov esi, [ecx+streamInfo.bufPtr] |
mov ecx, [ecx+streamInfo.bufDataLen] |
@@: |
jmp .filled2 |
.refill0: |
mov eax, [ebx+bcj_decoder.inStream] |
call fillBuf |
mov esi, [eax+streamInfo.bufPtr] |
mov ecx, [eax+streamInfo.bufDataLen] |
sub ecx, 1 |
js return.err |
jmp .filled1 |
.nopos: |
mov eax, [ebx+bcj_decoder.inStream] |
cmp dword [eax+streamInfo.fullSize+4], 0 |
jnz .hasdata |
push ecx |
add ecx, dword [eax+streamInfo.fullSize] |
pop ecx |
jc .hasdata |
add ecx, 4 |
jmp .mainloop |
.hasdata: |
mov [ebx+bcj_decoder.tempSize], ecx |
push 0 |
push edi |
lea edi, [esp+4] |
add ecx, 4 |
rep movsb |
sub esi, ebx |
sub esi, 1 |
cmp esi, bcj_decoder.tempDword+4 |
jbe @f |
call fillBuf |
@@: |
mov esi, [eax+streamInfo.bufPtr] |
mov ecx, [ebx+bcj_decoder.tempSize] |
neg ecx |
rep movsb |
pop edi |
mov ecx, [eax+streamInfo.bufDataLen] |
add ecx, [ebx+bcj_decoder.tempSize] |
cmp [ebx+bcj_decoder.tempSize], -4 |
jnz .posok |
and [ebx+bcj_decoder.tempSize], 0 |
jmp .posok |
.nopos2: |
mov eax, [ebx+bcj_decoder.inStream] |
add ecx, 4 |
jmp .hasdata |
virtual at 0 |
bcj2_decoder: |
.outStream rb streamInfo.size |
.mainInStream dd ? |
.callStream dd ? |
.jumpStream dd ? |
.rangeDecoder dd ? |
.dwordRest dd ? |
.prevByte db ? |
.numRest db ? |
.bInited db ? |
rb 1 |
.inPtr dd ? |
.inSize dd ? |
.callPtr dd ? |
.jumpPtr dd ? |
.callSize dd ? |
.jumpSize dd ? |
.rangeDecPtr dd ? |
.rangeDecSize dd ? |
.nowPos dd ? |
.range dd ? |
.code dd ? |
.statusE9Decoder dd ? |
.statusJccDecoder dd ? |
.statusE8Decoder rd 256 |
.size = $ |
end virtual |
bcj2_get_buf_size: |
mov eax, bcj2_decoder.size |
mov edx, 0x4000 |
ret |
bcj2_init_decoder: |
mov [ebp+streamInfo.fillBuf], bcj2_fillBuf |
mov eax, lzma_decoder.kBitModelTotal/2 |
mov ecx, 256+1+1 |
lea edi, [ebp+bcj2_decoder.statusE9Decoder] |
rep stosd |
mov dword [ebp+bcj2_decoder.prevByte], ecx |
mov [ebp+bcj2_decoder.inSize], ecx |
mov [ebp+bcj2_decoder.callSize], ecx |
mov [ebp+bcj2_decoder.jumpSize], ecx |
mov [ebp+bcj2_decoder.rangeDecSize], ecx |
mov [ebp+bcj2_decoder.nowPos], ecx |
ret |
bcj2_fillBuf.init: |
mov eax, [eax+bcj2_decoder.rangeDecoder] |
call fillBuf |
mov edx, [eax+streamInfo.bufDataLen] |
sub edx, 5 |
jb return.err |
mov [ebp+bcj2_decoder.rangeDecSize], edx |
mov edx, [eax+streamInfo.bufPtr] |
add edx, 5 |
mov [ebp+bcj2_decoder.rangeDecPtr], edx |
mov edx, [edx-4] |
bswap edx |
mov [ebp+bcj2_decoder.code], edx |
or [ebp+bcj2_decoder.range], -1 |
mov [ebp+bcj2_decoder.bInited], 1 |
mov eax, ebp |
jmp bcj2_fillBuf.inited |
bcj2_fillBuf: |
mov ebp, eax |
cmp [eax+bcj2_decoder.bInited], 0 |
jz .init |
.inited: |
add [eax+bcj2_decoder.nowPos], ecx |
mov esi, [eax+bcj2_decoder.inPtr] |
@@: |
cmp [ebp+bcj2_decoder.numRest], 0 |
jz .mainloop |
sub ecx, 1 |
js .mainloopdone |
dec [ebp+bcj2_decoder.numRest] |
mov eax, [ebp+bcj2_decoder.dwordRest] |
stosb |
mov [ebp+bcj2_decoder.prevByte], al |
shr eax, 8 |
mov [ebp+bcj2_decoder.dwordRest], eax |
jmp @b |
.mainloop: |
sub ecx, 1 |
js .mainloopdone |
sub [ebp+bcj2_decoder.inSize], 1 |
js .refill1 |
.filled1: |
lodsb |
stosb |
cmp al, 0xE8 |
jz .e8 |
cmp al, 0xE9 |
jz .e9 |
cmp [ebp+bcj2_decoder.prevByte], 0xF |
mov [ebp+bcj2_decoder.prevByte], al |
jnz .mainloop |
and al, 0xF0 |
cmp al, 0x80 |
jnz .mainloop |
.jcc: |
lea eax, [ebp+bcj2_decoder.statusJccDecoder] |
call .RangeDecoderBitDecode |
jnc .mainloop |
jmp .getptrj |
.e8: |
movzx eax, al |
xchg al, [ebp+bcj2_decoder.prevByte] |
lea eax, [ebp+bcj2_decoder.statusE8Decoder+eax*4] |
call .RangeDecoderBitDecode |
jnc .mainloop |
lea eax, [ebp+bcj2_decoder.callPtr] |
jmp .getptr |
.e9: |
mov [ebp+bcj2_decoder.prevByte], al |
lea eax, [ebp+bcj2_decoder.statusE9Decoder] |
call .RangeDecoderBitDecode |
jnc .mainloop |
.getptrj: |
lea eax, [ebp+bcj2_decoder.jumpPtr] |
.getptr: |
sub dword [eax+8], 4 |
js .refill2 |
.filled2: |
add dword [eax], 4 |
mov eax, [eax] |
mov eax, [eax-4] |
bswap eax |
sub eax, [ebp+bcj2_decoder.nowPos] |
add eax, [ebp+streamInfo.bufDataLen] |
sub eax, edi |
sub eax, 4 |
add eax, [ebp+streamInfo.bufPtr] |
sub ecx, 4 |
jb .finalize_dword |
stosd |
shr eax, 24 |
mov [ebp+bcj2_decoder.prevByte], al |
jmp .mainloop |
.finalize_dword: |
add ecx, 4 |
mov [ebp+bcj2_decoder.numRest], 4 |
@@: |
dec ecx |
js .save_dword |
stosb |
dec [ebp+bcj2_decoder.numRest] |
shr eax, 8 |
jmp @b |
.save_dword: |
mov [ebp+bcj2_decoder.dwordRest], eax |
.mainloopdone: |
mov [ebp+bcj2_decoder.inPtr], esi |
popad |
ret |
.refill1: |
mov eax, [ebp+bcj2_decoder.mainInStream] |
call fillBuf |
mov edx, [eax+streamInfo.bufDataLen] |
dec edx |
js return.err |
mov [ebp+bcj2_decoder.inSize], edx |
mov esi, [eax+streamInfo.bufPtr] |
jmp .filled1 |
.refill2: |
push eax |
mov eax, [eax-bcj2_decoder.callPtr+bcj2_decoder.callStream] |
call fillBuf |
mov edx, [eax+streamInfo.bufDataLen] |
sub edx, 4 |
js return.err |
push [eax+streamInfo.bufPtr] |
mov eax, [esp+4] |
pop dword [eax] |
pop eax |
mov [eax+8], edx |
jmp .filled2 |
.refill3: |
push eax |
mov eax, [ebp+bcj2_decoder.rangeDecoder] |
call fillBuf |
mov edx, [eax+streamInfo.bufDataLen] |
dec edx |
js return.err |
mov [ebp+bcj2_decoder.rangeDecSize], edx |
mov edx, [eax+streamInfo.bufPtr] |
mov [ebp+bcj2_decoder.rangeDecPtr], edx |
pop eax |
jmp .filled3 |
.RangeDecoderBitDecode: |
; in: eax->prob |
; out: CF=bit; destroys eax,edx |
mov edx, [ebp+bcj2_decoder.range] |
shr edx, lzma_decoder.kNumBitModelTotalBits |
imul edx, [eax] |
cmp [ebp+bcj2_decoder.code], edx |
jae .ae |
mov [ebp+bcj2_decoder.range], edx |
mov edx, lzma_decoder.kBitModelTotal |
sub edx, [eax] |
shr edx, lzma_decoder.kNumMoveBits |
add [eax], edx |
clc |
.n: |
lahf |
cmp [ebp+bcj2_decoder.range], lzma_decoder.kTopValue |
jae @f |
shl [ebp+bcj2_decoder.range], 8 |
shl [ebp+bcj2_decoder.code], 8 |
dec [ebp+bcj2_decoder.rangeDecSize] |
js .refill3 |
.filled3: |
mov edx, [ebp+bcj2_decoder.rangeDecPtr] |
mov al, [edx] |
add edx, 1 |
mov [ebp+bcj2_decoder.rangeDecPtr], edx |
mov byte [ebp+bcj2_decoder.code], al |
@@: |
sahf |
ret |
.ae: |
sub [ebp+bcj2_decoder.range], edx |
sub [ebp+bcj2_decoder.code], edx |
mov edx, [eax] |
shr edx, lzma_decoder.kNumMoveBits |
sub [eax], edx |
stc |
jmp .n |
/programs/fs/kfar/trunk/kfar_arc/aes.inc |
---|
0,0 → 1,274 |
; Implementation of AES crypto algorithm. |
; Buffer size is 0x10 bytes (128 bits), key size is not fixed. |
; Written by diamond in 2007. |
uglobal |
aes.pow_table rb 256 ; pow[a] = 3^a |
aes.log_table rb 256 ; log[3^a] = a |
aes.sbox rb 256 ; ShiftBytes(a) |
aes.sbox_rev rb 256 ; ShiftBytes^{-1}(a) |
aes.mctable rd 256 ; MixColumns(ShiftBytes(a,0,0,0)) |
aes.mcrtable rd 256 ; MixColumns^{-1}(a,0,0,0) |
endg |
init_aes: |
; Byte values in SubBytes transform are interpreted as items of |
; GF(2^8) \cong F_2[x]/(x^8+x^4+x^3+x+1)F_2[x]. |
; x+1 is primitive item in this field. |
xor ebx, ebx |
push 1 |
pop eax |
.1: |
mov [aes.pow_table+ebx], al |
mov [aes.log_table+eax], bl |
; Multiplication by x+1... |
mov cl, al ; save value |
; ...multiply by x with mod (x^8+x^4+x^3+x+1) = 0x11B... |
add al, al |
jnc @f |
xor al, 0x1B |
@@: |
; ...and add operand |
xor al, cl |
inc bl |
jnz .1 |
; generate table for SubBytes transform |
mov [aes.sbox+0], 0x63 |
mov [aes.sbox_rev+0x63], bl |
inc ebx |
.2: |
; calculate inverse in GF(2^8) |
mov al, [aes.log_table+ebx] |
xor al, 0xFF ; equivalent to "al = 0xFF - al" |
mov cl, [aes.pow_table+eax] |
; linear transform of byte as vector over F_2 |
mov al, cl |
rol cl, 1 |
xor al, cl |
rol cl, 1 |
xor al, cl |
rol cl, 1 |
xor al, cl |
rol cl, 1 |
xor al, cl |
xor al, 0x63 |
mov [aes.sbox+ebx], al |
mov [aes.sbox_rev+eax], bl |
inc bl |
jnz .2 |
; generate table for SubBytes + MixColumn transforms |
.3: |
mov al, [aes.sbox+ebx] ; SubBytes transform |
mov cl, al |
add cl, cl |
jnc @f |
xor cl, 0x1B |
@@: |
mov byte [aes.mctable+ebx*4], cl ; low byte of MixColumn(a,0,0,0) |
mov byte [aes.mctable+ebx*4+1], al |
mov byte [aes.mctable+ebx*4+2], al |
xor cl, al |
mov byte [aes.mctable+ebx*4+3], cl ; high byte of MixColumn(a,0,0,0) |
inc bl |
jnz .3 |
; generate table for reverse MixColumn transform |
mov dword [aes.mcrtable+0], ebx |
inc ebx |
.4: |
; log_table[9]=0xC7, log_table[0xB]=0x68, log_table[0xD]=0xEE, log_table[0xE]=0xDF |
mov cl, [aes.log_table+ebx] |
mov al, cl |
add al, 0xDF |
adc al, 0 |
mov al, [aes.pow_table+eax] |
mov byte [aes.mcrtable+ebx*4], al |
mov al, cl |
add al, 0xC7 |
adc al, 0 |
mov al, [aes.pow_table+eax] |
mov byte [aes.mcrtable+ebx*4+1], al |
mov al, cl |
add al, 0xEE |
adc al, 0 |
mov al, [aes.pow_table+eax] |
mov byte [aes.mcrtable+ebx*4+2], al |
mov al, cl |
add al, 0x68 |
adc al, 0 |
mov al, [aes.pow_table+eax] |
mov byte [aes.mcrtable+ebx*4+3], al |
inc bl |
jnz .4 |
ret |
aes_setkey: |
; in: esi->key, edx=key size in dwords, edi->AES data struc |
lea eax, [edx+6] ; calc number of rounds (buffer size=4) |
stosd |
shl eax, 4 |
lea ebx, [edi+eax+16] |
mov ecx, edx |
rep movsd |
push ebx |
mov bl, 1 |
.0: |
push 4 |
pop ecx |
@@: |
movzx esi, byte [edi-5+ecx] |
mov al, [aes.sbox+esi] |
rol eax, 8 |
loop @b |
ror eax, 16 |
mov esi, edx |
neg esi |
xor eax, [edi+esi*4] |
xor al, bl |
add bl, bl |
jnc @f |
xor bl, 0x1B |
@@: |
stosd |
lea ecx, [edx-1] |
.1: |
cmp edi, [esp] |
jz .ret |
cmp edx, 8 |
jnz @f |
cmp ecx, 4 |
jnz @f |
push eax |
movzx eax, al |
mov al, [aes.sbox+eax] |
mov [esp], al |
mov al, byte [esp+1] |
mov al, [aes.sbox+eax] |
mov [esp+1], al |
mov al, byte [esp+2] |
mov al, [aes.sbox+eax] |
mov [esp+2], al |
mov al, byte [esp+3] |
mov al, [aes.sbox+eax] |
mov [esp+3], al |
pop eax |
@@: |
xor eax, [edi+esi*4] |
stosd |
loop .1 |
cmp edi, [esp] |
jnz .0 |
.ret: |
pop eax |
ret |
aes_decode: |
; in: esi->in, ebx->out, edi->AES state |
push ebx ebp |
push dword [esi+12] |
push dword [esi+8] |
push dword [esi+4] |
push dword [esi] |
mov esi, esp |
; reverse final round |
mov ebp, [edi] ; number of rounds |
mov ecx, ebp |
shl ecx, 4 |
lea edi, [edi+ecx+4] ; edi->last round key |
; load buffer into registers |
mov eax, [esi] |
mov ebx, [esi+4] |
mov ecx, [esi+8] |
mov edx, [esi+12] |
; (AddRoundKey) |
xor eax, [edi] |
xor ebx, [edi+4] |
xor ecx, [edi+8] |
xor edx, [edi+12] |
; (ShiftRows) |
.loop0: |
xchg ch, dh |
xchg bh, ch |
xchg ah, bh |
rol eax, 16 |
rol ebx, 16 |
rol ecx, 16 |
rol edx, 16 |
xchg al, cl |
xchg bl, dl |
xchg ah, bh |
xchg bh, ch |
xchg ch, dh |
rol eax, 16 |
rol ebx, 16 |
rol ecx, 16 |
rol edx, 16 |
; (SubBytes) |
mov [esi], eax |
mov [esi+4], ebx |
mov [esi+8], ecx |
mov [esi+12], edx |
mov ecx, 16 |
@@: |
movzx eax, byte [esi] |
mov al, [aes.sbox_rev+eax] |
mov byte [esi], al |
add esi, 1 |
sub ecx, 1 |
jnz @b |
sub esi, 16 |
sub edi, 16 |
; reverse normal rounds |
sub ebp, 1 |
jz .done |
mov eax, [esi] |
mov ebx, [esi+4] |
mov ecx, [esi+8] |
mov edx, [esi+12] |
push esi edi |
; (AddRoundKey) |
xor eax, [edi] |
xor ebx, [edi+4] |
xor ecx, [edi+8] |
xor edx, [edi+12] |
; (MixColumns) |
macro mix_reg reg { |
movzx esi, reg#l |
mov edi, [aes.mcrtable+esi*4] |
movzx esi, reg#h |
rol e#reg#x, 16 |
mov esi, [aes.mcrtable+esi*4] |
rol esi, 8 |
xor edi, esi |
movzx esi, reg#l |
mov esi, [aes.mcrtable+esi*4] |
rol esi, 16 |
xor edi, esi |
movzx esi, reg#h |
mov esi, [aes.mcrtable+esi*4] |
ror esi, 8 |
xor edi, esi |
mov e#reg#x, edi |
} |
mix_reg a |
mix_reg b |
mix_reg c |
mix_reg d |
purge mix_reg |
pop edi esi |
jmp .loop0 |
.done: |
; (AddRoundKey) |
mov esi, [esp+20] |
pop eax |
xor eax, [edi] |
mov [esi], eax |
pop eax |
xor eax, [edi+4] |
mov [esi+4], eax |
pop eax |
xor eax, [edi+8] |
mov [esi+8], eax |
pop eax |
xor eax, [edi+12] |
mov [esi+12], eax |
pop ebp ebx |
ret |
/programs/fs/kfar/trunk/kfar_arc/crc.inc |
---|
0,0 → 1,32 |
init_crc_table: |
xor edx, edx |
mov edi, crc_table |
.1: |
mov ecx, 8 |
mov eax, edx |
.2: |
shr eax, 1 |
jnc @f |
xor eax, 0xEDB88320 |
@@: |
loop .2 |
stosd |
inc dl |
jnz .1 |
ret |
crc: |
; in: ecx=size, esi->buffer |
; out: eax=crc |
or eax, -1 |
jecxz .end |
.loop: |
movzx edx, al |
xor dl, byte [esi] |
inc esi |
shr eax, 8 |
xor eax, [crc_table+edx*4] |
loop .loop |
.end: |
xor eax, -1 |
ret |
/programs/fs/kfar/trunk/kfar_arc/kfar_arc.asm |
---|
0,0 → 1,1075 |
; |
; 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 |
; minimal kernel: no limit |
; |
; author: Diamond |
; email: diamondz@land.ru |
; web: http://diamondz.land.ru |
; |
; standard start of Kolibri dynamic library |
format MS COFF |
public EXPORTS |
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 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 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;; Interface for KFar ;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
virtual at 0 |
kfar_info_struc: |
.lStructSize dd ? |
.kfar_ver dd ? |
.open dd ? |
.read dd ? |
.write dd ? |
.seek 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.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 char* name, |
; const void* attr, const void* data, int datasize); |
; 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 ebp, [esp+4] |
; test for 7z archive |
cmp dword [esp+20], 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 |
.no_7z: |
xor eax, eax |
ret 20 |
; 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 ? |
; ... some plugin-specific data follows ... |
end virtual |
; 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 |
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] |
; int __stdcall ReadFolder(HANDLE hPlugin, |
; unsigned dirinfo_start, unsigned dirinfo_size, void* dirdata); |
ReadFolder: |
mov eax, [esp+4] |
mov eax, [eax] |
dec eax |
jmp dword [ReadFolderTable+eax*4] |
; 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] |
; void __stdcall GetFiles(HANDLE hPlugin, int NumItems, void* items[], |
; void* addfile, void* adddir); |
; 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 eax, [ebp] |
dec eax |
jmp dword [GetFilesTable+eax*4] |
; 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 |
; 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 |
@@: |
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] |
@@: |
ret 12 |
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size); |
myread: |
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] |
; void __stdcall close(HANDLE hFile); |
myclose: |
mov ebx, [esp+4] |
mov eax, [ebx] |
jmp dword [closeTable+eax*4] |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;; Auxiliary procedures ;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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] |
return.clear: |
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 |
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 |
; 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 |
; edx:eax = number of minutes |
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 |
; 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] |
@@: |
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 |
.leap: |
mov esi, months2 |
.noleap: |
pop edx |
xor eax, eax |
inc eax |
@@: |
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 |
; By given array of files information, initialize links between them |
; ("[folder] contains [item]" relations). |
; Information structure must be compatible with 'file_common'. |
; Size of information structure is in [esp+4]. |
init_file_links: |
; 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 |
; Loop through all files |
.mainloop: |
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 |
.parseloop: |
push esi |
.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 |
@@: |
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 |
.scancont: |
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 |
; 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 |
; 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 |
.1: |
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 |
.3: |
add eax, [hOut] |
.4: |
mov [eax+file_common.prev], edx |
; correct parent links in childrens |
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 |
@@: |
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 |
@@: |
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 |
; 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 |
; add old item to list of free items |
uglobal |
align 4 |
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 |
.nofolder: |
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 |
.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 |
@@: |
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 |
.newitem: |
mov [eax+file_common.namelen], ecx |
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 |
; add new item to end of L2-list |
and [eax+file_common.next], 0 |
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 |
@@: |
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 |
; set parent link |
and [eax+file_common.parent], 0 |
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] |
; if that was not last component, continue parse name |
add esi, [eax+file_common.namelen] |
lodsb |
test al, al |
jnz .parseloop |
.mainloopcont: |
; continue main loop |
add edx, [esp+4] |
jmp .mainloop |
.mainloopdone: |
; Loop done. |
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 |
; KFar operates with absolute names, skip first '/' |
cmp byte [esi], '/' |
jnz .notfound |
inc esi |
.mainloop: |
; get next component of name |
push -1 |
pop ecx |
@@: |
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 |
.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 |
.cont1: |
mov eax, [eax+file_common.next] |
jmp .scan1 |
.notfound1: |
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 |
.found1: |
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 |
; this was the last component |
.notfound: |
ret |
; Memory streams handling. |
; Archive handlers create memory stream for small files: |
; size of which is not greater than (free RAM size)/4 and |
; not greater than following constant... |
;LIMIT_FOR_MEM_STREAM = 2*1024*1024 |
; ...if it is defined. Now the definition is commented: |
; if user has many physical memory, why not to use it? |
virtual at 0 |
mem_stream: |
.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 |
@@: |
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 |
; void __stdcall setpos(ebx = HANDLE hFile, __int64 pos); |
setpos_mem_stream: |
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 |
; Allocate handle for file |
; esi -> handle table, ecx = size of handle |
alloc_handle: |
; Handle table is L2-list of allocated pages. |
; Scan for free entry |
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 |
; 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] |
.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 |
; 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 |
; initialize list of free entries |
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 |
; Free handle allocated in previous procedure |
; esi = handle |
free_handle: |
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 |
; delete page from common L2-list |
mov eax, [ecx] |
mov edx, [ecx+4] |
mov [eax+4], edx |
mov [edx], eax |
; free page |
call [pgfree] |
.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 |
; convert ANSI-cp866 to UNICODE string; also calculate 'password_size' |
mov esi, password_ansi |
mov edi, password_unicode |
or [password_size], -1 |
.cvt: |
inc [password_size] |
lodsb |
mov ah, 0 |
; 0x00-0x7F - trivial map |
cmp al, 0x80 |
jb .symb |
; 0x80-0xAF -> 0x410-0x43F |
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 |
@@: |
; 0xF0 -> 0x401 |
; 0xF1 -> 0x451 |
cmp al, 'ð' |
jz .yo1 |
cmp al, 'ñ' |
jz .yo2 |
.unk: |
mov al, '_' |
jmp .symb |
.yo1: |
mov ax, 0x401 |
jmp .symb |
.yo2: |
mov ax, 0x451 |
.symb: |
stosw |
test al, al |
jnz .cvt |
inc [bPasswordDefined] ; clears ZF flag |
.ret: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;; Initialized data ;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; export table |
align 4 |
EXPORTS: |
dd aVersion, 1 |
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 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 |
; common strings |
if lang eq ru |
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 |
aEnterPasswordLen = $ - aEnterPassword - 1 |
aEnterPasswordTitle db '¢®¤ ¯ ஫ï',0 |
aArchiveDataError db '訡ª ¢ ¤ ëå à娢 ',0 |
aArchiveDataErrorPass db '訡ª ¢ ¤ ëå à娢 ¨«¨ ¥¢¥àë© ¯ ஫ì',0 |
aChangePass db '¢¥á⨠¯ ஫ì',0 |
aNameTooLong 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 |
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 |
aEnterPasswordLen = $ - aEnterPassword - 1 |
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 |
end if |
; kfar_arc supports [hmm... will support...] 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. |
type_mem_stream = 0 ; memory stream - for file handles (returned from 'open') |
type_7z = 1 |
; 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 |
getattrTable: |
dd getattr_7z |
openTable: |
dd open_file_7z |
; file functions (types start from type_mem_stream) |
readTable: |
dd read_mem_stream |
dd read_7z |
setposTable: |
dd setpos_mem_stream |
dd setpos_7z |
closeTable: |
dd close_mem_stream |
dd close_file_7z |
; pointers for SayErr and Message |
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 |
aArchiveDataError_ptr dd aArchiveDataError |
aArchiveDataErrorPass_ptr dd aArchiveDataErrorPass |
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, 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 |
; 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 |
IncludeIGlobals |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;; Uninitialized data ;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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 ? |
error_proc dd ? |
clear_proc dd ? |
; import from kfar |
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 ? |
; converted password |
password_unicode rw password_maxlen+1 |
password_size dd ? |
IncludeUGlobals |
bWasWarning db ? |
/programs/fs/kfar/trunk/kfar_arc/kglobals.inc |
---|
0,0 → 1,50 |
;------------------------------------------------------------------ |
; use "iglobal" for inserting initialized global data definitions. |
;------------------------------------------------------------------ |
macro iglobal { |
IGlobals equ IGlobals, |
macro __IGlobalBlock { } |
;------------------------------------------------------------- |
; use 'uglobal' for inserting uninitialized global definitions. |
; even when you define some data values, these variables |
; will be stored as uninitialized data. |
;------------------------------------------------------------- |
macro uglobal { |
UGlobals equ UGlobals, |
macro __UGlobalBlock { } |
endg fix } ; Use endg for ending iglobal and uglobal blocks. |
macro IncludeIGlobals{ |
macro IGlobals dummy,[n] \{ __IGlobalBlock |
purge __IGlobalBlock \} |
match I, IGlobals \{ I \} } |
macro IncludeUGlobals{ |
macro UGlobals dummy,[n] \{ |
\common |
\local begin, size |
begin = $ |
virtual at $ |
\forward |
__UGlobalBlock |
purge __UGlobalBlock |
\common |
size = $ - begin |
end virtual |
rb size |
\} |
match U, UGlobals \{ U \} } |
macro IncludeAllGlobals { |
IncludeIGlobals |
IncludeUGlobals |
} |
iglobal |
endg |
uglobal |
endg |
/programs/fs/kfar/trunk/kfar_arc/lang.inc |
---|
0,0 → 1,0 |
lang fix ru |
/programs/fs/kfar/trunk/kfar_arc/lzma.inc |
---|
0,0 → 1,581 |
; LZMA decoder for *.7z archives. |
; Based on C decoder in LZMA SDK (c) Igor Pavlov. |
; Portions by Diamond, 2006, 2007. |
lzma_decoder: |
virtual at 0 |
.outStream rb streamInfo.size |
.inStream dd ? |
; RangeDecoder data |
.inLen dd ? |
.inPtr dd ? |
.code dd ? |
.range dd ? |
; parameters |
.pb db ? ; pos state bits (0 - 4) |
.lp db ? ; literal pos state bits (0 - 4) |
.lc db ? ; literal context bits (0 - 8) |
.previousByte db ? |
.posStateMask dd ? ; (1 shl .pb)-1 |
.literalPosMask dd ? ; (1 shl .lp)-1 |
; constants |
.kNumPosBitsMax = 4 |
.kNumPosStatesMax = (1 shl .kNumPosBitsMax) |
.kLenNumLowBits = 3 |
.kLenNumLowSymbols = (1 shl .kLenNumLowBits) |
.kLenNumMidBits = 3 |
.kLenNumMidSymbols = (1 shl .kLenNumMidBits) |
.kLenNumHighBits = 8 |
.kLenNumHighSymbols = (1 shl .kLenNumHighBits) |
.LenChoice = 0 |
.LenChoice2 = 1 |
.LenLow = 2 |
.LenMid = (.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits)) |
.LenHigh = (.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits)) |
.kNumLenProbs = (.LenHigh + .kLenNumHighSymbols) |
.kNumStates = 12 |
.kNumLitStates = 7 |
.kStartPosModelIndex = 4 |
.kEndPosModelIndex = 14 |
.kNumFullDistances = (1 shl (.kEndPosModelIndex/2)) |
.kNumPosSlotBits = 6 |
.kNumLenToPosStates = 4 |
.kNumAlignBits = 4 |
.kAlignTableSize = (1 shl .kNumAlignBits) |
.kMatchMinLen = 2 |
.IsMatch = 0 |
.IsRep = (.IsMatch + (.kNumStates shl .kNumPosBitsMax)) |
.IsRepG0 = (.IsRep + .kNumStates) |
.IsRepG1 = (.IsRepG0 + .kNumStates) |
.IsRepG2 = (.IsRepG1 + .kNumStates) |
.IsRep0Long = (.IsRepG2 + .kNumStates) |
.PosSlot = (.IsRep0Long + (.kNumStates shl .kNumPosBitsMax)) |
.SpecPos = (.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits)) |
.Align_ = (.SpecPos + .kNumFullDistances - .kEndPosModelIndex) |
.Lencoder = (.Align_ + .kAlignTableSize) |
.RepLencoder = (.Lencoder + .kNumLenProbs) |
.Literal = (.RepLencoder + .kNumLenProbs) |
LZMA_BASE_SIZE = 1846 ; must be ==Literal |
LZMA_LIT_SIZE = 768 |
.kNumTopBits = 24 |
.kTopValue = (1 shl .kNumTopBits) |
.kNumBitModelTotalBits = 11 |
.kBitModelTotal = (1 shl .kNumBitModelTotalBits) |
.kNumMoveBits = 5 |
; variables |
.continue dd ? |
.ecx dd ? |
.outEnd dd ? |
.dictSize dd ? |
.state dd ? |
.rep0 dd ? |
.rep1 dd ? |
.rep2 dd ? |
.rep3 dd ? |
.p rd LZMA_BASE_SIZE |
.basesize = $ |
; rd LZMA_LIT_SIZE shl (.lc+.lp) |
end virtual |
.fillBuf: |
mov ebp, eax |
mov ebx, [ebp+.state] |
jecxz .nodata |
add ecx, edi |
mov [ebp+.outEnd], ecx |
mov esi, [ebp+.inPtr] |
jmp [ebp+.continue] |
.nodata: |
popad |
ret |
.start: |
mov eax, [ebp+.inStream] |
call fillBuf |
mov esi, [eax+streamInfo.bufPtr] |
mov eax, [eax+streamInfo.bufDataLen] |
sub eax, 5 |
jb return.err |
mov [ebp+.inLen], eax |
inc esi |
lodsd |
bswap eax |
mov [ebp+.code], eax |
or [ebp+.range], -1 |
.main_loop: |
cmp edi, [ebp+.outEnd] |
jae .main_loop_done |
mov edx, edi |
and edx, [ebp+.posStateMask] |
mov eax, ebx |
shl eax, .kNumPosBitsMax |
add eax, edx |
lea eax, [ebp + .p + .IsMatch*4 + eax*4] |
call .RangeDecoderBitDecode |
jc .1 |
movzx eax, [ebp+.previousByte] |
mov ah, dl |
and ah, byte [ebp+.literalPosMask] |
mov cl, 8 |
sub cl, [ebp+.lc] |
shr eax, cl |
imul eax, LZMA_LIT_SIZE*4 |
lea eax, [ebp + eax + .p+.Literal*4] |
cmp ebx, .kNumLitStates |
jb .literal |
xor edx, edx |
sub edx, [ebp+.rep0] |
mov dl, [edi + edx] |
call .LzmaLiteralDecodeMatch |
jmp @f |
.literal: |
call .LzmaLiteralDecode |
@@: |
mov [ebp+.previousByte], al |
stosb |
mov al, bl |
cmp bl, 4 |
jb @f |
mov al, 3 |
cmp bl, 10 |
jb @f |
mov al, 6 |
@@: sub bl, al |
jmp .main_loop |
.1: |
lea eax, [ebp + .p + .IsRep*4 + ebx*4] |
call .RangeDecoderBitDecode |
jnc .10 |
lea eax, [ebp + .p + .IsRepG0*4 + ebx*4] |
call .RangeDecoderBitDecode |
jc .111 |
mov eax, ebx |
shl eax, .kNumPosBitsMax |
add eax, edx |
lea eax, [ebp + .p + .IsRep0Long*4 + eax*4] |
call .RangeDecoderBitDecode |
jc .1101 |
cmp bl, 7 |
setae bl |
lea ebx, [9 + ebx + ebx] |
xor edx, edx |
sub edx, [ebp+.rep0] |
mov al, [edi + edx] |
stosb |
mov [ebp+.previousByte], al |
jmp .main_loop |
.111: |
lea eax, [ebp + .p + .IsRepG1*4 + ebx*4] |
call .RangeDecoderBitDecode |
mov eax, [ebp+.rep1] |
jnc .l3 |
.l1: |
lea eax, [ebp + .p + .IsRepG2*4 + ebx*4] |
call .RangeDecoderBitDecode |
mov eax, [ebp+.rep2] |
jnc .l2 |
xchg [ebp+.rep3], eax |
.l2: |
push [ebp+.rep1] |
pop [ebp+.rep2] |
.l3: |
xchg eax, [ebp+.rep0] |
mov [ebp+.rep1], eax |
.1101: |
lea eax, [ebp + .p + .RepLencoder*4] |
call .LzmaLenDecode |
cmp bl, 7 |
setc bl |
adc bl, bl |
xor bl, 3 |
add bl, 8 |
jmp .repmovsb |
.10: |
mov eax, [ebp+.rep0] |
xchg eax, [ebp+.rep1] |
xchg eax, [ebp+.rep2] |
xchg eax, [ebp+.rep3] |
cmp bl, 7 |
setc bl |
adc bl, bl |
xor bl, 3 |
add bl, 7 |
lea eax, [ebp + .p + .Lencoder*4] |
call .LzmaLenDecode |
mov eax, .kNumLenToPosStates-1 |
cmp eax, ecx |
jb @f |
mov eax, ecx |
@@: |
push ecx |
mov ecx, .kNumPosSlotBits |
shl eax, cl |
lea eax, [ebp + .p+.PosSlot*4 + eax*4] |
call .RangeDecoderBitTreeDecode |
mov [ebp+.rep0], ecx |
cmp ecx, .kStartPosModelIndex |
jb .l6 |
push ecx |
mov eax, ecx |
and eax, 1 |
shr ecx, 1 |
or eax, 2 |
dec ecx |
shl eax, cl |
mov [ebp+.rep0], eax |
pop edx |
cmp edx, .kEndPosModelIndex |
jae .l5 |
sub eax, edx |
lea eax, [ebp + .p + (.SpecPos - 1)*4 + eax*4] |
call .RangeDecoderReverseBitTreeDecode |
add [ebp+.rep0], ecx |
jmp .l6 |
.l5: |
sub ecx, .kNumAlignBits |
call .RangeDecoderDecodeDirectBits |
mov ecx, .kNumAlignBits |
shl eax, cl |
add [ebp+.rep0], eax |
lea eax, [ebp+.p+.Align_*4] |
call .RangeDecoderReverseBitTreeDecode |
add [ebp+.rep0], ecx |
.l6: |
pop ecx |
inc [ebp+.rep0] |
jz .main_loop_done |
.repmovsb: |
add ecx, .kMatchMinLen |
.repmovsbz: |
push esi |
.repmovsbr: |
mov eax, [ebp+.rep0] |
cmp eax, [ebp+.dictSize] |
jae return.err |
mov esi, edi |
sub esi, eax |
mov eax, [ebp+streamInfo.bufPtr] |
sub eax, esi |
ja .repmovsb0 |
mov eax, [ebp+.outEnd] |
sub eax, edi |
push ecx |
cmp ecx, eax |
jb @f |
mov ecx, eax |
@@: |
sub [esp], ecx |
rep movsb |
pop ecx |
jz .repmovsb1 |
pop [ebp+.inPtr] |
mov [ebp+.state], ebx |
mov [ebp+.ecx], ecx |
mov [ebp+.continue], .restart_repmovsb |
popad |
ret |
.repmovsb0: |
mov edx, [ebp+.dictSize] |
cmp edx, [ebp+streamInfo.bufSize] |
jnz return.err |
add esi, edx |
push ecx |
cmp ecx, eax |
jb @f |
mov ecx, eax |
@@: |
mov eax, [ebp+.outEnd] |
sub eax, edi |
cmp ecx, eax |
jb @f |
mov ecx, eax |
@@: |
sub [esp], ecx |
rep movsb |
pop ecx |
jnz .repmovsbr |
.repmovsb1: |
pop esi |
mov al, [edi-1] |
mov [ebp+.previousByte], al |
jmp .main_loop |
.main_loop_done: |
mov [ebp+.state], ebx |
mov [ebp+.continue], .main_loop |
mov [ebp+.inPtr], esi |
popad |
ret |
.restart_repmovsb: |
mov ecx, [ebp+.ecx] |
jmp .repmovsbz |
.RangeDecoderBitDecode: |
; in: eax->prob |
; out: CF=bit; destroys eax |
push edx |
mov edx, [ebp+.range] |
shr edx, .kNumBitModelTotalBits |
imul edx, [eax] |
cmp [ebp+.code], edx |
jae .ae |
mov [ebp+.range], edx |
mov edx, .kBitModelTotal |
sub edx, [eax] |
shr edx, .kNumMoveBits |
add [eax], edx |
clc |
.n: |
lahf |
cmp [ebp+.range], .kTopValue |
jae @f |
shl [ebp+.range], 8 |
shl [ebp+.code], 8 |
sub [ebp+.inLen], 1 |
js .refill1 |
.refilled1: |
lodsb |
mov byte [ebp+.code], al |
@@: |
sahf |
pop edx |
ret |
.ae: |
sub [ebp+.range], edx |
sub [ebp+.code], edx |
mov edx, [eax] |
shr edx, .kNumMoveBits |
sub [eax], edx |
stc |
jmp .n |
.refill1: |
push eax |
call .refill |
pop eax |
jmp .refilled1 |
.refill: |
mov eax, [ebp+.inStream] |
cmp dword [eax+streamInfo.fullSize+4], 0 |
jnz @f |
cmp dword [eax+streamInfo.fullSize], 0 |
jz return.err |
@@: |
call fillBuf |
mov esi, [eax+streamInfo.bufPtr] |
mov eax, [eax+streamInfo.bufDataLen] |
dec eax |
js return.err |
mov [ebp+.inLen], eax |
ret |
.refill2: |
call .refill |
jmp .refilled2 |
.RangeDecoderDecodeDirectBits: |
; in: ecx=numTotalBits |
; out: eax=result; destroys edx |
xor eax, eax |
.l: |
shr [ebp+.range], 1 |
shl eax, 1 |
mov edx, [ebp+.code] |
sub edx, [ebp+.range] |
jb @f |
mov [ebp+.code], edx |
or eax, 1 |
@@: |
cmp [ebp+.range], .kTopValue |
jae @f |
shl [ebp+.range], 8 |
shl [ebp+.code], 8 |
push eax |
dec [ebp+.inLen] |
js .refill2 |
.refilled2: |
lodsb |
mov byte [ebp+.code], al |
pop eax |
@@: |
loop .l |
ret |
.LzmaLiteralDecode: |
; in: eax->probs |
; out: al=byte; destroys edx |
push ecx |
mov ecx, 1 |
@@: |
push eax |
lea eax, [eax+ecx*4] |
call .RangeDecoderBitDecode |
pop eax |
adc cl, cl |
jnc @b |
.LzmaLiteralDecode.ret: |
mov al, cl |
pop ecx |
ret |
.LzmaLiteralDecodeMatch: |
; in: eax->probs, dl=matchByte |
; out: al=byte; destroys edx |
push ecx |
mov ecx, 1 |
.LzmaLiteralDecodeMatch.1: |
add dl, dl |
setc ch |
push eax |
lea eax, [eax+ecx*4+0x100*4] |
call .RangeDecoderBitDecode |
pop eax |
adc cl, cl |
jc .LzmaLiteralDecode.ret |
xor ch, cl |
test ch, 1 |
mov ch, 0 |
jnz @b |
jmp .LzmaLiteralDecodeMatch.1 |
.LzmaLenDecode: |
; in: eax->prob, edx=posState |
; out: ecx=len |
push eax |
add eax, .LenChoice*4 |
call .RangeDecoderBitDecode |
pop eax |
jnc .0 |
push eax |
add eax, .LenChoice2*4 |
call .RangeDecoderBitDecode |
pop eax |
jc @f |
mov ecx, .kLenNumMidBits |
shl edx, cl |
lea eax, [eax + .LenMid*4 + edx*4] |
call .RangeDecoderBitTreeDecode |
add ecx, .kLenNumLowSymbols |
ret |
@@: |
add eax, .LenHigh*4 |
mov ecx, .kLenNumHighBits |
call .RangeDecoderBitTreeDecode |
add ecx, .kLenNumLowSymbols + .kLenNumMidSymbols |
ret |
.0: |
mov ecx, .kLenNumLowBits |
shl edx, cl |
lea eax, [eax + .LenLow*4 + edx*4] |
.RangeDecoderBitTreeDecode: |
; in: eax->probs,ecx=numLevels |
; out: ecx=length; destroys edx |
push ebx |
mov edx, 1 |
mov ebx, edx |
@@: |
push eax |
lea eax, [eax+edx*4] |
call .RangeDecoderBitDecode |
pop eax |
adc dl, dl |
add bl, bl |
loop @b |
sub dl, bl |
pop ebx |
mov ecx, edx |
ret |
.RangeDecoderReverseBitTreeDecode: |
; in: eax->probs,ecx=numLevels |
; out: ecx=length; destroys edx |
push ebx ecx |
mov edx, 1 |
xor ebx, ebx |
@@: |
push eax |
lea eax, [eax+edx*4] |
call .RangeDecoderBitDecode |
lahf |
adc edx, edx |
sahf |
rcr ebx, 1 |
pop eax |
loop @b |
pop ecx |
rol ebx, cl |
mov ecx, ebx |
pop ebx |
ret |
; LZMA parameters: |
; db lc + 9 * (lp + 5 * pb) |
; dd dictionarySize |
lzma_get_buf_size: |
cmp dword [esi-4], 5 |
jb return.err |
push ecx |
lodsb |
aam 9 |
mov cl, al |
mov al, ah |
aam 5 |
add cl, al |
mov eax, LZMA_LIT_SIZE |
shl eax, cl |
lea eax, [lzma_decoder.basesize+eax*4] |
pop ecx |
mov edx, [esi] |
ret |
lzma_init_decoder: |
lodsb |
aam 9 |
mov [ebp+lzma_decoder.lc], al |
mov al, ah |
aam 5 |
mov [ebp+lzma_decoder.lp], al |
mov [ebp+lzma_decoder.pb], ah |
cmp ah, lzma_decoder.kNumPosBitsMax |
ja return.err |
mov cl, ah |
lodsd |
mov [ebp+lzma_decoder.dictSize], eax |
push 1 |
pop eax |
shl eax, cl |
dec eax |
mov [ebp+lzma_decoder.posStateMask], eax |
mov cl, [ebp+lzma_decoder.lp] |
push 1 |
pop eax |
shl eax, cl |
dec eax |
mov [ebp+lzma_decoder.literalPosMask], eax |
mov [ebp+streamInfo.fillBuf], lzma_decoder.fillBuf |
mov [ebp+lzma_decoder.continue], lzma_decoder.start |
xor eax, eax |
mov [ebp+lzma_decoder.previousByte], al |
mov [ebp+lzma_decoder.state], eax |
inc eax |
lea edi, [ebp+lzma_decoder.rep0] |
stosd |
stosd |
stosd |
mov eax, LZMA_LIT_SIZE |
mov cl, [ebp+lzma_decoder.lc] |
add cl, [ebp+lzma_decoder.lp] |
shl eax, cl |
lea ecx, [eax+lzma_decoder.Literal] |
mov eax, lzma_decoder.kBitModelTotal/2 |
lea edi, [ebp+lzma_decoder.p] |
rep stosd |
ret |
/programs/fs/kfar/trunk/kfar_arc/ppmd.inc |
---|
0,0 → 1,1485 |
; PPMD decoder, ported from C++ sources of 7-Zip (c) Igor Pavlov |
; C++ code is based on Dmitry Shkarin's PPMdH code |
uglobal |
ppmd_decoder.NS2Indx rb 256 |
ppmd_decoder.NS2BSIndx rb 256 |
ppmd_decoder.HB2Flag rb 256 |
ppmd_decoder.Indx2Units rb ppmd_decoder.N_INDEXES |
ppmd_decoder.Units2Indx rb 128 |
endg |
iglobal |
label ppmd_decoder.InitBinEsc word |
dw 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051 |
ppmd_decoder.ExpEscape db 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 |
endg |
init_ppmd: |
; NS2Indx table |
mov edi, ppmd_decoder.NS2Indx |
xor eax, eax |
stosb |
inc eax |
stosb |
inc eax |
stosb |
mov edx, 3-256 |
@@: |
lea ecx, [eax-1] |
inc eax |
add edx, ecx |
jc @f |
rep stosb |
jmp @b |
@@: |
sub ecx, edx |
rep stosb |
; NS2BSIndx table |
xor eax, eax |
stosb |
add al, 2 |
stosb |
add al, 2 |
mov cl, 9 |
rep stosb |
add al, 2 |
mov cl, 256-11 |
rep stosb |
; HB2Flag table |
mov cl, 0x40/4 |
xor eax, eax |
rep stosd |
mov al, 8 |
mov cl, 0x100-0x40 |
rep stosb |
; Indx2Units table |
mov eax, 0x04030201 |
stosd |
mov eax, 0x0C0A0806 |
stosd |
mov eax, 0x1815120F |
stosd |
mov al, 0x1C |
@@: |
stosb |
add al, 4 |
cmp al, 0x80 |
jbe @b |
; Units2Indx table |
xor eax, eax |
xor edx, edx |
inc edx |
xor ecx, ecx |
@@: |
cmp [ppmd_decoder.Indx2Units+eax], dl |
adc al, 0 |
stosb |
inc edx |
cmp dl, 0x80 |
jbe @b |
ret |
ppmd_decoder: |
virtual at 0 |
; base is standard structure |
.outStream rb streamInfo.size |
.inStream dd ? |
; RangeDecoder data |
.inLen dd ? |
.inPtr dd ? |
.code dd ? |
.range dd ? |
.outSize dd ? ; number of bytes rest for output |
; PPMD data |
.order db ? |
.GlueCount db ? |
.bInited db ? |
rb 1 |
.usedMemorySize dd ? |
; CSubAllocator constants |
.N1 = 4 |
.N2 = 4 |
.N3 = 4 |
.N4 = (128+3-1*.N1-2*.N2-3*.N3)/4 |
.UNIT_SIZE = 12 |
.N_INDEXES = .N1+.N2+.N3+.N4 |
.kExtraSize = .UNIT_SIZE*3 |
.kMaxMemBlockSize = 0xFFFFFFFF - .kExtraSize |
; CSubAllocator data |
.HeapStart dd ? |
.LoUnit dd ? |
.HiUnit dd ? |
.pText dd ? |
.UnitsStart dd ? |
.FreeList rd .N_INDEXES |
; Context constants |
.INT_BITS = 7 |
.PERIOD_BITS = 7 |
.TOT_BITS = .INT_BITS + .PERIOD_BITS |
.INTERVAL = 1 shl .INT_BITS |
.BIN_SCALE = 1 shl .TOT_BITS |
.MAX_FREQ = 124 |
.kMaxOrderCompress = 32 |
.MAX_O = 255 |
; CDecodeInfo (inherits from CInfo) data |
; SEE2_CONTEXT is 4 bytes long |
.SEE2Cont rd 25*16 |
.DummySEE2Cont dd ? |
.MinContext dd ? |
.MaxContext dd ? |
.FoundState dd ? ; found next state transition |
.NumMasked dd ? |
.InitEsc dd ? |
.OrderFall dd ? |
.RunLength dd ? |
.InitRL dd ? |
.CharMask rb 256 |
.EscCount db ? |
.PrintCount db ? |
.PrevSuccess db ? |
.HiBitsFlag db ? |
.BinSumm rw 128*64 |
.basesize = $ |
.Base: |
; rb .kExtraSize + [.usedMemorySize] |
end virtual |
.init: |
mov eax, [eax+.inStream] |
call fillBuf |
mov esi, [eax+streamInfo.bufPtr] |
mov eax, [eax+streamInfo.bufDataLen] |
sub eax, 5 |
jb return.err |
mov [ebp+.inLen], eax |
inc esi |
lodsd |
mov [ebp+.inPtr], esi |
bswap eax |
mov [ebp+.code], eax |
or [ebp+.range], -1 |
mov [ebp+.bInited], 1 |
call .StartModelRare |
mov eax, ebp |
jmp .mainloop |
.fillBuf: |
mov ebp, eax |
mov [eax+.outSize], ecx |
cmp [eax+.bInited], 0 |
jz .init |
.mainloop: |
sub [ebp+.outSize], 1 |
js .mainloopdone |
; cmp edi, 0xde070+0x18 |
; jnz @f |
; int3 |
;@@: |
call .DecodeSymbol |
jmp .mainloop |
.mainloopdone: |
popad |
ret |
.GetBinSumm: |
; CInfo::GetBinSumm(ebx=rs, ecx=numStates) |
movzx eax, [ebp+.PrevSuccess] |
movzx edx, [.NS2BSIndx+ecx-1] |
add eax, edx |
mov edx, [ebp+.FoundState] |
movzx edx, byte [edx] |
movzx edx, [.HB2Flag+edx] |
mov [ebp+.HiBitsFlag], dl |
add eax, edx |
movzx edx, byte [ebx] |
movzx edx, [.HB2Flag+edx] |
lea eax, [eax+edx*2] |
mov edx, [ebp+.RunLength] |
shr edx, 26 |
and edx, 0x20 |
add eax, edx |
movzx edx, byte [ebx+1] |
shl edx, 6 |
add eax, edx |
lea ecx, [ebp+.BinSumm+eax*2-2*64] |
ret |
.StartModelRare: |
; CInfo::StartModelRare(.order) |
mov [ebp+.EscCount], 1 |
mov [ebp+.PrintCount], 1 |
; N.B. |
; 1. Original code has some handling of [.order]<2, but this handling is incorrect |
; and causes exception (access violation). |
; 2. 7-Zip never generates archives with [.order]<2 due to input preprocessing |
; (for PPMd method in switch -mo=<n> archiver checks that 2 <= n <= 32). |
; 3. If manually created archive says [.order]<2, the exception will be generated |
; in StartModelRare, but it will be handled in Code() resulting in "data error". |
cmp [ebp+.order], 2 |
jb return.err |
mov byte [ebp+.DummySEE2Cont+2], .PERIOD_BITS |
.RestartModelRare: |
; CInfo::RestartModelRare(void) |
push edi |
lea edi, [ebp+.CharMask] |
xor eax, eax |
push 0x40 |
pop ecx |
rep stosd |
; CSubAllocator::InitSubAllocator start |
mov [ebp+.GlueCount], al |
lea edi, [ebp+.FreeList] |
mov cl, .N_INDEXES |
rep stosd |
mov ebx, [ebp+.HeapStart] |
mov [ebp+.pText], ebx |
add ebx, [ebp+.usedMemorySize] |
mov [ebp+.HiUnit], ebx |
mov eax, [ebp+.usedMemorySize] |
xor edx, edx |
mov cl, 8*.UNIT_SIZE |
div ecx |
imul eax, 7*.UNIT_SIZE |
sub ebx, eax |
mov [ebp+.LoUnit], ebx |
mov [ebp+.UnitsStart], ebx |
; CSubAllocator::InitSubAllocator end |
pop edi |
movzx eax, [ebp+.order] |
cmp al, 12 |
jb @f |
mov al, 12 |
@@: |
neg eax |
dec eax |
mov [ebp+.InitRL], eax |
mov [ebp+.RunLength], eax |
call .AllocContext |
mov [ebp+.MinContext], eax |
mov [ebp+.MaxContext], eax |
and dword [eax+8], 0 |
mov esi, eax |
movzx edx, [ebp+.order] |
mov [ebp+.OrderFall], edx |
mov dword [eax], 257*10000h+256 |
mov ecx, 256/2 |
call .AllocUnits |
mov [ebp+.FoundState], eax |
mov [esi+4], eax |
push edi |
mov edi, eax |
xor eax, eax |
mov [ebp+.PrevSuccess], al |
@@: |
stosb |
mov byte [edi], 1 |
and dword [edi+1], 0 |
add edi, 5 |
inc al |
jnz @b |
lea edi, [ebp+.BinSumm] |
push 2 |
pop ecx |
.rmr1: |
mov esi, .InitBinEsc |
@@: |
lodsw |
xor edx, edx |
div ecx |
sub eax, .BIN_SCALE |
neg eax |
mov [edi+2*8], ax |
mov [edi+2*16], ax |
mov [edi+2*24], ax |
mov [edi+2*32], ax |
mov [edi+2*40], ax |
mov [edi+2*48], ax |
mov [edi+2*56], ax |
stosw |
cmp esi, .InitBinEsc+2*8 |
jb @b |
add edi, 128-16 |
inc ecx |
cmp ecx, 128+2 |
jb .rmr1 |
lea edi, [ebp+.SEE2Cont] |
mov eax, (10 shl (.PERIOD_BITS-4)) + ((.PERIOD_BITS-4) shl 16) + (4 shl 24) |
push 25 |
pop edx |
@@: |
push 16 |
pop ecx |
rep stosd |
add ax, 5 shl (.PERIOD_BITS-4) |
dec edx |
jnz @b |
pop edi |
ret |
.CreateSuccessors: |
; CInfo::CreateSuccessors(bool al=skip,STATE* esi=p1) |
push ebx edi |
mov ebx, [ebp+.MinContext] ; ebx=pc |
mov ecx, [ebp+.FoundState] |
mov ecx, [ecx+2] ; ecx=UpBranch |
sub esp, .MAX_O*4 ; esp=ps |
mov edi, esp ; edi=pps |
test al, al |
jnz @f |
mov eax, [ebp+.FoundState] |
stosd |
cmp dword [ebx+8], 0 |
jz .csnoloop |
@@: |
test esi, esi |
jz .csloopstart |
mov edx, esi ; edx=p |
mov ebx, [ebx+8] |
jmp .csloopentry |
.csloopstart: |
mov ebx, [ebx+8] |
lea edx, [ebx+2] |
cmp word [ebx], 1 |
jz .csloopentry |
mov edx, [ebx+4] |
mov eax, [ebp+.FoundState] |
sub edx, 6 |
mov al, [eax] |
@@: |
add edx, 6 |
cmp al, [edx] |
jnz @b |
.csloopentry: |
cmp ecx, [edx+2] |
jz @f |
mov ebx, [edx+2] |
jmp .csnoloop |
@@: |
mov [edi], edx |
add edi, 4 |
cmp dword [ebx+8], 0 |
jnz .csloopstart |
.csnoloop: |
cmp edi, esp |
jz .csr |
push eax |
push eax |
mov al, [ecx] |
mov [esp], al |
add ecx, 1 |
mov [esp+2], ecx |
mov ah, [ebx+3] |
cmp word [ebx], 1 |
jz .cs2 |
mov edx, [ebx+4] |
sub edx, 6 |
@@: |
add edx, 6 |
cmp [edx], al |
jnz @b |
movzx edx, byte [edx+1] |
sub edx, 1 ; edx=cf |
movzx ecx, word [ebx+2] |
movzx eax, word [ebx] |
sub ecx, eax |
sub ecx, edx ; ecx=s0 |
lea eax, [edx+edx] |
cmp eax, ecx |
ja .cs0 |
lea eax, [edx*5] |
cmp eax, ecx |
seta ah |
jmp .cs1 |
.cs0: |
lea eax, [eax+ecx*2] |
lea eax, [eax+ecx-1] |
add ecx, ecx |
xor edx, edx |
div ecx |
mov ah, al |
.cs1: |
add ah, 1 |
.cs2: |
mov [esp+1], ah |
sub edi, 8 |
.cs3: |
; PPM_CONTEXT::createChild(this=ebx,pStats=[edi+4],FirstState=esp) begin |
call .AllocContext |
test eax, eax |
jz .csr0 |
mov word [eax], 1 |
mov dx, [esp] |
mov [eax+2], dx |
mov edx, [esp+2] |
mov [eax+4], edx |
mov [eax+8], ebx |
mov edx, [edi+4] |
mov [edx+2], eax |
; PPM_CONTEXT::createChild end |
mov ebx, eax |
sub edi, 4 |
cmp edi, esp |
jnz .cs3 |
pop eax eax |
.csr: |
mov eax, ebx |
@@: |
add esp, .MAX_O*4 |
pop edi ebx |
ret |
.csr0: |
pop eax eax |
xor eax, eax |
jmp @b |
; CInfo::UpdateModel(void) |
.UpdateModel: |
mov ebx, [ebp+.FoundState] |
xor esi, esi ; esi=p |
movzx eax, word [ebx] |
mov ebx, [ebx+2] ; ebx=fs.Successor |
push eax |
cmp ah, .MAX_FREQ/4 |
jae .um2 |
mov eax, [ebp+.MinContext] |
mov eax, [eax+8] |
test eax, eax |
jz .um2 |
cmp word [eax], 1 |
jz .um1 |
push eax |
mov esi, [eax+4] |
mov al, [esp+4] |
cmp al, [esi] |
jz .um0 |
@@: |
add esi, 6 |
cmp al, [esi] |
jnz @b |
mov al, [esi+1] |
cmp al, [esi-6+1] |
jb @f |
mov eax, [esi] |
xchg [esi-6], eax |
mov [esi], eax |
mov ax, [esi+4] |
xchg [esi-6+4], ax |
mov [esi+4], ax |
sub esi, 6 |
@@: |
.um0: |
pop eax |
cmp byte [esi+1], .MAX_FREQ-9 |
jae @f |
add byte [esi+1], 2 |
add word [eax+2], 2 |
@@: |
jmp .um2 |
.um1: |
lea esi, [eax+2] |
cmp byte [esi+1], 32 |
adc byte [esi+1], 0 |
.um2: |
cmp [ebp+.OrderFall], 0 |
jnz .um3 |
pop eax |
mov al, 1 |
call .CreateSuccessors |
mov [ebp+.MinContext], eax |
mov [ebp+.MaxContext], eax |
mov edx, [ebp+.FoundState] |
mov [edx+2], eax |
test eax, eax |
jz .RestartModel |
ret |
.um3: |
mov edx, [ebp+.pText] |
mov al, [esp] |
mov [edx], al |
add edx, 1 ; edx=Successor |
mov [ebp+.pText], edx |
cmp edx, [ebp+.UnitsStart] |
jae .RestartModelPop |
test ebx, ebx |
jz .um4 |
cmp ebx, [ebp+.pText] |
ja @f |
push edx |
xor eax, eax |
call .CreateSuccessors |
pop edx |
mov ebx, eax |
test eax, eax |
jz .RestartModelPop |
@@: |
sub [ebp+.OrderFall], 1 |
jnz @f |
mov edx, ebx |
xor ecx, ecx |
mov eax, [ebp+.MinContext] |
cmp eax, [ebp+.MaxContext] |
setnz cl |
sub [ebp+.pText], ecx |
@@: |
jmp .um5 |
.um4: |
mov eax, [ebp+.FoundState] |
mov [eax+2], edx |
mov ebx, [ebp+.MinContext] |
.um5: |
mov eax, [ebp+.MinContext] |
movzx ecx, word [eax] ; ecx=ns |
movzx eax, word [eax+2] |
sub eax, ecx |
push eax |
movzx eax, byte [esp+5] |
sub eax, 1 |
sub [esp], eax ; [esp]=s0 |
mov esi, [ebp+.MaxContext] ; ebx=pc |
cmp esi, [ebp+.MinContext] |
jz .um12 |
.um6: |
movzx eax, word [esi] |
cmp eax, 1 |
jz .um8 |
push eax |
shr eax, 1 |
jc .um7 |
push esi |
mov esi, [esi+4] |
call .ExpandUnits |
pop esi |
mov [esi+4], eax |
test eax, eax |
jz .RestartModelPop3 |
.um7: |
pop eax |
add eax, eax |
cmp eax, ecx |
adc word [esi+2], 0 |
add eax, eax |
cmp eax, ecx |
ja @f |
lea eax, [eax+eax+1] |
cmp word [esi+2], ax |
ja @f |
add word [esi+2], 2 |
@@: |
push edx |
jmp .um9 |
.um8: |
push edx ecx |
mov ecx, 1 |
call .AllocUnits |
pop ecx |
test eax, eax |
jz .RestartModelPop3 |
mov dx, [esi+2] |
mov [eax], dx |
mov edx, [esi+4] |
mov [eax+2], edx |
mov [esi+4], eax |
movzx edx, byte [eax+1] |
add edx, edx |
cmp edx, (.MAX_FREQ/4-1)*2 |
jb @f |
mov edx, .MAX_FREQ-4 |
@@: |
mov [eax+1], dl |
add edx, [ebp+.InitEsc] |
cmp ecx, 4 |
sbb edx, -1 |
mov [esi+2], dx |
.um9: |
movzx edx, word [esi+2] |
mov eax, [esp+4] |
push ecx |
lea ecx, [eax+edx] ; ecx=sf |
add edx, 6 |
movzx eax, byte [esp+13] |
add eax, eax |
imul eax, edx ; eax=cf |
lea edx, [ecx*3] |
add edx, edx |
cmp eax, edx |
jae .um10 |
mov edx, 1 |
cmp ecx, eax |
adc edx, 0 |
shl ecx, 2 |
add eax, 1 |
cmp ecx, eax |
adc edx, 0 |
add word [esi+2], 3 |
jmp .um11 |
.um10: |
lea ecx, [ecx*3] |
lea edx, [ecx*3] |
add eax, 1 |
push 4 |
cmp edx, eax |
adc dword [esp], 0 |
add edx, ecx |
cmp edx, eax |
adc dword [esp], 0 |
add edx, ecx |
cmp edx, eax |
adc dword [esp], 0 |
pop edx |
add [esi+2], dx |
.um11: |
movzx eax, word [esi] |
lea eax, [eax*3] |
add eax, eax |
add eax, [esi+4] |
mov ecx, [esp+4] |
mov [eax+2], ecx |
mov cl, [esp+12] |
mov [eax], cl |
mov [eax+1], dl |
add word [esi], 1 |
pop ecx edx |
mov esi, [esi+8] |
cmp esi, [ebp+.MinContext] |
jnz .um6 |
.um12: |
pop eax |
pop eax |
mov [ebp+.MinContext], ebx |
mov [ebp+.MaxContext], ebx |
ret |
.RestartModelPop3: |
pop eax |
pop eax |
.RestartModelPop: |
pop eax |
.RestartModel: |
call .RestartModelRare |
mov [ebp+.EscCount], 0 |
mov [ebp+.PrintCount], 0xFF |
ret |
.rescale: |
mov esi, [ebp+.MinContext] |
movzx ecx, word [esi] |
push ecx ; [esp]=OldNS |
sub ecx, 1 |
mov ebx, [ebp+.FoundState] |
cmp ebx, [esi+4] |
jz .r1 |
.r0: |
mov ax, [ebx] |
xchg [ebx-6], ax |
mov [ebx], ax |
mov eax, [ebx+2] |
xchg [ebx-6+2], eax |
mov [ebx+2], eax |
sub ebx, 6 |
cmp ebx, [esi+4] |
jnz .r0 |
.r1: |
add byte [ebx+1], 4 |
add word [esi+2], 4 |
movzx eax, byte [ebx+1] |
movzx edx, word [esi+2] |
sub edx, eax ; edx=EscFreq |
cmp [ebp+.OrderFall], 1 |
sbb eax, -1 |
shr eax, 1 |
mov [ebx+1], al |
mov [esi+2], ax |
.r2: |
add ebx, 6 |
movzx eax, byte [ebx+1] |
sub edx, eax |
cmp [ebp+.OrderFall], 1 |
sbb eax, -1 |
shr eax, 1 |
mov [ebx+1], al |
add [esi+2], ax |
cmp al, [ebx-6+1] |
jbe .r3 |
push ecx |
push ebx |
push dword [ebx] |
push word [ebx+4] |
@@: |
mov ecx, [ebx-6] |
mov [ebx], ecx |
mov cx, [ebx-6+4] |
mov [ebx+4], cx |
sub ebx, 6 |
cmp ebx, [esi+4] |
jz @f |
cmp al, [ebx-6+1] |
ja @b |
@@: |
pop word [ebx+4] |
pop dword [ebx] |
pop ebx |
pop ecx |
.r3: |
sub ecx, 1 |
jnz .r2 |
cmp byte [ebx+1], 0 |
jnz .r4 |
@@: |
add ecx, 1 |
sub ebx, 6 |
cmp byte [ebx+1], 0 |
jz @b |
add edx, ecx |
sub word [esi], cx |
cmp word [esi], 1 |
jnz .r4 |
pop ebx |
mov eax, [esi+4] |
movzx ecx, word [eax+4] |
push ecx |
push dword [eax] |
movzx eax, byte [eax+1] |
@@: |
add eax, 1 |
shr eax, 1 |
shr edx, 1 |
cmp edx, 1 |
ja @b |
mov [esp+1], al |
add ebx, 1 |
shr ebx, 1 |
mov eax, [esi+4] |
call .FreeUnits |
lea ebx, [esi+2] |
mov [ebp+.FoundState], ebx |
pop dword [ebx] |
pop eax |
mov [ebx+4], ax |
ret |
.r4: |
add edx, 1 |
shr edx, 1 |
add [esi+2], dx |
pop ebx |
add ebx, 1 |
shr ebx, 1 |
movzx ecx, word [esi] |
add ecx, 1 |
shr ecx, 1 |
cmp ebx, ecx |
jz @f |
mov eax, [esi+4] |
call .ShrinkUnits |
mov [esi+4], eax |
@@: |
mov eax, [esi+4] |
mov [ebp+.FoundState], eax |
ret |
.DecodeSymbol: |
; CDecodeInfo::DecodeSymbol |
mov esi, [ebp+.MinContext] |
cmp word [esi], 1 |
jz .binsymbol |
; CDecodeInfo::DecodeSymbol1 start |
mov ebx, [esi+4] ; state |
movzx ecx, word [esi+2] |
mov eax, [ebp+.range] |
xor edx, edx |
div ecx |
mov [ebp+.range], eax |
mov ecx, eax |
mov eax, [ebp+.code] |
xor edx, edx |
div ecx |
movzx edx, byte [ebx+1] |
cmp eax, edx |
jae .ds0 |
push edx |
add edx, edx |
cmp dx, [esi+2] |
pop edx |
seta [ebp+.PrevSuccess] |
movzx eax, [ebp+.PrevSuccess] |
add [ebp+.RunLength], eax |
xor eax, eax |
call .RangeDecoder.Decode |
mov [ebp+.FoundState], ebx |
add edx, 4 |
mov [ebx+1], dl |
add word [esi+2], 4 |
cmp edx, .MAX_FREQ |
jbe @f |
call .rescale |
@@: |
jmp .dscmn |
.ds0: |
mov [ebp+.PrevSuccess], 0 |
movzx ecx, word [esi] |
sub ecx, 1 |
push eax |
.ds1: |
add ebx, 6 |
movzx eax, byte [ebx+1] |
add edx, eax |
cmp edx, [esp] |
ja .ds2 |
sub ecx, 1 |
jnz .ds1 |
pop eax |
mov eax, [ebp+.FoundState] |
movzx eax, byte [eax] |
mov al, [.HB2Flag+eax] |
mov [ebp+.HiBitsFlag], al |
mov eax, edx |
movzx edx, word [esi+2] |
sub edx, eax |
call .RangeDecoder.Decode |
mov al, [ebp+.EscCount] |
movzx edx, byte [ebx] |
mov [ebp+.CharMask+edx], al |
movzx ecx, word [esi] |
mov [ebp+.NumMasked], ecx |
sub ecx, 1 |
@@: |
sub ebx, 6 |
movzx edx, byte [ebx] |
mov [ebp+.CharMask+edx], al |
sub ecx, 1 |
jnz @b |
mov [ebp+.FoundState], ecx |
jmp .dscmn |
.ds2: |
pop eax |
mov eax, edx |
movzx edx, byte [ebx+1] |
sub eax, edx |
call .RangeDecoder.Decode |
.update1: |
mov [ebp+.FoundState], ebx |
add byte [ebx+1], 4 |
add word [esi+2], 4 |
mov al, [ebx+1] |
cmp al, [ebx-6+1] |
jbe @f |
mov eax, [ebx] |
xchg eax, [ebx-6] |
mov [ebx], eax |
mov ax, [ebx+4] |
xchg ax, [ebx-6+4] |
mov [ebx+4], ax |
sub ebx, 6 |
mov [ebp+.FoundState], ebx |
cmp byte [ebx+1], .MAX_FREQ |
jbe @f |
call .rescale |
@@: |
jmp .dscmn |
; CDecodeInfo::DecodeSymbol1 end |
.binsymbol: |
; CDecodeInfo::DecodeBinSymbol start |
lea ebx, [esi+2] |
mov ecx, [esi+8] |
movzx ecx, word [ecx] |
call .GetBinSumm |
movzx eax, word [ecx] |
call .RangeDecoder.DecodeBit |
jc .ds3 |
mov [ebp+.FoundState], ebx |
cmp byte [ebx+1], 128 |
adc byte [ebx+1], 0 |
movzx eax, word [ecx] |
add eax, 1 shl (.PERIOD_BITS-2) |
shr eax, .PERIOD_BITS |
sub eax, .INTERVAL |
sub [ecx], ax |
mov [ebp+.PrevSuccess], 1 |
add [ebp+.RunLength], 1 |
jmp .dscmn |
.ds3: |
movzx eax, word [ecx] |
add eax, 1 shl (.PERIOD_BITS-2) |
shr eax, .PERIOD_BITS |
sub [ecx], ax |
movzx eax, word [ecx] |
shr eax, 10 |
movzx eax, [.ExpEscape+eax] |
mov [ebp+.InitEsc], eax |
mov [ebp+.NumMasked], 1 |
mov al, [ebp+.EscCount] |
movzx edx, byte [ebx] |
mov [ebp+.CharMask+edx], al |
mov [ebp+.PrevSuccess], 0 |
and [ebp+.FoundState], 0 |
; CDecodeInfo::DecodeBinSymbol end |
.dscmn: |
cmp [ebp+.FoundState], 0 |
jnz .dsfnd |
.ds4: |
add [ebp+.OrderFall], 1 |
mov eax, [ebp+.MinContext] |
mov eax, [eax+8] |
test eax, eax |
jz return.err ; no end-of-stream mark |
mov [ebp+.MinContext], eax |
movzx ecx, word [eax] |
sub ecx, [ebp+.NumMasked] |
jz .ds4 |
; CDecodeInfo::DecodeSymbol2 start |
call .makeEscFreq2 |
push eax |
mov ebx, [esi+4] |
sub ebx, 6 |
sub esp, 256*4 |
mov esi, esp |
xor eax, eax |
push eax |
@@: |
add ebx, 6 |
mov al, [ebx] |
mov al, [ebp+.CharMask+eax] |
cmp al, [ebp+.EscCount] |
jz @b |
mov al, [ebx+1] |
add [esp], eax |
mov [esi], ebx |
add esi, 4 |
sub ecx, 1 |
jnz @b |
add edx, [esp] |
mov ecx, edx |
mov eax, [ebp+.range] |
xor edx, edx |
div ecx |
mov [ebp+.range], eax |
mov eax, [ebp+.code] |
xor edx, edx |
div [ebp+.range] |
cmp eax, [esp] |
jae .ds5 |
pop ecx |
mov esi, esp |
xor ecx, ecx |
@@: |
mov ebx, [esi] |
add esi, 4 |
movzx edx, byte [ebx+1] |
add ecx, edx |
cmp eax, ecx |
jae @b |
mov eax, ecx |
movzx edx, byte [ebx+1] |
sub eax, edx |
call .RangeDecoder.Decode |
add esp, 256*4 |
pop eax |
mov cl, [eax+2] |
cmp cl, .PERIOD_BITS |
jae @f |
sub byte [eax+3], 1 |
jnz @f |
shl word [eax], 1 |
mov dl, 3 |
shl dl, cl |
mov [eax+3], dl |
add byte [eax+2], 1 |
@@: |
.update2: |
mov [ebp+.FoundState], ebx |
add byte [ebx+1], 4 |
mov esi, [ebp+.MinContext] |
add word [esi+2], 4 |
cmp byte [ebx+1], .MAX_FREQ |
jbe @f |
call .rescale |
@@: |
add [ebp+.EscCount], 1 |
mov eax, [ebp+.InitRL] |
mov [ebp+.RunLength], eax |
jmp .dsfnd |
.ds5: |
pop eax |
mov edx, ecx |
sub edx, eax |
call .RangeDecoder.Decode |
mov eax, [ebp+.MinContext] |
movzx eax, word [eax] |
mov ebx, eax |
sub ebx, [ebp+.NumMasked] |
mov [ebp+.NumMasked], eax |
mov esi, esp |
mov al, [ebp+.EscCount] |
@@: |
mov edx, [esi] |
add esi, 4 |
movzx edx, byte [edx] |
mov [ebp+.CharMask+edx], al |
sub ebx, 1 |
jnz @b |
add esp, 256*4 |
pop eax |
add word [eax], cx |
; CDecodeInfo::DecodeSymbol2 end |
cmp [ebp+.FoundState], 0 |
jz .ds4 |
.dsfnd: |
mov eax, [ebp+.FoundState] |
mov al, [eax] |
stosb |
.NextContext: |
; CInfo::NextContext(void) |
mov ebx, [ebp+.FoundState] |
mov ebx, [ebx+2] |
cmp [ebp+.OrderFall], 0 |
jnz .nc0 |
cmp ebx, [ebp+.pText] |
jbe .nc0 |
mov [ebp+.MinContext], ebx |
mov [ebp+.MaxContext], ebx |
ret |
.nc0: |
call .UpdateModel |
cmp [ebp+.EscCount], 0 |
jz @f |
ret |
@@: |
mov [ebp+.EscCount], 1 |
push edi |
lea edi, [ebp+.CharMask] |
mov ecx, 256/4 |
xor eax, eax |
rep stosd |
pop edi |
ret |
.makeEscFreq2: |
; CInfo::makeEscFreq2(ecx=Diff)->{eax->SEE2_CONTEXT,edx=scale} |
mov esi, [ebp+.MinContext] |
cmp word [esi], 256 |
jz .mef0 |
movzx edx, [.NS2Indx+ecx-1] |
shl edx, 4 |
mov eax, [esi+8] |
movzx eax, word [eax] |
sub ax, [esi] |
cmp ecx, eax |
adc edx, 0 |
movzx eax, word [esi] |
push edx |
lea edx, [eax*9] |
lea edx, [edx+eax*2] |
movzx eax, word [esi+2] |
cmp eax, edx |
pop edx |
setc al |
movzx eax, al |
lea edx, [edx+eax*2] |
cmp ecx, [ebp+.NumMasked] |
setc al |
lea edx, [edx+eax*4] |
add dl, [ebp+.HiBitsFlag] |
lea eax, [ebp+edx*4+.SEE2Cont] |
movzx edx, word [eax] |
push ecx |
mov cl, [eax+2] |
shr edx, cl |
sub [eax], dx |
pop ecx |
cmp edx, 1 |
adc edx, 0 |
ret |
.mef0: |
lea eax, [ebp+.DummySEE2Cont] |
mov edx, 1 |
ret |
.RangeDecoder.DecodeBit: |
; CRangeDecoder::DecodeBit(eax=size0,numTotalBits=.TOT_BITS) |
mov edx, [ebp+.range] |
shr edx, .TOT_BITS |
imul eax, edx |
cmp [ebp+.code], eax |
jae .rddb |
mov [ebp+.range], eax |
call .RangeDecoder.Normalize |
clc |
ret |
.rddb: |
sub [ebp+.code], eax |
sub [ebp+.range], eax |
call .RangeDecoder.Normalize |
stc |
ret |
.RangeDecoder.Decode: |
imul eax, [ebp+.range] |
sub [ebp+.code], eax |
mov eax, [ebp+.range] |
imul eax, edx |
mov [ebp+.range], eax |
.RangeDecoder.Normalize: |
cmp byte [ebp+.range+3], 0 |
jz @f |
ret |
@@: |
sub [ebp+.inLen], 1 |
js .refill |
.filled: |
shl [ebp+.range], 8 |
shl [ebp+.code], 8 |
mov eax, [ebp+.inPtr] |
add [ebp+.inPtr], 1 |
mov al, [eax] |
mov byte [ebp+.code], al |
jmp .RangeDecoder.Normalize |
.refill: |
mov eax, [ebp+.inStream] |
call fillBuf |
push [eax+streamInfo.bufPtr] |
pop [ebp+.inPtr] |
mov eax, [eax+streamInfo.bufDataLen] |
sub eax, 1 |
js return.err |
mov [ebp+.inLen], eax |
jmp .filled |
.GlueFreeBlocks: |
; CSubAllocator::GlueFreeBlocks, called from AllocUnitsRare |
push eax |
mov [ebp+.GlueCount], 255 |
mov edx, [ebp+.HeapStart] |
add edx, [ebp+.usedMemorySize] |
; we need add extra MEM_BLK with Stamp=0 |
and word [edx], 0 |
add edx, .UNIT_SIZE |
mov eax, [ebp+.LoUnit] |
cmp eax, [ebp+.HiUnit] |
jz @f |
mov byte [eax], 0 |
@@: |
mov [edx+4], edx |
mov [edx+8], edx |
push ecx |
xor ecx, ecx |
.gfb1: |
mov eax, [ebp+ecx*4+.FreeList] |
test eax, eax |
jz .gfb2 |
push dword [eax] |
pop dword [ebp+ecx*4+.FreeList] |
mov [eax+8], edx |
push edx |
mov edx, [edx+4] |
mov [eax+4], edx |
mov [edx+8], eax |
or word [eax], 0xFFFF |
movzx edx, [.Indx2Units+ecx] |
mov [eax+2], dx |
pop edx |
mov [edx+4], eax |
jmp .gfb1 |
.gfb2: |
inc ecx |
cmp ecx, .N_INDEXES |
jb .gfb1 |
mov ecx, edx |
.gfb3: |
mov ecx, [ecx+4] |
cmp ecx, edx |
jz .gfb5 |
.gfb4: |
movzx eax, word [ecx+2] |
lea eax, [eax*3] |
lea eax, [ecx+eax*4] |
cmp word [eax], 0xFFFF |
jnz .gfb3 |
push eax |
mov ax, [eax+2] |
add ax, [ecx+2] |
pop eax |
jc .gfb3 |
push edx |
mov edx, [eax+4] |
push dword [eax+8] |
pop dword [edx+8] |
mov edx, [eax+8] |
push dword [eax+4] |
pop dword [edx+4] |
pop edx |
mov ax, [eax+2] |
add [ecx+2], ax |
jmp .gfb4 |
.gfb5: |
mov ecx, [edx+4] |
cmp ecx, edx |
jz .gfb8 |
mov eax, [ecx+4] |
mov [eax+8], edx |
mov [edx+4], eax |
movzx eax, word [ecx+2] |
push edx |
.gfb6: |
sub eax, 128 |
jbe .gfb7 |
mov edx, ecx |
xchg edx, [ebp+.FreeList+(.N_INDEXES-1)*4] |
mov [ecx], edx |
add ecx, 128*.UNIT_SIZE |
jmp .gfb6 |
.gfb7: |
add eax, 128 |
movzx edx, [.Units2Indx+eax-1] |
cmp [.Indx2Units+edx], al |
jz @f |
dec edx |
push edx |
movzx edx, [.Indx2Units+edx] |
sub eax, edx |
lea eax, [ebp+.FreeList+(eax-1)*4] |
lea edx, [edx*3] |
lea edx, [ecx+edx*4] |
push dword [eax] |
pop dword [edx] |
mov [eax], edx |
pop edx |
@@: |
mov eax, ecx |
xchg eax, [ebp+.FreeList+edx*4] |
mov [ecx], eax |
pop edx |
jmp .gfb5 |
.gfb8: |
pop ecx |
pop eax |
mov edx, [ebp+.FreeList+eax*4] |
test edx, edx |
jz .aur.cont |
push edx |
mov edx, [edx] |
mov [ebp+.FreeList+eax*4], edx |
pop eax |
ret |
.AllocContext: |
; CSubAllocator::AllocContext |
mov eax, [ebp+.HiUnit] |
cmp eax, [ebp+.LoUnit] |
jz @f |
sub eax, .UNIT_SIZE |
mov [ebp+.HiUnit], eax |
ret |
@@: |
mov eax, [ebp+.FreeList] |
test eax, eax |
jz @f |
mov edx, [eax] |
mov [ebp+.FreeList], edx |
ret |
@@: |
xor eax, eax |
jmp .AllocUnitsRare |
.AllocUnits: |
; CSubAllocator::AllocUnits(ecx) |
movzx ecx, [.Units2Indx+ecx-1] |
mov eax, [ebp+.FreeList+ecx*4] |
test eax, eax |
jz @f |
mov edx, [eax] |
mov [ebp+.FreeList+ecx*4], edx |
ret |
@@: |
mov eax, [ebp+.LoUnit] |
movzx edx, [.Indx2Units+ecx] |
lea edx, [edx*3] |
lea eax, [eax+edx*4] |
cmp eax, [ebp+.HiUnit] |
ja @f |
xchg eax, [ebp+.LoUnit] |
ret |
@@: |
mov eax, ecx |
.AllocUnitsRare: |
; CSubAllocator::AllocUnitsRare(eax) |
cmp [ebp+.GlueCount], 0 |
jz .GlueFreeBlocks |
.aur.cont: |
push eax |
.aur1: |
inc eax |
cmp eax, .N_INDEXES |
jz .aur3 |
mov edx, [ebp+.FreeList+eax*4] |
test edx, edx |
jz .aur1 |
push edx |
mov edx, [edx] |
mov [ebp+.FreeList+eax*4], edx |
call .SplitBlock |
pop eax |
pop edx |
ret |
.aur3: |
dec [ebp+.GlueCount] |
pop eax |
movzx eax, [.Indx2Units+eax] |
lea edx, [eax*3] |
shl edx, 2 |
mov eax, [ebp+.UnitsStart] |
sub eax, [ebp+.pText] |
cmp eax, edx |
jbe .aur4 |
mov eax, [ebp+.UnitsStart] |
sub eax, edx |
mov [ebp+.UnitsStart], eax |
ret |
.aur4: |
xor eax, eax |
ret |
.SplitBlock: |
; CSubAllocator::SplitBlock(pv=[esp+4],oldIndx=eax,newIndx=[esp+8]) |
push eax |
mov edx, [esp+12] |
movzx eax, [.Indx2Units+eax] |
movzx edx, [.Indx2Units+edx] |
sub eax, edx |
lea edx, [edx*3] |
push ecx |
mov ecx, [esp+12] |
lea ecx, [ecx+edx*4] |
movzx edx, [.Units2Indx+eax-1] |
cmp [.Indx2Units+edx], al |
jz .aur2 |
push dword [ebp+.FreeList+(edx-1)*4] |
pop dword [ecx] |
mov [ebp+.FreeList+(edx-1)*4], ecx |
movzx edx, [.Indx2Units+edx-1] |
sub eax, edx |
lea edx, [edx*3] |
lea ecx, [ecx+edx*4] |
.aur2: |
movzx eax, [.Units2Indx+eax-1] |
push dword [ebp+.FreeList+eax*4] |
pop dword [ecx] |
mov [ebp+.FreeList+eax*4], ecx |
pop ecx |
pop eax |
ret |
.ExpandUnits: |
; CSubAllocator::ExpandUnits(void* oldPtr=esi, int oldNU=eax) |
push edx |
movzx edx, [.Units2Indx + eax - 1] |
cmp dl, [.Units2Indx + eax] |
jnz @f |
pop edx |
mov eax, esi |
ret |
@@: |
push eax ecx edx |
lea ecx, [eax+1] |
call .AllocUnits |
pop edx |
test eax, eax |
jz @f |
push esi edi |
mov edi, eax |
mov ecx, [esp+8+4] |
lea ecx, [ecx*3] |
rep movsd |
pop edi esi |
mov ecx, [ebp+.FreeList+edx*4] |
mov [esi], ecx |
mov [ebp+.FreeList+edx*4], esi |
@@: |
pop ecx |
add esp, 4 |
pop edx |
ret |
.ShrinkUnits: |
; CSubAllocator::ShrinkUnits(void* oldPtr=eax, int oldNU=ebx, int newNU=ecx) |
push ecx |
movzx ebx, [.Units2Indx+ebx-1] |
movzx ecx, [.Units2Indx+ecx-1] |
cmp ebx, ecx |
jnz @f |
pop ecx |
ret |
@@: |
mov edx, [ebp+.FreeList+ecx*4] |
test edx, edx |
jz @f |
push dword [edx] |
pop [ebp+.FreeList+ecx*4] |
pop ecx |
push esi edi |
mov esi, eax |
mov edi, edx |
lea ecx, [ecx*3] |
rep movsd |
pop edi esi |
mov ecx, [ebp+.FreeList+ebx*4] |
mov [eax], ecx |
mov [ebp+.FreeList+ebx*4], eax |
mov eax, edx |
ret |
@@: |
push ecx |
push eax |
mov eax, ebx |
call .SplitBlock |
pop eax |
pop ecx |
pop ecx |
ret |
.FreeUnits: |
; CSubAllocator::FreeUnits(void* ptr=eax, int oldNU=ebx) |
movzx ebx, [.Units2Indx+ebx-1] |
push [ebp+.FreeList+ebx*4] |
pop dword [eax] |
mov [ebp+.FreeList+ebx*4], eax |
ret |
ppmd_get_buf_size: |
cmp dword [esi-4], 5 |
jb return.err |
lodsb |
lodsd |
cmp eax, ppmd_decoder.kMaxMemBlockSize |
ja return.err |
add eax, ppmd_decoder.basesize + ppmd_decoder.kExtraSize |
mov edx, 0x4000 |
ret |
ppmd_init_decoder: |
mov [ebp+ppmd_decoder.bInited], 0 |
; CDecoder::SetDecoderProperties2 |
lodsb |
mov [ebp+ppmd_decoder.order], al |
lodsd |
mov [ebp+ppmd_decoder.usedMemorySize], eax |
; CSubAllocator::CSubAllocator |
xor eax, eax |
mov [ebp+ppmd_decoder.GlueCount], al |
lea edi, [ebp+ppmd_decoder.LoUnit] |
mov ecx, (ppmd_decoder.SEE2Cont - ppmd_decoder.LoUnit)/4 |
rep stosd |
; CSubAllocator::StartSubAllocator |
lea eax, [ebp+ppmd_decoder.Base+ppmd_decoder.UNIT_SIZE] |
mov [ebp+ppmd_decoder.HeapStart], eax |
mov [ebp+streamInfo.fillBuf], ppmd_decoder.fillBuf |
ret |
/programs/fs/kfar/trunk/kfar_arc/sha256.inc |
---|
0,0 → 1,238 |
; Implementation of SHA-256 hash algorithm. |
; Written by diamond in 2007. |
iglobal |
align 4 |
sha256_start_digest: |
dd 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A |
dd 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 |
sha256_const: |
dd 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5 |
dd 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5 |
dd 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3 |
dd 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174 |
dd 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC |
dd 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA |
dd 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7 |
dd 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967 |
dd 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13 |
dd 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85 |
dd 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3 |
dd 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070 |
dd 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5 |
dd 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3 |
dd 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208 |
dd 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 |
endg |
uglobal |
align 4 |
sha256_buf rb 64 |
sha256_digest rd 8 |
sha256_count dd ? |
sha256_size dq ? |
endg |
sha256_init: |
mov edi, sha256_digest |
mov esi, sha256_start_digest |
push 8 |
pop ecx |
rep movsd |
xor eax, eax |
stosd ; 0 bytes in buffer |
stosd |
stosd ; 0 bytes processed |
ret |
; Core of SHA-256: transform 64-byte 'sha256_buf' to updated 'sha256_digest' |
sha256_transform: |
mov esi, sha256_buf |
mov edi, esi |
rept 16 |
{ |
lodsd |
bswap eax |
stosd |
} |
push ebp |
mov ebp, [esi+7*4] |
mov edi, [esi+6*4] |
push dword [esi+5*4] |
push dword [esi+4*4] |
push dword [esi+3*4] |
push dword [esi+2*4] |
push dword [esi+1*4] |
push dword [esi+0*4] |
xor ecx, ecx |
.loop: |
macro cmd1 cmd,a,b |
{ |
if (b and 7) = 7 |
cmd a, ebp |
else if (b and 7) = 6 |
cmd a, edi |
else |
cmd a, [esp+(b and 7)*4] |
end if |
} |
macro cmd2 cmd,a,b |
{ |
if (a and 7) = 7 |
cmd ebp, b |
else if (a and 7) = 6 |
cmd edi, b |
else |
cmd [esp+(a and 7)*4], b |
end if |
} |
rept 16 counter |
{ |
cmd1 mov, eax, (5-counter) |
ror eax, 6 |
mov edx, eax |
ror eax, 5 |
xor edx, eax |
ror eax, 14 |
xor edx, eax |
cmd1 mov, eax, (6-counter) |
cmd1 mov, esi, (7-counter) |
xor eax, esi |
cmd1 and, eax, (5-counter) |
xor eax, esi |
add edx, eax |
add edx, [sha256_const+ecx+(counter-1)*4] |
add edx, dword [sha256_buf+(counter-1)*4] |
test ecx, ecx |
jz @f |
mov eax, dword [sha256_buf+((counter-3) and 15)*4] |
mov esi, eax |
ror eax, 17 |
shr esi, 10 |
xor esi, eax |
ror eax, 2 |
xor esi, eax |
add esi, dword [sha256_buf+((counter-8) and 15)*4] |
mov eax, dword [sha256_buf+(counter and 15)*4] |
mov ebx, eax |
ror eax, 7 |
shr ebx, 3 |
xor ebx, eax |
ror eax, 11 |
xor ebx, eax |
add esi, ebx |
add dword [sha256_buf+(counter-1)*4], esi |
add edx, esi |
@@: |
cmd1 add, edx, (8-counter) |
cmd2 mov, (8-counter), edx |
cmd2 add, (4-counter), edx |
cmd1 mov, ebx, (1-counter) |
mov eax, ebx |
cmd1 mov, edx, (2-counter) |
mov esi, ebx |
ror eax, 2 |
or esi, edx |
and ebx, edx |
cmd1 and, esi, (3-counter) |
mov edx, eax |
or esi, ebx |
ror eax, 11 |
xor edx, eax |
ror eax, 9 |
xor edx, eax |
add esi, edx |
cmd2 add, (8-counter), esi |
} |
purge cmd1,cmd2 |
add cl, 64 |
jnz .loop |
mov esi, sha256_digest |
pop eax |
add [esi+0*4], eax |
pop eax |
add [esi+1*4], eax |
pop eax |
add [esi+2*4], eax |
pop eax |
add [esi+3*4], eax |
pop eax |
add [esi+4*4], eax |
pop eax |
add [esi+5*4], eax |
add [esi+6*4], edi |
add [esi+7*4], ebp |
pop ebp |
ret |
sha256_update.transform: |
push esi edx |
call sha256_transform |
pop edx esi |
mov [sha256_count], ecx |
sha256_update: |
; in: esi->data, edx=size |
mov eax, 64 |
sub eax, [sha256_count] |
sub eax, edx |
sbb ecx, ecx |
and ecx, eax |
add ecx, edx |
sub edx, ecx |
mov edi, sha256_buf |
add edi, [sha256_count] |
add [sha256_count], ecx |
add dword [sha256_size], ecx |
adc dword [sha256_size+4], 0 |
rep movsb |
cmp edi, sha256_buf+64 |
jz .transform |
.ret: |
ret |
sha256_final: |
; out: edi->digest |
push edi |
mov eax, [sha256_count] |
mov [sha256_buf+eax], 0x80 |
inc eax |
cmp al, 64-8 |
jbe @f |
lea edi, [sha256_buf+eax] |
push 64 |
pop ecx |
sub ecx, eax |
xor eax, eax |
rep stosb |
push edx |
call sha256_transform |
pop edx |
xor eax, eax |
@@: |
push 64-8 |
pop ecx |
sub ecx, eax |
lea edi, [sha256_buf+eax] |
xor eax, eax |
rep stosb |
mov eax, dword [sha256_size] |
mov edx, dword [sha256_size+4] |
shld edx, eax, 3 |
shl eax, 3 |
bswap edx |
bswap eax |
xchg eax, edx |
stosd |
xchg eax, edx |
stosd |
call sha256_transform |
mov esi, sha256_digest |
mov cl, 8 |
pop edi |
@@: |
lodsd |
bswap eax |
stosd |
loop @b |
ret |
/programs/fs/kfar/trunk/tools.inc |
---|
1,3 → 1,12 |
CHECK_FOR_LEAKS = 0 |
if CHECK_FOR_LEAKS |
uglobal |
allocatedregions rd 1024 |
endg |
iglobal |
numallocatedregions dd 0 |
endg |
end if |
pgalloc: |
; in: ecx=size |
; out: eax=pointer or NULL |
7,6 → 16,20 |
push 12 |
pop ebx |
int 0x40 |
if CHECK_FOR_LEAKS |
test eax, eax |
jz .no |
.b: |
mov ebx, [numallocatedregions] |
cmp ebx, 1024 |
jb @f |
int3 |
jmp $ |
@@: |
mov [allocatedregions+ebx*4], eax |
inc [numallocatedregions] |
.no: |
end if |
pop ebx |
ret |
13,6 → 36,30 |
pgfree: |
; in: ecx=pointer |
; destroys eax |
if CHECK_FOR_LEAKS |
jecxz .no |
mov eax, [numallocatedregions] |
@@: |
dec eax |
js .a |
cmp [allocatedregions+eax*4], ecx |
jnz @b |
jmp @f |
.a: |
int3 |
jmp $ |
@@: |
dec [numallocatedregions] |
@@: |
cmp eax, [numallocatedregions] |
jae @f |
push [allocatedregions+eax*4+4] |
pop [allocatedregions+eax*4] |
inc eax |
jmp @b |
@@: |
.no: |
end if |
push ebx |
push 68 |
pop eax |
31,6 → 78,29 |
push 20 |
pop ebx |
int 0x40 |
if CHECK_FOR_LEAKS |
test edx, edx |
jz pgalloc.b |
test eax, eax |
jz .no |
cmp eax, edx |
jz .no |
xor ebx, ebx |
@@: |
cmp ebx, [numallocatedregions] |
jae .a |
cmp [allocatedregions+ebx*4], edx |
jz @f |
inc ebx |
jmp @b |
@@: |
mov [allocatedregions+ebx*4], eax |
jmp .no |
.a: |
int3 |
jmp $ |
.no: |
end if |
pop ebx |
ret |
52,6 → 122,17 |
call pgrealloc |
jmp xpgalloc.common |
getfreemem: |
; out: eax=size of free RAM in Kb |
push ebx |
push 18 |
pop eax |
push 16 |
pop ebx |
int 0x40 |
pop ebx |
ret |
get_error_msg: |
; in: eax=error code |
; out: eax=pointer to message (in static buffer) |
85,6 → 166,7 |
test al, al |
jnz @b |
pop eax |
dec edi |
push edx ecx |
test eax, eax |
jns @f |
162,7 → 244,8 |
pop eax |
pop esi |
jz .do |
push eax |
.big: |
push esi |
mov edi, aFileNameTooBig |
.sayerr: |
push dword aCannotLoadDLL |
173,9 → 256,6 |
push 1 |
push eax |
push 3 |
push -1 |
push -1 |
push dword aError |
call SayErr |
add esp, 16 |
xor eax, eax |
192,9 → 272,15 |
mov edi, aInvalidDLL |
test eax, eax |
jz .sayerr |
mov edx, eax |
cmp ebp, -1 |
jnz @f |
pop eax |
xor eax, eax |
ret |
@@: |
; initialize import |
mov edi, aMissingExport |
mov edx, eax |
.import_loop: |
lodsd |
test eax, eax |
/programs/fs/kfar/trunk/viewer.inc |
---|
6,6 → 6,9 |
.buf_pos dd ? |
.buf_size dd ? |
.col dq ? |
.hPlugin dd ? |
.hFile dd ? |
.hWorkFile dd ? |
.encoding db ? |
.bEofReached db ? |
.flags db ? ; & 1: hex mode |
13,6 → 16,7 |
; & 4: big-endian unicode |
rb 1 |
.filename rb 1024 |
.hostname rb 1024 |
.buf rb 16384 |
.size = $ |
end virtual |
34,6 → 38,30 |
jnz @f |
ret |
@@: |
mov eax, dword [esi+panel1_hPlugin-panel1_dir] |
mov [ebp+viewer_data.hPlugin], eax |
test eax, eax |
jz .nocopyhostname |
lea edi, [ebp+viewer_data.hostname] |
push esi |
mov eax, dword [esi+panel1_parents-panel1_dir] |
mov esi, dword [esi+panel1_parents_sz-panel1_dir] |
add esi, eax |
@@: |
dec esi |
cmp byte [esi-1], 0 |
jz @f |
cmp byte [esi-1], '/' |
jnz @b |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
pop esi |
.nocopyhostname: |
mov eax, dword [esi+panel1_hFile-panel1_dir] |
mov [ebp+viewer_data.hFile], eax |
mov [ebp+viewer_data.encoding], encodings.cp866 |
mov [ebp+viewer_data.flags], 0 |
and dword [ebp+viewer_data.col], 0 |
48,6 → 76,8 |
jmp @b |
@@: |
lea esi, [ecx+40] |
cmp byte [edi-1], '/' |
jz @f |
mov al, '/' |
stosb |
@@: |
60,9 → 90,21 |
mov ebx, attrinfo |
mov [ebx+21], eax |
.attr_retry: |
mov edx, [ebp+viewer_data.hPlugin] |
test edx, edx |
jz .attr_native |
push ebp |
push dword [ebx+16] |
push eax |
push [ebp+viewer_data.hFile] |
call [edx+PluginInfo.getattr] |
pop ebp |
jmp .attr_common |
.attr_native: |
push 70 |
pop eax |
int 40h |
.attr_common: |
test eax, eax |
jz @f |
lea ebx, [ebp+viewer_data.filename] |
75,14 → 117,12 |
push 2 |
push eax |
push 3 |
push -1 |
push -1 |
push aError |
call SayErr |
add esp, 3*4 |
mov ebx, attrinfo |
test eax, eax |
jz .attr_retry |
pop eax |
jmp delete_active_screen |
@@: |
mov eax, dword [attrinfo.attr+32] |
102,7 → 142,40 |
mov [readinfo.data], eax |
mov [ebp+viewer_data.buf_pos], eax |
pop dword [readinfo.name] |
mov eax, [ebp+viewer_data.hPlugin] |
test eax, eax |
jz .retry |
push ebx ebp |
push O_READ |
push dword [readinfo.name] |
push [ebp+viewer_data.hFile] |
call [eax+PluginInfo.open] |
pop ebp ebx |
mov [ebp+viewer_data.hWorkFile], eax |
test eax, eax |
jnz .retry |
push ContinueBtn |
push 1 |
push aCannotOpenFile_ptr |
push 1 |
call SayErr |
jmp delete_active_screen |
.retry: |
mov eax, [ebp+viewer_data.hPlugin] |
test eax, eax |
jz .read_native |
push ebp |
push 16384 |
push [ebx+readinfo.data-readinfo] |
push [ebp+viewer_data.hWorkFile] |
call [eax+PluginInfo.read] |
pop ebp |
cmp eax, -1 |
jz .readok ; let's hope that plugin says error itself |
mov [ebp+viewer_data.buf_size], eax |
mov ebx, eax |
jmp .readok |
.read_native: |
push 70 |
pop eax |
int 40h |
111,6 → 184,7 |
jz .readok |
cmp eax, 6 |
jz .readok |
.readerr: |
lea ebx, [ebp+viewer_data.filename] |
push ebx |
push aCannotReadFile |
121,9 → 195,6 |
push 2 |
push eax |
push 3 |
push -1 |
push -1 |
push aError |
call SayErr |
add esp, 3*4 |
mov ebx, readinfo |
194,6 → 265,21 |
mov [readinfo.name], eax |
.readretry: |
mov ebx, readinfo |
mov eax, [ebp+viewer_data.hPlugin] |
test eax, eax |
jz .native |
push ecx ebp |
push 8192 |
push [ebx+readinfo.data-readinfo] |
push [ebp+viewer_data.hWorkFile] |
call [eax+PluginInfo.read] |
pop ebp ecx |
mov ebx, eax |
cmp eax, -1 |
jnz .readok |
xor ebx, ebx |
jmp .readok |
.native: |
push 70 |
pop eax |
int 40h |
201,6 → 287,7 |
jz .readok |
cmp eax, 6 |
jz .readok |
.readerr: |
call ask_retry_ignore |
jz .readretry |
.readok: |
976,16 → 1063,7 |
mov [ebx+16], eax |
lea eax, [ebp+viewer_data.filename] |
mov [ebx+21], eax |
push 70 |
pop eax |
int 40h |
test eax, eax |
jz .readok |
cmp eax, 6 |
jz .readok |
call ask_retry_ignore |
jz .doread |
.readok: |
call .q |
cmp ebx, [readinfo.size] |
jnz @f |
add ebx, [ebp+viewer_data.buf_size] |
1027,22 → 1105,47 |
mov [ebx+12], eax |
lea eax, [ebp+viewer_data.filename] |
mov [ebx+21], eax |
call .q |
sub ebx, [readinfo.size] |
add ebx, 16384 |
jmp .ret |
.q: |
mov ebx, readinfo |
mov eax, [ebp+viewer_data.hPlugin] |
test eax, eax |
jz .native |
push ebp |
push dword [ebx+12] |
push dword [ebx+16] |
push [ebp+viewer_data.hWorkFile] |
push eax |
push dword [ebx+8] |
push dword [ebx+4] |
push [ebp+viewer_data.hWorkFile] |
call [eax+PluginInfo.setpos] |
pop eax |
call [eax+PluginInfo.read] |
pop ebp |
mov ebx, eax |
cmp eax, -1 |
jnz @f |
xor ebx, ebx |
@@: |
ret |
.native: |
push 70 |
pop eax |
int 40h |
test eax, eax |
jz @f |
jz .readok |
cmp eax, 6 |
jz @f |
jz .readok |
.readerr: |
call ask_retry_ignore |
jnz @f |
mov ebx, readinfo |
jmp @b |
@@: |
sub ebx, [readinfo.size] |
add ebx, 16384 |
jmp .ret |
jz .q |
.readok: |
ret |
ask_retry_ignore: |
push esi |
1056,9 → 1159,6 |
push 2 |
push eax |
push 3 |
push -1 |
push -1 |
push aError |
call SayErr |
add esp, 3*4 |
pop esi |
1268,12 → 1368,33 |
call viewer_draw_text |
ret |
viewer_OnExit: |
mov edx, [ebp+viewer_data.hPlugin] |
test edx, edx |
jz @f |
and [ebp+viewer_data.hPlugin], 0 |
push edx ebp |
push [ebp+viewer_data.hWorkFile] |
call [edx+PluginInfo.close] |
pop ebp edx |
mov ebx, [ebp+viewer_data.hFile] |
call close_handle_if_unused |
@@: |
ret |
viewer_IsHandleUsed: |
cmp edx, [ebp+viewer_data.hPlugin] |
jnz @f |
cmp ebx, [ebp+viewer_data.hFile] |
@@: |
ret |
viewer_OnKey: |
mov esi, viewer_ctrlkeys |
jmp process_ctrl_keys |
.exit: |
call delete_active_screen |
ret |
call viewer_OnExit |
jmp delete_active_screen |
.down: |
cmp [ebp+viewer_data.bEofReached], 0 |
jnz .ret |
1459,7 → 1580,26 |
stosb |
end if |
sub ecx, 13 |
cmp [ebp+viewer_data.hPlugin], 0 |
jz .native |
lea esi, [ebp+viewer_data.hostname] |
push ecx edi |
shr ecx, 1 |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
loop @b |
@@: |
sub edi, [esp] |
sub [esp+4], edi |
add [esp], edi |
pop edi ecx |
lea esi, [ebp+viewer_data.filename] |
jmp .main |
.native: |
lea esi, [ebp+viewer_data.filename] |
push 3 |
pop edx |
@@: |
1466,10 → 1606,13 |
lodsb |
stosb |
dec ecx |
test al, al |
jz .ret |
cmp al, '/' |
jnz @b |
dec edx |
jnz @b |
.main: |
push esi |
@@: |
lodsb |
1493,4 → 1636,5 |
stosb |
test al, al |
jnz @b |
.ret: |
ret |