Compare commits

..
Author SHA1 Message Date
Leency 068181928d apps/open: start the letter search from the top when nothing is selected
Test PR / Build (en_US) (pull_request) Successful in 1m46s
Test PR / Build (ru_RU) (pull_request) Successful in 1m55s
Test PR / Build (es_ES) (pull_request) Successful in 2m1s
last_x/last_y are -1 until the first selection, so the search began 64
bytes below the list, compared junk bytes and could select index -2.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 12:17:48 +03:00
Leency 593bf4e25e apps/open: fix the crash on keys starting a search past the list end (fix #587)
Test PR / Build (en_US) (pull_request) Successful in 1m59s
Test PR / Build (ru_RU) (pull_request) Successful in 2m29s
Test PR / Build (es_ES) (pull_request) Successful in 2m32s
The type-to-search loop stopped only when its pointer was exactly equal to
the end of the list. When the search started past the end, it read beyond
the program's memory and page-faulted.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 03:44:31 +03:00
78 changed files with 572 additions and 3829 deletions

No files matched your search

-24
View File
@@ -54,27 +54,3 @@
src: "{{ stable_artifact_path }}/"
dest: "{{ storage_path }}/../"
mode: preserve
# older builds shrink to compressed images and lose their unpacked tree; the newest few keep both
- name: Looking for zstd on the storage server
ansible.builtin.shell: command -v zstd
register: zstd_present
changed_when: false
failed_when: false
- name: Requiring zstd for compaction
ansible.builtin.assert:
that: zstd_present.rc == 0
fail_msg: >-
zstd is not installed on the storage server, so older builds cannot
be compacted. Install it and re-run this build.
- name: Compacting older builds
ansible.builtin.script:
cmd: >-
../../utils/compact-builds.sh
{{ storage_path | quote }}
{{ compact_keep | default(5) | int }}
{{ compact_max | default(10) | int }}
register: compaction
changed_when: "'compacted 0 of' not in compaction.stdout"
-74
View File
@@ -1,74 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
# SPDX-FileCopyrightText: 2026 KolibriOS team
# Shrink older builds on the storage server: compress their images and drop
# their unpacked tree, which is rebuildable from the commit. sha256sums.txt
# keeps naming the bare images, so a compacted build has to be decompressed
# before it can be verified.
#
# Layout: <root>/<version>/<lang>/kolibrios-<descr>-<lang>.{img,iso,raw} -> .zst
# <root>/<version>/<lang>/data/ -> removed
#
# Usage: compact-builds.sh <storage-root> [keep] [max-per-run]
# DRY_RUN=1 walks the same selection and changes nothing
set -euo pipefail
root=${1:?storage root required}
# the build just published is always among these, so an upload in flight is safe
keep=${2:-5}
# a build is hundreds of MiB to re-compress: cap the first pass over the backlog
max=${3:-10}
dry=${DRY_RUN:-0}
verb=compacted
[ "$dry" = 1 ] && verb="would compact"
# --rm drops the source only once the archive is written; the box serves the
# site over NFS, so compaction yields to it
compress_image() {
nice -n 10 ionice -c3 zstd -12 -T1 -q --rm "$1"
}
export -f compress_image
leftovers() {
local build=$1
find "$build" -mindepth 2 -maxdepth 2 \
\( -type d -name data \
-o -type f \( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) \) \
-print -quit
}
compacted=0
pending=0
while IFS= read -r version; do
dir="$root/$version"
[ -n "$(leftovers "$dir")" ] || continue
pending=$((pending + 1))
[ "$compacted" -lt "$max" ] || continue
if [ "$dry" = 1 ]; then
compacted=$((compacted + 1))
echo "$verb $version"
continue
fi
# a build holds nine images: one per core, each zstd kept to one thread so
# the two levels of parallelism do not fight. Archive before dropping the
# tree, so a failure here leaves the build merely uncompacted and the next
# run picks it up again
find "$dir" -mindepth 2 -maxdepth 2 -type f \
\( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) -print0 \
| xargs -0 -r -P "$(nproc)" -I{} bash -c 'compress_image "$@"' _ {}
find "$dir" -mindepth 2 -maxdepth 2 -type d -name data -exec rm -rf {} +
compacted=$((compacted + 1))
echo "$verb $version"
# <tag>-<commit count>-g<sha>: order by the count, never by mtime
done < <(find "$root" -mindepth 1 -maxdepth 1 -type d -name '*-*-g*' -printf '%f\n' \
| sort -t- -k2,2n | head -n "-$keep")
echo "$verb $compacted of $pending older build(s), $((pending - compacted)) left for the next run"
+1 -6
View File
@@ -128,8 +128,7 @@ jobs:
fi
# cache restore resets ctimes; realign tup DB to skip a full rebuild,
# but keep files changed since the cache's commit dirty so tup rebuilds them.
# A submodule bump diffs as a bare gitlink, so expand it to its whole subtree
# but keep files changed since the cache's commit dirty so tup rebuilds them
- name: Sync tup DB with filesystem ctime
if: steps.check-tup-cache.outputs.cache_restored == 'true'
run: |
@@ -137,10 +136,6 @@ jobs:
BASE=$(cat .tup/build-commit 2>/dev/null || true)
if [ -n "$BASE" ] && git cat-file -e "${BASE}^{commit}" 2>/dev/null; then
git -c core.quotePath=false diff --name-only "$BASE" HEAD > "$DIRTY"
git diff --raw "$BASE" HEAD | awk '$2 == "160000" { print $NF }' |
while read -r sub; do
git -C "$sub" -c core.quotePath=false ls-files | sed "s|^|$sub/|"
done >> "$DIRTY"
echo "Cache built at $BASE; $(wc -l < "$DIRTY") changed files kept dirty"
python3 .gitea/utils/sync-tup-ctime.py .tup/db "$DIRTY"
else
+1 -2
View File
@@ -34,11 +34,10 @@ jobs:
uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.BOT_TOKEN }}
- name: Bump ${{ matrix.name }} and open PR
env:
TOKEN: ${{ secrets.BOT_TOKEN }}
TOKEN: ${{ secrets.GITEA_TOKEN }}
API: ${{ github.api_url }}
REPO: ${{ github.repository }}
NAME: ${{ matrix.name }}
+18 -20
View File
@@ -41,6 +41,10 @@ img_files = {
{"LIB/KMENU.OBJ", "common/lib/kmenu.obj"},
{"LIB/PIXLIB.OBJ", "common/lib/pixlib.obj"},
{"MEDIA/AC97SND", "common/media/ac97snd"},
{"MEDIA/IMGF/IMGF", "common/media/ImgF/ImgF"},
{"MEDIA/IMGF/CEDG.OBJ", "common/media/ImgF/cEdg.obj"},
{"MEDIA/IMGF/DITHER.OBJ", "common/media/ImgF/dither.obj"},
{"MEDIA/IMGF/INVSOL.OBJ", "common/media/ImgF/invSol.obj"},
{"NETWORK/FTPC.INI", SRC_PROGS .. "/network/ftpc/ftpc.ini"},
{"NETWORK/FTPD.INI", "common/network/ftpd.ini"},
{"NETWORK/KNMAP", "common/network/knmap"},
@@ -54,7 +58,8 @@ img_files = {
{"SETTINGS/FB2READ.INI", "common/settings/fb2read.ini"},
{"SETTINGS/HA.CFG", SRC_PROGS .. "/other/ha/SETTINGS/HA.CFG"},
{"SETTINGS/ICON.INI", build_type .. "/settings/icon.ini"},
{"SETTINGS/KEYMAP.KEY", VAR_PROGS .. "/system/taskbar/keymap.key.kpack"},
{"SETTINGS/KEYMAP.KEY", SRC_PROGS .. "/system/taskbar/KEYMAP.KEY"},
{"SETTINGS/KOLIBRI.LBL", build_type .. "/settings/kolibri.lbl"},
{"SETTINGS/LANG.INI", build_type .. "/settings/lang.ini"},
{"SETTINGS/MENU.DAT", build_type .. "/settings/menu.dat"},
{"SETTINGS/NETWORK.INI", "common/settings/network.ini"},
@@ -268,10 +273,6 @@ extra_files = {
{"kolibrios/lib/i915_dri.drv", "common/lib/i915_dri.drv"},
{"kolibrios/media/fplay", "common/media/fplay"},
{"kolibrios/media/fplay_run", "common/media/fplay_run"},
{"kolibrios/media/ImgF/ImgF", "common/media/ImgF/ImgF"},
{"kolibrios/media/ImgF/cEdg.obj", "common/media/ImgF/cEdg.obj"},
{"kolibrios/media/ImgF/dither.obj", "common/media/ImgF/dither.obj"},
{"kolibrios/media/ImgF/invSol.obj", "common/media/ImgF/invSol.obj"},
{"kolibrios/media/minimp3", "common/media/minimp3"},
{"kolibrios/media/updf", SRC .. "/contrib/media/updf/build/uPDF"},
{"kolibrios/media/vttf", "common/media/vttf"},
@@ -486,6 +487,11 @@ tup.append_table(img_files, {
{"DEVELOP/MTDBG", VAR_PROGS .. "/develop/mtdbg/mtdbg"},
{"DEVELOP/MSTATE", VAR_PROGS .. "/develop/mstate/mstate"},
{"DEVELOP/SCANCODE", VAR_PROGS .. "/develop/scancode/scancode"},
{"DEVELOP/EXAMPLES/CIRCLE", VAR_PROGS .. "/develop/examples/circle/circle"},
{"DEVELOP/EXAMPLES/COLORREF", VAR_PROGS .. "/demos/colorref/colorref"},
{"DEVELOP/EXAMPLES/CONGET", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
{"DEVELOP/EXAMPLES/CSLIDE", VAR_PROGS .. "/demos/cslide/cslide"},
{"DEVELOP/EXAMPLES/THREAD", VAR_PROGS .. "/develop/examples/thread/thread"},
{"File Managers/KFAR", VAR_PROGS .. "/fs/kfar/kfar"},
{"File Managers/OPENDIAL", VAR_PROGS .. "/fs/opendial/opendial"},
{"LOD", VAR_PROGS .. "/fs/lod/lod"},
@@ -646,28 +652,20 @@ tup.append_table(extra_files, {
{"kolibrios/3D/blocks/block.bin", VAR_PROGS .. "/bcc32/games/blocks/block.bin"},
{"kolibrios/develop/tcc/lib/crt0.o", VAR_PROGS .. "/develop/ktcc/bin/lib/crt0.o", group = "../programs/develop/ktcc/<crt0.o>"},
{"kolibrios/develop/tcc/lib/tiny.o", VAR_PROGS .. "/develop/ktcc/bin/lib/tiny.o", group = "../programs/develop/ktcc/<tiny.o>"},
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"},
{"kolibrios/develop/examples/circle", VAR_PROGS .. "/develop/examples/circle/circle"},
{"kolibrios/develop/examples/colorref", VAR_PROGS .. "/demos/colorref/colorref"},
{"kolibrios/develop/examples/conget", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
{"kolibrios/develop/examples/cslide", VAR_PROGS .. "/demos/cslide/cslide"},
{"kolibrios/develop/examples/thread", VAR_PROGS .. "/develop/examples/thread/thread"}
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"}
})
-- -- For russian build, add russian-only programs.
-- if build_type == "ru_RU" then tup.append_table(img_files, {
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
-- }) else tup.append_table(img_files, {
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
-- }) end
-- For russian build, add russian-only programs.
if build_type == "ru_RU" then tup.append_table(img_files, {
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
}) else tup.append_table(img_files, {
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
}) end
if build_type == "ru_RU" then tup.append_table(extra_files, {
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
{"kolibrios/utils/period", VAR_PROGS .. "/other/period/period"},
{"kolibrios/games/Dungeons/Dungeons", VAR_PROGS .. "/games/Dungeons/Dungeons"},
{"kolibrios/games/klavisha/klavisha", VAR_PROGS .. "/games/klavisha/klavisha"},
{"kolibrios/games/klavisha/basekurs.kla", "ru_RU/games/basekurs.kla"},
}) else tup.append_table(extra_files, {
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
}) end
end -- tup.getconfig('NO_FASM') ~= 'full'
+1 -1
View File
@@ -40,7 +40,7 @@
06 zSea Image Viewer * |/kolibrios/media/zsea/zsea
38 Animage |media/animage
38 IconEdit |media/iconedit
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
40 Image Filtering |media/imgf/imgf
52 Palitra |media/palitra
39 Pipet |develop/pipet
#4 **** MULTIMEDIA
+1 -1
View File
@@ -41,7 +41,7 @@
16 Image viewer KIV |media/kiv
16 Image viewer zSea * |/kolibrios/media/zsea/zsea
16 Animage |media/animage
16 Efectos de imаgenes * |/kolibrios/media/ImgF/ImgF
16 Efectos de imаgenes |media/imgf/imgf
16 Palitra |media/palitra
#4 **** MULTIMEDIA
16 Pixie Audioplayer |media/pixie
+1 -1
View File
@@ -41,7 +41,7 @@
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
38 Animage |media/animage
38 IconEdit |media/iconedit
16 Image Filtering * |/kolibrios/media/ImgF/ImgF
16 Image Filtering |media/imgf/imgf
52 Palitra |media/palitra
39 Pipet |develop/pipet
#4 **** MULTIMEDIA ****
+1 -1
View File
@@ -41,7 +41,7 @@
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
38 Animage |media/animage
38 IconEdit |media/iconedit
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
40 Image Filtering |media/imgf/imgf
52 Palitra |media/palitra
39 Pipet |develop/pipet
#4 **** MULTIMEDIA
+1 -1
View File
@@ -40,7 +40,7 @@
06 Просмотр фото zSea |/kolibrios/media/zsea/zsea
38 Редактор Animage |media/animage
38 Редактор иконок |media/iconedit
40 Наложение фильтров * |/kolibrios/media/ImgF/ImgF
40 Наложение фильтров |media/imgf/imgf
52 Палитра |media/palitra
39 Пипетка |develop/pipet
#4 **** Звук и видео
+14 -100
View File
@@ -130,8 +130,6 @@ RU_STATUS_IDLE = 0000b shl 2
RU_STATUS_SUSPENDED = 0001b shl 2
RU_STATUS_NO_RESOURCES = 0010b shl 2
RU_STATUS_READY = 0100b shl 2
SCB_STATUS_CUS = 11000000b ; CU Status
CU_STATUS_ACTIVE = 10b shl 6
SCB_STATUS_FCP = 1 shl 8 ; Flow Control Pause
SCB_STATUS_SWI = 1 shl 10 ; Software Interrupt
SCB_STATUS_MDI = 1 shl 11 ; MDI read/write complete
@@ -185,8 +183,6 @@ struct txfd
ends
TXFD_STATUS_C = 1 shl 15
TXFD_CMD_IA = 1 shl 0
TXFD_CMD_CFG = 1 shl 1
TXFD_CMD_TX = 1 shl 2
@@ -632,9 +628,6 @@ reset:
mov ax, CU_START or INT_MASK
out dx, ax
call cmd_wait
; cmd_wait only means the SCB accepted the command. The Configure below
; reuses confcmd, so a slow chip would read it instead of our MAC.
call confcmd_wait
;-------------
; Configure CU
@@ -659,7 +652,6 @@ reset:
mov ax, CU_START ; expect Interrupts from now on
out dx, ax
call cmd_wait
call confcmd_wait
; Start media check timer
mov [ebx + device.state], ETH_LINK_DOWN
@@ -686,11 +678,6 @@ init_rx_ring:
;---------------------
; build rxfd structure
cmp [ebx + device.rx_desc], 0 ; the RFD of an earlier reset
je @f
invoke NetFree, [ebx + device.rx_desc]
mov [ebx + device.rx_desc], 0
@@:
invoke NetAlloc, 2000
test eax, eax
jz .out_of_mem
@@ -702,7 +689,6 @@ init_rx_ring:
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
ret
@@ -723,15 +709,6 @@ init_tx_ring:
invoke GetPhysAddr
mov ecx, TX_RING_SIZE
.next_desc:
; after a reset with frames still unreclaimed: free them, or transmit sees the
; descriptor busy (virt_addr) and reports TX overrun forever
cmp [esi + txfd.virt_addr], 0
je @f
push eax ecx
invoke NetFree, [esi + txfd.virt_addr]
pop ecx eax
mov [esi + txfd.virt_addr], 0
@@:
mov [esi + txfd.status], 0
mov [esi + txfd.command], 0
lea edx, [eax + txfd.buf_addr]
@@ -786,7 +763,7 @@ proc transmit stdcall bufferptr
lea edi, [ebx + device.tx_ring + eax]
; Check if current descriptor is free or still in use
cmp [edi + txfd.virt_addr], 0 ; buffer not reclaimed yet
cmp [edi + txfd.status], 0
jne .overrun
; Fill in status and command values
@@ -809,22 +786,6 @@ proc transmit stdcall bufferptr
mov eax, edi
invoke GetPhysAddr
set_io [ebx + device.io_addr], 0
; CU_START is only valid while the CU is idle or suspended:
; wait for the previous frame to leave (1.2 ms at 10 Mbit)
push eax ecx
set_io [ebx + device.io_addr], REG_SCB_STATUS
mov ecx, 100000
.cu_busy:
in al, dx
and al, SCB_STATUS_CUS
cmp al, CU_STATUS_ACTIVE
jne .cu_free
dec ecx
jnz .cu_busy
DEBUGF 2, "CU still active, starting anyway\n"
.cu_free:
pop ecx eax
set_io [ebx + device.io_addr], REG_SCB_PTR
out dx, eax
@@ -893,7 +854,7 @@ int_handler:
DEBUGF 1,"Status: %x\n", ax
test ax, SCB_STATUS_FR or SCB_STATUS_RNR ; frame received or receiver stopped?
test ax, SCB_STATUS_FR ; did we receive a frame?
jz .no_rx
push ax
@@ -940,7 +901,6 @@ int_handler:
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
; restart RX
@@ -956,22 +916,11 @@ int_handler:
mov ax, RX_START
out dx, ax
call cmd_wait
.out_of_mem:
; Hand the frame over to the kernel
jmp [EthInput]
.out_of_mem:
; The buffer is still our only RFD: drop the frame and reuse it
mov esi, [esp] ; the buffer
mov ecx, [esi + NET_BUFF.length]
dec [ebx + device.packets_rx] ; counted above, before the allocation
sub dword [ebx + device.bytes_rx], ecx
sbb dword [ebx + device.bytes_rx + 4], 0
inc [ebx + device.packets_rx_drop]
add esp, 12 ; buffer, .rx_loop, ebx
mov esi, [ebx + device.rx_desc]
jmp .not_ok
.not_ok:
; Reset the FD
mov [esi + sizeof.NET_BUFF + rxfd.status], 0
@@ -996,27 +945,6 @@ int_handler:
.no_rx_:
DEBUGF 1, "no more data\n"
; With a single RFD the receiver sits in No Resources/Suspended whenever a
; frame arrived before we re-armed it. Nothing restarts it but us.
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_SCB_STATUS
in al, dx
and al, SCB_STATUS_RUS
cmp al, RU_STATUS_READY
je .ru_ready
test byte[esp], 1 ; bit 0 of the saved status is reserved,
jnz .ru_ready ; we mark it: one restart per IRQ
or byte[esp], 1
movzx eax, al
DEBUGF 1, "Restarting receiver, RU status %x\n", eax:2
mov esi, [ebx + device.rx_desc]
push ebx
test [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C
jnz .rx_loop ; a frame completed meanwhile
add esp, 4
jmp .not_ok ; re-arm the empty RFD
.ru_ready:
pop ax
.no_rx:
@@ -1027,13 +955,13 @@ int_handler:
push eax
.loop_tx:
mov eax, [ebx + device.last_tx]
mov edx, sizeof.txfd
mul edx
mov edi, [ebx + device.last_tx]
mov eax, sizeof.txfd
mul eax
lea edi, [ebx + device.tx_ring + eax]
test [edi + txfd.status], TXFD_STATUS_C ; sent by the device?
jz .tx_done
cmp [edi + txfd.status], 0
je .tx_done
cmp [edi + txfd.virt_addr], 0
je .tx_done
@@ -1042,7 +970,6 @@ int_handler:
push [edi + txfd.virt_addr]
mov [edi + txfd.virt_addr], 0
mov [edi + txfd.status], 0 ; free for transmit again
invoke NetFree
inc [ebx + device.last_tx]
@@ -1053,6 +980,12 @@ int_handler:
pop eax
.no_tx:
test ax, RU_STATUS_NO_RESOURCES
jz .not_out_of_resources
DEBUGF 2, "Out of resources!\n"
.not_out_of_resources:
pop edi esi ebx
xor eax, eax
inc eax
@@ -1146,25 +1079,6 @@ proc check_media_mii stdcall dev:dword
endp
; Wait (up to 1 s) until the device has executed the command in confcmd.
align 4
confcmd_wait:
mov ecx, 1000 ; udelay = Sleep(1), 1 ms
.loop:
test [ebx + device.confcmd.status], TXFD_STATUS_C
jnz .done
call udelay
dec ecx
jnz .loop
movzx eax, [ebx + device.confcmd.command]
DEBUGF 2, "Command 0x%x not completed\n", eax:4
ret
.done:
movzx eax, [ebx + device.confcmd.command]
movzx ecx, [ebx + device.confcmd.status]
DEBUGF 1, "Command 0x%x done, status 0x%x\n", eax:4, ecx:4
ret
align 4
cmd_wait:
+3 -91
View File
@@ -72,26 +72,9 @@ I2CHID_PWR_ON = 0x00
; single tick forever.
MAX_POLL_ERRORS = 100
; Polls of silence before the next recovery step is tried (10 ms each).
; The ladder exists for bringing up a pad that never reports at all, and is
; compiled in only at debug level 1: on a working pad it would run merely
; because nobody touched it during the first seconds after boot, and the
; power cycle, the second reset and the poll-mode flips it consists of are
; exactly the kind of thing a fragile firmware answers with silence.
; Polls of silence before the next recovery step is tried (20 ms each).
SILENT_LIMIT = 150
; A pad that has ever answered an idle poll with an empty length, yet keeps
; returning one and the same non-empty frame, has stopped producing frames:
; a finger on the surface changes the scan time in every report, and a pad
; that holds its last frame instead of answering empty (Elan) never counts
; here. Seen on the SIPODEV SP1064: a single frame came through and was
; then repeated on every poll for good. This many identical answers in a
; row, and the device is reset and switched into touchpad mode again; the
; limit doubles on each reset, up to the maximum, so a pad that stays wedged
; is retried, not hammered.
STUCK_DUPS = 100
STUCK_DUPS_MAX = 3000
; ---------------------------- Settings -------------------------------------
; Everything below has a built-in default and can be overridden from the
; [touchpad] section of /sys/settings/system.ini. The file is read once at
@@ -1703,56 +1686,6 @@ proc set_ptp_mode uses ebx esi edi
ret
endp
; The pad has wedged (see STUCK_DUPS): drop whatever touch the driver holds,
; then bring the device up again the way setup_device did - RESET, a quiet
; wait, one read to consume the ack, SET_POWER(ON), and the touchpad mode,
; which the reset cleared. Runs in the poll thread.
proc reinit_device uses ebx esi edi
inc [StReinit]
DEBUGF 2, "i2chid: pad stuck: the same frame %u polls in a row, resetting it (%u so far)\n", [DupRun], [StReinit]
mov [DupRun], 0
mov eax, [StuckLimit]
add eax, eax
cmp eax, STUCK_DUPS_MAX
jbe @f
mov eax, STUCK_DUPS_MAX
@@:
mov [StuckLimit], eax
; Whatever the driver was in the middle of is over: no finger, no button.
call ptp_forget
mov [PrevTip], 0
mov [BtnLatch], 0
mov [HeldBtn], 0
mov [TapHold], 0
mov [TapRelease], 0
mov [PendingPress], 0
mov [DragActive], 0
invoke SetMouseData, 0, 0, 0, 0, 0
stdcall hid_command, 0, I2CHID_OP_RESET
test eax, eax
jz @f
DEBUGF 2, "i2chid: RESET failed (%x)\n", eax
@@:
mov esi, 150
invoke Sleep
stdcall dw_read_block, [SlaveAddr], 0, 0, input_buf, [MaxInput]
stdcall hid_command, I2CHID_PWR_ON, I2CHID_OP_SET_POWER
test eax, eax
jz @f
DEBUGF 2, "i2chid: post-reset SET_POWER failed (%x)\n", eax
@@:
mov esi, 10
invoke Sleep
call set_ptp_mode
mov [PollMode], 0
; The held frame is stale now; the next one the pad sends must count as new.
mov edi, prev_rep
mov ecx, MAX_INPUT_BUF
xor eax, eax
rep stosb
ret
endp
; Asks the device for every report it declared, as both an Input and a
; Feature report, and logs each answer. A pad whose sensor is alive but
; whose reporting mode was never selected will answer at least one of
@@ -1950,8 +1883,8 @@ proc i2chid_thread
test edx, edx
jnz @f
.stats:
DEBUGF 2, "i2chid: after %u polls: %u reads, %u reports, %u duplicates, %u empty, at most %u per poll, %u lifts by silence, %u resets\n", \
[StPolls], [StReads], [StReports], [StDups], [StEmpty], [StMaxDrain], [StForced], [StReinit]
DEBUGF 2, "i2chid: after %u polls: %u reads, %u reports, %u duplicates, %u empty, at most %u per poll, %u lifts by silence\n", \
[StPolls], [StReads], [StReports], [StDups], [StEmpty], [StMaxDrain], [StForced]
@@:
; Syscall 5 is the delay that sleeps on an event and yields; the Sleep import
; drivers normally use is delay_ms, which busy-waits and would burn a core.
@@ -2032,8 +1965,6 @@ proc i2chid_poll_once uses ebx esi edi
mov [GotAny], 1
mov [Consumed], 1
inc [StReports]
mov [DupRun], 0
mov [StuckLimit], STUCK_DUPS
; The first few reports are dumped raw, before any interpretation, so that a
; touchpad which does send data but whose bytes the driver reads wrongly can
; be told apart from one that says nothing at all.
@@ -2137,17 +2068,9 @@ proc i2chid_poll_once uses ebx esi edi
.duplicate:
pop eax
inc [StDups]
cmp [StEmpty], 0
je .done ; holding the last frame is this pad's idle
inc [DupRun]
mov eax, [DupRun]
cmp eax, [StuckLimit]
jb .done
call reinit_device
jmp .done
.silent:
inc [StEmpty]
mov [DupRun], 0
; Nothing arrived. An idle answer is still evidence: if the device reacts
; to a finger at all, something in those bytes changes even when it never
; sets a length, so the first answers and every change are logged.
@@ -2157,8 +2080,6 @@ proc i2chid_poll_once uses ebx esi edi
; If any of them wakes the device, GotAny freezes the ladder for good.
cmp [GotAny], 0
jnz .done
cmp [LadderOn], 0
jz .done
inc [SilentPolls]
cmp [SilentPolls], SILENT_LIMIT
jb .done
@@ -2838,15 +2759,6 @@ TraceCount dd 8
DecodeTrace dd 8
GotAny dd 0
SilentPolls dd 0
DupRun dd 0
; The bring-up ladder runs only in a level-1 (chatty) build.
if __DEBUG_LEVEL__ > 1
LadderOn dd 0
else
LadderOn dd 1
end if
StuckLimit dd STUCK_DUPS
StReinit dd 0
; Parser state (see hidmin.inc).
p_usage_page dd 0
File diff suppressed because it is too large. Load diff
+2 -1
View File
@@ -842,7 +842,8 @@ disk_scan_partitions:
cmp ebx, mbr_buffer
jz .release_partition_buffer
; 15b. If we have allocated it, free it.
stdcall kernel_free, ebx
xchg eax, ebx
call free
jmp .nothing
; 15c. Otherwise, release reference.
.release_partition_buffer:
-1
View File
@@ -4148,7 +4148,6 @@ Structure of block of data for folder entry (BDFE):
and after archiving this bit is cleared - it can be useful
for automatically creating of backup-archives as at writing
this bit is usually set
* bit 6 (mask 0x40): this is a symbolic link (currently only set by the ext driver).
* +4: dword: encoding, equals to field +8 in the information structure
* +8: 4*byte: time of file creation
* +12 = +0xC: 4*byte: date of file creation
-6
View File
@@ -212,7 +212,6 @@ DIR_DIRECTORY = 2
DIR_SYMLINK = 7
KOS_HIDDEN = 2
KOS_DIRECTORY = 10h
KOS_SYMLINK = 40h
READ_ONLY = 1
SYMLINK_MAX_DEPTH = 40
FAST_SYMLINK_MAX_SIZE = 60
@@ -3393,11 +3392,6 @@ ext_ReadFolder:
stosd
mov eax, [esi+INODE.fileSizeHigh]
stosd
movzx eax, [esi+INODE.accessMode]
and eax, TYPE_MASK
cmp eax, FLAG_SYMLINK
jne @f
or dword [edx], KOS_SYMLINK
@@:
mov esi, [esp+12]
movzx ecx, [esi+DIRENTRY.nameLength]
-28
View File
@@ -83,31 +83,6 @@ macro arp_init {
}
;-----------------------------------------------------------------;
; ;
; arp_clear_device: Empty the ARP table and counters of a removed ;
; device. ;
; ;
; IN: edi = device number * 4 ;
; ;
;-----------------------------------------------------------------;
macro arp_clear_device {
xor eax, eax
mov [ARP_entries + edi], eax
mov [ARP_packets_tx + edi], eax
mov [ARP_packets_rx + edi], eax
mov [ARP_conflicts + edi], eax
push edi
imul edi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
add edi, ARP_table
mov ecx, (ARP_TABLE_SIZE * sizeof.ARP_entry)/2
rep stosw
pop edi
}
;-----------------------------------------------------------------;
; ;
; arp_decrease_entry_ttls ;
@@ -338,9 +313,6 @@ arp_output_request:
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
[esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
test ebx, ebx ; device is gone
jz .exit
mov ax, ETHER_PROTO_ARP
mov ecx, sizeof.ARP_header
mov edx, ETH_BROADCAST ; broadcast mac
+1 -40
View File
@@ -105,29 +105,6 @@ macro ipv4_init {
}
;-----------------------------------------------------------------;
; ;
; ipv4_clear_device: Reset the IPv4 settings of a removed device, ;
; so no route points to it anymore. ;
; ;
; IN: edi = device number * 4 ;
; ;
;-----------------------------------------------------------------;
macro ipv4_clear_device {
xor eax, eax
mov [IPv4_address + edi], eax
mov [IPv4_subnet + edi], eax
mov [IPv4_nameserver + edi], eax
mov [IPv4_gateway + edi], eax
mov [IPv4_broadcast + edi], eax
mov [IPv4_packets_tx + edi], eax
mov [IPv4_packets_rx + edi], eax
mov [IPv4_packets_dumped + edi], eax
}
;-----------------------------------------------------------------;
; ;
; Decrease TimeToLive of all fragment slots ;
@@ -780,8 +757,6 @@ ipv4_output_raw:
push esi eax
call ipv4_route
test eax, eax
jz .arp_error
call arp_ip_to_mac
test eax, 0xffff0000 ; error bits
@@ -992,8 +967,6 @@ ipv4_route:
; Check for on-link
xor edi, edi
.loop:
cmp [net_device_list + edi], 0 ; skip slots without a device
je .next
mov ebx, [IPv4_address + edi]
and ebx, [IPv4_subnet + edi]
jz .next
@@ -1010,10 +983,7 @@ ipv4_route:
mov edi, 4 ; skip loopback device
.loop_gw:
cmp [IPv4_gateway + edi], 0
je .next_gw
cmp [net_device_list + edi], 0
jne .found_gw
.next_gw:
add edi, 4
cmp edi, 4*NET_DEVICES_MAX
jb .loop_gw
@@ -1079,23 +1049,14 @@ ipv4_route:
cmp eax, 0xffffffff
je @f
; An interface without an address (DHCP not done yet, or the lease
; dropped when the link went down) can send nothing but broadcasts: with
; address and mask both zero every destination compared as on-link, and
; the stack went asking ARP for internet addresses on behalf of 0.0.0.0.
test edx, edx
jz .fail
; Check if we should route to gateway or not
mov ebx, edx
mov ebx, [IPv4_address + edi]
and ebx, [IPv4_subnet + edi]
mov ecx, eax
and ecx, [IPv4_subnet + edi]
cmp ecx, ebx
je @f
mov eax, [IPv4_gateway + edi]
test eax, eax
jz .fail ; off-link and no gateway
@@:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
ret
+1 -44
View File
@@ -61,41 +61,6 @@ macro eth_init {
}
;-----------------------------------------------------------------;
; ;
; eth_clear_device: Drop the frames of a removed device that are ;
; still waiting in the input queue, their ;
; NET_BUFF.device will not be valid anymore. ;
; ;
; IN: ebx = device ptr ;
; ;
;-----------------------------------------------------------------;
macro eth_clear_device {
local .loop, .done
spin_lock_irqsave
mov esi, [ETH_frame_head]
.loop:
cmp esi, ETH_frame_head
je .done
mov eax, esi
mov esi, [esi + NET_BUFF.NextPtr]
cmp [eax + NET_BUFF.device], ebx
jne .loop
; unlink it, ETH_frame_head/tail double as the NextPtr/PrevPtr of the list head
mov ecx, [eax + NET_BUFF.PrevPtr]
mov [ecx + NET_BUFF.NextPtr], esi
mov [esi + NET_BUFF.PrevPtr], ecx
dec [ETH_frame_queued]
stdcall net_buff_free, eax
jmp .loop
.done:
spin_unlock_irqrestore
}
align 4
; This function is called by ethernet drivers.
; Push the received ethernet packet onto the ethernet input queue.
@@ -280,9 +245,6 @@ eth_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
test ebx, ebx
jz .no_device
cmp ecx, [ebx + ETH_DEVICE.mtu]
ja .too_large
@@ -333,16 +295,11 @@ eth_output:
ret
.too_large:
inc [ebx + NET_DEVICE.packets_tx_err]
inc [eax + NET_DEVICE.packets_tx_err]
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: Packet too large!\n"
xor eax, eax
ret
.no_device:
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: no device!\n"
xor eax, eax
ret
;-----------------------------------------------------------------;
-10
View File
@@ -597,16 +597,6 @@ net_remove_device:
mov dword [edi-4], eax
dec [net_device_count]
;-----------------------------------------------------------------
; Forget everything the protocols still know about this interface.
; Otherwise its IP address keeps matching in ipv4_route, and output
; ends up calling through the now empty net_device_list slot.
sub edi, net_device_list + 4 ; device number * 4
ipv4_clear_device
arp_clear_device
eth_clear_device
call net_send_event
xor eax, eax
+1 -1
View File
@@ -63,7 +63,7 @@ TCP_OPT_TIMESTAMP = 8
TCP_time_MSL = 47 ; max segment lifetime (30s)
TCP_time_re_min = 2 ; min retransmission (1,28s)
TCP_time_re_max = 100 ; max retransmission (64s)
TCP_time_pers_min = 2 ; min persist (1,28s)
TCP_time_pers_min = 8 ; min persist (5,12s)
TCP_time_pers_max = 94 ; max persist (60,16s)
TCP_time_keep_init = 118 ; connection establishment (75,52s)
TCP_time_keep_idle = 4608 ; idle time before 1st probe (2h)
+2 -12
View File
@@ -525,11 +525,8 @@ endl
test [temp_bits], TCP_BIT_TIMESTAMP
jz .no_timestamp_rtt
cmp [ebx + TCP_SOCKET.ts_ecr], 0 ; nothing echoed
je .no_timestamp_rtt
mov eax, [timestamp]
sub eax, [ebx + TCP_SOCKET.ts_ecr]
shr eax, 6 ; 1/100 s -> 640 ms ticks
inc eax
call tcp_xmit_timer
jmp .rtt_done
@@ -1117,11 +1114,8 @@ endl
test [temp_bits], TCP_BIT_TIMESTAMP
jz .timestamp_not_present
cmp [ebx + TCP_SOCKET.ts_ecr], 0 ; nothing echoed
je .timestamp_not_present
mov eax, [timestamp]
sub eax, [ebx + TCP_SOCKET.ts_ecr]
shr eax, 6 ; 1/100 s -> 640 ms ticks
inc eax
call tcp_xmit_timer
jmp .rtt_done_
@@ -1428,14 +1422,10 @@ endl
test [edx + TCP_header.Flags], TH_ACK
jz .drop
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop eax
mov eax, ebx
mov ebx, ECONNREFUSED
call tcp_drop
jmp .drop_no_socket
jmp .drop
@@:
;-----------------------------------------------------------------------------------
+9 -11
View File
@@ -234,25 +234,23 @@ endl
mov ebx, TCP_max_win
shl ebx, cl
pop ecx
; Clamp to available window first, then subtract what the peer already knows (as in BSD)
cmp ebx, ecx
jbe @f
mov ebx, ecx
@@:
sub ebx, [eax + TCP_SOCKET.RCV_ADV]
add ebx, [eax + TCP_SOCKET.RCV_NXT]
cmp ebx, ecx
jl @f
mov ebx, ecx
@@:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: we can increase window by %d bytes\n", ebx
mov edi, [eax + TCP_SOCKET.t_maxseg]
shl edi, 1
cmp ebx, edi ; signed: may be negative if window shrank
jge .send
cmp ebx, edi
jae .send
cmp ebx, SOCKET_BUFFER_SIZE/2
jge .send
jae .send
.no_window:
@@ -626,7 +624,7 @@ endl
mov [eax + TCP_SOCKET.SND_MAX], edx ; [eax + TCP_SOCKET.SND_NXT] from before we updated it
cmp [eax + TCP_SOCKET.t_rtt], 0 ; are we currently timing anything?
jne @f
je @f
mov [eax + TCP_SOCKET.t_rtt], 1 ; nope, start transmission timer
mov [eax + TCP_SOCKET.t_rtseq], edi
inc [TCPS_segstimed]
+5 -15
View File
@@ -96,7 +96,7 @@ macro tcp_init_socket socket {
mov [socket + TCP_SOCKET.t_srtt], TCP_time_srtt_default
mov [socket + TCP_SOCKET.t_rttvar], TCP_time_rtt_default * 4
mov [socket + TCP_SOCKET.t_rttmin], TCP_time_re_min
mov [socket + TCP_SOCKET.t_rxtcur], TCP_time_rtt_default
;;; TODO: TCP_time_rangeset
mov [socket + TCP_SOCKET.SND_CWND], TCP_max_win shl TCP_max_winshift
mov [socket + TCP_SOCKET.SND_SSTHRESH], TCP_max_win shl TCP_max_winshift
@@ -518,7 +518,7 @@ tcp_xmit_timer:
inc [TCPS_rttupdated]
cmp [ebx + TCP_SOCKET.t_srtt], 0 ; first sample?
cmp [ebx + TCP_SOCKET.t_rtt], 0
je .no_rtt_yet
; srtt is stored as a fixed point with 3 bits after the binary point.
@@ -534,7 +534,7 @@ tcp_xmit_timer:
pop ecx
add [ebx + TCP_SOCKET.t_srtt], eax
jg @f ; signed: delta may be negative
ja @f
mov [ebx + TCP_SOCKET.t_srtt], 1
@@:
@@ -556,10 +556,10 @@ tcp_xmit_timer:
pop edx
add [ebx + TCP_SOCKET.t_rttvar], eax
jg @f
ja @f
mov [ebx + TCP_SOCKET.t_rttvar], 1
@@:
jmp .rto
ret
.no_rtt_yet:
@@ -572,16 +572,6 @@ tcp_xmit_timer:
mov [ebx + TCP_SOCKET.t_rttvar], eax
pop ecx
.rto:
; Retransmit timeout = srtt + 4*rttvar, reset the backoff
push ecx
mov ecx, [ebx + TCP_SOCKET.t_srtt]
shr ecx, TCP_RTT_SHIFT
add ecx, [ebx + TCP_SOCKET.t_rttvar]
tcpt_rangeset [ebx + TCP_SOCKET.t_rxtcur], ecx, TCP_time_re_min, TCP_time_re_max
pop ecx
mov [ebx + TCP_SOCKET.t_rxtshift], 0
mov [ebx + TCP_SOCKET.t_rtt], 0 ; the timed segment is done
ret
-93
View File
@@ -91,10 +91,6 @@ proc tcp_timer_640ms
jne .loop
inc [eax + TCP_SOCKET.t_idle]
cmp [eax + TCP_SOCKET.t_rtt], 0 ; timing a segment?
je @f
inc [eax + TCP_SOCKET.t_rtt]
@@:
test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission
jz .check_more2
@@ -103,95 +99,6 @@ proc tcp_timer_640ms
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: Retransmission timer expired\n", eax
; Lock socket, an ACK may have stopped or restarted the timer meanwhile
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission
jz .rexmt_cancelled
cmp [eax + TCP_SOCKET.timer_retransmission], 0
jne .rexmt_cancelled
; Too many retransmissions? Drop the connection
inc [eax + TCP_SOCKET.t_rxtshift]
cmp [eax + TCP_SOCKET.t_rxtshift], TCP_max_rxtshift
jbe .rexmt
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
popa
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: too many retransmissions, dropping\n", eax
push [eax + SOCKET.NextPtr]
mov ebx, ETIMEDOUT
call tcp_drop
pop eax
jmp .check_only
.rexmt_cancelled:
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
popa
jmp .check_more2
.rexmt:
push ebx ecx edx
; Restart timer with backoff: t_rxtcur << min(t_rxtshift, 6)
mov ebx, [eax + TCP_SOCKET.t_rxtcur]
mov cl, [eax + TCP_SOCKET.t_rxtshift]
cmp cl, 6
jbe @f
mov cl, 6
@@:
shl ebx, cl
cmp ebx, TCP_time_re_min
jae @f
mov ebx, TCP_time_re_min
@@:
cmp ebx, TCP_time_re_max
jbe @f
mov ebx, TCP_time_re_max
@@:
mov [eax + TCP_SOCKET.timer_retransmission], ebx
; Resend from the last acknowledged byte, don't time it
push [eax + TCP_SOCKET.SND_UNA]
pop [eax + TCP_SOCKET.SND_NXT]
mov [eax + TCP_SOCKET.t_rtt], 0
mov [eax + TCP_SOCKET.t_dupacks], 0
; Slow start: ssthresh = max(2, min(wnd, cwnd) / 2 / mss) * mss, cwnd = mss
mov ecx, [eax + TCP_SOCKET.t_maxseg]
mov edx, [eax + TCP_SOCKET.SND_WND]
cmp edx, [eax + TCP_SOCKET.SND_CWND]
jbe @f
mov edx, [eax + TCP_SOCKET.SND_CWND]
@@:
mov ebx, eax ; socket ptr
mov eax, edx
shr eax, 1
xor edx, edx
div ecx
cmp eax, 2
jae @f
mov eax, 2
@@:
mul ecx
mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax
mov [ebx + TCP_SOCKET.SND_CWND], ecx
mov eax, ebx
pop edx ecx ebx
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
popa
push eax
call tcp_output
pop eax
-4
View File
@@ -180,8 +180,6 @@ tcp_connect:
.nomem:
pop edx eax
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
xor eax, eax
dec eax
mov ebx, ENOMEM
@@ -196,8 +194,6 @@ tcp_connect:
.enoroute:
pop eax
popa
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
xor eax, eax
dec eax
mov ebx, EADDRNOTAVAIL
+4
View File
@@ -238,6 +238,7 @@ BEGIN
m.active := FALSE;
resetTimer;
m.tid := 0;
G.destroy(m.canvas);
K.Exit
END exit;
@@ -249,6 +250,7 @@ BEGIN
resetTimer
END;
m.tid := 0;
G.destroy(m.canvas);
K.Exit
END escape;
@@ -354,6 +356,7 @@ BEGIN
END;
temp := m.tid;
m.tid := 0;
G.destroy(m.canvas);
K.ExitID(temp);
m.active := FALSE
END
@@ -509,6 +512,7 @@ BEGIN
IF m.parent # NIL THEN
temp := m.parent.tid;
m.parent.tid := 0;
G.destroy(m.parent.canvas);
K.ExitID(temp)
END;
exit(m)
@@ -1,6 +1,6 @@
#include <shell_api.h>
int shell_getc()
char shell_getc()
{
__shell_init();
@@ -9,7 +9,7 @@ int shell_getc()
__shell_shm->cmd = SHELL_GETC;
__SHELL_WAIT();
return *((int*)__shell_shm->data);
return __shell_shm->data[0];
}
else
{
@@ -1,28 +1,15 @@
#include <shell_api.h>
#include <stdio.h>
#include <string.h>
char *shell_gets(char *str, int n)
void shell_gets(char *str, int n)
{
__shell_init();
char *ptr = NULL;
if (__shell_is_init == __SHELL_INIT_OK)
{
__shell_shm->cmd = SHELL_GETS;
__SHELL_WAIT();
strncpy(str, __shell_shm->data, n);
if (__shell_shm->return_value.str == EOF || !__shell_shm->return_value.str)
{
ptr = __shell_shm->return_value.str;
}
else
{
ptr = str;
}
}
return ptr;
}
@@ -1,13 +1,12 @@
#include <shell_api.h>
#include <stdio.h>
int shell_printf(const char *format, ...)
void shell_printf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
int val = vsnprintf(__shell_shm->data, sizeof(__shell_shm->data), format, ap);
vsnprintf(__shell_shm->data, sizeof(__shell_shm->data), format, ap);
__shell_shm->cmd = SHELL_PUTS;
va_end(ap);
__SHELL_WAIT();
return val;
}
@@ -1,7 +1,7 @@
#include <shell_api.h>
#include <string.h>
size_t shell_puts(const char *str)
void shell_puts(const char *str)
{
return shell_write_string(str, strlen(str));
shell_write_string(str, strlen(str));
}
@@ -1,27 +1,22 @@
#include <shell_api.h>
#include <string.h>
size_t shell_write_string(const char *s, size_t len)
void shell_write_string(const char *s, size_t len)
{
__shell_init();
if (__shell_is_init == __SHELL_INIT_OK)
{
size_t written_bytes = 0;
if (len > sizeof(__shell_shm->data) - 1)
{
written_bytes += shell_write_string(s, sizeof(__shell_shm->data) - 1); // Outputs as much as it can.
written_bytes += shell_write_string(s + (sizeof(__shell_shm->data) - 1), len - (sizeof(__shell_shm->data) - 1)); // Outputs the rest.
shell_write_string(s, sizeof(__shell_shm->data) - 1); // Outputs as much as it can.
shell_write_string(s + (sizeof(__shell_shm->data) - 1), len - (sizeof(__shell_shm->data) - 1)); // Outputs the rest.
}
else
{
memset(__shell_shm->data, 0, sizeof(__shell_shm->data)); // without int shell show \t, \n, lose chars and other trash
memcpy(__shell_shm->data, s, len);
memset(__shell_shm->data, 0, sizeof(__shell_shm->data)); // without int shell show \t, \n, lose chars and other trash
memcpy(__shell_shm->data, s, len);
__shell_shm->cmd = SHELL_PUTS;
__SHELL_WAIT();
written_bytes += __shell_shm->return_value.written_bytes;
}
return written_bytes;
}
return 0;
}
@@ -31,15 +31,9 @@ enum __SHELL_INIT_STATE {
};
#pragma pack(push, 1)
struct return_value {
size_t written_bytes;
char* str;
};
struct shell_shm_buffer {
uint8_t cmd;
char data[SHELL_SHM_MAX - sizeof(((struct shell_shm_buffer*)NULL)->cmd) - sizeof(struct return_value)];
struct return_value return_value;
char data[SHELL_SHM_MAX - sizeof(((struct shell_shm_buffer*)NULL)->cmd)];
};
#pragma pack(pop)
@@ -57,14 +51,14 @@ __EXTERN int shell_ping();
__EXTERN unsigned shell_get_pid();
__EXTERN void shell_exit();
__EXTERN int shell_getc();
__EXTERN char* shell_gets(char* str, int n);
__EXTERN char shell_getc();
__EXTERN void shell_gets(char* str, int n);
__EXTERN void shell_putc(char c);
__EXTERN size_t shell_puts(const char* str);
__EXTERN int shell_printf(const char* format, ...);
__EXTERN void shell_puts(const char* str);
__EXTERN void shell_printf(const char* format, ...);
__EXTERN size_t shell_write_string(const char* s, size_t len);
__EXTERN void shell_write_string(const char* s, size_t len);
__EXTERN void shell_cls();
+5 -15
View File
@@ -34,8 +34,6 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
DLLAPI int puts(const char* str);
DLLAPI int printf(const char* format, ...);
@@ -52,23 +50,15 @@ typedef size_t fpos_t;
#define _FILEMODE_R 1 << 0 // Read
#define _FILEMODE_W 1 << 1 // Write
#define _FILEMODE_A 1 << 2 // Append
#define _FILEFLAG_ERR 1 << 3 // Error
#define _FILEFLAG_EOF 1 << 4 // EOF
#define _FILEMODE_PLUS 1 << 3 // Plus
typedef struct FILE_s {
char* name;
fpos_t position;
int error;
int eof;
int mode; // flags _FILEMODE_*
int __ungetc_emu_buff; // Uses __ungetc_emu (temporary solution!)
union {
struct {
bool read : 1;
bool write : 1;
bool append : 1;
bool error : 1;
bool eof : 1;
};
uint32_t val; // exist just because tcc won't optimize bitfields
} flags;
} FILE;
#define _IOFBF 0
@@ -92,7 +82,7 @@ typedef struct FILE_s {
#define TMP_MAX FOPEN_MAX
#define stderr (FILE*)3
#define stdin (FILE*)1
#define stdin (FILE*)1
#define stdout (FILE*)2
DLLAPI int fgetc(FILE*);
@@ -61,8 +61,6 @@
/* strntold() is used by vsscanf() below; include its definition first */
#include "stdlib/strntold.c"
#include "stdio/vsscanf.c"
#include "stdio/fclose_r.c"
#include "stdio/fopen_r.c"
#include "string/memccpy.c"
#include "string/memchr.c"
@@ -1,9 +0,0 @@
#ifndef __LIBC_STDIO_H
#define __LIBC_STDIO_H
#include <stdio.h>
int fclose_r(FILE* stream);
FILE* fopen_r(const char* restrict name, const char* restrict mode, FILE* restrict stream);
#endif // __LIBC_STDIO_H
@@ -1,6 +1,6 @@
#include <stdio.h>
void clearerr(FILE* stream)
{
stream->flags.val &= ~(_FILEFLAG_ERR | _FILEFLAG_EOF);
void clearerr(FILE *stream) {
stream->error = 0;
stream->eof = 0;
}
@@ -1,15 +1,8 @@
#include "_stdio.h"
#include "stddef.h"
#include <stdio.h>
#include <stdlib.h>
int fclose(FILE* stream)
{
int err = fclose_r(stream);
if (err) {
return err;
}
int fclose(FILE *stream) {
free(stream);
stream = NULL;
return 0;
@@ -1,10 +0,0 @@
#include "_stdio.h"
int fclose_r(FILE* stream)
{
if (stream->name) {
free(stream->name);
}
return 0;
}
@@ -1,6 +1,5 @@
#include <stdio.h>
int feof(FILE* stream)
{
return stream->flags.eof;
int feof(FILE *stream) {
return stream->eof;
}
@@ -1,6 +1,5 @@
#include <stdio.h>
int ferror(FILE* stream)
{
return stream->flags.error;
int ferror(FILE *stream) {
return stream->error;
}
@@ -1,22 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "_stdio.h"
FILE* fopen(const char* restrict _name, const char* restrict _mode)
{
FILE* stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
FILE* out = fopen_r(_name, _mode, stream);
if (out == NULL) {
free(stream);
}
return out;
FILE *fopen(const char *restrict _name, const char *restrict _mode) {
FILE *out = malloc(sizeof(FILE));
return freopen(_name, _mode, out);
}
@@ -1,81 +0,0 @@
#include "_stdio.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ksys.h>
#include <sys/dirent.h>
/*
Open new file
*/
FILE* fopen_r(const char* restrict _name, const char* restrict _mode, FILE* restrict out)
{
if (!_name || !_mode || !out) {
errno = EINVAL;
return NULL;
}
bool file_not_exits = false;
ksys_bdfe_t info;
{
int err = _ksys_file_get_info(_name, &info);
switch (err) {
case KSYS_FS_ERR_SUCCESS:
if (info.attributes & IS_FOLDER) {
errno = EISDIR;
return NULL;
}
break;
case KSYS_FS_ERR_5:
file_not_exits = true;
break;
default:
errno = err;
return NULL;
break;
}
}
out->flags.val = 0;
out->position = 0;
out->name = strdup(_name);
if (strchr(_mode, 'r')) {
out->flags.read = true;
if (file_not_exits) {
errno = ENOENT;
free(out->name);
return NULL;
}
}
if (strchr(_mode, 'w')) {
out->flags.write = true;
}
if (strchr(_mode, 'a')) {
out->flags.val |= _FILEMODE_W | _FILEMODE_A;
}
if (strchr(_mode, '+')) {
out->flags.val |= _FILEMODE_R | _FILEMODE_W;
}
if (out->flags.write) {
if (file_not_exits) {
int err = _ksys_file_create(_name);
if (err != KSYS_FS_ERR_SUCCESS) {
errno = err;
free(out->name);
return NULL;
}
}
}
if (out->flags.append) {
out->position = info.size;
}
return out;
}
@@ -14,7 +14,7 @@ size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict strea
if(size<=0 || nmemb<=0){
errno = EINVAL;
stream->flags.error = true;
stream->error=errno;
return 0;
}
@@ -23,7 +23,7 @@ size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict strea
return nmemb;
}
if(stream->flags.read){
if(stream->mode != _FILEMODE_W && stream->mode != _FILEMODE_A){
if(!stream->__ungetc_emu_buff){
((char*) ptr)[0]=(char)stream->__ungetc_emu_buff;
//debug_printf("Ungetc: %x\n", ((char*) ptr)[0]);
@@ -31,10 +31,10 @@ size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict strea
unsigned status = _ksys_file_read_file(stream->name, stream->position, bytes_count, ptr , &bytes_read);
if (status != KSYS_FS_ERR_SUCCESS) {
if(status == KSYS_FS_ERR_EOF){
stream->flags.eof = true;
stream->eof=1;
}else{
errno = EIO;
stream->flags.error = true;
stream->error = errno;
return 0;
}
}
@@ -1,14 +1,62 @@
#include <stddef.h>
#include <sys/ksys.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "_stdio.h"
#include <string.h>
#include <sys/dirent.h>
FILE* freopen(const char* restrict _name, const char* restrict _mode, FILE* restrict out)
{
fclose_r(out);
if (_name == NULL) {
_name = out->name;
static FILE* _set_errno(FILE *out, int err){
errno = err;
if(out){
free(out->name);
free(out);
}
out = NULL;
return out;
}
static void _create_file(char *name, FILE *out){
if(_ksys_file_create(name)){
_set_errno(out, EIO);
}
}
FILE *freopen(const char *restrict _name, const char *restrict _mode, FILE *restrict out) {
if(!_name || !_mode || !out){
return _set_errno(out, EINVAL);
}
return fopen_r(_name, _mode, out);
}
ksys_bdfe_t info;
int no_file = _ksys_file_get_info(_name, &info);
if(!no_file && info.attributes & IS_FOLDER){
return _set_errno(out, EISDIR);
}
out->eof=0;
out->error=0;
out->position=0;
out->name = strdup(_name);
if (strchr(_mode, 'r')) { out->mode = _FILEMODE_R; }
if (strchr(_mode, 'w')) { out->mode = _FILEMODE_W; }
if (strchr(_mode, 'a')) { out->mode = _FILEMODE_A; }
if (strchr(_mode, '+')) { out->mode |= _FILEMODE_PLUS; }
if(out->mode & _FILEMODE_A){
if(no_file){
_create_file(out->name, out);
}
out->position = info.size;
}else if(out->mode & _FILEMODE_W){
_create_file(out->name, out);
}else if((out->mode & _FILEMODE_R)){
if(no_file){
_set_errno(out, ENOENT);
}
}else{
_set_errno(out, EINVAL);
}
return out;
}
@@ -1,19 +1,18 @@
#include <stdio.h>
#include <sys/ksys.h>
int fseek(FILE* stream, long int offset, int whence)
{
if (whence == SEEK_SET) {
stream->position = offset;
} else if (whence == SEEK_CUR) {
stream->position += offset;
} else if (whence == SEEK_END) {
ksys_bdfe_t info;
if (_ksys_file_get_info(stream->name, &info)) {
return -1;
}
stream->position = info.size + offset;
}
stream->flags.eof = false;
int fseek(FILE *stream, long int offset, int whence) {
if (whence == SEEK_SET) {
stream->position = offset;
} else if (whence == SEEK_CUR) {
stream->position += offset;
} else if (whence == SEEK_END) {
ksys_bdfe_t info;
if (_ksys_file_get_info(stream->name, &info)) {
return -1;
}
stream->position = info.size + offset;
}
stream->eof = 0;
return 0;
}
@@ -1,8 +1,7 @@
#include <stdio.h>
int fsetpos(FILE* stream, const fpos_t* pos)
{
int fsetpos(FILE *stream, const fpos_t *pos) {
stream->position = *pos;
stream->flags.eof = false;
stream->eof = 0;
return 0;
}
@@ -16,7 +16,7 @@ size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb, FILE* restric
if (size <= 0 || nmemb <= 0) {
errno = EINVAL;
stream->flags.error = true;
stream->error = errno;
return 0;
}
@@ -33,11 +33,11 @@ size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb, FILE* restric
return nmemb;
}
if (stream->flags.write) {
if (stream->mode != _FILEMODE_R) {
unsigned status = _ksys_file_write_file(stream->name, stream->position, bytes_count, ptr, &bytes_written);
if (status != KSYS_FS_ERR_SUCCESS) {
errno = EIO;
stream->flags.error = true;
stream->error = errno;
return 0;
}
stream->position += bytes_written;
@@ -6,21 +6,22 @@ int ungetc(int c, FILE* file)
{
int res;
if (!file) {
errno = EBADF;
if(!file){
errno = EBADF;
return EOF;
}
if (file->mode != _FILEMODE_R){
errno = EACCES;
return EOF;
}
if (file->position == 0 || c == EOF)
{
errno = EOF;
return EOF;
}
if (!file->flags.read) {
errno = EACCES;
return EOF;
}
if (file->position == 0 || c == EOF) {
errno = EOF;
return EOF;
}
file->__ungetc_emu_buff = c;
file->position--;
return c;
+3 -5
View File
@@ -1618,23 +1618,21 @@ endl
; Open a new TCP socket
mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1
je .error3
test eax, eax
jz .error3
mov [socketnum], eax
DEBUGF 1, "Socket: 0x%x\n", eax
; Connect to the server
mcall connect, [socketnum], [sockaddr], 18
test eax, eax
jnz .error4
jnz .error3
DEBUGF 1, "Socket is now connected.\n"
invoke freeaddrinfo ; Free allocated memory
mov eax, [socketnum]
ret
.error4:
mcall close, [socketnum]
.error3:
DEBUGF 2, "Could not connect to the remote server\n"
invoke freeaddrinfo ; Free allocated memory
@@ -501,8 +501,7 @@ img.decode.jpg:
jnz .no_create_palette
push ecx edi
mov edi, [eax + Image.Palette]
mov eax, 0xFF000000 ; opaque, like the palettes of the other decoders:
; converted to 32 bpp, alpha 0 made the picture invisible
xor eax, eax
mov ecx, 256
@@:
stosd
+4 -9
View File
@@ -1,6 +1,5 @@
format MS COFF
public EXPORTS
include '../../../KOSfuncs.inc'
section '.flat' code readable align 16
; void __stdcall START(dword state);
DLL_ENTRY equ 1
@@ -61,7 +60,6 @@ START:
; SORT_BY_ACCESSED = 12, SORT_BY_ACCESSED_REV = 13 };
; int __stdcall sort_dir(BDFE* folder_data, unsigned num_folder_entries, sort_mode mode);
; return: 0 = ok, 1 = error
align 4
sort_dir:
cmp dword [esp+12], num_compare_fns
jae .error
@@ -75,9 +73,9 @@ sort_dir:
jz .done
cmp eax, ecx
jae .memok
push SF_SYS_MISC
push 68
pop eax
push SSF_MEM_ALLOC
push 12
pop ebx
int 0x40
test eax, eax
@@ -105,8 +103,6 @@ sort_dir:
pop ecx
mov ebx, edx
sub esp, 304
cld
align 4
.moveloop:
mov esi, [ebx]
test esi, esi
@@ -143,9 +139,9 @@ align 4
.done_free:
cmp edx, ptr_table
jz .done
push SF_SYS_MISC
push 68
pop eax
push SSF_MEM_FREE
push 13
pop ebx
mov ecx, edx
int 0x40
@@ -273,7 +269,6 @@ compare_name_rev:
stc
ret
align 4
strcmpi:
push eax
@@:
-4
View File
@@ -1,10 +1,6 @@
HISTORY:
4.1.1 (18/09/2026, Leency)
bug-fixes:
- fixed crash on deleting the whole text (Ctrl+A, Del)
4.1 (17/07/2015, Pathoswithin)
- various fixes
+3 -3
View File
@@ -5,8 +5,8 @@
; project name: TINYPAD
; compiler: flat assembler 1.67.21
; memory to compile: 3.0/9.0 MBytes (without/with size optimizations)
; version: SVN (4.1.1)
; last update: 2026-09-18 (Sep 18, 2026)
; version: SVN (4.1)
; last update: 2015-07-17 (Jul 17, 2015)
; minimal kernel: revision #4199 (https://git.kolibrios.org/KolibriOS/kolibrios/src/branch/main/kernel/trunk)
;-----------------------------------------------------------------------------
; originally by: Ville Michael Turjanmaa >> villemt@aton.co.jyu.fi
@@ -40,7 +40,7 @@ include 'tinypad.inc'
__header '01',1,@CODE,TINYPAD_END,STATIC_MEM_END,MAIN_STACK,@PARAMS,ini_path
APP_VERSION equ '4.1.1'
APP_VERSION equ '4.1'
TRUE = 1
FALSE = 0
+1 -30
View File
@@ -355,7 +355,7 @@ proc line_add_spaces ;////////////////////////////////////////////////////////
; ESI = line offset
; ECX = needed line length
; Output:
; EAX = delta, CF = 1 on failure
; EAX = delta
;-----------------------------------------------------------------------------
xor eax,eax
pushad
@@ -365,7 +365,6 @@ proc line_add_spaces ;////////////////////////////////////////////////////////
sub ecx,edx
lea eax,[ecx+sizeof.EDITOR_LINE_DATA]
call editor_realloc_lines
jc .failed
mov [esp+4*7],eax
add esi,eax
push ecx
@@ -389,26 +388,6 @@ proc line_add_spaces ;////////////////////////////////////////////////////////
rep stosb
.exit:
popad
clc
ret
.failed:
popad
stc
ret
endp
;-----------------------------------------------------------------------------
proc set_lines_terminator ;///////////////////////////////////////////////////
;-----------------------------------------------------------------------------
; Lines buffer is terminated by a line header with zero Size, restore it after
; the data has been compacted (line count decreased)
;-----------------------------------------------------------------------------
push ecx esi
mov ecx,[cur_editor.Lines.Count]
call get_line_offset
mov [esi+EDITOR_LINE_DATA.Size],0
mov [esi+EDITOR_LINE_DATA.Flags],0
pop esi ecx
ret
endp
@@ -429,7 +408,6 @@ proc delete_selection ;///////////////////////////////////////////////////////
or [esi+EDITOR_LINE_DATA.Flags],EDITOR_LINE_FLAG_MOFIFIED
mov ecx,[sel.begin.x]
call line_add_spaces
jc .abort
add esi,eax
lea edi,[esi+sizeof.EDITOR_LINE_DATA]
mov ecx,[sel.end.y]
@@ -478,8 +456,6 @@ proc delete_selection ;///////////////////////////////////////////////////////
rep movsb
.exit:
call set_lines_terminator
mov eax,[sel.begin.x]
mov [cur_editor.Caret.X],eax
mov [cur_editor.SelStart.X],eax
@@ -502,11 +478,6 @@ proc delete_selection ;///////////////////////////////////////////////////////
clc
ret
.abort:
popad
clc
ret
.exit.2:
stc
ret
-13
View File
@@ -993,30 +993,17 @@ endp
proc editor_realloc_lines ;///// ADD $DELTA$ TO LINES SIZE ///////////////////
;-----------------------------------------------------------------------------
; EAX = delta
; Output:
; EAX = buffer displacement, CF = 1 on failure (buffer left untouched)
;-----------------------------------------------------------------------------
push ebx ecx
mov ebx,[cur_editor.Lines.Size]
push ebx
add ebx,eax
mov eax,[cur_editor.Lines]
mov [cur_editor.Lines.Size],ebx
mov ecx,eax
stdcall mem.ReAlloc,eax,ebx
test eax,eax
jz .failed
add esp,4
mov [cur_editor.Lines],eax
sub eax,ecx
pop ecx ebx
clc
ret
.failed:
pop [cur_editor.Lines.Size]
xor eax,eax
pop ecx ebx
stc
ret
endp
-1
View File
@@ -237,7 +237,6 @@ proc load_from_memory ;///////////////////////////////////////////////////////
lea edx,[ebx+ecx]
imul ebx,eax,16
add ebx,edx
add ebx,sizeof.EDITOR_LINE_DATA
mov [ebp+EDITOR.Lines.Size],ebx
stdcall mem.ReAlloc,[ebp+EDITOR.Lines],ebx
mov [ebp+EDITOR.Lines],eax
-14
View File
@@ -591,12 +591,10 @@ proc key.ctrl_v ;///// PASTE ///////////////////////////////////
mov eax,[copy_size]
sub eax,sizeof.EDITOR_LINE_DATA
call editor_realloc_lines
jc .exit_1
mov ecx,[cur_editor.Caret.Y]
call get_line_offset
mov ecx,[cur_editor.Caret.X]
call line_add_spaces
jc .exit_1
pushd [esi+EDITOR_LINE_DATA.Size]
push esi
lea eax,[esi+ecx+sizeof.EDITOR_LINE_DATA]
@@ -694,7 +692,6 @@ proc key.ctrl_d ;///// INSERT SEPARATOR ////////////////////////
;---------------------------------------------------------------
mov eax,90+sizeof.EDITOR_LINE_DATA
call editor_realloc_lines
jc .exit
mov ecx,[cur_editor.Caret.Y]
call get_line_offset
@@ -751,7 +748,6 @@ proc key.ctrl_y ;///// DELETE CURRENT LINE /////////////////////
shr ecx,2
cld
rep movsd
call set_lines_terminator
pop eax
add eax,sizeof.EDITOR_LINE_DATA
@@ -1155,7 +1151,6 @@ proc key.del ;///// DELETE NEXT CHAR OR SELECTION //////////////
.ok.dec.lines:
dec [cur_editor.Lines.Count]
call set_lines_terminator
mov eax,[cur_editor.Lines.Count]
cmp [cur_editor.Caret.Y],eax
jb @f
@@ -1269,7 +1264,6 @@ proc key.tab ;///// TABULATE ///////////////////////////////////
push eax
call editor_realloc_lines
pop eax
jc .failed
mov ecx,[cur_editor.Caret.Y]
call get_line_offset
and [esi+EDITOR_LINE_DATA.Flags],not EDITOR_LINE_FLAG_SAVED
@@ -1288,7 +1282,6 @@ proc key.tab ;///// TABULATE ///////////////////////////////////
push eax
mov eax,10
call editor_realloc_lines
jc .failed.1
add esi,eax
pop eax
pushad
@@ -1339,12 +1332,6 @@ proc key.tab ;///// TABULATE ///////////////////////////////////
.exit:
ret
.failed.1:
pop eax
.failed:
add esp,4*2
ret
endp
;---------------------------------------------------------------
@@ -1355,7 +1342,6 @@ proc key.return ;///// CARRIAGE RETURN /////////////////////////
; so you should do a little more value
mov eax,14*100
call editor_realloc_lines
jc .exit
mov ecx,[cur_editor.Caret.Y]
call get_line_offset
+25 -34
View File
@@ -51,7 +51,6 @@ include '../../load_lib.mac'
include '../../dll.inc'
include '../../develop/libraries/libs-dev/libio/libio.inc'
include '../../develop/libraries/libs-dev/libimg/libimg.inc'
include '../../develop/libraries/box_lib/box_lib.mac'
;include '../../debug.inc'
@use_library mem.Alloc,mem.Free,mem.ReAlloc,dll.Load
@@ -64,16 +63,15 @@ ci_offs_skin_w equ 5 ;adjustment to the width of the skin frame
ci_offs_skin_h equ 24 ;skin height adjustment
; main window
ci_wnd_start_siz_x equ 585
ci_wnd_start_siz_y equ 400
ci_wnd_min_siz_x equ 510 ;minimum size x
ci_wnd_min_siz_y equ 180 ;minimum size y
ci_wnd_min_siz_x equ 585 ;minimum size x
ci_wnd_min_siz_y equ 400 ;minimum size y
; toolbar
ci_panel_x_pos equ 0 ;coord. x for panel
ci_panel_y_pos equ 20 ;coord. y for panel
ci_panel_but_y1 equ ci_panel_y_pos +5 ;y coordinate for 1st row of buttons
ci_panel_but_y2 equ ci_panel_y_pos+30 ;y coordinate for 2nd row of buttons
ci_palete_y_pos equ ci_panel_y_pos+51 ;y coordinate for color palette
ci_panel_zoom_x equ 178 ;x coordinate for zoom bar buttons
; editor window
@@ -82,7 +80,7 @@ ci_edit_wnd_y_pos equ 71 ;y coordinate for editor window
ci_edit_wnd_border equ 3 ;frame around the editor window
; scrolling
ci_scroll_dim equ 16 ;scroll sizes
ci_scroll_dim equ 22 ;scroll sizes
ci_scrollh_coord_x_min equ (ci_edit_wnd_x_pos+3) ;x minimum slider position
;horizontal scrolling
ci_scrollv_coord_y_min equ (ci_edit_wnd_y_pos+3) ;y minimum slider position
@@ -151,12 +149,6 @@ include 'init_data.inc'
;OpenDialog initialisation
stdcall [OpenDialog_Init], OpenDialog_data
stdcall [ColorDialog_Init], ColorDialog_data
mcall SF_REDRAW,SSF_BEGIN_DRAW
mov ebx,50 shl 16 + ci_wnd_start_siz_x
mov ecx,50 shl 16 + ci_wnd_start_siz_y
mcall SF_CREATE_WINDOW,,,0x73aabbcc,,name_of_program
mcall SF_REDRAW,SSF_END_DRAW
;---------------------------------------------------------------------
align 4
@@ -169,16 +161,16 @@ align 4
still:
mcall SF_WAIT_EVENT
cmp eax,EV_REDRAW
cmp eax,1
je red
cmp eax,EV_KEY
cmp eax,2
je keys
cmp eax,EV_BUTTON
cmp eax,3
je buttons
cmp eax,EV_MOUSE
cmp eax,6
je mouse
jmp still
@@ -194,16 +186,7 @@ copy_str_1:
jnz @b
ret
;---------------------------------------------------------------------
;description:
; move both scrollbars back to the top left corner (0,0)
align 4
scrollbar_move_00:
and [PosX],0
and [PosY],0
mov [sb_horizont.position],0
mov [sb_vertical.position],0
ret
;---------------------------------------------------------------------
include 'events.inc'
include 'events_of_window.inc'
include 'events_of_keys.inc'
include 'events_of_buttons.inc'
@@ -222,6 +205,7 @@ include 'menu.inc'
;-----------------------------------------------------------
;------------variables and data of program------------------
;-----------------------------------------------------------
;sound_havent_memory db 150,64,0
include 'lib_data.inc'
include 'panel_data.inc'
@@ -256,13 +240,6 @@ spray_cursor:
file 'cursors/spray.cur'
zoom_cursor:
file 'cursors/zoom.cur'
align 4
scroll_drag dd 0
sb_horizont scrollbar ci_wnd_start_siz_x-ci_scroll_dim-2*ci_offs_skin_w,0,\
ci_scroll_dim,ci_edit_wnd_y_pos+284, 15, 100,30,0, 0xaaaaaa, 0xcccccc,0, 1
sb_vertical scrollbar ci_scroll_dim,ci_wnd_start_siz_x-ci_scroll_dim-2*ci_offs_skin_w,\
284,ci_edit_wnd_y_pos, 15, 100,30,0, 0xaaaaaa, 0xcccccc,0, 1
;----------------------------------------------------------
align 4
IM_END:
@@ -328,6 +305,20 @@ counter2 rd 1
number_panel rd 1
number_menu rd 1
Scroll1CoordinatX rd 1 ;scroll x screen position
Scroll1CoordinatY rd 1 ;scroll y screen position
Scroll1MaxSizeX rd 1
Scroll1MaxSizeY rd 1
Scroll1SizeX rd 1 ;scroll polzunok size
Scroll1FreeX rd 1
Scroll2CoordinatX rd 1
Scroll2CoordinatY rd 1
Scroll2MaxSizeX rd 1
Scroll2MaxSizeY rd 1
Scroll2SizeY rd 1
Scroll2FreeY rd 1
x rd 1
y rd 1
@@ -375,7 +366,7 @@ filename_area rb 256
temp_dir_pach rb 4096
library_path rb 4096
cur_dir_path rb 4096
procinfo process_information
procinfo: rb 1024
align 4
syscolors rb 192
syscolors_end:
+21
View File
@@ -0,0 +1,21 @@
;----------------------------------------------------------
;---------------------sound of events----------------------
;----------------------------------------------------------
align 4
sound:
mcall SF_SPEAKER_PLAY,55
ret
;----------------------------------------------------------
;---------------------user events--------------------------
;----------------------------------------------------------
;description:
; перемещение скроллингов в левый верхний угол (0,0)
align 4
scrollbar_move_00:
and [PosX],0
and [PosY],0
mov [Scroll1CoordinatX],ci_scrollh_coord_x_min
mov [Scroll2CoordinatY],ci_scrollv_coord_y_min
ret
+78 -33
View File
@@ -1,22 +1,17 @@
;---------------------------------------------
;-------------interraction MOUSE--------------
;---------------------------------------------
align 4
mouse:
stdcall [kmainmenu_dispatch_cursorevent], [main_menu]
or ecx,-1
mcall SF_THREAD_INFO,procinfo
movzx eax,byte [procinfo.wnd_state]
mov eax,[procinfo+70] ;staus of window
test eax,100b
jne still
call GetMouseClick
bt [MouseBut],16
jnc @f
mov [scroll_drag],0
@@:
call GetMouseCoordinats
mov eax,[MouseX]
@@ -26,11 +21,6 @@ mouse:
add ecx,ci_scrollh_coord_x_min
add edx,ci_scrollv_coord_y_min
cmp [scroll_drag],1
je sb_hor_mouse
cmp [scroll_drag],2
je sb_ver_mouse
cmp eax,ecx
jae mouse_scroll
@@ -46,50 +36,105 @@ mouse_scroll:
;call GetMouseCoordinats
;interraction with horizontal scroller
movzx eax,[sb_horizont.x_pos]
movzx ebx,[sb_horizont.y_pos]
mov eax,[Scroll1CoordinatX]
mov ebx,[Scroll1CoordinatY]
mov ecx,[MouseX]
mov edx,[MouseY]
movzx esi,[sb_horizont.x_size]
movzx edi,[sb_horizont.y_size]
mov esi,[Scroll1MaxSizeX]
mov edi,[Scroll1MaxSizeY]
call columnus
test eax,eax
jz no_horizontal
bt [MouseBut],8
jnc sb_hor_mouse
mov [scroll_drag],1
sb_hor_mouse:
stdcall [scrollbar_h_mouse],sb_horizont
mov eax,[sb_horizont.position]
mov eax,ci_scrollh_coord_x_min
mov ebx,[Scroll1CoordinatY]
mov ecx,[Scroll1MaxSizeX]
inc ecx
mov edx,ci_scroll_dim-6
mov esi,7
call draw_volume_rectangle ; horizontal scrollbar clear
mov eax,[MouseX]
mov ebx,[Scroll1SizeX]
shr ebx,1
sub eax,ebx
mov ecx,[MouseX]
add ecx,ebx
mov edx,ci_scrollh_coord_x_min
add edx,[Scroll1MaxSizeX]
mov [Scroll1CoordinatX],eax
sub eax,ci_scrollh_coord_x_min
jns no_min_scroll
mov [Scroll1CoordinatX],ci_scrollh_coord_x_min
no_min_scroll:
cmp ecx,edx
jl no_max_scroll
sub edx,ebx
sub edx,ebx
mov [Scroll1CoordinatX],edx
no_max_scroll:
mov eax,[Scroll1CoordinatX]
sub eax,ci_scrollh_coord_x_min
mov ebx,[Picture_SizeX]
imul eax,ebx
mov ebx,[sb_horizont.max_area]
mov ebx,[Scroll1MaxSizeX]
cdq
idiv ebx
mov [PosX],eax
jmp no_vertical
no_horizontal:
movzx eax,[sb_vertical.x_pos]
movzx ebx,[sb_vertical.y_pos]
mov eax,[Scroll2CoordinatX]
mov ebx,[Scroll2CoordinatY]
mov ecx,[MouseX]
mov edx,[MouseY]
movzx esi,[sb_vertical.x_size]
movzx edi,[sb_vertical.y_size]
mov esi,[Scroll2MaxSizeX]
mov edi,[Scroll2MaxSizeY]
call columnus
test eax,eax
jz no_vertical
bt [MouseBut],8
jnc sb_ver_mouse
mov [scroll_drag],2
sb_ver_mouse:
stdcall [scrollbar_v_mouse],sb_vertical
mov eax,[sb_vertical.position]
mov eax,[Scroll2CoordinatX]
mov ebx,ci_scrollv_coord_y_min
mov ecx,ci_scroll_dim-6
mov edx,[Scroll2MaxSizeY]
inc edx
mov esi,7
call draw_volume_rectangle ; vertical scrollbar clear
mov eax,[MouseY]
mov ebx,[Scroll2SizeY]
shr ebx,1
sub eax,ebx
mov ecx,[MouseY]
add ecx,ebx
mov edx,ci_scrollv_coord_y_min
add edx,[Scroll2MaxSizeY]
mov [Scroll2CoordinatY],eax
sub eax,ci_scrollv_coord_y_min
jns no_min_scroll2
mov [Scroll2CoordinatY],ci_scrollv_coord_y_min
no_min_scroll2:
cmp ecx,edx
jl no_max_scroll2
sub edx,ebx
sub edx,ebx
mov [Scroll2CoordinatY],edx
no_max_scroll2:
mov eax,[Scroll2CoordinatY]
sub eax,ci_scrollv_coord_y_min
mov ebx,[Picture_SizeY]
imul eax,ebx
mov ebx,[sb_vertical.max_area]
mov ebx,[Scroll2MaxSizeY]
cdq
idiv ebx
mov [PosY],eax
+24 -20
View File
@@ -4,11 +4,12 @@
drawwin:
or ecx,-1
mcall SF_THREAD_INFO,procinfo
mov esi,procinfo
mov eax,[procinfo.box.left]
mov ebx,[procinfo.box.top]
mov ecx,[procinfo.box.width]
mov edx,[procinfo.box.height]
mov eax,[esi+process_information.box.left]
mov ebx,[esi+process_information.box.top]
mov ecx,[esi+process_information.box.width]
mov edx,[esi+process_information.box.height]
mov [Window_CordinatX],eax
mov [Window_CordinatY],ebx
@@ -22,20 +23,6 @@ drawwin:
@@:
mov [Window_SizeX],ecx
mov [Window_SizeY],edx
; keep the size alone for a rolled up window
test [procinfo.wnd_state],byte 100b
jnz .no_change
cmp ecx,[procinfo.box.width]
jne @f
cmp edx,[procinfo.box.height]
jz .no_change
@@:
push ecx edx esi
mov esi,edx
mov edx,ecx
mcall SF_CHANGE_WINDOW, -1, -1
pop esi edx ecx
.no_change:
mov [MaxWorkScreen_SizeX],ecx
mov [MaxWorkScreen_SizeY],edx
sub [MaxWorkScreen_SizeX],ci_edit_wnd_x_pos+2*ci_edit_wnd_border\
@@ -64,7 +51,7 @@ no_znak2:
add ecx, [Window_SizeY]
mcall SF_CREATE_WINDOW,,,0x73aabbcc,,name_of_program
movzx eax,byte [procinfo.wnd_state]
mov eax,[procinfo+70] ;staus of window
test eax,100b
jne .end
@@ -94,7 +81,7 @@ no_znak2:
add ebx,ci_edit_wnd_x_pos+ci_edit_wnd_border
mov edx,[Window_SizeX]
sub edx,ebx
sub edx,ci_scroll_dim+5+ci_edit_wnd_border
sub edx,ci_scroll_dim+5-ci_edit_wnd_border
shl ebx,16
mov bx,dx ;ширина бордюра
@@ -126,6 +113,23 @@ no_znak2:
;------------------------------------------------
mcall ,,<ci_edit_wnd_y_pos,ci_edit_wnd_border> ;бордюр под панелью и над окном
;------------------------------------------------
mov eax,ci_edit_wnd_x_pos
mov ebx,[Window_SizeY]
mov ecx,[Window_SizeX]
mov edx,ci_scroll_dim
mov esi,3
sub ecx,ci_scroll_dim+5+ci_edit_wnd_x_pos+ci_offs_skin_w
sub ebx,ci_scroll_dim+5+ci_offs_skin_h
call draw_volume_rectangle ; horizontal scrollbar border
;------------------------------------------------
mov eax,[Window_SizeX]
mov ebx,ci_edit_wnd_y_pos
mov ecx,ci_scroll_dim
mov edx,[Window_SizeY]
mov esi,3
sub eax,ci_scroll_dim+5+ci_offs_skin_w
sub edx,ci_scroll_dim+5+ci_edit_wnd_y_pos+ci_offs_skin_h
call draw_volume_rectangle ; vertical scrollbar border
call draw_scrollers
;------------------------------------------------
mov eax,[Window_SizeX]
+45 -5
View File
@@ -2,14 +2,12 @@
system_dir_1: db '/sys/lib/libimg.obj',0
system_dir_2 db '/sys/lib/proc_lib.obj',0
system_dir_3: db '/sys/lib/kmenu.obj',0
system_dir_4: db '/sys/lib/box_lib.obj',0
;---------------------------------------------------------------------
align 4
l_libs_start:
lib1 l_libs system_dir_1+9, library_path, system_dir_1, import_libimg
lib2 l_libs system_dir_2+9, library_path, system_dir_2, ProcLib_import
lib3 l_libs system_dir_3+9, library_path, system_dir_3, import_libkmenu
lib4 l_libs system_dir_4+9, library_path, system_dir_4, import_box_lib
end_l_libs:
;---------------------------------------------------------------------
align 4
@@ -81,7 +79,51 @@ colordialog_path:
path4 db '/sys/noname.bmp',0
;---------------------------------------------------------------------
include '../../develop/libraries/libs-dev/libimg/import.inc'
align 4
import_libimg:
dd alib_init1
img_is_img dd aimg_is_img
img_info dd aimg_info
img_from_file dd aimg_from_file
img_to_file dd aimg_to_file
img_from_rgb dd aimg_from_rgb
img_to_rgb dd aimg_to_rgb
img_to_rgb2 dd aimg_to_rgb2
img_decode dd aimg_decode
img_encode dd aimg_encode
img_create dd aimg_create
img_destroy dd aimg_destroy
img_destroy_layer dd aimg_destroy_layer
img_count dd aimg_count
img_lock_bits dd aimg_lock_bits
img_unlock_bits dd aimg_unlock_bits
img_flip dd aimg_flip
img_flip_layer dd aimg_flip_layer
img_rotate dd aimg_rotate
img_rotate_layer dd aimg_rotate_layer
img_draw dd aimg_draw
dd 0,0
alib_init1 db 'lib_init',0
aimg_is_img db 'img_is_img',0
aimg_info db 'img_info',0
aimg_from_file db 'img_from_file',0
aimg_to_file db 'img_to_file',0
aimg_from_rgb db 'img_from_rgb',0
aimg_to_rgb db 'img_to_rgb',0
aimg_to_rgb2 db 'img_to_rgb2',0
aimg_decode db 'img_decode',0
aimg_encode db 'img_encode',0
aimg_create db 'img_create',0
aimg_destroy db 'img_destroy',0
aimg_destroy_layer db 'img_destroy_layer',0
aimg_count db 'img_count',0
aimg_lock_bits db 'img_lock_bits',0
aimg_unlock_bits db 'img_unlock_bits',0
aimg_flip db 'img_flip',0
aimg_flip_layer db 'img_flip_layer',0
aimg_rotate db 'img_rotate',0
aimg_rotate_layer db 'img_rotate_layer',0
aimg_draw db 'img_draw',0
align 4
ProcLib_import:
@@ -121,6 +163,4 @@ dd 0,0
akmenuitem_new db 'kmenuitem_new',0
akmenuitem_delete db 'kmenuitem_delete',0
akmenuitem_draw db 'kmenuitem_draw',0
include '../../develop/libraries/box_lib/import.inc'
;---------------------------------------------------------------------
+1 -1
View File
@@ -1,7 +1,7 @@
;**********************************************************
;------------------TEXT DATA-------------------------------
;**********************************************************
name_of_program db 'ANIMAGE graphics editor v1.53',0
name_of_program db 'ANIMAGE graphics editor v1.52',0
mouse_pos_x db 'X='
mouse_pos_y db 'Y='
new_text1 db 'PICTURE SIZE X'
+26 -17
View File
@@ -58,16 +58,18 @@ PrintMousePos:
;----------------------------------------------------------
;------------draw lines of scoll---------------------------
;----------------------------------------------------------
align 4
draw_scrollers:
mov edi,[CounterX]
mov eax,[Scroll1CoordinatX]
mov ebx,[Window_SizeY]
sub ebx,ci_scroll_dim+5+ci_offs_skin_h
sub ebx,(ci_scroll_dim-3)+5+ci_offs_skin_h
mov ecx,[Window_SizeX]
sub ecx,ci_scroll_dim+2+ci_scrollh_coord_x_min+ci_offs_skin_w
mov [sb_horizont.y_pos],bx
mov [sb_horizont.max_area],ecx
mov [sb_horizont.x_size],cx
sub ecx,ci_scroll_dim+5+4+ci_scrollh_coord_x_min+ci_offs_skin_w
mov edx,ci_scroll_dim-6
mov esi,1
mov [Scroll1CoordinatY],ebx
mov [Scroll1MaxSizeY],edx
mov [Scroll1MaxSizeX],ecx
imul ecx,edi
push eax ebx edx
mov eax,ecx
@@ -76,15 +78,22 @@ draw_scrollers:
idiv ebx
mov ecx,eax
pop edx ebx eax
mov [sb_horizont.cur_area],ecx
mov [Scroll1SizeX],ecx
mov edi,[Scroll1MaxSizeX]
sub edi,ecx
mov [Scroll1FreeX],edi
call draw_volume_rectangle ; horizontal scrollbar polzunok
mov eax,[Window_SizeX]
sub eax,ci_scroll_dim+5+ci_offs_skin_w
sub eax,(ci_scroll_dim-3)+5+ci_offs_skin_w
mov ebx,[Scroll2CoordinatY]
mov ecx,ci_scroll_dim-6
mov edx,[Window_SizeY]
sub edx,ci_scroll_dim+2+ci_scrollv_coord_y_min+ci_offs_skin_h
mov [sb_vertical.x_pos],ax
mov [sb_vertical.max_area],edx
mov [sb_vertical.y_size],dx
sub edx,ci_scroll_dim+5+4+ci_scrollv_coord_y_min+ci_offs_skin_h
mov esi,1
mov [Scroll2CoordinatX],eax
mov [Scroll2MaxSizeX],ecx
mov [Scroll2MaxSizeY],edx
imul edx,[CounterY]
push eax ebx
@@ -94,12 +103,12 @@ draw_scrollers:
idiv ebx
mov edx,eax
pop ebx eax
mov [sb_vertical.cur_area],edx
mov [Scroll2SizeY],edx
mov edi,[Scroll2MaxSizeY]
sub edi,edx
mov [Scroll2FreeY],edi
call draw_volume_rectangle ; vertical scrollbar polzunok
mov [sb_vertical.all_redraw],1
stdcall [scrollbar_v_draw],sb_vertical
mov [sb_horizont.all_redraw],1
stdcall [scrollbar_h_draw],sb_horizont
ret
button_menu_size_x dd 0
+21 -97
View File
@@ -14,7 +14,6 @@ struct thread_data
socketnum dd ? ; Commands socket
state dd ? ; disconnected/logging in/logged in/..
passivesocknum dd ? ; when in passive mode, this is the listening socket
pasv_ports_left dd ? ; ports left to try for the current PASV
datasocketnum dd ? ; socket used for data transfers
permissions dd ? ; read/write/execute/....
buffer_ptr dd ?
@@ -137,48 +136,12 @@ socketerror:
sendFTP "425 Can't open data connection"
ret
align 4
; Close the data socket if this thread currently owns one. datasocketnum only
; holds a live socket in these two modes; in any other mode it is a handle that
; has already been closed or was never opened.
close_data_sock:
cmp [ebp + thread_data.mode], MODE_PASSIVE_OK
je @f
cmp [ebp + thread_data.mode], MODE_ACTIVE
jne .done
@@:
mov [ebp + thread_data.mode], MODE_NOTREADY
mcall close, [ebp + thread_data.datasocketnum]
mov [ebp + thread_data.datasocketnum], -1
.done:
ret
align 4
; Close the passive listening socket if one is still open. It is open only
; while waiting for the client (MODE_PASSIVE_WAIT, MODE_PASSIVE_FAILED) or after
; a failed listen, so no data connection exists and the mode drops to NOTREADY.
close_pasv_sock:
cmp [ebp + thread_data.passivesocknum], -1
je .done
mcall close, [ebp + thread_data.passivesocknum]
mov [ebp + thread_data.passivesocknum], -1
mov [ebp + thread_data.mode], MODE_NOTREADY
.done:
ret
align 4
; A data transfer failed with the file in ebx open: close the file and the data
; socket, then report the error.
transfer_error:
invoke file.close, ebx
call close_data_sock
jmp socketerror
align 4
abort_transfer:
and [ebp + thread_data.permissions], not ABORT
mov [ebp + thread_data.mode], MODE_NOTREADY
invoke file.close, ebx
call close_data_sock
mcall close, [ebp + thread_data.datasocketnum]
sendFTP "530 Transfer aborted"
ret
@@ -364,7 +327,7 @@ open_datasock:
.pasv_ok:
mov [ebp + thread_data.datasocketnum], eax
mov [ebp + thread_data.mode], MODE_PASSIVE_OK
mcall close, [ebp + thread_data.passivesocknum]
mcall close ; [ebp + thread_data.passivesocknum]
mov [ebp + thread_data.passivesocknum], -1
invoke con_write_asciiz, str_datasock
@@ -728,13 +691,13 @@ cmdLIST:
mcall send
; close the data socket..
call close_data_sock
mov [ebp + thread_data.mode], MODE_NOTREADY
mcall close, [ebp + thread_data.datasocketnum]
sendFTP "226 List OK"
ret
.nosuchdir:
call close_data_sock
sendFTP "550 Directory does not exist"
ret
@@ -830,9 +793,10 @@ cmdPASS:
align 4
cmdPASV:
; Drop whatever data connection the previous PASV/PORT left behind
call close_data_sock
call close_pasv_sock
; cmp [ebp + thread_data.passivesocknum], -1
; je @f
; mcall close, [ebp + thread_data.passivesocknum] ; if there is still a socket open, close it
; @@:
; Open a new TCP socket
mcall socket, AF_INET4, SOCK_STREAM, 0
@@ -848,13 +812,7 @@ cmdPASV:
lea edx, [ebp + thread_data.datasock]
mov esi, sizeof.thread_data.datasock
movzx eax, word [pasv_end]
movzx ebx, word [pasv_start]
sub eax, ebx
inc eax
mov [ebp + thread_data.pasv_ports_left], eax ; number of ports in the range
.next_port:
.next_port: ; TODO: break the endless loop
call nextpasvport
mov ax, [pasv_port]
xchg al, ah
@@ -862,23 +820,12 @@ cmdPASV:
mcall bind
cmp eax, -1
jne .bound
dec dword [ebp + thread_data.pasv_ports_left] ; only count a port once bind failed
jnz .next_port
; No usable port: the range is exhausted, or listen() refused the bound one.
; Give up instead of spinning, and drop the socket before answering 425.
.fail:
call close_data_sock
call close_pasv_sock
jmp socketerror
.bound:
je .next_port
; And set it to listen!
mcall listen, , 1
cmp eax, -1
je .fail
je socketerror
; Tell our thread we are ready to accept incoming calls
mov [ebp + thread_data.mode], MODE_PASSIVE_WAIT
@@ -985,10 +932,6 @@ cmdPWD:
align 4
cmdPORT:
; Drop whatever data connection the previous PASV/PORT left behind
call close_data_sock
call close_pasv_sock
; PORT a1,a2,a3,a4,p1,p2
; IP address a1.a2.a3.a4, port p1*256+p2
@@ -1029,8 +972,7 @@ align 4
cmdQUIT:
sendFTP "221 Bye!"
call close_data_sock
call close_pasv_sock
mcall close, [ebp + thread_data.datasocketnum]
mcall close, [ebp + thread_data.socketnum]
add esp, 4 ; get rid of call return address
@@ -1093,7 +1035,7 @@ cmdRETR:
lea eax, [ebp + thread_data.buffer] ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
invoke file.read, ebx, eax, BUFFERSIZE
cmp eax, -1
je .read_error ; FIXME: this is not the correct error
je .cannot_open ; FIXME: this is not the correct error
push eax
invoke con_write_asciiz, str2
@@ -1107,7 +1049,7 @@ cmdRETR:
mcall send
pop ebx ecx
cmp eax, -1
je transfer_error ; FIXME: not the correct error
je socketerror ; FIXME: not the correct error
; cmp eax, ecx
; jne not_all_byes_sent ; TODO
@@ -1119,15 +1061,13 @@ cmdRETR:
invoke con_write_asciiz, str2b
call close_data_sock
mov [ebp + thread_data.mode], MODE_NOTREADY
mcall close, [ebp + thread_data.datasocketnum]
sendFTP "226 Transfer OK, closing connection"
ret
.read_error:
invoke file.close, ebx
.cannot_open:
call close_data_sock
invoke con_set_flags, 0x0c
invoke con_write_asciiz, str_notfound
invoke con_set_flags, 0x07
@@ -1186,14 +1126,7 @@ cmdSTOR:
test eax, eax
jz .cannot_open
; STOR replaces the file: drop the previous, possibly longer contents
push eax
invoke file.truncate, eax
pop ebx
test eax, eax
js .truncate_error
push ebx
sendFTP "150 Here it comes.."
pop ebx
@@ -1209,7 +1142,7 @@ cmdSTOR:
mcall recv
pop ebx ecx
cmp eax, -1
je transfer_error ; FIXME: not the correct error
je socketerror ; FIXME: not the correct error
test eax, eax
jz @f
@@ -1221,7 +1154,7 @@ cmdSTOR:
pop edx
cmp eax, -1
je .write_error ; FIXME: this is not the correct error
je .cannot_open ; FIXME: this is not the correct error
invoke con_write_asciiz, str2
@@ -1237,7 +1170,8 @@ cmdSTOR:
invoke con_write_asciiz, str2b
call close_data_sock
mov [ebp + thread_data.mode], MODE_NOTREADY
mcall close, [ebp + thread_data.datasocketnum]
@@ -1251,20 +1185,10 @@ cmdSTOR:
sendFTP "226 Transfer OK"
ret
.write_error:
invoke file.close, ebx
.cannot_open:
call close_data_sock
sendFTP "550 No create file"
ret
.truncate_error:
invoke file.close, ebx
mov [ebp + thread_data.mode], MODE_NOTREADY
mcall close, [ebp + thread_data.datasocketnum]
sendFTP "550 Cannot truncate file"
ret
;------------------------------------------------
; "SYST"
;
+1 -11
View File
@@ -172,14 +172,6 @@ start:
invoke ini.get_int, path, str_pasv, str_end, 5000
mov [pasv_end], ax
; an inverted range would leave no port to bind, fall back to the defaults
mov ax, [pasv_start]
cmp ax, [pasv_end]
jbe @f
mov word [pasv_start], 2000
mov word [pasv_end], 5000
@@:
mov [alive], 1
mainloop:
@@ -245,7 +237,6 @@ end if
lea eax, [ebp + thread_data.buffer]
mov [ebp + thread_data.buffer_ptr], eax
mov [ebp + thread_data.passivesocknum], -1
mov [ebp + thread_data.datasocketnum], -1
sendFTP "220 Welcome to KolibriOS FTP daemon" ; fix output code
@@ -273,7 +264,7 @@ threadloop:
je .not_passive
mov [ebp + thread_data.datasocketnum], eax
mov [ebp + thread_data.mode], MODE_PASSIVE_OK
mcall close, [ebp + thread_data.passivesocknum]
mcall close ; [ebp + thread_data.passivesocknum]
mov [ebp + thread_data.passivesocknum], -1
invoke con_write_asciiz, str_datasock
@@ -456,7 +447,6 @@ import libio,\
file.open, 'file_open',\
file.read, 'file_read',\
file.write, 'file_write',\
file.truncate, 'file_truncate',\
file.close, 'file_close',\
file.find.first, 'file_find_first',\
file.find.next, 'file_find_next',\
-3
View File
@@ -1,5 +1,2 @@
if tup.getconfig("NO_FASM") ~= "" then return end
tup.rule("kpack.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "kpack")
-- Native host ports (windowless in-place compressor):
tup.rule("kpackw.asm", "fasm %f %o", "kpackw.exe") -- Windows PE
tup.rule("kpackl.asm", "fasm %f %o", "kpackl") -- Linux ELF32
-5
View File
@@ -1,5 +0,0 @@
#!/bin/bash
# Build the native Linux port of kpack (windowless, in-place compressor).
# Self-contained ELF32 - only FASM is needed, no gcc / no linker.
fasm kpackl.asm kpackl
chmod +x kpackl
-4
View File
@@ -1,4 +0,0 @@
@echo off
rem Build the native Windows port of kpack (no window, drag-and-drop compressor).
rem Requires FASM in PATH (or edit the line below to point at fasm.exe).
fasm -m 16384 kpackw.asm kpackw.exe
-795
View File
@@ -1,795 +0,0 @@
; kpackl = Kolibri Packer, native Linux port (no output, in-place compressor)
;
; Usage: kpackl <file>
; The file is compressed in place (overwritten).
; If the file name is "kernel.mnt" it is packed with the "Kernel" option
; (self-extracting KERNPACK format), otherwise the normal KPCK format is used.
; The program prints nothing; on any problem it just leaves the file alone.
;
; Self-contained ELF32 using raw Linux int 0x80 syscalls - no libc, no linker.
; Compression core (LZMA + calltrick) and the self-extractor stub are the
; original KolibriOS kpack sources by diamond; only the OS glue is new.
format ELF executable 3
entry _start
segment readable writeable executable
use_lzma = 1
use_calltrick1 = 40h
use_calltrick2 = 80h
; Linux i386 syscalls
sys_exit = 1
sys_read = 3
sys_write = 4
sys_open = 5
sys_close = 6
sys_lseek = 19
sys_mmap2 = 192
_start:
; ---- get the file argument (argv[1]) ------------------------------
mov eax, [esp] ; argc
cmp eax, 2
jb quit
mov esi, [esp+8] ; argv[1]
mov [infilename], esi
; ---- is the base name "kernel.mnt" ? ------------------------------
mov ebx, esi ; ebx = start of base name
.bn:
mov al, [esi]
test al, al
jz .bn_done
cmp al, '/'
jne .bn_n
inc esi
mov ebx, esi
jmp .bn
.bn_n:
inc esi
jmp .bn
.bn_done:
mov esi, ebx
mov edi, kernel_name
.cmpk:
mov al, [esi]
mov ah, [edi]
test ah, ah
jnz .notend
test al, al ; kernel_name ended: match iff input ended too
jz do_kerpack
jmp do_pack
.notend:
or al, 20h ; tolower (kernel_name is lowercase)
cmp al, ah
jne do_pack
inc esi
inc edi
jmp .cmpk
;=====================================================================
; helper: allocate ecx bytes -> eax = ptr, or eax = 0 on failure
;=====================================================================
alloc:
push ebx
push edx
push esi
push edi
push ebp
mov eax, sys_mmap2
xor ebx, ebx ; addr = NULL
mov edx, 3 ; PROT_READ|PROT_WRITE
mov esi, 22h ; MAP_PRIVATE|MAP_ANONYMOUS
or edi, -1 ; fd = -1
xor ebp, ebp ; offset = 0
int 0x80
pop ebp
pop edi
pop esi
pop edx
pop ebx
cmp eax, 0xFFFFF000 ; -4096..-1 == error
jb .ok
xor eax, eax
.ok:
ret
;=====================================================================
; Normal packing (KPCK)
;=====================================================================
do_pack:
; open input (O_RDONLY)
mov eax, sys_open
mov ebx, [infilename]
xor ecx, ecx
xor edx, edx
int 0x80
test eax, eax
js quit
mov [fd], eax
; size = lseek(fd, 0, SEEK_END)
mov eax, sys_lseek
mov ebx, [fd]
xor ecx, ecx
mov edx, 2
int 0x80
test eax, eax
jle quit
mov [insize], eax
; rewind
mov eax, sys_lseek
mov ebx, [fd]
xor ecx, ecx
xor edx, edx
int 0x80
; allocate infile
mov ecx, [insize]
call alloc
test eax, eax
jz quit
mov [infile], eax
; read
mov eax, sys_read
mov ebx, [fd]
mov ecx, [infile]
mov edx, [insize]
int 0x80
; close
mov eax, sys_close
mov ebx, [fd]
int 0x80
; maximum output size
mov eax, [insize]
shr eax, 3
add eax, [insize]
add eax, 400h
mov esi, eax ; esi = maxout (preserved across alloc)
add eax, eax
mov ecx, eax
call alloc
test eax, eax
jz quit
mov [outfile], eax
mov [outfile1], eax
mov [outfilebest], eax
add eax, esi
mov [outfile2], eax
; KPCK header
mov eax, [outfile1]
mov dword [eax], 'KPCK'
mov ecx, [insize]
mov [eax+4], ecx
; LZMA dictionary size
dec ecx
bsr eax, ecx
inc eax
cmp eax, 28
jb @f
mov eax, 28
@@:
push eax
push eax
call lzma_set_dict_size ; ret 4
pop ecx
mov eax, 1
shl eax, cl
; workmem
imul eax, 19
shr eax, 1
add eax, 509000h
mov ecx, eax
call alloc
test eax, eax
jz quit
mov [workmem], eax
; first pass: plain LZMA
mov eax, [outfile2]
mov [outfile], eax
xchg eax, edi
mov esi, [outfile1]
movsd
movsd
call pk_pack_lzma
mov [outsize], eax
mov eax, [outfile]
mov [outfilebest], eax
mov [method], use_lzma
; calltrick 1
call pk_preprocess_calltrick
test eax, eax
jz .noct1
call pk_set_outfile
call pk_pack_lzma
add eax, 5
cmp eax, [outsize]
jae .noct1
mov [outsize], eax
mov eax, [outfile]
mov [outfilebest], eax
mov [method], use_lzma or use_calltrick1
.noct1:
call pk_set_outfile
push dword [ctn]
movzx eax, byte [cti]
push eax
call pk_preprocess_calltrick2
test eax, eax
jz .noct2
call pk_set_outfile
call pk_pack_lzma
add eax, 5
cmp eax, [outsize]
jae .noct2
mov [outsize], eax
mov eax, [outfile]
mov [outfilebest], eax
mov [method], use_lzma or use_calltrick2
pop ecx
pop ecx
push dword [ctn]
movzx eax, byte [cti]
push eax
.noct2:
pop eax
mov [cti], al
pop eax
mov [ctn], eax
add dword [outsize], 12
mov eax, [outsize]
cmp eax, [insize]
jb .packed_ok
jmp quit ; not smaller: leave original
.packed_ok:
movzx eax, byte [method]
mov edi, [outfilebest]
mov [edi+8], eax
test al, use_calltrick1 or use_calltrick2
jz .save
mov ecx, [outsize]
add ecx, edi
mov eax, [ctn]
mov [ecx-5], eax
mov al, [cti]
mov [ecx-1], al
.save:
; open(name, O_WRONLY|O_CREAT|O_TRUNC, 0644)
mov eax, sys_open
mov ebx, [infilename]
mov ecx, 0x241
mov edx, 0x1A4
int 0x80
test eax, eax
js quit
mov [fd], eax
mov eax, sys_write
mov ebx, [fd]
mov ecx, [outfilebest]
mov edx, [outsize]
int 0x80
mov eax, sys_close
mov ebx, [fd]
int 0x80
quit:
mov eax, sys_exit
xor ebx, ebx
int 0x80
;---------------------------------------------------------------------
pk_set_outfile:
mov eax, [outfilebest]
xor eax, [outfile1]
xor eax, [outfile2]
mov [outfile], eax
ret
;---------------------------------------------------------------------
pk_pack_lzma:
mov eax, [outfile]
add eax, 11
push [workmem]
push [insize]
push eax
push [infile]
call lzma_compress ; ret 16
mov ecx, [outfile]
mov edx, [ecx+12]
bswap edx
mov [ecx+12], edx
dec eax
ret
;---------------------------------------------------------------------
pk_ct_fail:
xor eax, eax
mov [ctn], eax
ret
;---------------------------------------------------------------------
pk_preprocess_calltrick:
mov ecx, [insize]
call alloc
test eax, eax
jz pk_ct_fail
push eax
xor eax, eax
mov edi, ct1
mov ecx, 256/4
push edi
rep stosd
pop edi
mov ecx, [insize]
mov esi, [infile]
xchg eax, edx ; edx = 0
pop eax
xchg eax, ebx ; ebx = temp buffer
push ebx
.pre:
lodsb
sub al, 0E8h
cmp al, 1
ja .cont
cmp ecx, 5
jb .done
lodsd
add eax, esi
sub eax, [infile]
cmp eax, [insize]
jae .xxx
cmp eax, 1000000h
jae .xxx
sub ecx, 4
bswap eax
mov [esi-4], eax
inc edx
mov [ebx], esi
add ebx, 4
jmp .cont
.xxx:
sub esi, 4
movzx eax, byte [esi]
mov byte [eax+edi], 1
.cont:
loop .pre
.done:
mov [ctn], edx
pop edx ; edx = base of temp buffer
xor eax, eax
mov ecx, 256
repnz scasb
jnz pk_ct_fail
not cl
mov [cti], cl
@@:
cmp ebx, edx
jz @f
sub ebx, 4
mov eax, [ebx]
mov [eax-4], cl
jmp @b
@@:
mov al, 1
ret
;---------------------------------------------------------------------
pk_preprocess_calltrick2:
; restore input
mov esi, [infile]
mov ecx, [ctn]
jecxz .pre_init
.restore:
lodsb
sub al, 0E8h
cmp al, 1
ja .restore
mov al, [cti]
cmp [esi], al
jnz .restore
lodsd
mov al, 0
bswap eax
sub eax, esi
add eax, [infile]
mov [esi-4], eax
loop .restore
.pre_init:
mov ecx, [insize]
call alloc
test eax, eax
jz pk_ct_fail
mov edi, ct1
xchg eax, ebx
xor eax, eax
push edi
mov ecx, 256/4
rep stosd
pop edi
mov ecx, [insize]
mov esi, [infile]
xchg eax, edx ; edx = 0
push ebx
.pre:
lodsb
.chk0f:
cmp al, 0Fh
jnz .ip1
dec ecx
jz .done
lodsb
cmp al, 80h
jb .chk0f
cmp al, 90h
jb .take
.ip1:
sub al, 0E8h
cmp al, 1
ja .cont
.take:
cmp ecx, 5
jb .done
lodsd
add eax, esi
sub eax, [infile]
cmp eax, [insize]
jae .xxx
cmp eax, 1000000h
jae .xxx
sub ecx, 4
bswap eax
mov [esi-4], eax
inc edx
mov [ebx], esi
add ebx, 4
jmp .cont
.xxx:
sub esi, 4
movzx eax, byte [esi]
mov byte [eax+edi], 1
.cont:
loop .pre
.done:
mov [ctn], edx
pop edx
xor eax, eax
mov ecx, 256
repnz scasb
jnz pk_ct_fail
not cl
mov [cti], cl
@@:
cmp ebx, edx
jz @f
sub ebx, 4
mov eax, [ebx]
mov [eax-4], cl
jmp @b
@@:
mov al, 1
ret
;=====================================================================
; Kernel packing (self-extracting KERNPACK)
;=====================================================================
do_kerpack:
mov ecx, 300*1024*3 + 6A8000h
call alloc
test eax, eax
jz quit
mov [infile], eax
add eax, 300*1024
mov [inbuftmp], eax
add eax, 300*1024
mov [outfile], eax
add eax, 300*1024
mov [workmem], eax
; open + read
mov eax, sys_open
mov ebx, [infilename]
xor ecx, ecx
xor edx, edx
int 0x80
test eax, eax
js quit
mov [fd], eax
mov eax, sys_lseek
mov ebx, [fd]
xor ecx, ecx
mov edx, 2
int 0x80
test eax, eax
jle quit
cmp eax, 300*1024
jbe @f
mov eax, 300*1024
@@:
mov [insize3], eax
mov eax, sys_lseek
mov ebx, [fd]
xor ecx, ecx
xor edx, edx
int 0x80
mov eax, sys_read
mov ebx, [fd]
mov ecx, [infile]
mov edx, [insize3]
int 0x80
mov eax, sys_close
mov ebx, [fd]
int 0x80
; already packed?
mov ebx, [insize3]
mov edi, [infile]
add edi, ebx
cmp dword [edi-8], 'KERN'
jnz .go
cmp dword [edi-4], 'PACK'
jz quit
.go:
push 18
call lzma_set_dict_size
; find jump to 32-bit code
mov edi, [infile]
mov eax, edi
add eax, [insize3]
dec edi
.find:
cmp eax, edi
je quit ; not a kernel
inc edi
cmp dword [edi], 0xE88EE08E ; mov fs,ax / mov gs,ax
jnz .find
cmp dword [edi+4], 0x00BCD08E ; mov ss,ax / mov esp,00xxxxxx
jnz .find
add edi, 11
mov [inptr], edi
sub edi, [infile]
mov [indelta], edi
lea eax, [ebx+0x10000]
mov dword [loader_patch3+2], eax
sub ebx, edi
mov [insize1], ebx
call ker_preprocess_calltrick3
mov al, [cti]
mov [loader_patch5-1], al
mov eax, [ctn]
mov [loader_patch4+1], eax
mov eax, [inptr]
add eax, [outfile]
sub eax, [infile]
add eax, loader_size - 5
push [workmem]
push [insize1]
push eax
push [inptr]
call lzma_compress
add eax, loader_size - 5
mov [loader_patch1+6], eax
add eax, [indelta]
mov [outsize3], eax
mov eax, [indelta]
mov ecx, eax
add ecx, [outfile]
mov ecx, [ecx + loader_size - 4]
bswap ecx
mov [loader_patch2+4], ecx
add eax, 0x10000
mov [loader_patch1+1], eax
mov esi, [infile]
mov edi, [outfile]
mov ecx, [indelta]
rep movsb
mov esi, loader_start
mov ecx, loader_size
rep movsb
mov eax, [outfile]
add eax, [outsize3]
mov dword [eax], 'KERN'
mov dword [eax+4], 'PACK'
add dword [outsize3], 8
; save
mov eax, sys_open
mov ebx, [infilename]
mov ecx, 0x241
mov edx, 0x1A4
int 0x80
test eax, eax
js quit
mov [fd], eax
mov eax, sys_write
mov ebx, [fd]
mov ecx, [outfile]
mov edx, [outsize3]
int 0x80
mov eax, sys_close
mov ebx, [fd]
int 0x80
jmp quit
;---------------------------------------------------------------------
ker_preprocess_calltrick3:
mov edi, ct1
xor eax, eax
push edi
mov ecx, 256/4
rep stosd
pop edi
mov ecx, ebx ; ecx = insize1
mov esi, [inptr]
mov ebx, [inbuftmp]
xchg eax, edx ; edx = 0
.pre:
lodsb
.chk0f:
cmp al, 0Fh
jnz .ip1
dec ecx
jz .done
lodsb
cmp al, 80h
jb .chk0f
cmp al, 90h
jb .take
.ip1:
sub al, 0E8h
cmp al, 1
ja .cont
.take:
cmp ecx, 5
jb .done
lodsd
add eax, esi
sub eax, [inptr]
cmp eax, [insize1]
jae .xxx
cmp eax, 1000000h
jae .xxx
sub ecx, 4
bswap eax
mov [esi-4], eax
inc edx
mov [ebx], esi
add ebx, 4
jmp .cont
.xxx:
sub esi, 4
movzx eax, byte [esi]
mov byte [eax+edi], 1
.cont:
loop .pre
.done:
mov [ctn], edx
xor eax, eax
mov ecx, 256
repnz scasb
jnz .ret
not cl
mov [cti], cl
@@:
cmp ebx, [inbuftmp]
jz .ret
sub ebx, 4
mov eax, [ebx]
mov [eax-4], cl
jmp @b
.ret:
ret
;---------------------------------------------------------------------
; LZMA compressor and the self-extractor stub (original diamond code)
;---------------------------------------------------------------------
include 'lzma_compress.inc'
include 'lzma_set_dict_size.inc'
include 'loader_lzma.inc'
;---------------------------------------------------------------------
; initialized data
;---------------------------------------------------------------------
kernel_name db 'kernel.mnt', 0
align 4
LiteralNextStates:
db 0,0,0,0,1,2,3,4,5,6,4,5
MatchNextStates:
db 7,7,7,7,7,7,7,10,10,10,10,10
RepNextStates:
db 8,8,8,8,8,8,8,11,11,11,11,11
ShortRepNextStates:
db 9,9,9,9,9,9,9,11,11,11,11,11
align 4
method db 1
;---------------------------------------------------------------------
; uninitialized data (BSS - must stay at the very end of the segment)
;---------------------------------------------------------------------
align 4
infilename dd ?
fd dd ?
infile dd ?
outfile dd ?
outfile1 dd ?
outfile2 dd ?
outfilebest dd ?
inbuftmp dd ?
workmem dd ?
insize dd ?
outsize dd ?
insize3 dd ?
outsize3 dd ?
inptr dd ?
indelta dd ?
insize1 dd ?
ctn dd ?
cti db ?
db 0,0,0
ct1 rb 256
align 4
; LZMA compressor work area (from kpack data.inc) - referenced by name
; from lzma_compress.inc; must keep this exact layout.
_lenEncoder: rd 8451
_prices: rd 4384
rd 17
_finished: rb 1
_writeEndMark: rb 1
_longestMatchWasFound: rb 1
_previousByte: rb 1
_longestMatchLength: rd 1
g_FastPos: rb 1024
_posSlotPrices: rd 256
_isRep0Long: rd 192
distances: rd 274
_optimumCurrentIndex: rd 1
_additionalOffset: rd 1
_isRepG1: rd 12
_isMatch: rd 192
_alignPriceCount: rd 1
_numLiteralContextBits: rd 1
_literalEncoder: rd 114
nowPos64: rd 2
_distancesPrices: rd 512
_repDistances: rd 4
_posSlotEncoder: rd 1028
lastPosSlotFillingPos: rd 2
_numFastBytes: rd 1
_posStateMask: rd 1
_isRepG0: rd 12
_repMatchLenEncoder: rd 8451
rd 4384
rd 17
_isRepG2: rd 12
_dictionarySize: rd 1
_numLiteralPosStateBits:rd 1
_distTableSize: rd 1
_optimumEndIndex: rd 1
state.State: rb 1
state.Prev1IsChar: rb 1
state.Prev2: rb 2
state.PosPrev2: rd 1
state.BackPrev2: rd 1
state.Price: rd 1
state.PosPrev: rd 1
state.BackPrev: rd 1
state.Backs: rd 4
rd 40950
_alignPrices: rd 16
_isRep: rd 12
_posAlignEncoder: rd 256
i_01: rd 1
_state: rb 1
_cache: rb 1
_state.Prev2: rb 2
_posEncoders: rd 1
_numPrevBits: rd 1
_numPosBits: rd 1
_posMask: rd 1
_posStateBits: rd 1
_range: rd 1
_cacheSize: rd 1
_cyclicBufferSize: rd 1
low: rd 2
Models: rd 512
_matchMaxLen: rd 1
pack_pos: rd 1
_cutValue: rd 1
_hash: rd 1
crc_table: rd 256
_buffer: rd 1
_pos: rd 1
_streamPos: rd 1
pack_length: rd 1
-890
View File
@@ -1,890 +0,0 @@
; kpackw = Kolibri Packer, native Windows port (no window, not even a console)
;
; Usage: drag a file onto kpackw.exe, or kpackw.exe <file>
; The file is compressed in place (overwritten).
; If the file name is "kernel.mnt" it is packed with the "Kernel" option
; (self-extracting KERNPACK format), otherwise the normal KPCK format is used.
;
; Compression core (LZMA + calltrick) and the self-extractor stub are the
; original KolibriOS kpack sources by diamond; only the OS glue is new.
format PE GUI 4.0
entry start
;=====================================================================
section '.text' code readable writeable executable
;=====================================================================
use_lzma = 1
use_calltrick1 = 40h
use_calltrick2 = 80h
start:
; ---- get command line, extract the file argument ------------------
call [GetCommandLineA]
mov esi, eax
; skip leading spaces
.skip1:
mov al, [esi]
cmp al, ' '
jne .arg0
inc esi
jmp .skip1
; skip program name (argv[0])
.arg0:
cmp byte [esi], '"'
jne .arg0_plain
inc esi
.arg0_q:
mov al, [esi]
test al, al
jz .no_arg
inc esi
cmp al, '"'
jne .arg0_q
jmp .skip2
.arg0_plain:
mov al, [esi]
test al, al
jz .no_arg
cmp al, ' '
je .skip2
inc esi
jmp .arg0_plain
; skip spaces between argv[0] and argv[1]
.skip2:
mov al, [esi]
cmp al, ' '
jne .arg1
inc esi
jmp .skip2
; read the file name argument into infilename
.arg1:
mov al, [esi]
test al, al
jz .no_arg
mov edi, infilename
cmp al, '"'
jne .arg1_plain
inc esi
.arg1_q:
mov al, [esi]
test al, al
jz .name_done
inc esi
cmp al, '"'
je .name_done
stosb
jmp .arg1_q
.arg1_plain:
mov al, [esi]
test al, al
jz .name_done
cmp al, ' '
je .name_done
inc esi
stosb
jmp .arg1_plain
.name_done:
mov byte [edi], 0
; ---- is the base name "kernel.mnt" ? ------------------------------
; find base name (after last '\' or '/')
mov esi, infilename
mov ebx, esi ; ebx = start of base name
.bn:
mov al, [esi]
test al, al
jz .bn_done
cmp al, '\'
je .bn_sep
cmp al, '/'
je .bn_sep
inc esi
jmp .bn
.bn_sep:
inc esi
mov ebx, esi
jmp .bn
.bn_done:
; case-insensitive compare ebx with "kernel.mnt"
mov esi, ebx
mov edi, kernel_name
.cmpk:
mov al, [esi]
mov ah, [edi]
test ah, ah
jnz .notend
test al, al ; kernel_name ended: match iff input ended too
jz do_kerpack
jmp do_pack
.notend:
or al, 20h ; tolower (kernel_name is lowercase)
cmp al, ah
jne do_pack
inc esi
inc edi
jmp .cmpk
.no_arg:
push 0
call [ExitProcess]
;=====================================================================
; Normal packing (KPCK) - transcribed from the KolibriOS/linux kpack
;=====================================================================
do_pack:
; open input
push 0
push 0
push 3 ; OPEN_EXISTING
push 0
push 1 ; FILE_SHARE_READ
push 80000000h ; GENERIC_READ
push infilename
call [CreateFileA]
cmp eax, -1
je quit
mov esi, eax ; handle
push 0
push esi
call [GetFileSize]
cmp eax, -1
je quit
test eax, eax
jz quit
mov [insize], eax
; allocate infile
push 4
push 3000h
push eax
push 0
call [VirtualAlloc]
test eax, eax
jz quit
mov [infile], eax
; read
push 0
push bytesdone
push [insize]
push eax
push esi
call [ReadFile]
test eax, eax
jz quit
push esi
call [CloseHandle]
; maximum output size
mov eax, [insize]
shr eax, 3
add eax, [insize]
add eax, 400h
mov esi, eax ; esi = maxout
add eax, eax ; two copies
push 4
push 3000h
push eax
push 0
call [VirtualAlloc]
test eax, eax
jz quit
mov [outfile], eax
mov [outfile1], eax
mov [outfilebest], eax
add eax, esi
mov [outfile2], eax
; KPCK header
mov eax, [outfile1]
mov dword [eax], 'KPCK'
mov ecx, [insize]
mov [eax+4], ecx
; LZMA dictionary size
dec ecx
bsr eax, ecx
inc eax
cmp eax, 28
jb @f
mov eax, 28
@@:
push eax
push eax
call lzma_set_dict_size ; ret 4 (pops one)
pop ecx ; ecx = log2(dict)
mov eax, 1
shl eax, cl
; workmem
imul eax, 19
shr eax, 1
add eax, 509000h
push 4
push 3000h
push eax
push 0
call [VirtualAlloc]
test eax, eax
jz quit
mov [workmem], eax
; first pass: plain LZMA
mov eax, [outfile2]
mov [outfile], eax
xchg eax, edi
mov esi, [outfile1]
movsd
movsd
call pk_pack_lzma
mov [outsize], eax
mov eax, [outfile]
mov [outfilebest], eax
mov [method], use_lzma
; calltrick 1
call pk_preprocess_calltrick
test eax, eax
jz .noct1
call pk_set_outfile
call pk_pack_lzma
add eax, 5
cmp eax, [outsize]
jae .noct1
mov [outsize], eax
mov eax, [outfile]
mov [outfilebest], eax
mov [method], use_lzma or use_calltrick1
.noct1:
call pk_set_outfile
push dword [ctn]
movzx eax, byte [cti]
push eax
call pk_preprocess_calltrick2
test eax, eax
jz .noct2
call pk_set_outfile
call pk_pack_lzma
add eax, 5
cmp eax, [outsize]
jae .noct2
mov [outsize], eax
mov eax, [outfile]
mov [outfilebest], eax
mov [method], use_lzma or use_calltrick2
pop ecx
pop ecx
push dword [ctn]
movzx eax, byte [cti]
push eax
.noct2:
pop eax
mov [cti], al
pop eax
mov [ctn], eax
add dword [outsize], 12
mov eax, [outsize]
cmp eax, [insize]
jb .packed_ok
jmp quit ; output not smaller: leave original untouched
.packed_ok:
movzx eax, byte [method]
mov edi, [outfilebest]
mov [edi+8], eax
test al, use_calltrick1 or use_calltrick2
jz .save
mov ecx, [outsize]
add ecx, edi
mov eax, [ctn]
mov [ecx-5], eax
mov al, [cti]
mov [ecx-1], al
.save:
push 0
push 80h ; FILE_ATTRIBUTE_NORMAL
push 2 ; CREATE_ALWAYS
push 0
push 0
push 40000000h ; GENERIC_WRITE
push infilename
call [CreateFileA]
cmp eax, -1
je quit
mov esi, eax
push 0
push bytesdone
push [outsize]
push [outfilebest]
push esi
call [WriteFile]
push esi
call [CloseHandle]
quit:
push 0
call [ExitProcess]
;---------------------------------------------------------------------
pk_set_outfile:
mov eax, [outfilebest]
xor eax, [outfile1]
xor eax, [outfile2]
mov [outfile], eax
ret
;---------------------------------------------------------------------
pk_pack_lzma:
mov eax, [outfile]
add eax, 11
push [workmem]
push [insize]
push eax
push [infile]
call lzma_compress ; ret 16
mov ecx, [outfile]
mov edx, [ecx+12]
bswap edx
mov [ecx+12], edx
dec eax
ret
;---------------------------------------------------------------------
pk_ct_fail:
xor eax, eax
mov [ctn], eax
ret
;---------------------------------------------------------------------
pk_preprocess_calltrick:
push 4
push 3000h
push [insize]
push 0
call [VirtualAlloc]
test eax, eax
jz pk_ct_fail
push eax
xor eax, eax
mov edi, ct1
mov ecx, 256/4
push edi
rep stosd
pop edi
mov ecx, [insize]
mov esi, [infile]
xchg eax, edx ; edx = 0
pop eax
xchg eax, ebx ; ebx = temp buffer
push ebx
.pre:
lodsb
sub al, 0E8h
cmp al, 1
ja .cont
cmp ecx, 5
jb .done
lodsd
add eax, esi
sub eax, [infile]
cmp eax, [insize]
jae .xxx
cmp eax, 1000000h
jae .xxx
sub ecx, 4
bswap eax
mov [esi-4], eax
inc edx
mov [ebx], esi
add ebx, 4
jmp .cont
.xxx:
sub esi, 4
movzx eax, byte [esi]
mov byte [eax+edi], 1
.cont:
loop .pre
.done:
mov [ctn], edx
pop edx ; edx = base of temp buffer
xor eax, eax
mov ecx, 256
repnz scasb
jnz pk_ct_fail
not cl
mov [cti], cl
@@:
cmp ebx, edx
jz @f
sub ebx, 4
mov eax, [ebx]
mov [eax-4], cl
jmp @b
@@:
mov al, 1
ret
;---------------------------------------------------------------------
pk_preprocess_calltrick2:
; restore input
mov esi, [infile]
mov ecx, [ctn]
jecxz .pre_init
.restore:
lodsb
sub al, 0E8h
cmp al, 1
ja .restore
mov al, [cti]
cmp [esi], al
jnz .restore
lodsd
mov al, 0
bswap eax
sub eax, esi
add eax, [infile]
mov [esi-4], eax
loop .restore
.pre_init:
push 4
push 3000h
push [insize]
push 0
call [VirtualAlloc]
test eax, eax
jz pk_ct_fail
mov edi, ct1
xchg eax, ebx
xor eax, eax
push edi
mov ecx, 256/4
rep stosd
pop edi
mov ecx, [insize]
mov esi, [infile]
xchg eax, edx ; edx = 0
push ebx
.pre:
lodsb
.chk0f:
cmp al, 0Fh
jnz .ip1
dec ecx
jz .done
lodsb
cmp al, 80h
jb .chk0f
cmp al, 90h
jb .take
.ip1:
sub al, 0E8h
cmp al, 1
ja .cont
.take:
cmp ecx, 5
jb .done
lodsd
add eax, esi
sub eax, [infile]
cmp eax, [insize]
jae .xxx
cmp eax, 1000000h
jae .xxx
sub ecx, 4
bswap eax
mov [esi-4], eax
inc edx
mov [ebx], esi
add ebx, 4
jmp .cont
.xxx:
sub esi, 4
movzx eax, byte [esi]
mov byte [eax+edi], 1
.cont:
loop .pre
.done:
mov [ctn], edx
pop edx
xor eax, eax
mov ecx, 256
repnz scasb
jnz pk_ct_fail
not cl
mov [cti], cl
@@:
cmp ebx, edx
jz @f
sub ebx, 4
mov eax, [ebx]
mov [eax-4], cl
jmp @b
@@:
mov al, 1
ret
;=====================================================================
; Kernel packing (self-extracting KERNPACK) - from kerpack.inc
;=====================================================================
do_kerpack:
push 4
push 3000h
push 300*1024*3 + 6A8000h
push 0
call [VirtualAlloc]
test eax, eax
jz quit
mov [infile], eax
add eax, 300*1024
mov [inbuftmp], eax
add eax, 300*1024
mov [outfile], eax
add eax, 300*1024
mov [workmem], eax
; open + read
push 0
push 0
push 3
push 0
push 1
push 80000000h
push infilename
call [CreateFileA]
cmp eax, -1
je quit
mov esi, eax
push 0
push esi
call [GetFileSize]
cmp eax, -1
je quit
test eax, eax
jz quit
cmp eax, 300*1024
jbe @f
mov eax, 300*1024
@@:
mov [insize3], eax
push 0
push bytesdone
push [insize3]
push [infile]
push esi
call [ReadFile]
push esi
call [CloseHandle]
; already packed?
mov ebx, [insize3]
mov edi, [infile]
add edi, ebx
cmp dword [edi-8], 'KERN'
jnz .go
cmp dword [edi-4], 'PACK'
jz quit
.go:
push 18
call lzma_set_dict_size
; find jump to 32-bit code
mov edi, [infile]
mov eax, edi
add eax, [insize3]
dec edi
.find:
cmp eax, edi
je quit ; not a kernel
inc edi
cmp dword [edi], 0xE88EE08E ; mov fs,ax / mov gs,ax
jnz .find
cmp dword [edi+4], 0x00BCD08E ; mov ss,ax / mov esp,00xxxxxx
jnz .find
add edi, 11
mov [inptr], edi
sub edi, [infile]
mov [indelta], edi
lea eax, [ebx+0x10000]
mov dword [loader_patch3+2], eax
sub ebx, edi
mov [insize1], ebx
call ker_preprocess_calltrick3
mov al, [cti]
mov [loader_patch5-1], al
mov eax, [ctn]
mov [loader_patch4+1], eax
mov eax, [inptr]
add eax, [outfile]
sub eax, [infile]
add eax, loader_size - 5
push [workmem]
push [insize1]
push eax
push [inptr]
call lzma_compress
add eax, loader_size - 5
mov [loader_patch1+6], eax
add eax, [indelta]
mov [outsize3], eax
mov eax, [indelta]
mov ecx, eax
add ecx, [outfile]
mov ecx, [ecx + loader_size - 4]
bswap ecx
mov [loader_patch2+4], ecx
add eax, 0x10000
mov [loader_patch1+1], eax
mov esi, [infile]
mov edi, [outfile]
mov ecx, [indelta]
rep movsb
mov esi, loader_start
mov ecx, loader_size
rep movsb
mov eax, [outfile]
add eax, [outsize3]
mov dword [eax], 'KERN'
mov dword [eax+4], 'PACK'
add dword [outsize3], 8
; save
push 0
push 80h
push 2
push 0
push 0
push 40000000h
push infilename
call [CreateFileA]
cmp eax, -1
je quit
mov esi, eax
push 0
push bytesdone
push [outsize3]
push [outfile]
push esi
call [WriteFile]
push esi
call [CloseHandle]
jmp quit
;---------------------------------------------------------------------
ker_preprocess_calltrick3:
mov edi, ct1
xor eax, eax
push edi
mov ecx, 256/4
rep stosd
pop edi
mov ecx, ebx ; ecx = insize1
mov esi, [inptr]
mov ebx, [inbuftmp]
xchg eax, edx ; edx = 0
.pre:
lodsb
.chk0f:
cmp al, 0Fh
jnz .ip1
dec ecx
jz .done
lodsb
cmp al, 80h
jb .chk0f
cmp al, 90h
jb .take
.ip1:
sub al, 0E8h
cmp al, 1
ja .cont
.take:
cmp ecx, 5
jb .done
lodsd
add eax, esi
sub eax, [inptr]
cmp eax, [insize1]
jae .xxx
cmp eax, 1000000h
jae .xxx
sub ecx, 4
bswap eax
mov [esi-4], eax
inc edx
mov [ebx], esi
add ebx, 4
jmp .cont
.xxx:
sub esi, 4
movzx eax, byte [esi]
mov byte [eax+edi], 1
.cont:
loop .pre
.done:
mov [ctn], edx
xor eax, eax
mov ecx, 256
repnz scasb
jnz .ret
not cl
mov [cti], cl
@@:
cmp ebx, [inbuftmp]
jz .ret
sub ebx, 4
mov eax, [ebx]
mov [eax-4], cl
jmp @b
.ret:
ret
;---------------------------------------------------------------------
; LZMA compressor and the self-extractor stub (original diamond code)
;---------------------------------------------------------------------
include 'lzma_compress.inc'
include 'lzma_set_dict_size.inc'
include 'loader_lzma.inc'
;=====================================================================
section '.data' data readable writeable
;=====================================================================
kernel_name db 'kernel.mnt', 0
align 4
; LZMA state-transition tables (constants, referenced by lzma_compress)
LiteralNextStates:
db 0,0,0,0,1,2,3,4,5,6,4,5
MatchNextStates:
db 7,7,7,7,7,7,7,10,10,10,10,10
RepNextStates:
db 8,8,8,8,8,8,8,11,11,11,11,11
ShortRepNextStates:
db 9,9,9,9,9,9,9,11,11,11,11,11
align 4
method db 1
db 0,0,0
infile dd ?
outfile dd ?
outfile1 dd ?
outfile2 dd ?
outfilebest dd ?
inbuftmp dd ?
workmem dd ?
insize dd ?
outsize dd ?
insize3 dd ?
outsize3 dd ?
inptr dd ?
indelta dd ?
insize1 dd ?
ctn dd ?
cti db ?
db 0,0,0
bytesdone dd ?
;=====================================================================
section '.bss' data readable writeable
;=====================================================================
infilename rb 1024
ct1 rb 256
align 4
;---------------------------------------------------------------------
; LZMA compressor work area (from kpack data.inc) - referenced by name
; from lzma_compress.inc; must keep this exact layout.
;---------------------------------------------------------------------
_lenEncoder: rd 8451
_prices: rd 4384
rd 17
_finished: rb 1
_writeEndMark: rb 1
_longestMatchWasFound: rb 1
_previousByte: rb 1
_longestMatchLength: rd 1
g_FastPos: rb 1024
_posSlotPrices: rd 256
_isRep0Long: rd 192
distances: rd 274
_optimumCurrentIndex: rd 1
_additionalOffset: rd 1
_isRepG1: rd 12
_isMatch: rd 192
_alignPriceCount: rd 1
_numLiteralContextBits: rd 1
_literalEncoder: rd 114
nowPos64: rd 2
_distancesPrices: rd 512
_repDistances: rd 4
_posSlotEncoder: rd 1028
lastPosSlotFillingPos: rd 2
_numFastBytes: rd 1
_posStateMask: rd 1
_isRepG0: rd 12
_repMatchLenEncoder: rd 8451
rd 4384
rd 17
_isRepG2: rd 12
_dictionarySize: rd 1
_numLiteralPosStateBits:rd 1
_distTableSize: rd 1
_optimumEndIndex: rd 1
state.State: rb 1
state.Prev1IsChar: rb 1
state.Prev2: rb 2
state.PosPrev2: rd 1
state.BackPrev2: rd 1
state.Price: rd 1
state.PosPrev: rd 1
state.BackPrev: rd 1
state.Backs: rd 4
rd 40950
_alignPrices: rd 16
_isRep: rd 12
_posAlignEncoder: rd 256
i_01: rd 1
_state: rb 1
_cache: rb 1
_state.Prev2: rb 2
_posEncoders: rd 1
_numPrevBits: rd 1
_numPosBits: rd 1
_posMask: rd 1
_posStateBits: rd 1
_range: rd 1
_cacheSize: rd 1
_cyclicBufferSize: rd 1
low: rd 2
Models: rd 512
_matchMaxLen: rd 1
pack_pos: rd 1
_cutValue: rd 1
_hash: rd 1
crc_table: rd 256
_buffer: rd 1
_pos: rd 1
_streamPos: rd 1
pack_length: rd 1
;=====================================================================
section '.idata' import data readable writeable
;=====================================================================
dd 0,0,0, RVA kernel_txt, RVA kernel_iat
dd 0,0,0, 0, 0
kernel_iat:
GetCommandLineA dd RVA _GetCommandLineA
CreateFileA dd RVA _CreateFileA
GetFileSize dd RVA _GetFileSize
ReadFile dd RVA _ReadFile
WriteFile dd RVA _WriteFile
CloseHandle dd RVA _CloseHandle
VirtualAlloc dd RVA _VirtualAlloc
VirtualFree dd RVA _VirtualFree
ExitProcess dd RVA _ExitProcess
dd 0
kernel_txt db 'KERNEL32.DLL', 0
align 2
_GetCommandLineA dw 0
db 'GetCommandLineA', 0
_CreateFileA dw 0
db 'CreateFileA', 0
_GetFileSize dw 0
db 'GetFileSize', 0
_ReadFile dw 0
db 'ReadFile', 0
_WriteFile dw 0
db 'WriteFile', 0
_CloseHandle dw 0
db 'CloseHandle', 0
_VirtualAlloc dw 0
db 'VirtualAlloc', 0
_VirtualFree dw 0
db 'VirtualFree', 0
_ExitProcess dw 0
db 'ExitProcess', 0
+5 -1
View File
@@ -440,6 +440,10 @@ end if
push eax
stdcall get_index
test eax, eax ; nothing selected yet: last_x/last_y are -1
jns @f
or eax, -1 ; start the search from the first item
@@:
inc eax
mov ecx, eax
@@ -455,7 +459,7 @@ end if
shl esi, 5
add esi, list
@@:
cmpe ebx, esi, @f
cmpge ebx, esi, @f ; >=, not ==: the search may start past the list end
movzx edx, byte [ebx]
stdcall downcase_char, edx
@@ -55,18 +55,17 @@ int program_console(int pid) {
break;
case SHELL_PUTS:
buffer->return_value.written_bytes = printf("%s", &buffer->data );
printf("%s", &buffer->data );
buffer->cmd = SHELL_OK;
break;
case SHELL_GETC:
*((int *)buffer->data) = getch();
buffer->data[0] = (char) getch() ;
buffer->cmd = SHELL_OK;
break;
case SHELL_GETS:
buffer->return_value.str = gets(buffer->data, size - 2);
buffer->return_value.written_bytes = strlen(buffer->data);
gets(buffer->data, size - 2);
buffer->cmd = SHELL_OK;
break;
+10 -25
View File
@@ -104,26 +104,10 @@ applyKeymap:
cmp al, 9
jnc @f
push eax
push esi edi
shl eax,7
lea edi,[eax*2+eax] ; offset of the layout = index*384
cmp [keymap_file],0
jnz .loaded
mcall 68,27,keymap_path
test eax,eax
jz .fail
mov [keymap_file],eax
mov [keymap_size],edx
.loaded:
lea eax,[edi+384]
cmp eax,[keymap_size]
ja .fail
mov esi,[keymap_file]
add esi,edi
mov edi,current_keymap
mov ecx,384/4
rep movsd
pop edi esi
lea eax,[eax*2+eax]
mov [point],eax
mcall 70,get_key
mcall 21,2,1,current_keymap
inc ecx
mcall 21,,,current_keymap_shift
@@ -134,9 +118,6 @@ applyKeymap:
mcall 21,,9
@@:
ret
.fail:
pop edi esi eax
ret
;---------------------------------------------------------------
align 4
current_keymap rb 128
@@ -151,9 +132,13 @@ point2 dd 0
dd inicont
db '/sys/settings/lang.ini',0
keymap_path db '/sys/settings/keymap.key',0
keymap_file dd 0
keymap_size dd 0
get_key:
dd 0
point dd 0
dd 0
dd 384
dd current_keymap
db '/sys/settings/keymap.key',0
key_r db 0
key_r2 db 0
-3
View File
@@ -1,6 +1,3 @@
-- @taskbar loads keymap.key with f68.27, which unpacks kpack'ed files.
tup.rule("KEYMAP.KEY", "cp %f %o" .. tup.getconfig("KPACK_CMD"), "keymap.key.kpack")
if tup.getconfig("NO_FASM") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_fasm.lua")