From fc4d6ab4af96a871b2ae81ac2d8eb91d825ae5b2 Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Mon, 16 Oct 2006 12:17:49 +0000 Subject: [PATCH] Kernel: support for kernel packer kfar: updated to 0.14 (warning when deleting) git-svn-id: svn://kolibrios.org@183 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/boot/bootcode.inc | 156 ++++++--- kernel/trunk/boot/shutdown.inc | 13 +- kernel/trunk/core/sys32.inc | 75 ----- kernel/trunk/kernel.asm | 6 + kernel/trunk/unpacker.inc | 504 +++++++++++++++++++++++++++++ programs/fs/kfar/trunk/dialogs.inc | 299 ++++++++++++++++- programs/fs/kfar/trunk/kfar.asm | 197 +++++++++-- 7 files changed, 1092 insertions(+), 158 deletions(-) create mode 100755 kernel/trunk/unpacker.inc diff --git a/kernel/trunk/boot/bootcode.inc b/kernel/trunk/boot/bootcode.inc index 15ac49917c..d4a32e779b 100644 --- a/kernel/trunk/boot/bootcode.inc +++ b/kernel/trunk/boot/bootcode.inc @@ -15,6 +15,119 @@ ; ;========================================================================== +; 16-bit data + org $+0x10000 + +old_ints_h: + dw 0x400 + dd 0 + dw 0 + +kernel_restart_bootblock: + db 1 ; version + dw 1 ; floppy image is in memory + dd 0 ; cannot save parameters + + +align 32 + +; GDT TABLE + +gdts: + + dw gdte-$-1 + dd gdts + dw 0 + +int_code_l: +os_code_l: + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10011010b + db 0x00 + +int_data_l: +os_data_l: + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10010010b + db 0x00 + +; --------------- APM --------------------- +apm_code_32: + dw 0x10 ; limit 64kb + db 0, 0, 0 + dw 11011111b *256 +10011010b + db 0x00 +apm_code_16: + dw 0x10 + db 0, 0, 0 + dw 10011111b *256 +10011010b + db 0x00 +apm_data_16: + dw 0x10 + db 0, 0, 0 + dw 10011111b *256 +10010010b + db 0x00 +; ----------------------------------------- + +app_code_l: + dw 0xFFFF;((0x80000000-std_application_base_address) shr 12) and 0xffff + dw 0 + db 0x40 + db cpl3 + dw G32+D32+0x6000+0x7; + +app_data_l: + dw 0xFFFF;(0x80000000-std_application_base_address) shr 12 and 0xffff + dw 0 + db 0x40 + db drw3 + dw G32+D32+0x6000+0x7; + +graph_data_l: + + dw 0x3ff + dw 0x0000 + db 0x00 + dw 11010000b *256 +11110010b + db 0x00 + +tss0_l: +; times (max_processes+10) dd 0,0 +gdte = $ + (max_processes+10)*8 + +; videomodes table +gr_table: + dw 0x112+0100000000000000b , 640 , 480 ; 1 + dw 0x115+0100000000000000b , 800 , 600 ; 2 + dw 0x118+0100000000000000b , 1024 , 768 ; 3 + dw 0x11B+0100000000000000b , 1280 , 1024 ; 4 + dw 0x112 , 640 , 480 ; 5 + dw 0x115 , 800 , 600 ; 6 + dw 0x118 , 1024 , 768 ; 7 + dw 0x11B , 1280 ,1024 ; 8 + dw 0x13, 640, 480 ; 9 + dw 0x12, 640, 480 ; 0 + +; table for move to extended memory (int 15h, ah=87h) + movedesc: + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + + db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 + db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 + + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + org $-0x10000 + putchar: ; in: al=character mov ah, 0Eh @@ -139,16 +252,16 @@ macro _setcursor row,column call setcursor } -pagetable_set: +;pagetable_set: ;eax - physical address ;es:di - page table ;ecx - number of pages to map - or al, 7 -@@: - stosd - add eax, 1000h - loop @b - ret +; or al, 7 +;@@: +; stosd +; add eax, 1000h +; loop @b +; ret boot_read_floppy: push si @@ -170,35 +283,6 @@ sayerr_plain: pop si ret -; 16-bit data -; videomodes table - org $+0x10000 -gr_table: - dw 0x112+0100000000000000b , 640 , 480 ; 1 - dw 0x115+0100000000000000b , 800 , 600 ; 2 - dw 0x118+0100000000000000b , 1024 , 768 ; 3 - dw 0x11B+0100000000000000b , 1280 , 1024 ; 4 - dw 0x112 , 640 , 480 ; 5 - dw 0x115 , 800 , 600 ; 6 - dw 0x118 , 1024 , 768 ; 7 - dw 0x11B , 1280 ,1024 ; 8 - dw 0x13, 640, 480 ; 9 - dw 0x12, 640, 480 ; 0 - -; table for move to extended memory (int 15h, ah=87h) - movedesc: - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - - db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 - db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 - - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - org $-0x10000 - ;========================================================================= ; ; 16 BIT CODE diff --git a/kernel/trunk/boot/shutdown.inc b/kernel/trunk/boot/shutdown.inc index 5c54dd5ea7..2edafb9f7d 100644 --- a/kernel/trunk/boot/shutdown.inc +++ b/kernel/trunk/boot/shutdown.inc @@ -287,12 +287,6 @@ org $-0x10000 pause_key_1: loop pause_key_1 ret -org $+0x10000 -old_ints_h: - dw 0x400 - dd 0 - dw 0 -org $-0x10000 rdelay: ret @@ -371,15 +365,10 @@ restart_kernel_4000: ; bootloader interface push 0x1000 pop ds - mov si, .bootloader_block;-0x10000 + mov si, kernel_restart_bootblock-0x10000 mov ax, 'KL' jmp 0x1000:0000 -.bootloader_block: - db 1 ; version - dw 1 ; floppy image is in memory - dd 0 ; cannot save parameters - APM_PowerOff: mov ax, 5304h xor bx, bx diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 1fa09be318..44643fac19 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -7,87 +7,12 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -align 32 - -; GDT TABLE - -gdts: - - dw gdte-$-1 - dd gdts - dw 0 - -int_code_l: -os_code_l: - - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10011010b - db 0x00 - -int_data_l: -os_data_l: - - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10010010b - db 0x00 - -; --------------- APM --------------------- -apm_code_32: - dw 0x10 ; limit 64kb - db 0, 0, 0 - dw 11011111b *256 +10011010b - db 0x00 -apm_code_16: - dw 0x10 - db 0, 0, 0 - dw 10011111b *256 +10011010b - db 0x00 -apm_data_16: - dw 0x10 - db 0, 0, 0 - dw 10011111b *256 +10010010b - db 0x00 -; ----------------------------------------- - -app_code_l: - dw 0xFFFF;((0x80000000-std_application_base_address) shr 12) and 0xffff - dw 0 - db 0x40 - db cpl3 - dw G32+D32+0x6000+0x7; - -app_data_l: - dw 0xFFFF;(0x80000000-std_application_base_address) shr 12 and 0xffff - dw 0 - db 0x40 - db drw3 - dw G32+D32+0x6000+0x7; - -graph_data_l: - - dw 0x3ff - dw 0x0000 - db 0x00 - dw 11010000b *256 +11110010b - db 0x00 - -tss0_l: - times (max_processes+10) dd 0,0 - -gdte: - - idtreg: dw 8*0x41-1 dd idts+8 ;label idts at 0xB100-8 - uglobal tss_sceleton: l.back dw 0,0 diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 50c47e65fe..fa7591f2e3 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -162,8 +162,14 @@ org $+0x10000 mov esp,0x3ec00 ; Set stack jmp pword os_code:B32 ; jmp to enable 32 bit mode +if gdte >= $ +error 'GDT overlaps with used code!' +end if + use32 +include 'unpacker.inc' + iglobal boot_memdetect db 'Determining amount of memory',0 boot_fonts db 'Fonts loaded',0 diff --git a/kernel/trunk/unpacker.inc b/kernel/trunk/unpacker.inc new file mode 100755 index 0000000000..044ad697cf --- /dev/null +++ b/kernel/trunk/unpacker.inc @@ -0,0 +1,504 @@ +; void __stdcall unpack(void* packed_data, void* unpacked_data); +unpack: + pushad + mov esi, [esp+32+4] + mov edi, [esp+32+8] + mov eax, [esi+8] + and al, 0xC0 + cmp al, 0xC0 + jz .failed + mov eax, [esi+8] + push eax + add esi, 12 + and al, not 0xC0 + dec eax + jz .lzma +.failed: + pop eax + popad + ret 8 +.lzma: + call .lzma_unpack +.common: + pop eax + test al, 0x80 + jnz .ctr1 + test al, 0x40 + jz .ok + lodsd + mov ecx, eax + jecxz .ok + mov dl, [esi] + mov esi, [esp+32+8] +.c1: + lodsb + sub al, 0E8h + cmp al, 1 + ja .c1 + cmp byte [esi], dl + jnz .c1 + lodsd +; "bswap eax" is not supported on i386 + shr ax, 8 + ror eax, 16 + xchg al, ah + sub eax, esi + add eax, [esp+32+8] + mov [esi-4], eax + loop .c1 +.ok: + popad + ret 8 +.ctr1: + lodsd + mov ecx, eax + jecxz .ok + mov dl, [esi] + mov esi, [esp+32+8] +.c2: + lodsb +@@: + cmp al, 0xF + jnz .f + lodsb + cmp al, 80h + jb @b + cmp al, 90h + jb @f +.f: + sub al, 0E8h + cmp al, 1 + ja .c2 +@@: + cmp byte [esi], dl + jnz .c2 + lodsd + shr ax, 8 + ror eax, 16 + xchg al, ah + sub eax, esi + add eax, [esp+32+8] + mov [esi-4], eax + loop .c2 + jmp .ok + +.lzma_unpack: + +.pb = 2 ; pos state bits +.lp = 0 ; literal pos state bits +.lc = 3 ; literal context bits +.posStateMask = ((1 shl .pb)-1) +.literalPosMask = ((1 shl .lp)-1) + +.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 + + push edi +; int state=0; + xor ebx, ebx + mov [.previousByte], bl +; unsigned rep0=1,rep1=1,rep2=1,rep3=1; + mov eax, 1 + mov edi, .rep0 + stosd + stosd + stosd + stosd +; int len=0; +; result=0; + mov ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp)) + mov eax, .kBitModelTotal/2 + mov edi, .p + rep stosd +; RangeDecoderInit +; rd->ExtraBytes = 0 +; rd->Buffer = stream +; rd->BufferLim = stream+bufferSize +; rd->Range = 0xFFFFFFFF + pop edi + mov ebp, [esi-8] ; dest_length + add ebp, edi ; ebp = destination limit + lodsd +; rd->code_ = eax + mov [.code_], eax + or [.range], -1 +.main_loop: + cmp edi, ebp + jae .main_loop_done + mov edx, edi + and edx, .posStateMask + mov eax, ebx + shl eax, .kNumPosBitsMax+2 + lea eax, [.p + .IsMatch*4 + eax + edx*4] + call .RangeDecoderBitDecode + jc .1 + movzx eax, [.previousByte] +if .literalPosMask + mov ah, dl + and ah, .literalPosMask +end if + shr eax, 8-.lc + imul eax, .LZMA_LIT_SIZE*4 + add eax, .p+.Literal*4 + cmp ebx, .kNumLitStates + jb .literal + xor edx, edx + sub edx, [.rep0] + mov dl, [edi + edx] + call .LzmaLiteralDecodeMatch + jmp @f +.literal: + call .LzmaLiteralDecode +@@: + mov [.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, [.p + .IsRep*4 + ebx*4] + call .RangeDecoderBitDecode + jnc .10 + lea eax, [.p + .IsRepG0*4 + ebx*4] + call .RangeDecoderBitDecode + jc .111 + mov eax, ebx + shl eax, .kNumPosBitsMax+2 + lea eax, [.p + .IsRep0Long*4 + eax + edx*4] + call .RangeDecoderBitDecode + jc .1101 + cmp bl, 7 + setae bl + lea ebx, [9 + ebx + ebx] + xor edx, edx + sub edx, [.rep0] + mov al, [edi + edx] + stosb + mov [.previousByte], al + jmp .main_loop +.111: + lea eax, [.p + .IsRepG1*4 + ebx*4] + call .RangeDecoderBitDecode + mov eax, [.rep1] + jnc .l3 +.l1: + lea eax, [.p + .IsRepG2*4 + ebx*4] + call .RangeDecoderBitDecode + mov eax, [.rep2] + jnc .l2 + xchg [.rep3], eax +.l2: + push [.rep1] + pop [.rep2] +.l3: + xchg eax, [.rep0] + mov [.rep1], eax +.1101: + mov eax, .p + .RepLencoder*4 + call .LzmaLenDecode + cmp bl, 7 + setc bl + adc bl, bl + xor bl, 3 + add bl, 8 + jmp .repmovsb +.10: + mov eax, [.rep0] + xchg eax, [.rep1] + xchg eax, [.rep2] + xchg eax, [.rep3] + cmp bl, 7 + setc bl + adc bl, bl + xor bl, 3 + add bl, 7 + mov eax, .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 + shl eax, 2 + add eax, .p+.PosSlot*4 + call .RangeDecoderBitTreeDecode + mov [.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 [.rep0], eax + pop edx + cmp edx, .kEndPosModelIndex + jae .l5 + sub eax, edx + shl eax, 2 + add eax, .p + (.SpecPos - 1)*4 + call .RangeDecoderReverseBitTreeDecode + add [.rep0], ecx + jmp .l6 +.l5: + sub ecx, .kNumAlignBits + call .RangeDecoderDecodeDirectBits + mov ecx, .kNumAlignBits + shl eax, cl + add [.rep0], eax + mov eax, .p+.Align_*4 + call .RangeDecoderReverseBitTreeDecode + add [.rep0], ecx +.l6: + pop ecx + inc [.rep0] + jz .main_loop_done +.repmovsb: + add ecx, .kMatchMinLen + push esi + mov esi, edi + sub esi, [.rep0] + rep movsb + pop esi + mov al, [edi-1] + mov [.previousByte], al + jmp .main_loop +.main_loop_done: + ret + +.RangeDecoderBitDecode: +; in: eax->prob +; out: CF=bit; destroys eax + push edx + mov edx, [.range] + shr edx, .kNumBitModelTotalBits + imul edx, [eax] + cmp [.code_], edx + jae .ae + mov [.range], edx + mov edx, .kBitModelTotal + sub edx, [eax] + shr edx, .kNumMoveBits + add [eax], edx + clc +.n: + lahf + cmp [.range], .kTopValue + jae @f + shl [.range], 8 + shl [.code_], 8 + lodsb + mov byte [.code_], al +@@: + sahf + pop edx + ret +.ae: + sub [.range], edx + sub [.code_], edx + mov edx, [eax] + shr edx, .kNumMoveBits + sub [eax], edx + stc + jmp .n + +.RangeDecoderDecodeDirectBits: +; in: ecx=numTotalBits +; out: eax=result; destroys edx + xor eax, eax +.l: + shr [.range], 1 + shl eax, 1 + mov edx, [.code_] + sub edx, [.range] + jb @f + mov [.code_], edx + or eax, 1 +@@: + cmp [.range], .kTopValue + jae @f + shl [.range], 8 + shl [.code_], 8 + push eax + lodsb + mov byte [.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 + +uglobal +align 4 +unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp)) +unpack.code_ dd ? +unpack.range dd ? +unpack.rep0 dd ? +unpack.rep1 dd ? +unpack.rep2 dd ? +unpack.rep3 dd ? +unpack.previousByte db ? +endg diff --git a/programs/fs/kfar/trunk/dialogs.inc b/programs/fs/kfar/trunk/dialogs.inc index 358d499c81..d331ac7c85 100644 --- a/programs/fs/kfar/trunk/dialogs.inc +++ b/programs/fs/kfar/trunk/dialogs.inc @@ -1,5 +1,5 @@ -; int __stdcall DialogBox(DLGTEMPLATE* dlg, void* DlgProc); -; int __stdcall DlgProc(int msg, int param1, int param2); +; int __stdcall GenericBox(DLGTEMPLATE* dlg, void* DlgProc); +; int __stdcall DlgProc(DLGTEMPLATE* dlg, int msg, int param1, int param2); virtual at 0 dlgtemplate: @@ -15,12 +15,28 @@ dlgtemplate: .border_color db ? .header_color db ? db ? ; align +.size = $ end virtual -DialogBox: +GenericBox: pushad -; some checks mov ebx, [esp+20h+4] +; center window if required + cmp [ebx+dlgtemplate.x], -1 + jnz @f + mov eax, [cur_width] + sub eax, [ebx+dlgtemplate.width] + shr eax, 1 + mov [ebx+dlgtemplate.x], eax +@@: + cmp [ebx+dlgtemplate.y], -1 + jnz @f + mov eax, [cur_height] + sub eax, [ebx+dlgtemplate.height] + shr eax, 1 + mov [ebx+dlgtemplate.y], eax +@@: +; some checks mov eax, [ebx+dlgtemplate.x] cmp eax, 1 jl .sizeerr @@ -259,6 +275,7 @@ DialogBox: push 0 push 0 push 1 + push ebx call eax call draw_image pop ebp ebx @@ -309,6 +326,7 @@ DialogBox: push 0 push eax push 2 + push ebx call ecx pop ebp ebx test eax, eax @@ -649,7 +667,7 @@ menu_centered_in: mov [ebx+dlgtemplate.header_color], al push MenuDlgProc push ebx - call DialogBox + call GenericBox mov [esp+28], eax mov eax, ebx call mf_free @@ -657,17 +675,17 @@ menu_centered_in: ret 28 MenuDlgProc: - mov eax, [esp+4] + mov eax, [esp+8] cmp al, 1 jz .draw cmp al, 2 jz .key - ret 12 + ret 16 .draw: call .dodraw - ret 12 + ret 16 .key: - mov al, [esp+8] + mov al, [esp+12] cmp al, 0x48 jz .prev cmp al, 0x4B @@ -707,14 +725,14 @@ MenuDlgProc: cmp [ascii2scan+ecx], al jnz .n mov eax, edx - ret 12 + ret 16 .n: mov edx, [edx] test edx, edx jnz .l .ret: xor eax, eax - ret 12 + ret 16 .pgup: mov eax, [ebx+36] mov ecx, [ebx+dlgtemplate.height] @@ -735,7 +753,7 @@ MenuDlgProc: call .dodraw call draw_image xor eax, eax - ret 12 + ret 16 .next: mov eax, [ebx+36] cmp dword [eax], 0 @@ -797,10 +815,10 @@ MenuDlgProc: jmp .posret .esc: or eax, -1 - ret 12 + ret 16 .enter: mov eax, [ebx+36] - ret 12 + ret 16 .line_prev: cmp eax, [ebx+44] @@ -932,3 +950,256 @@ MenuDlgProc: stosw .noscrollbar: ret + +virtual at 0 +dlgitemtemplate: +; Элементы: +; 1 = статический текст +.type dd ? +.x1 dd ? +.y1 dd ? +.x2 dd ? +.y2 dd ? +.data dd ? +.flags dd ? +; Флаги: +; 0 = выравнивание влево +; 1 = выравнивание по центру +; 2 = выравнивание вправо +; 4 = элемент имеет фокус ввода +.size = $ +end virtual +; struct DLGDATA +; { +; DLGTEMPLATE dialog; /* window description */ +; void* DlgProc; /* dialog procedure */ +; /* int __stdcall DlgProc(DLGDATA* dlg, int msg, int param1, int param2); */ +; void* user_data; /* arbitrary user data */ +; unsigned num_items; /* number of items in the following array */ +; DLGITEMTEMPLATE items[]; /* array of dialog items */ +; } +; int __stdcall DialogBox(DLGDATA* dlg); +DialogBox: + push ManagerDlgProc + push dword [esp+8] + call GenericBox + ret 8 + +ManagerDlgProc: + mov eax, [esp+8] + dec eax + jz .draw + dec eax + jz .key + xor eax, eax + ret 16 +.draw: + call .dodraw + ret 16 +.key: +; find item with focus + add ebx, dlgtemplate.size+12 + mov ecx, [ebx-4] + jecxz .nobtns +@@: + test [ebx+dlgitemtemplate.flags], 4 + jnz @f + add ebx, dlgitemtemplate.size + loop @b +@@: +.nobtns: + mov al, [esp+12] + cmp al, 1 + jz .esc + cmp al, 0x1C + jz .enter + cmp al, 0xF + jz .tab + cmp al, 0x48 + jz .up + cmp al, 0x4B + jz .left + cmp al, 0x4D + jz .right + cmp al, 0x50 + jz .down +.ret0: + xor eax, eax + ret 16 +.esc: + or eax, -1 + ret 16 +.enter: + mov eax, ebx + ret 16 +.tab: + test [ctrlstate], 3 + jnz .shift_tab +.right: +.down: + jecxz .ret0 + and byte [ebx+dlgitemtemplate.flags], not 4 + dec ecx + jz .find_first_btn +@@: + add ebx, dlgitemtemplate.size + cmp [ebx+dlgitemtemplate.type], 2 + jz .btn_found + loop @b +.find_first_btn: + mov ebx, [esp+4] + add ebx, dlgtemplate.size+12 +@@: + cmp [ebx+dlgitemtemplate.type], 2 + jz .btn_found + add ebx, dlgitemtemplate.size + jmp @b +.btn_found: + or byte [ebx+dlgitemtemplate.flags], 4 + mov ebx, [esp+4] + call .dodraw + call draw_image + xor eax, eax + ret 16 +.shift_tab: +.left: +.up: + jecxz .ret0 + and byte [ebx+dlgitemtemplate.flags], not 4 + mov eax, [esp+4] + sub ecx, [eax+dlgtemplate.size+8] + neg ecx + jz .find_last_btn +@@: + sub ebx, dlgitemtemplate.size + cmp [ebx+dlgitemtemplate.type], 2 + loopnz @b + jz .btn_found +.find_last_btn: + mov ebx, [eax+dlgtemplate.size+8] + imul ebx, dlgitemtemplate.size + lea ebx, [ebx+eax+dlgtemplate.size+12] +@@: + sub ebx, dlgitemtemplate.size + cmp [ebx+dlgitemtemplate.type], 2 + jnz @b + jmp .btn_found + +.dodraw: + add ebx, dlgtemplate.size+8 + mov ecx, [ebx] + add ebx, 4 + jecxz .done_draw +.draw_loop: + push ecx + mov eax, [ebx+dlgitemtemplate.type] + dec eax + jz .draw_text + dec eax + jnz .draw_loop_continue + call draw_button + jmp .draw_loop_continue +.draw_text: + call draw_static_text +.draw_loop_continue: + pop ecx + add ebx, dlgitemtemplate.size + loop .draw_loop +.done_draw: + ret + +draw_static_text: +; рисуем статический текст + mov ah, [dialog_main_color] +draw_text: +; определяем длину строки + mov esi, [ebx+dlgitemtemplate.data] + test esi, esi + jz .ret + or ecx, -1 +@@: + inc ecx + cmp byte [ecx+esi], 0 + jnz @b +; в ecx длина строки + push eax + xor eax, eax + mov edx, [ebx+dlgitemtemplate.x2] + sub edx, [ebx+dlgitemtemplate.x1] + inc edx + cmp ecx, edx + jae .text_draw + mov al, byte [ebx+dlgitemtemplate.flags] + and al, 3 + jz .text_align_left + cmp al, 1 + jz .text_align_center +; текст выровнен вправо + mov eax, edx + sub eax, ecx + jmp .text_draw +.text_align_center: + mov eax, edx + sub eax, ecx + shr eax, 1 + jmp .text_draw +.text_align_left: + xor eax, eax +.text_draw: + push ecx + mov ecx, [esp+24] + push eax + mov eax, [ebx+dlgitemtemplate.x1] + add eax, [ecx+dlgtemplate.x] + push edx + mov edx, [ebx+dlgitemtemplate.y1] + add edx, [ecx+dlgtemplate.y] + call get_console_ptr + pop edx + pop ecx + mov ah, [esp+5] + mov al, ' ' + rep stosw + pop ecx + cmp ecx, edx + jbe .text_copy + cmp edx, 3 + jb .ret + mov al, '.' + stosw + stosw + stosw + add esi, ecx + mov ecx, edx + sub ecx, 3 + sub esi, ecx +.text_copy: + jecxz .ret +@@: + lodsb + stosw + loop @b +.ret: + mov ecx, [esp+20] + mov eax, [ecx+dlgtemplate.x] + mov edx, [ecx+dlgtemplate.y] + add eax, [ebx+dlgitemtemplate.x2] + inc eax + add edx, [ebx+dlgitemtemplate.y1] + mov ecx, edi + call get_console_ptr + xchg ecx, edi + sub ecx, edi + shr ecx, 1 + pop eax + mov al, ' ' + rep stosw + ret + +draw_button: + mov ah, [dialog_normal_btn_color] + test [ebx+dlgitemtemplate.flags], 4 + jz @f + mov ah, [dialog_selected_btn_color] +@@: + jmp draw_text diff --git a/programs/fs/kfar/trunk/kfar.asm b/programs/fs/kfar/trunk/kfar.asm index 24529c16d4..91f8e8cee2 100644 --- a/programs/fs/kfar/trunk/kfar.asm +++ b/programs/fs/kfar/trunk/kfar.asm @@ -578,11 +578,7 @@ panels_OnKey: mov [ebp + panel1_start - panel1_data], eax jmp .done_redraw .enter: - mov eax, [ebp + panel1_files - panel1_data] - mov ecx, [eax+ecx*4] - mov eax, [ebp + panel1_nfa - panel1_data] - lea ecx, [ecx+eax*4+32] - add ecx, [ebp + panel1_files - panel1_data] + call get_curfile_folder_entry test byte [ecx], 10h jnz .enter_folder ; find extension @@ -889,11 +885,73 @@ panels_OnKey: .ret2: ret .f8: - mov eax, [ebp + panel1_files - panel1_data] - mov ecx, [eax+ecx*4] - mov eax, [ebp + panel1_nfa - panel1_data] - lea ecx, [ecx+eax*4+32] - add ecx, [ebp + panel1_files - panel1_data] + call get_curfile_folder_entry + cmp [bConfirmDelete], 0 + jz .f8_allowed + mov ebx, f8_confirm_dlgdata + mov esi, aConfirmDeleteText + mov edi, aConfirmDeleteTextBuf +@@: + lodsb + stosb + test al, al + jnz @b + dec edi + mov esi, aDeleteFolder + test byte [ecx], 10h + jnz @f + mov esi, aDeleteFile +@@: + lodsb + stosb + test al, al + jnz @b + lea esi, [ecx+40] + mov [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.name], esi + or eax, -1 +@@: + inc eax + cmp byte [eax+esi], 0 + jnz @b + sub edi, aConfirmDeleteTextBuf+1 + cmp eax, edi + jae @f + mov eax, edi +@@: + inc eax + inc eax + mov edx, [cur_width] + sub edx, 8 + cmp eax, edx + jbe @f + mov eax, edx +@@: + mov [ebx + dlgtemplate.width], eax + dec eax + dec eax + mov [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.width2], eax + mov [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.width3], eax + shr eax, 1 + mov [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.del_x2], eax + sub eax, aDeleteLength-1 + mov [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.del_x1], eax + add eax, aDeleteLength + mov [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.cnl_x1], eax + add eax, aCancelLength - 1 + mov [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.cnl_x2], eax + mov al, [dialog_border_color] + mov [ebx + dlgtemplate.border_color], al + mov al, [dialog_header_color] + mov [ebx + dlgtemplate.header_color], al + mov al, [dialog_main_color] + mov [ebx + dlgtemplate.main_color], al + or byte [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.flags1], 4 + and byte [ebx - f8_confirm_dlgdata + f8_confirm_dlgdata.flags2], not 4 + push ebx + call DialogBox + cmp eax, f8_confirm_dlgdata.del_btn + jnz .ret2 +.f8_allowed: lea esi, [ebp + panel1_dir - panel1_data] mov edi, execdata @@: @@ -921,11 +979,8 @@ panels_OnKey: ; jmp .done_redraw mov eax, [ebp + panel1_index - panel1_data] push eax - mov ecx, [ebp + panel1_files - panel1_data] - mov ecx, [ecx+eax*4] - mov eax, [ebp + panel1_nfa - panel1_data] - lea esi, [ecx+eax*4+32+40] - add esi, [ebp + panel1_files - panel1_data] + call get_curfile_name + mov esi, eax mov edi, saved_file_name @@: lodsb @@ -1012,6 +1067,21 @@ init_console: mov [panel2_height], eax ret +get_curfile_folder_entry: + push eax + mov ecx, [ebp + panel1_index - panel1_data] + mov eax, [ebp + panel1_files - panel1_data] + mov ecx, [eax+ecx*4] + mov eax, [ebp + panel1_nfa - panel1_data] + lea ecx, [ecx+eax*4+32] + add ecx, [ebp + panel1_files - panel1_data] + pop eax + ret +get_curfile_name: + call get_curfile_folder_entry + add ecx, 40 + ret + panels_getname: if lang eq ru mov eax, 'Пане' @@ -2811,7 +2881,7 @@ match_symbol: ret -header db 'Kolibri Far 0.13' +header db 'Kolibri Far 0.14' ;.length = $ - header db 0 @@ -3407,6 +3477,8 @@ else compare_names db 'nNxXmMsSuUcCaA' end if +; Здесь начинаются конфигурационные данные - в текущей реализации они зашиты в бинарник + ; Панель panel_normal_color db 1Bh panel_border_color db 1Bh @@ -3415,6 +3487,12 @@ panel_header_color db 1Bh panel_active_header_color db 30h column_header_color db 1Eh panel_nscreens_color db 0Bh +; Диалоги +dialog_main_color db 70h +dialog_border_color db 70h +dialog_header_color db 70h +dialog_normal_btn_color db 70h +dialog_selected_btn_color db 30h ; Меню menu_normal_color db 3Fh menu_selected_color db 0Fh @@ -3511,10 +3589,6 @@ highlight_group9: db 10h db '*',0 -bWasE0 db 0 -ctrlstate db 0 -MemForImage dd 0 - associations: dd aAsm, tinypad dd aInc, tinypad @@ -3558,6 +3632,85 @@ archer db '/rd/1/@rcher',0 aRtf db 'rtf',0 rtfread db '/rd/1/RtfRead',0 +bConfirmDelete db 1 + +; Здесь заканчиваются конфигурационные данные + +bWasE0 db 0 +ctrlstate db 0 +MemForImage dd 0 + +align 4 +f8_confirm_dlgdata: + dd 0 +.x dd -1 +.y dd -1 +.width dd ? +.height dd 3 + dd 4 + dd 2 + dd aDeleteCaption +.main_color db ? +.border_color db ? +.header_color db ? + db 0 + dd 0 + dd 0 + dd 4 +; строка "Вы хотите удалить ..." + dd 1 + dd 1,0 +.width2 dd ? + dd 0 + dd aConfirmDeleteTextBuf + dd 1 +; строка с именем файла/папки + dd 1 + dd 1,1 +.width3 dd ? + dd 1 +.name dd ? + dd 1 +; кнопка "удалить" +.del_btn: + dd 2 +.del_x1 dd ? + dd 2 +.del_x2 dd ? + dd 2 + dd aDelete +.flags1 dd 4 +; кнопка "отменить" + dd 2 +.cnl_x1 dd ? + dd 2 +.cnl_x2 dd ? + dd 2 + dd aCancel +.flags2 dd 0 + +if lang eq ru +aDeleteCaption db 'Удаление',0 +aConfirmDeleteText db 'Вы хотите удалить ',0 +aDeleteFolder db 'папку',0 +aConfirmDeleteTextMax = $ - aConfirmDeleteText - 2 +aDeleteFile db 'файл',0 +aDelete db ' Удалить ',0 +aDeleteLength = $ - aDelete - 1 +aCancel db ' Отменить ',0 +aCancelLength = $ - aCancel - 1 +else +aDeleteCaption db 'Delete',0 +aConfirmDeleteText db 'Do you wish to delete ',0 +aDeleteFolder db 'the folder',0 +aConfirmDeleteTextMax = $ - aConfirmDeleteText - 2 +aDeleteFile db 'the file',0 +aDelete db ' Delete ',0 +aDeleteLength = $ - aDelete - 1 +aCancel db ' Cancel ',0 +aCancelLength = $ - aCancel - 1 +end if + execinfo: dd 7 dd 0 @@ -3637,8 +3790,10 @@ num_screens dd ? active_screen_vtable dd ? active_screen_data dd ? +aConfirmDeleteTextBuf rb aConfirmDeleteTextMax + 1 + ; stack - align 512 + align 4 rb 512 stacktop: ; buffers for directory - may be resized dynamically